llamagen-python 0.1.7__tar.gz → 0.1.8__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llamagen-python
3
- Version: 0.1.7
3
+ Version: 0.1.8
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
@@ -23,7 +23,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Python: >=3.9
24
24
  Description-Content-Type: text/markdown
25
25
 
26
- # llamagen-python
26
+ # LlamaGen Python SDK
27
27
 
28
28
  Official Python SDK for LlamaGen's Comic API and Animation API.
29
29
 
@@ -53,6 +53,9 @@ LLAMAGEN_API_KEY=YOUR_API_KEY
53
53
 
54
54
  ## Quick Start
55
55
 
56
+ This example creates one comic generation and waits for the final result. API
57
+ generation calls consume credits.
58
+
56
59
  ```python
57
60
  import os
58
61
 
@@ -78,8 +81,28 @@ done = client.comic.wait_for_completion(created["id"], timeout_ms=WAIT_TIMEOUT_M
78
81
  print("comic.wait_for_completion:", done["id"], done.get("status"), done.get("comics"))
79
82
  ```
80
83
 
84
+ The full runnable demo is in [`examples/quickstart.py`](examples/quickstart.py):
85
+
86
+ ```bash
87
+ python examples/quickstart.py
88
+ ```
89
+
90
+ Pass a local image path to run the upload example:
91
+
92
+ ```bash
93
+ python examples/quickstart.py upload /path/to/reference.png
94
+ ```
95
+
96
+ Other README examples are available as subcommands, such as `comic-create`,
97
+ `comic-create-advanced`, `comic-get`, `comic-wait`, `comic-create-and-wait`,
98
+ `comic-continue`, `comic-update-panel`, `usage`, `animation-create`,
99
+ `animation-create-wait`, `animation-wait`, and `animation-create-and-wait`.
81
100
 
82
- ## Client
101
+ All Python examples below are self-contained for copy/paste usage. Replace
102
+ `YOUR_COMIC_ID` or `YOUR_ANIMATION_ID` with an existing generation ID when an
103
+ example fetches, waits for, continues, or updates an existing job.
104
+
105
+ ## Configure The Client
83
106
 
84
107
  ```python
85
108
  from llamagen import LlamaGenClient
@@ -101,6 +124,8 @@ dependencies.
101
124
  Use `llamagen.comic` to create comics, manga, webtoons, storyboards,
102
125
  consistent-character pages, and panel edits.
103
126
 
127
+ Create with advanced options:
128
+
104
129
  ```python
105
130
  import os
106
131
 
@@ -271,14 +296,15 @@ from llamagen import LlamaGenClient
271
296
 
272
297
  client = LlamaGenClient(api_key=os.environ["LLAMAGEN_API_KEY"])
273
298
 
274
- upload_file = os.environ.get("LLAMAGEN_UPLOAD_FILE")
275
- if upload_file:
276
- uploaded = client.comic.upload(Path(upload_file))
277
- print("comic.upload:", uploaded)
299
+ image_path = Path("reference.png")
300
+ uploaded = client.comic.upload(image_path)
301
+ print("comic.upload:", uploaded)
278
302
  ```
279
303
 
280
304
  ## Animation API
281
305
 
306
+ Create an animation job and wait for completion:
307
+
282
308
  ```python
283
309
  import os
284
310
 
@@ -294,12 +320,14 @@ video = client.animation.create({
294
320
  "aspect_ratio": "16:9",
295
321
  },
296
322
  })
323
+ print("animation.create:", video["id"], video.get("status"))
297
324
 
298
325
  finished = client.animation.wait_for_completion(
299
326
  video["id"],
300
327
  interval_ms=5000,
301
328
  timeout_ms=30 * 60 * 1000,
302
329
  )
330
+ print("animation.wait_for_completion:", finished["id"], finished.get("status"))
303
331
  ```
304
332
 
305
333
  Animation methods:
@@ -311,6 +339,8 @@ Animation methods:
311
339
 
312
340
  Animation examples:
313
341
 
342
+ Create an animation job:
343
+
314
344
  ```python
315
345
  import os
