llamagen-python 0.1.2__tar.gz → 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/.gitignore +1 -0
  2. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/PKG-INFO +1 -1
  3. llamagen_python-0.1.5/examples/quickstart.py +40 -0
  4. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/pyproject.toml +1 -1
  5. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/__init__.py +1 -1
  6. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/_http.py +12 -2
  7. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/resources/animations.py +9 -2
  8. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/resources/comics.py +9 -2
  9. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/tests/test_client.py +37 -0
  10. llamagen_python-0.1.2/Untitled.ipynb +0 -126
  11. llamagen_python-0.1.2/examples/quickstart.py +0 -17
  12. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/LICENSE +0 -0
  13. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/README.md +0 -0
  14. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/docs/RELEASE.md +0 -0
  15. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/_client.py +0 -0
  16. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/_errors.py +0 -0
  17. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/_types.py +0 -0
  18. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/_webhooks.py +0 -0
  19. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/py.typed +0 -0
  20. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/src/llamagen/resources/__init__.py +0 -0
  21. {llamagen_python-0.1.2 → llamagen_python-0.1.5}/tests/test_webhooks.py +0 -0
@@ -6,6 +6,7 @@
6
6
  /.ruff_cache/
7
7
  /.mypy_cache/
8
8
  /.venv/
9
+ /.env
9
10
  __pycache__/
10
11
  .ipynb_checkpoints/
11
12
  *.py[cod]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llamagen-python
3
- Version: 0.1.2
3
+ Version: 0.1.5
4
4
  Summary: Official Python SDK for LlamaGen Comic API and Animation API
5
5
  Project-URL: Homepage, https://llamagen.ai/comic-api
6
6
  Project-URL: Documentation, https://llamagen.ai/comic-api/docs
@@ -0,0 +1,40 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ from llamagen import LlamaGenAPIError, LlamaGenConnectionError, LlamaGenClient, LlamaGenTimeoutError
5
+
6
+
7
+ def load_dotenv(path: Path) -> None:
8
+ if not path.exists():
9
+ return
10
+
11
+ for raw_line in path.read_text(encoding="utf-8").splitlines():
12
+ line = raw_line.strip()
13
+ if not line or line.startswith("#") or "=" not in line:
14
+ continue
15
+ key, value = line.split("=", 1)
16
+ key = key.strip()
17
+ value = value.strip().strip('"').strip("'")
18
+ os.environ.setdefault(key, value)
19
+
20
+
21
+ load_dotenv(Path(__file__).resolve().parents[1] / ".env")
22
+ client = LlamaGenClient(api_key=os.environ["LLAMAGEN_API_KEY"], max_retries=5)
23
+
24
+ try:
25
+ created = client.comic.create(
26
+ {
27
+ "prompt": "A 4-panel comic about Leo finding a glowing key in a quiet library.",
28
+ "style": "manga",
29
+ "fixPanelNum": 4,
30
+ }
31
+ )
32
+ print("created:", created["id"], created.get("status"))
33
+ done = client.comic.wait_for_completion(created["id"])
34
+ print("done:", done["status"])
35
+ except LlamaGenAPIError as error:
36
+ print("LlamaGen API error:", error.status, error.data)
37
+ except LlamaGenConnectionError as error:
38
+ print("LlamaGen connection error:", error)
39
+ except LlamaGenTimeoutError as error:
40
+ print("LlamaGen timeout:", error)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "llamagen-python"
7
- version = "0.1.2"
7
+ version = "0.1.5"
8
8
  description = "Official Python SDK for LlamaGen Comic API and Animation API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -19,4 +19,4 @@ __all__ = [
19
19
  "verify_webhook_signature",
20
20
  ]
21
21
 
22
- __version__ = "0.1.2"
22
+ __version__ = "0.1.5"
@@ -10,6 +10,8 @@ from typing import Any, Dict, Mapping, Optional, Protocol, Tuple
10
10
 
11
11
  from ._errors import LlamaGenAPIError, LlamaGenConnectionError, LlamaGenTimeoutError
12
12
 
13
+ DEFAULT_USER_AGENT = "llamagen-python/0.1.5"
14
+
13
15
 
14
16
  class Transport(Protocol):