316
346
 
@@ -327,7 +357,6 @@ video = client.animation.create({
327
357
  },
328
358
  })
329
359
  print("animation.create:", video["id"], video.get("status"))
330
-
331
360
  ```
332
361
 
333
362
  Fetch and wait for an animation:
@@ -369,10 +398,13 @@ finished = client.animation.create_and_wait({
369
398
  },
370
399
  }, timeout_ms=WAIT_TIMEOUT_MS)
371
400
  print("animation.create_and_wait:", finished["id"], finished.get("status"))
372
-
373
401
  ```
374
402
 
375
- ## Errors
403
+ ## Error Handling
404
+
405
+ API errors include the HTTP status, parsed server response, and a readable
406
+ message. For example, a `429` response can include an error code and message
407
+ such as insufficient credits.
376
408
 
377
409
  ```python
378
410
  import os
@@ -1,4 +1,4 @@
1
- # llamagen-python
1
+ # LlamaGen Python SDK
2
2
 
3
3
  Official Python SDK for LlamaGen's Comic API and Animation API.
4
4
 
@@ -28,6 +28,9 @@ LLAMAGEN_API_KEY=YOUR_API_KEY
28
28
 
29
29
  ## Quick Start
30
30
 
31
+ This example creates one comic generation and waits for the final result. API
32
+ generation calls consume credits.
33
+
31
34
  ```python
32
35
  import os
33
36
 
@@ -53,8 +56,28 @@ done = client.comic.wait_for_completion(created["id"], timeout_ms=WAIT_TIMEOUT_M
53
56
  print("comic.wait_for_completion:", done["id"], done.get("status"), done.get("comics"))
54
57
  ```
55
58
 
59
+ The full runnable demo is in [`examples/quickstart.py`](examples/quickstart.py):
60
+
61
+ ```bash
62
+ python examples/quickstart.py
63
+ ```
64
+
65
+ Pass a local image path to run the upload example:
66
+
67
+ ```bash
68
+ python examples/quickstart.py upload /path/to/reference.png
69
+ ```
70
+
71
+ Other README examples are available as subcommands, such as `comic-create`,
72
+ `comic-create-advanced`, `comic-get`, `comic-wait`, `comic-create-and-wait`,
73
+ `comic-continue`, `comic-update-panel`, `usage`, `animation-create`,
74
+ `animation-create-wait`, `animation-wait`, and `animation-create-and-wait`.
56
75
 
57
- ## Client
76
+ All Python examples below are self-contained for copy/paste usage. Replace
77
+ `YOUR_COMIC_ID` or `YOUR_ANIMATION_ID` with an existing generation ID when an
78
+ example fetches, waits for, continues, or updates an existing job.
79
+
80
+ ## Configure The Client
58
81
 
59
82
  ```python
60
83
  from llamagen import LlamaGenClient
@@ -76,6 +99,8 @@ dependencies.
76
99
  Use `llamagen.comic` to create comics, manga, webtoons, storyboards,
77
100
  consistent-character pages, and panel edits.
78
101
 
102
+ Create with advanced options:
103
+
79
104
  ```python
80
105
  import os
81
106
 
@@ -246,14 +271,15 @@ from llamagen import LlamaGenClient
246
271
 
247
272
  client = LlamaGenClient(api_key=os.environ["LLAMAGEN_API_KEY"])
248
273
 
249
- upload_file = os.environ.get("LLAMAGEN_UPLOAD_FILE")
250
- if upload_file:
251
- uploaded = client.comic.upload(Path(upload_file))
252
- print("comic.upload:", uploaded)
274
+ image_path = Path("reference.png")
275
+ uploaded = client.comic.upload(image_path)
276
+ print("comic.upload:", uploaded)
253
277
  ```
254
278
 
255
279
  ## Animation API
256
280
 
281
+ Create an animation job and wait for completion:
282
+
257
283
  ```python
258
284
  import os
259
285
 
@@ -269,12 +295,14 @@ video = client.animation.create({
269
295
  "aspect_ratio": "16:9",
270
296
  },
271
297
  })
298
+ print("animation.create:", video["id"], video.get("status"))
272
299
 
273
300
  finished = client.animation.wait_for_completion(
274
301
  video["id"],
275
302
  interval_ms=5000,
276
303
  timeout_ms=30 * 60 * 1000,
277
304
  )
305
+ print("animation.wait_for_completion:", finished["id"], finished.get("status"))
278
306
  ```
279
307
 
280
308
  Animation methods:
@@ -286,6 +314,8 @@ Animation methods:
286
314
 
287
315
  Animation examples:
288
316
 
317
+ Create an animation job:
318
+
289
319
  ```python
290
320
  import os
291
321
 
@@ -302,7 +332,6 @@ video = client.animation.create({
302
332
  },
303
333
  })
304
334
  print("animation.create:", video["id"], video.get("status"))
305
-
306
335
  ```
307
336
 
308
337
  Fetch and wait for an animation:
@@ -344,10 +373,13 @@ finished = client.animation.create_and_wait({
344
373
  },
345
374
  }, timeout_ms=WAIT_TIMEOUT_MS)
346
375
  print("animation.create_and_wait:", finished["id"], finished.get("status"))
347
-
348
376
  ```
349
377
 
350
- ## Errors
378
+ ## Error Handling
379
+
380
+ API errors include the HTTP status, parsed server response, and a readable
381
+ message. For example, a `429` response can include an error code and message
382
+ such as insufficient credits.
351
383
 
352
384
  ```python
353
385
  import os
@@ -0,0 +1,279 @@
1
+ import argparse
2
+ import os
3
+ from pathlib import Path
4
+
5
+ from llamagen import (
6
+ LlamaGenAPIError,
7
+ LlamaGenClient,
8
+ LlamaGenConnectionError,
9
+ LlamaGenTimeoutError,
10
+ )
11
+
12
+
13
+ ROOT = Path(__file__).resolve().parents[1]
14
+ WAIT_TIMEOUT_MS = 30 * 60 * 1000
15
+
16
+
17
+ def load_dotenv(path: Path) -> None:
18
+ if not path.exists():
19
+ return
20
+
21
+ for raw_line in path.read_text(encoding="utf-8").splitlines():
22
+ line = raw_line.strip()
23
+ if not line or line.startswith("#") or "=" not in line:
24
+ continue
25
+ key, value = line.split("=", 1)
26
+ os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'"))
27
+
28
+
29
+ def make_client() -> LlamaGenClient:
30
+ load_dotenv(ROOT / ".env")
31
+ return LlamaGenClient(
32
+ api_key=os.environ["LLAMAGEN_API_KEY"],
33
+ timeout_ms=30000,
34
+ max_retries=5,
35
+ retry_delay_ms=500,
36
+ )
37
+
38
+
39
+ def quick_start(client: LlamaGenClient) -> None:
40
+ created = client.comic.create(
41
+ {
42
+ "prompt": "A 4-panel comic about Leo finding a glowing key in a quiet library.",
43
+ "style": "manga",
44
+ "fixPanelNum": 4,
45
+ }
46
+ )
47
+ print("comic.create:", created["id"], created.get("status"))
48
+
49
+ done = client.comic.wait_for_completion(created["id"], timeout_ms=WAIT_TIMEOUT_MS)
50
+ print("comic.wait_for_completion:", done["id"], done.get("status"), done.get("comics"))
51
+
52
+
53
+ def create_comic(client: LlamaGenClient) -> None:
54
+ created = client.comic.create(
55
+ {
56
+ "prompt": "A 4-panel comic about Leo finding a glowing key in a quiet library.",
57
+ "style": "manga",
58
+ "fixPanelNum": 4,
59
+ }
60
+ )
61
+ print("comic.create:", created["id"], created.get("status"))
62
+
63
+
64
+ def create_comic_with_advanced_options(client: LlamaGenClient) -> None:
65
+ generation = client.comic.create(
66
+ {
67
+ "prompt": "The Little Prince meets the Fox in a luminous desert.",
68
+ "style": "storybook manga",
69
+ "size": "1024x1024",
70
+ "pagination": {"totalPages": 2, "panelsPerPage": 4},
71
+ "comicRoles": [
72
+ {
73
+ "name": "The Little Prince",
74
+ "image": "https://example.com/prince.png",
75
+ "clothing": "green coat and yellow scarf",
76
+ }
77
+ ],
78
+ "attachments": [{"type": "image", "url": "https://example.com/reference.png"}],
79
+ "language": "en",
80
+ "upscale": "2K",
81
+ }
82
+ )
83
+ print("comic.create advanced:", generation["id"], generation.get("status"))
84
+
85
+
86
+ def get_comic(client: LlamaGenClient, comic_id: str) -> None:
87
+ fetched = client.comic.get(comic_id)
88
+ print("comic.get:", fetched["id"], fetched.get("status"))
89
+
90
+ panel = client.comic.get(comic_id, page=0, panel=0)
91
+ print("comic.get panel:", panel.get("id", comic_id), panel.get("status"))
92
+
93
+
94
+ def wait_for_comic(client: LlamaGenClient, comic_id: str) -> None:
95
+ done = client.comic.wait_for_completion(comic_id, timeout_ms=WAIT_TIMEOUT_MS)
96
+ print("comic.wait_for_completion:", done["id"], done.get("status"), done.get("comics"))
97
+
98
+
99
+ def create_and_wait_for_comic(client: LlamaGenClient) -> None:
100
+ finished = client.comic.create_and_wait(
101
+ {
102
+ "prompt": "A cozy 3-panel comic about a robot learning to bake bread.",
103
+ "style": "storybook",
104
+ "fixPanelNum": 3,
105
+ },
106
+ timeout_ms=WAIT_TIMEOUT_MS,
107
+ )
108
+ print("comic.create_and_wait:", finished["id"], finished.get("status"))
109
+
110
+
111
+ def continue_comic(client: LlamaGenClient, comic_id: str) -> None:
112
+ continued = client.comic.continue_write(
113
+ comic_id,
114
+ {
115
+ "prompt": "Continue the story with Leo opening a secret reading room.",
116
+ "pagination": {"totalPages": 1, "panelsPerPage": 4},
117
+ },
118
+ )
119
+ print("comic.continue_write:", continued["id"], continued.get("status"))
120
+
121
+
122
+ def update_comic_panel(client: LlamaGenClient, comic_id: str) -> None:
123
+ updated = client.comic.update_panel(
124
+ comic_id,
125
+ {
126
+ "panelIndex": 0,
127
+ "prompt": "Make the glowing key brighter and add dramatic moonlight.",
128
+ },
129
+ )
130
+ print("comic.update_panel:", updated["id"], updated.get("status"))
131
+
132
+
133
+ def show_usage(client: LlamaGenClient) -> None:
134
+ usage = client.comic.usage()
135
+ print("comic.usage:", usage)
136
+
137
+
138
+ def upload_reference_image(client: LlamaGenClient, image_path: Path) -> None:
139
+ uploaded = client.comic.upload(image_path)
140
+ print("comic.upload:", uploaded)
141
+
142
+
143
+ def create_animation(client: LlamaGenClient) -> None:
144
+ video = client.animation.create(
145
+ {
146
+ "prompt": "A heroic fox detective walks through neon rain, cinematic camera move.",
147
+ "videoOptions": {
148
+ "duration": 5,
149
+ "resolution": "720p",
150
+ "aspect_ratio": "16:9",
151
+ },
152
+ }
153
+ )
154
+ print("animation.create:", video["id"], video.get("status"))
155
+
156
+
157
+ def create_and_wait_for_animation_with_manual_wait(client: LlamaGenClient) -> None:
158
+ video = client.animation.create(
159
+ {
160
+ "prompt": "A heroic fox detective walks through neon rain, cinematic camera move.",
161
+ "videoOptions": {
162
+ "duration": 5,
163
+ "resolution": "720p",
164
+ "aspect_ratio": "16:9",
165
+ },
166
+ }
167
+ )
168
+ print("animation.create:", video["id"], video.get("status"))
169
+
170
+ finished = client.animation.wait_for_completion(
171
+ video["id"],
172
+ interval_ms=5000,
173
+ timeout_ms=WAIT_TIMEOUT_MS,
174
+ )
175
+ print("animation.wait_for_completion:", finished["id"], finished.get("status"))
176
+
177
+
178
+ def create_and_wait_for_animation(client: LlamaGenClient) -> None:
179
+ finished = client.animation.create_and_wait(
180
+ {
181
+ "prompt": "A paper boat sailing across a watercolor city at sunrise.",
182
+ "videoOptions": {
183
+ "duration": 5,
184
+ "resolution": "720p",
185
+ "aspect_ratio": "16:9",
186
+ },
187
+ },
188
+ timeout_ms=WAIT_TIMEOUT_MS,
189
+ )
190
+ print("animation.create_and_wait:", finished["id"], finished.get("status"))
191
+
192
+
193
+ def wait_for_animation(client: LlamaGenClient, animation_id: str) -> None:
194
+ fetched = client.animation.get(animation_id)
195
+ print("animation.get:", fetched["id"], fetched.get("status"))
196
+
197
+ finished = client.animation.wait_for_completion(animation_id, timeout_ms=WAIT_TIMEOUT_MS)
198
+ print("animation.wait_for_completion:", finished["id"], finished.get("status"))
199
+
200
+
201
+ def parse_args() -> argparse.Namespace:
202
+ parser = argparse.ArgumentParser(description="Run LlamaGen Python SDK examples.")
203
+ subparsers = parser.add_subparsers(dest="command")
204
+
205
+ subparsers.add_parser("quickstart", help="Create one comic and wait for completion.")
206
+ subparsers.add_parser("comic-create", help="Create one comic generation.")
207
+ subparsers.add_parser("comic-create-advanced", help="Create a comic with advanced options.")
208
+ subparsers.add_parser("comic-create-and-wait", help="Create one comic and wait in one call.")
209
+ subparsers.add_parser("usage", help="Fetch comic API usage.")
210
+
211
+ get_parser = subparsers.add_parser("comic-get", help="Fetch a comic generation, page, and panel.")
212
+ get_parser.add_argument("comic_id")
213
+
214
+ wait_parser = subparsers.add_parser("comic-wait", help="Wait for a comic generation.")
215
+ wait_parser.add_argument("comic_id")
216
+
217
+ continue_parser = subparsers.add_parser("comic-continue", help="Continue an existing comic.")
218
+ continue_parser.add_argument("comic_id")
219
+
220
+ update_parser = subparsers.add_parser("comic-update-panel", help="Regenerate one panel.")
221
+ update_parser.add_argument("comic_id")
222
+
223
+ upload_parser = subparsers.add_parser("upload", help="Upload a local reference image.")
224
+ upload_parser.add_argument("image_path", type=Path)
225
+
226
+ subparsers.add_parser("animation-create", help="Create an animation job.")
227
+ subparsers.add_parser("animation-create-wait", help="Create an animation job and wait for completion.")
228
+ subparsers.add_parser("animation-create-and-wait", help="Create an animation job and wait in one call.")
229
+
230
+ animation_wait_parser = subparsers.add_parser("animation-wait", help="Fetch and wait for an animation.")
231
+ animation_wait_parser.add_argument("animation_id")
232
+
233
+ return parser.parse_args()
234
+
235
+
236
+ def main() -> None:
237
+ args = parse_args()
238
+ client = make_client()
239
+ command = args.command or "quickstart"
240
+
241
+ if command == "quickstart":
242
+ quick_start(client)
243
+ elif command == "comic-create":
244
+ create_comic(client)
245
+ elif command == "comic-create-advanced":
246
+ create_comic_with_advanced_options(client)
247
+ elif command == "comic-get":
248
+ get_comic(client, args.comic_id)
249
+ elif command == "comic-wait":
250
+ wait_for_comic(client, args.comic_id)
251
+ elif command == "comic-create-and-wait":
252
+ create_and_wait_for_comic(client)
253
+ elif command == "comic-continue":
254
+ continue_comic(client, args.comic_id)
255
+ elif command == "comic-update-panel":
256
+ update_comic_panel(client, args.comic_id)
257
+ elif command == "usage":
258
+ show_usage(client)
259
+ elif command == "upload":
260
+ upload_reference_image(client, args.image_path)
261
+ elif command == "animation-create":
262
+ create_animation(client)
263
+ elif command == "animation-create-wait":
264
+ create_and_wait_for_animation_with_manual_wait(client)
265
+ elif command == "animation-wait":
266
+ wait_for_animation(client, args.animation_id)
267
+ elif command == "animation-create-and-wait":
268
+ create_and_wait_for_animation(client)
269
+
270
+
271
+ if __name__ == "__main__":
272
+ try:
273
+ main()
274
+ except LlamaGenAPIError as error:
275
+ print("LlamaGen API error:", error)
276
+ except LlamaGenConnectionError as error:
277
+ print("LlamaGen connection error:", error)
278
+ except LlamaGenTimeoutError as error:
279
+ 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.7"
7
+ version = "0.1.8"
8
8
  description = "Official Python SDK for LlamaGen Comic API and Animation API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -14,4 +14,4 @@ __all__ = [