15
17
  def request(
@@ -24,6 +26,10 @@ class Transport(Protocol):
24
26
 
25
27
 
26
28
  class UrllibTransport:
29
+ def __init__(self) -> None:
30
+ self.context = ssl.create_default_context()
31
+ self.context.minimum_version = ssl.TLSVersion.TLSv1_2
32
+
27
33
  def request(
28
34
  self,
29
35
  method: str,
@@ -34,7 +40,7 @@ class UrllibTransport:
34
40
  ) -> Tuple[int, Mapping[str, str], bytes]:
35
41
  request = urllib.request.Request(url, data=body, method=method, headers=dict(headers))
36
42
  try:
37
- with urllib.request.urlopen(request, timeout=timeout) as response:
43
+ with urllib.request.urlopen(request, timeout=timeout, context=self.context) as response:
38
44
  return response.status, dict(response.headers.items()), response.read()
39
45
  except urllib.error.HTTPError as error:
40
46
  return error.code, dict(error.headers.items()), error.read()
@@ -70,7 +76,11 @@ class HTTPClient:
70
76
  if json_body is not None and body is not None:
71
77
  raise ValueError("Pass either json_body or body, not both.")
72
78
 
73
- prepared_headers: Dict[str, str] = {"Authorization": f"Bearer {self.api_key}"}
79
+ prepared_headers: Dict[str, str] = {
80
+ "Accept": "application/json",
81
+ "Authorization": f"Bearer {self.api_key}",
82
+ "User-Agent": DEFAULT_USER_AGENT,
83
+ }
74
84
  if json_body is not None:
75
85
  body = json.dumps(json_body, separators=(",", ":")).encode("utf-8")
76
86
  prepared_headers["Content-Type"] = "application/json"
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import time
4
4
  from typing import Mapping, Optional, Sequence
5
5
 
6
- from .._errors import LlamaGenTimeoutError
6
+ from .._errors import LlamaGenConnectionError, LlamaGenTimeoutError
7
7
  from .._http import HTTPClient
8
8
  from .._types import AnimationArtworkResponse
9
9
 
@@ -34,7 +34,14 @@ class AnimationsResource:
34
34
  start = time.monotonic()
35
35
 
36
36
  while True:
37
- result = self.get(artwork_id)
37
+ try:
38
+ result = self.get(artwork_id)
39
+ except (LlamaGenConnectionError, LlamaGenTimeoutError):
40
+ if (time.monotonic() - start) * 1000 >= timeout_ms:
41
+ raise
42
+ time.sleep(interval_ms / 1000)
43
+ continue
44
+
38
45
  if str(result.get("status", "")).upper() in done:
39
46
  return result
40
47
 
@@ -9,7 +9,7 @@ from pathlib import Path
9
9
  from typing import Any, BinaryIO, Dict, Iterable, List, Mapping, Optional, Sequence, Union
10
10
  from urllib.parse import urlencode
11
11
 
12
- from .._errors import LlamaGenTimeoutError
12
+ from .._errors import LlamaGenConnectionError, LlamaGenTimeoutError
13
13
  from .._http import HTTPClient
14
14
  from .._types import ComicArtworkResponse, ComicUploadResponse, ComicUsage, SUPPORTED_COMIC_SIZES
15
15
 
@@ -99,7 +99,14 @@ class ComicsResource:
99
99
  start = time.monotonic()
100
100
 
101
101
  while True:
102
- result = self.get(artwork_id)
102
+ try:
103
+ result = self.get(artwork_id)
104
+ except (LlamaGenConnectionError, LlamaGenTimeoutError):
105
+ if (time.monotonic() - start) * 1000 >= timeout_ms:
106
+ raise
107
+ time.sleep(interval_ms / 1000)
108
+ continue
109
+
103
110
  if str(result.get("status", "")).upper() in done:
104
111
  return result
105
112
 
@@ -44,6 +44,27 @@ class FailingTransport:
44
44
  raise self.errors.pop(0)
45
45
 
46
46
 
47
+ class MixedTransport:
48
+ def __init__(self, events):
49
+ self.events = list(events)
50
+ self.calls = []
51
+
52
+ def request(
53
+ self,
54
+ method: str,
55
+ url: str,
56
+ headers: Mapping[str, str],
57
+ body: Optional[bytes],
58
+ timeout: float,
59
+ ) -> Tuple[int, Mapping[str, str], bytes]:
60
+ self.calls.append({"method": method, "url": url, "headers": dict(headers), "body": body})
61
+ event = self.events.pop(0)
62
+ if isinstance(event, BaseException):
63
+ raise event
64
+ status, payload = event
65
+ return status, {"content-type": "application/json"}, json.dumps(payload).encode("utf-8")
66
+
67
+
47
68
  class ClientTests(unittest.TestCase):
48
69
  def test_create_comic_applies_defaults_and_auth(self):
49
70
  transport = FakeTransport([(200, {"id": "gen_1", "status": "PENDING"})])
@@ -56,6 +77,8 @@ class ClientTests(unittest.TestCase):
56
77
  self.assertEqual(call["method"], "POST")
57
78
  self.assertEqual(call["url"], "https://api.llamagen.ai/v1/comics/generations")
58
79
  self.assertEqual(call["headers"]["Authorization"], "Bearer test-key")
80
+ self.assertEqual(call["headers"]["Accept"], "application/json")
81
+ self.assertEqual(call["headers"]["User-Agent"], "llamagen-python/0.1.5")
59
82
  body = json.loads(call["body"].decode("utf-8"))
60
83
  self.assertEqual(body["preset"], "neutral")
61
84
  self.assertEqual(body["size"], "1024x1024")
@@ -120,6 +143,20 @@ class ClientTests(unittest.TestCase):
120
143
 
121
144
  self.assertEqual(len(transport.calls), 3)
122
145
 
146
+ def test_wait_for_completion_continues_after_transient_connection_error(self):
147
+ transport = MixedTransport(
148
+ [
149
+ urllib.error.URLError(ssl.SSLEOFError("unexpected eof")),
150
+ (200, {"id": "gen_1", "status": "SUCCEEDED"}),
151
+ ]
152
+ )
153
+ client = LlamaGenClient(api_key="test-key", max_retries=0, retry_delay_ms=1, transport=transport)
154
+
155
+ result = client.comic.wait_for_completion("gen_1", interval_ms=1, timeout_ms=1000)
156
+
157
+ self.assertEqual(result["status"], "SUCCEEDED")
158
+ self.assertEqual(len(transport.calls), 2)
159
+
123
160
 
124
161
  if __name__ == "__main__":
125
162
  unittest.main()
@@ -1,126 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 6,
6
- "id": "83b6314c-08bb-4dcb-b62b-7e362a5aa15b",
7
- "metadata": {},
8
- "outputs": [
9
- {
10
- "ename": "LlamaGenAPIError",
11
- "evalue": "LlamaGen API request failed with status 403",
12
- "output_type": "error",
13
- "traceback": [
14
- "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
15
- "\u001b[31mLlamaGenAPIError\u001b[39m Traceback (most recent call last)",
16
- "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[6]\u001b[39m\u001b[32m, line 6\u001b[39m\n\u001b[32m 2\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m llamagen \u001b[38;5;28;01mimport\u001b[39;00m LlamaGenClient\n\u001b[32m 3\u001b[39m \n\u001b[32m 4\u001b[39m llamagen = LlamaGenClient(api_key=\u001b[33m'sk-5d609cd64379d048edcb04dcc109a6cfaf7c066f12138c13c8c404766ab9629d'\u001b[39m)\n\u001b[32m 5\u001b[39m \n\u001b[32m----> \u001b[39m\u001b[32m6\u001b[39m created = llamagen.comic.create({\n\u001b[32m 7\u001b[39m \u001b[33m\"prompt\"\u001b[39m: \u001b[33m\"A 4-panel comic about Leo finding a glowing key in a quiet library.\"\u001b[39m,\n\u001b[32m 8\u001b[39m \u001b[33m\"style\"\u001b[39m: \u001b[33m\"manga\"\u001b[39m,\n\u001b[32m 9\u001b[39m \u001b[33m\"fixPanelNum\"\u001b[39m: \u001b[32m4\u001b[39m,\n",
17
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/site-packages/llamagen/resources/comics.py:35\u001b[39m, in \u001b[36mComicsResource.create\u001b[39m\u001b[34m(self, params)\u001b[39m\n\u001b[32m 33\u001b[39m body: Dict[\u001b[38;5;28mstr\u001b[39m, Any] = {\u001b[33m\"\u001b[39m\u001b[33mpreset\u001b[39m\u001b[33m\"\u001b[39m: DEFAULT_PRESET, \u001b[33m\"\u001b[39m\u001b[33msize\u001b[39m\u001b[33m\"\u001b[39m: DEFAULT_SIZE}\n\u001b[32m 34\u001b[39m body.update(params)\n\u001b[32m---> \u001b[39m\u001b[32m35\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_http\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m/comics/generations\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mmethod\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mPOST\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mjson_body\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mbody\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
18
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/site-packages/llamagen/_http.py:105\u001b[39m, in \u001b[36mHTTPClient.request\u001b[39m\u001b[34m(self, path, method, json_body, body, headers)\u001b[39m\n\u001b[32m 102\u001b[39m time.sleep(\u001b[38;5;28mself\u001b[39m.retry_delay * attempt)\n\u001b[32m 103\u001b[39m \u001b[38;5;28;01mcontinue\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m105\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m LlamaGenAPIError(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mLlamaGen API request failed with status \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mstatus\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m, status, data)\n",
19
- "\u001b[31mLlamaGenAPIError\u001b[39m: LlamaGen API request failed with status 403"
20
- ]
21
- }
22
- ],
23
- "source": [
24
- "import os\n",
25
- "from llamagen import LlamaGenClient\n",
26
- "\n",
27
- "llamagen = LlamaGenClient(api_key='sk-5d609cd64379d048edcb04dcc109a6cfaf7c066f12138c13c8c404766ab9629d')\n",
28
- "\n",
29
- "created = llamagen.comic.create({\n",
30
- " \"prompt\": \"A 4-panel comic about Leo finding a glowing key in a quiet library.\",\n",
31
- " \"style\": \"manga\",\n",
32
- " \"fixPanelNum\": 4,\n",
33
- "})\n",
34
- "\n",
35
- "done = llamagen.comic.wait_for_completion(created[\"id\"])\n",
36
- "print(done[\"status\"], done.get(\"comics\"))"
37
- ]
38
- },
39
- {
40
- "cell_type": "code",
41
- "execution_count": 7,
42
- "id": "34cf0202-a209-4f09-b16e-eca092d7a0c4",
43
- "metadata": {},
44
- "outputs": [
45
- {
46
- "ename": "URLError",
47
- "evalue": "<urlopen error [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1000)>",
48
- "output_type": "error",
49
- "traceback": [
50
- "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
51
- "\u001b[31mSSLEOFError\u001b[39m Traceback (most recent call last)",
52
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/urllib/request.py:1344\u001b[39m, in \u001b[36mAbstractHTTPHandler.do_open\u001b[39m\u001b[34m(self, http_class, req, **http_conn_args)\u001b[39m\n\u001b[32m 1343\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1344\u001b[39m \u001b[30;43mh\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mget_method\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mselector\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mdata\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mheaders\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1345\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mencode_chunked\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mhas_header\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m'\u001b[39;49m\u001b[30;43mTransfer-encoding\u001b[39;49m\u001b[30;43m'\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1346\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err: \u001b[38;5;66;03m# timeout error\u001b[39;00m\n",
53
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/http/client.py:1336\u001b[39m, in \u001b[36mHTTPConnection.request\u001b[39m\u001b[34m(self, method, url, body, headers, encode_chunked)\u001b[39m\n\u001b[32m 1335\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Send a complete request to the server.\"\"\"\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1336\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_send_request\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mmethod\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43murl\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mbody\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mheaders\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mencode_chunked\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
54
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/http/client.py:1382\u001b[39m, in \u001b[36mHTTPConnection._send_request\u001b[39m\u001b[34m(self, method, url, body, headers, encode_chunked)\u001b[39m\n\u001b[32m 1381\u001b[39m body = _encode(body, \u001b[33m'\u001b[39m\u001b[33mbody\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1382\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mendheaders\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mbody\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mencode_chunked\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mencode_chunked\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
55
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/http/client.py:1331\u001b[39m, in \u001b[36mHTTPConnection.endheaders\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1330\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CannotSendHeader()\n\u001b[32m-> \u001b[39m\u001b[32m1331\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_send_output\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mmessage_body\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mencode_chunked\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mencode_chunked\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
56
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/http/client.py:1091\u001b[39m, in \u001b[36mHTTPConnection._send_output\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1090\u001b[39m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m._buffer[:]\n\u001b[32m-> \u001b[39m\u001b[32m1091\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43msend\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mmsg\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1093\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m message_body \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 1094\u001b[39m \n\u001b[32m 1095\u001b[39m \u001b[38;5;66;03m# create a consistent interface to message_body\u001b[39;00m\n",
57
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/http/client.py:1035\u001b[39m, in \u001b[36mHTTPConnection.send\u001b[39m\u001b[34m(self, data)\u001b[39m\n\u001b[32m 1034\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.auto_open:\n\u001b[32m-> \u001b[39m\u001b[32m1035\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mconnect\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1036\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n",
58
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/http/client.py:1477\u001b[39m, in \u001b[36mHTTPSConnection.connect\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1475\u001b[39m server_hostname = \u001b[38;5;28mself\u001b[39m.host\n\u001b[32m-> \u001b[39m\u001b[32m1477\u001b[39m \u001b[38;5;28mself\u001b[39m.sock = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_context\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mwrap_socket\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43msock\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1478\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mserver_hostname\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mserver_hostname\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
59
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/ssl.py:455\u001b[39m, in \u001b[36mSSLContext.wrap_socket\u001b[39m\u001b[34m(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)\u001b[39m\n\u001b[32m 449\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mwrap_socket\u001b[39m(\u001b[38;5;28mself\u001b[39m, sock, server_side=\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[32m 450\u001b[39m do_handshake_on_connect=\u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[32m 451\u001b[39m suppress_ragged_eofs=\u001b[38;5;28;01mTrue\u001b[39;00m,\n\u001b[32m 452\u001b[39m server_hostname=\u001b[38;5;28;01mNone\u001b[39;00m, session=\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[32m 453\u001b[39m \u001b[38;5;66;03m# SSLSocket class handles server_hostname encoding before it calls\u001b[39;00m\n\u001b[32m 454\u001b[39m \u001b[38;5;66;03m# ctx._wrap_socket()\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m455\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43msslsocket_class\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_create\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 456\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43msock\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43msock\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 457\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mserver_side\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mserver_side\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 458\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mdo_handshake_on_connect\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mdo_handshake_on_connect\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 459\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43msuppress_ragged_eofs\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43msuppress_ragged_eofs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 460\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mserver_hostname\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mserver_hostname\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 461\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcontext\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 462\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43msession\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43msession\u001b[39;49m\n\u001b[32m 463\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
60
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/ssl.py:1041\u001b[39m, in \u001b[36mSSLSocket._create\u001b[39m\u001b[34m(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)\u001b[39m\n\u001b[32m 1040\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mdo_handshake_on_connect should not be specified for non-blocking sockets\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1041\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mdo_handshake\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1042\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m:\n",
61
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/ssl.py:1319\u001b[39m, in \u001b[36mSSLSocket.do_handshake\u001b[39m\u001b[34m(self, block)\u001b[39m\n\u001b[32m 1318\u001b[39m \u001b[38;5;28mself\u001b[39m.settimeout(\u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[32m-> \u001b[39m\u001b[32m1319\u001b[39m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_sslobj\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mdo_handshake\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1320\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n",
62
- "\u001b[31mSSLEOFError\u001b[39m: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1000)",
63
- "\nDuring handling of the above exception, another exception occurred:\n",
64
- "\u001b[31mURLError\u001b[39m Traceback (most recent call last)",
65
- "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 12\u001b[39m\n\u001b[32m 8\u001b[39m \u001b[33m\"style\"\u001b[39m: \u001b[33m\"manga\"\u001b[39m,\n\u001b[32m 9\u001b[39m \u001b[33m\"fixPanelNum\"\u001b[39m: \u001b[32m4\u001b[39m,\n\u001b[32m 10\u001b[39m })\n\u001b[32m 11\u001b[39m print(created)\n\u001b[32m---> \u001b[39m\u001b[32m12\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m LlamaGenAPIError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m 13\u001b[39m print(\u001b[33m\"status:\"\u001b[39m, e.status)\n\u001b[32m 14\u001b[39m print(\u001b[33m\"data:\"\u001b[39m, e.data)\n",
66
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/site-packages/llamagen/resources/comics.py:35\u001b[39m, in \u001b[36mComicsResource.create\u001b[39m\u001b[34m(self, params)\u001b[39m\n\u001b[32m 33\u001b[39m body: Dict[\u001b[38;5;28mstr\u001b[39m, Any] = {\u001b[33m\"\u001b[39m\u001b[33mpreset\u001b[39m\u001b[33m\"\u001b[39m: DEFAULT_PRESET, \u001b[33m\"\u001b[39m\u001b[33msize\u001b[39m\u001b[33m\"\u001b[39m: DEFAULT_SIZE}\n\u001b[32m 34\u001b[39m body.update(params)\n\u001b[32m---> \u001b[39m\u001b[32m35\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_http\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m/comics/generations\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mmethod\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mPOST\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mjson_body\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mbody\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
67
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/site-packages/llamagen/_http.py:84\u001b[39m, in \u001b[36mHTTPClient.request\u001b[39m\u001b[34m(self, path, method, json_body, body, headers)\u001b[39m\n\u001b[32m 82\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[32m 83\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m84\u001b[39m status, response_headers, response_body = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mtransport\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 85\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mmethod\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 86\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43murl\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 87\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mprepared_headers\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 88\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mbody\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 89\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mtimeout\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 90\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 91\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m error:\n\u001b[32m 92\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m _is_timeout_error(error):\n",
68
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/site-packages/llamagen/_http.py:36\u001b[39m, in \u001b[36mUrllibTransport.request\u001b[39m\u001b[34m(self, method, url, headers, body, timeout)\u001b[39m\n\u001b[32m 34\u001b[39m request = urllib.request.Request(url, data=body, method=method, headers=\u001b[38;5;28mdict\u001b[39m(headers))\n\u001b[32m 35\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m36\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[30;43murllib\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43murlopen\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mrequest\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtimeout\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mtimeout\u001b[39;49m\u001b[30;43m)\u001b[39;49m \u001b[38;5;28;01mas\u001b[39;00m response:\n\u001b[32m 37\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m response.status, \u001b[38;5;28mdict\u001b[39m(response.headers.items()), response.read()\n\u001b[32m 38\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m urllib.error.HTTPError \u001b[38;5;28;01mas\u001b[39;00m error:\n",
69
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/urllib/request.py:215\u001b[39m, in \u001b[36murlopen\u001b[39m\u001b[34m(url, data, timeout, cafile, capath, cadefault, context)\u001b[39m\n\u001b[32m 213\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 214\u001b[39m opener = _opener\n\u001b[32m--> \u001b[39m\u001b[32m215\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mopener\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mopen\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43murl\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mdata\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mtimeout\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
70
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/urllib/request.py:515\u001b[39m, in \u001b[36mOpenerDirector.open\u001b[39m\u001b[34m(self, fullurl, data, timeout)\u001b[39m\n\u001b[32m 512\u001b[39m req = meth(req)\n\u001b[32m 514\u001b[39m sys.audit(\u001b[33m'\u001b[39m\u001b[33murllib.Request\u001b[39m\u001b[33m'\u001b[39m, req.full_url, req.data, req.headers, req.get_method())\n\u001b[32m--> \u001b[39m\u001b[32m515\u001b[39m response = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_open\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mdata\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 517\u001b[39m \u001b[38;5;66;03m# post-process response\u001b[39;00m\n\u001b[32m 518\u001b[39m meth_name = protocol+\u001b[33m\"\u001b[39m\u001b[33m_response\u001b[39m\u001b[33m\"\u001b[39m\n",
71
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/urllib/request.py:532\u001b[39m, in \u001b[36mOpenerDirector._open\u001b[39m\u001b[34m(self, req, data)\u001b[39m\n\u001b[32m 529\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n\u001b[32m 531\u001b[39m protocol = req.type\n\u001b[32m--> \u001b[39m\u001b[32m532\u001b[39m result = \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_call_chain\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mhandle_open\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mprotocol\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mprotocol\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m+\u001b[39;49m\n\u001b[32m 533\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m'\u001b[39;49m\u001b[30;43m_open\u001b[39;49m\u001b[30;43m'\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 534\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result:\n\u001b[32m 535\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n",
72
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/urllib/request.py:492\u001b[39m, in \u001b[36mOpenerDirector._call_chain\u001b[39m\u001b[34m(self, chain, kind, meth_name, *args)\u001b[39m\n\u001b[32m 490\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m handler \u001b[38;5;129;01min\u001b[39;00m handlers:\n\u001b[32m 491\u001b[39m func = \u001b[38;5;28mgetattr\u001b[39m(handler, meth_name)\n\u001b[32m--> \u001b[39m\u001b[32m492\u001b[39m result = \u001b[30;43mfunc\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 493\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 494\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n",
73
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/urllib/request.py:1392\u001b[39m, in \u001b[36mHTTPSHandler.https_open\u001b[39m\u001b[34m(self, req)\u001b[39m\n\u001b[32m 1391\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mhttps_open\u001b[39m(\u001b[38;5;28mself\u001b[39m, req):\n\u001b[32m-> \u001b[39m\u001b[32m1392\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mdo_open\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mhttp\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mclient\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mHTTPSConnection\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mreq\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 1393\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcontext\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_context\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n",
74
- "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/lib/python3.12/urllib/request.py:1347\u001b[39m, in \u001b[36mAbstractHTTPHandler.do_open\u001b[39m\u001b[34m(self, http_class, req, **http_conn_args)\u001b[39m\n\u001b[32m 1344\u001b[39m h.request(req.get_method(), req.selector, req.data, headers,\n\u001b[32m 1345\u001b[39m encode_chunked=req.has_header(\u001b[33m'\u001b[39m\u001b[33mTransfer-encoding\u001b[39m\u001b[33m'\u001b[39m))\n\u001b[32m 1346\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err: \u001b[38;5;66;03m# timeout error\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1347\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m URLError(err)\n\u001b[32m 1348\u001b[39m r = h.getresponse()\n\u001b[32m 1349\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m:\n",
75
- "\u001b[31mURLError\u001b[39m: <urlopen error [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1000)>"
76
- ]
77
- }
78
- ],
79
- "source": [
80
- "from llamagen import LlamaGenClient, LlamaGenAPIError\n",
81
- "\n",
82
- "client = LlamaGenClient(api_key=\"sk-5d609cd64379d048edcb04dcc109a6cfaf7c066f12138c13c8c404766ab9629d\")\n",
83
- "\n",
84
- "try:\n",
85
- " created = client.comic.create({\n",
86
- " \"prompt\": \"A 4-panel comic about Leo finding a glowing key in a quiet library.\",\n",
87
- " \"style\": \"manga\",\n",
88
- " \"fixPanelNum\": 4,\n",
89
- " })\n",
90
- " print(created)\n",
91
- "except LlamaGenAPIError as e:\n",
92
- " print(\"status:\", e.status)\n",
93
- " print(\"data:\", e.data)"
94
- ]
95
- },
96
- {
97
- "cell_type": "code",
98
- "execution_count": null,
99
- "id": "0b238159-ea0a-4a41-9c57-0ca986456db4",
100
- "metadata": {},
101
- "outputs": [],
102
- "source": []
103
- }
104
- ],
105
- "metadata": {
106
- "kernelspec": {
107
- "display_name": "Python 3 (ipykernel)",
108
- "language": "python",
109
- "name": "python3"
110
- },
111
- "language_info": {
112
- "codemirror_mode": {
113
- "name": "ipython",
114
- "version": 3
115
- },
116
- "file_extension": ".py",
117
- "mimetype": "text/x-python",
118
- "name": "python",
119
- "nbconvert_exporter": "python",
120
- "pygments_lexer": "ipython3",
121
- "version": "3.12.7"
122
- }
123
- },
124
- "nbformat": 4,
125
- "nbformat_minor": 5
126
- }
@@ -1,17 +0,0 @@
1
- import os
2
-
3
- from llamagen import LlamaGenClient
4
-
5
-
6
- client = LlamaGenClient(api_key=os.environ["LLAMAGEN_API_KEY"])
7
-
8
- created = client.comic.create(
9
- {
10
- "prompt": "A 4-panel comic about Leo finding a glowing key in a quiet library.",
11
- "style": "manga",
12
- "fixPanelNum": 4,
13
- }
14
- )
15
-
16
- done = client.comic.wait_for_completion(created["id"])
17
- print(done["status"])
File without changes