14
14
  "SUPPORTED_COMIC_SIZES",
15
15
  ]
16
16
 
17
- __version__ = "0.1.7"
17
+ __version__ = "0.1.8"
@@ -10,7 +10,7 @@ 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.7"
13
+ DEFAULT_USER_AGENT = "llamagen-python/0.1.8"
14
14
 
15
15
 
16
16
  class Transport(Protocol):
@@ -80,7 +80,7 @@ class ClientTests(unittest.TestCase):
80
80
  self.assertEqual(call["url"], "https://api.llamagen.ai/v1/comics/generations")
81
81
  self.assertEqual(call["headers"]["Authorization"], "Bearer test-key")
82
82
  self.assertEqual(call["headers"]["Accept"], "application/json")
83
- self.assertEqual(call["headers"]["User-Agent"], "llamagen-python/0.1.7")
83
+ self.assertEqual(call["headers"]["User-Agent"], "llamagen-python/0.1.8")
84
84
  body = json.loads(call["body"].decode("utf-8"))
85
85
  self.assertEqual(body["preset"], "neutral")
86
86
  self.assertEqual(body["size"], "1024x1024")
@@ -1,84 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": null,
6
- "id": "cdc9de5a-8720-4448-abc3-f4a1a5c8f988",
7
- "metadata": {},
8
- "outputs": [
9
- {
10
- "name": "stdout",
11
- "output_type": "stream",
12
- "text": [
13
- "comic.create: cmrf1zulc000rl204y6b0w4kg LOADING\n"
14
- ]
15
- }
16
- ],
17
- "source": [
18
- "import os\n",
19
- "from pathlib import Path\n",
20
- "\n",
21
- "from llamagen import LlamaGenClient\n",
22
- "\n",
23
- "WAIT_TIMEOUT_MS = 30 * 60 * 1000\n",
24
- "\n",
25
- "client = LlamaGenClient(\n",
26
- " api_key=\"sk-5d609cd64379d048edcb04dcc109a6cfaf7c066f12138c13c8c404766ab9629d\",\n",
27
- " timeout_ms=30000,\n",
28
- " max_retries=5,\n",
29
- " retry_delay_ms=500,\n",
30
- ")\n",
31
- "\n",
32
- "created = client.comic.create({\n",
33
- " \"prompt\": \"The Little Prince meets the Fox in a luminous desert.\",\n",
34
- " \"style\": \"storybook manga\",\n",
35
- " \"size\": \"1024x1024\",\n",
36
- " \"pagination\": {\"totalPages\": 2, \"panelsPerPage\": 4},\n",
37
- " \"comicRoles\": [\n",
38
- " {\n",
39
- " \"name\": \"The Little Prince\",\n",
40
- " \"image\": \"https://example.com/prince.png\",\n",
41
- " \"clothing\": \"green coat and yellow scarf\",\n",
42
- " }\n",
43
- " ],\n",
44
- " \"attachments\": [{\"type\": \"image\", \"url\": \"https://example.com/reference.png\"}],\n",
45
- " \"language\": \"en\",\n",
46
- " \"upscale\": \"2K\",\n",
47
- "})\n",
48
- "print(\"comic.create:\", created[\"id\"], created.get(\"status\"))\n",
49
- "\n",
50
- "done = client.comic.wait_for_completion(created[\"id\"], timeout_ms=WAIT_TIMEOUT_MS)\n",
51
- "print(\"comic.wait_for_completion:\", done[\"id\"], done.get(\"status\"), done.get(\"comics\"))"
52
- ]
53
- },
54
- {
55
- "cell_type": "code",
56
- "execution_count": null,
57
- "id": "9be79812-b6f6-443e-9916-c9130dc0526b",
58
- "metadata": {},
59
- "outputs": [],
60
- "source": []
61
- }
62
- ],
63
- "metadata": {
64
- "kernelspec": {
65
- "display_name": "Python 3 (ipykernel)",
66
- "language": "python",
67
- "name": "python3"
68
- },
69
- "language_info": {
70
- "codemirror_mode": {
71
- "name": "ipython",
72
- "version": 3
73
- },
74
- "file_extension": ".py",
75
- "mimetype": "text/x-python",
76
- "name": "python",
77
- "nbconvert_exporter": "python",
78
- "pygments_lexer": "ipython3",
79
- "version": "3.12.7"
80
- }
81
- },
82
- "nbformat": 4,
83
- "nbformat_minor": 5
84
- }
@@ -1,171 +0,0 @@
1
- import os
2
- from pathlib import Path
3
-
4
- from llamagen import (
5
- LlamaGenAPIError,
6
- LlamaGenClient,
7
- LlamaGenConnectionError,
8
- LlamaGenTimeoutError,
9
- )
10
-
11
-
12
- ROOT = Path(__file__).resolve().parents[1]
13
- WAIT_TIMEOUT_MS = 30 * 60 * 1000
14
-
15
-
16
- def load_dotenv(path: Path) -> None:
17
- if not path.exists():
18
- return
19
-
20
- for raw_line in path.read_text(encoding="utf-8").splitlines():
21
- line = raw_line.strip()
22
- if not line or line.startswith("#") or "=" not in line:
23
- continue
24
- key, value = line.split("=", 1)
25
- os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'"))
26
-
27
-
28
- def make_client() -> LlamaGenClient:
29
- load_dotenv(ROOT / ".env")
30
- return LlamaGenClient(
31
- api_key=os.environ["LLAMAGEN_API_KEY"],
32
- timeout_ms=30000,
33
- max_retries=5,
34
- retry_delay_ms=500,
35
- )
36
-
37
-
38
- def demo_comic_create_get_wait(client: LlamaGenClient) -> str:
39
- created = client.comic.create(
40
- {
41
- "prompt": "A 4-panel comic about Leo finding a glowing key in a quiet library.",
42
- "style": "manga",
43
- "fixPanelNum": 4,
44
- }
45
- )
46
- print("comic.create:", created["id"], created.get("status"))
47
-
48
- fetched = client.comic.get(created["id"])
49
- print("comic.get:", fetched["id"], fetched.get("status"))
50
-
51
- panel = client.comic.get(created["id"], page=0, panel=0)
52
- print("comic.get panel:", panel.get("id", created["id"]), panel.get("status"))
53
-
54
- done = client.comic.wait_for_completion(created["id"], timeout_ms=WAIT_TIMEOUT_MS)
55
- print("comic.wait_for_completion:", done["id"], done.get("status"), done.get("comics"))
56
- return created["id"]
57
-
58
-
59
- def demo_comic_usage(client: LlamaGenClient) -> None:
60
- usage = client.comic.usage()
61
- print("comic.usage:", usage)
62
-
63
-
64
- def demo_comic_upload(client: LlamaGenClient, image_path: Path) -> str:
65
- uploaded = client.comic.upload(image_path)
66
- print("comic.upload:", uploaded)
67
- return str(uploaded.get("url") or uploaded.get("fileUrl") or uploaded.get("id") or "")
68
-
69
-
70
- def demo_comic_continue_write(client: LlamaGenClient, comic_id: str) -> str:
71
- continued = client.comic.continue_write(
72
- comic_id,
73
- {
74
- "prompt": "Continue the story with Leo opening a secret reading room.",
75
- "pagination": {"totalPages": 1, "panelsPerPage": 4},
76
- },
77
- )
78
- print("comic.continue_write:", continued["id"], continued.get("status"))
79
- return continued["id"]
80
-
81
-
82
- def demo_comic_update_panel(client: LlamaGenClient, comic_id: str) -> str:
83
- updated = client.comic.update_panel(
84
- comic_id,
85
- {
86
- "panelIndex": 0,
87
- "prompt": "Make the glowing key brighter and add dramatic moonlight.",
88
- },
89
- )
90
- print("comic.update_panel:", updated["id"], updated.get("status"))
91
- return updated["id"]
92
-
93
-
94
- def demo_comic_create_and_wait(client: LlamaGenClient) -> str:
95
- done = client.comic.create_and_wait(
96
- {
97
- "prompt": "A cozy 3-panel comic about a robot learning to bake bread.",
98
- "style": "storybook",
99
- "fixPanelNum": 3,
100
- },
101
- timeout_ms=WAIT_TIMEOUT_MS,
102
- )
103
- print("comic.create_and_wait:", done["id"], done.get("status"))
104
- return done["id"]
105
-
106
-
107
- def demo_animation_create_get_wait(client: LlamaGenClient) -> str:
108
- created = client.animation.create(
109
- {
110
- "prompt": "A heroic fox detective walks through neon rain, cinematic camera move.",
111
- "videoOptions": {
112
- "duration": 5,
113
- "resolution": "720p",
114
- "aspect_ratio": "16:9",
115
- },
116
- }
117
- )
118
- print("animation.create:", created["id"], created.get("status"))
119
-
120
- fetched = client.animation.get(created["id"])
121
- print("animation.get:", fetched["id"], fetched.get("status"))
122
-
123
- done = client.animation.wait_for_completion(created["id"], timeout_ms=WAIT_TIMEOUT_MS)
124
- print("animation.wait_for_completion:", done["id"], done.get("status"))
125
- return created["id"]
126
-
127
-
128
- def demo_animation_create_and_wait(client: LlamaGenClient) -> str:
129
- done = client.animation.create_and_wait(
130
- {
131
- "prompt": "A paper boat sailing across a watercolor city at sunrise.",
132
- "videoOptions": {
133
- "duration": 5,
134
- "resolution": "720p",
135
- "aspect_ratio": "16:9",
136
- },
137
- },
138
- timeout_ms=WAIT_TIMEOUT_MS,
139
- )
140
- print("animation.create_and_wait:", done["id"], done.get("status"))
141
- return done["id"]
142
-
143
-
144
- def main() -> None:
145
- client = make_client()
146
-
147
- comic_id = demo_comic_create_get_wait(client)
148
- demo_comic_usage(client)
149
-
150
- upload_file = os.environ.get("LLAMAGEN_UPLOAD_FILE")
151
- if upload_file:
152
- demo_comic_upload(client, Path(upload_file))
153
-
154
- if os.environ.get("LLAMAGEN_RUN_OPTIONAL_DEMOS") == "1":
155
- demo_comic_continue_write(client, comic_id)
156
- demo_comic_update_panel(client, comic_id)
157
- demo_comic_create_and_wait(client)
158
-
159
- demo_animation_create_get_wait(client)
160
- demo_animation_create_and_wait(client)
161
-
162
-
163
- if __name__ == "__main__":
164
- try:
165
- main()
166
- except LlamaGenAPIError as error:
167
- print("LlamaGen API error:", error)
168
- except LlamaGenConnectionError as error:
169
- print("LlamaGen connection error:", error)
170
- except LlamaGenTimeoutError as error:
171
- print("LlamaGen timeout:", error)
File without changes