llamagen-python 0.1.7__tar.gz → 0.1.9__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.9
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,12 @@ 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
+ All Python examples below are self-contained for copy/paste usage in your own
85
+ script, notebook, worker, or backend service. Replace `YOUR_COMIC_ID` or
86
+ `YOUR_ANIMATION_ID` with an existing generation ID when an example fetches,
87
+ waits for, continues, or updates an existing job.
81
88
 
82
- ## Client
89
+ ## Configure The Client
83
90
 
84
91
  ```python
85
92
  from llamagen import LlamaGenClient
@@ -101,6 +108,8 @@ dependencies.
101
108
  Use `llamagen.comic` to create comics, manga, webtoons, storyboards,
102
109
  consistent-character pages, and panel edits.
103
110
 
111
+ Create with advanced options:
112
+
104
113
  ```python
105
114
  import os
106
115
 
@@ -271,14 +280,15 @@ from llamagen import LlamaGenClient
271
280
 
272
281
  client = LlamaGenClient(api_key=os.environ["LLAMAGEN_API_KEY"])
273
282
 
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)
283
+ image_path = Path("reference.png")
284
+ uploaded = client.comic.upload(image_path)
285
+ print("comic.upload:", uploaded)
278
286
  ```
279
287
 
280
288
  ## Animation API
281
289
 
290
+ Create an animation job and wait for completion:
291
+
282
292
  ```python
283
293
  import os
284
294
 
@@ -294,12 +304,14 @@ video = client.animation.create({
294
304
  "aspect_ratio": "16:9",
295
305
  },
296
306
  })
307
+ print("animation.create:", video["id"], video.get("status"))
297
308
 
298
309
  finished = client.animation.wait_for_completion(
299
310
  video["id"],
300
311
  interval_ms=5000,
301
312
  timeout_ms=30 * 60 * 1000,
302
313
  )
314
+ print("animation.wait_for_completion:", finished["id"], finished.get("status"))
303
315
  ```
304
316
 
305
317
  Animation methods:
@@ -311,6 +323,8 @@ Animation methods:
311
323
 
312
324
  Animation examples:
313
325
 
326
+ Create an animation job:
327
+
314
328
  ```python
315
329
  import os
316
330
 
@@ -327,7 +341,6 @@ video = client.animation.create({
327
341
  },
328
342
  })
329
343
  print("animation.create:", video["id"], video.get("status"))
330
-
331
344
  ```
332
345
 
333
346
  Fetch and wait for an animation:
@@ -369,10 +382,13 @@ finished = client.animation.create_and_wait({
369
382
  },
370
383
  }, timeout_ms=WAIT_TIMEOUT_MS)
371
384
  print("animation.create_and_wait:", finished["id"], finished.get("status"))
372
-
373
385
  ```
374
386
 
375
- ## Errors
387
+ ## Error Handling
388
+
389
+ API errors include the HTTP status, parsed server response, and a readable
390
+ message. For example, a `429` response can include an error code and message
391
+ such as insufficient credits.
376
392
 
377
393
  ```python
378
394
  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,12 @@ 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
+ All Python examples below are self-contained for copy/paste usage in your own
60
+ script, notebook, worker, or backend service. Replace `YOUR_COMIC_ID` or
61
+ `YOUR_ANIMATION_ID` with an existing generation ID when an example fetches,
62
+ waits for, continues, or updates an existing job.
56
63
 
57
- ## Client
64
+ ## Configure The Client
58
65
 
59
66
  ```python
60
67
  from llamagen import LlamaGenClient
@@ -76,6 +83,8 @@ dependencies.
76
83
  Use `llamagen.comic` to create comics, manga, webtoons, storyboards,
77
84
  consistent-character pages, and panel edits.
78
85
 
86
+ Create with advanced options:
87
+
79
88
  ```python
80
89
  import os
81
90
 
@@ -246,14 +255,15 @@ from llamagen import LlamaGenClient
246
255
 
247
256
  client = LlamaGenClient(api_key=os.environ["LLAMAGEN_API_KEY"])
248
257
 
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)
258
+ image_path = Path("reference.png")
259
+ uploaded = client.comic.upload(image_path)
260
+ print("comic.upload:", uploaded)
253
261
  ```
254
262
 
255
263
  ## Animation API
256
264
 
265
+ Create an animation job and wait for completion:
266
+
257
267
  ```python
258
268
  import os
259
269
 
@@ -269,12 +279,14 @@ video = client.animation.create({
269
279
  "aspect_ratio": "16:9",
270
280
  },
271
281
  })
282
+ print("animation.create:", video["id"], video.get("status"))
272
283
 
273
284
  finished = client.animation.wait_for_completion(
274
285
  video["id"],
275
286
  interval_ms=5000,
276
287
  timeout_ms=30 * 60 * 1000,
277
288
  )
289
+ print("animation.wait_for_completion:", finished["id"], finished.get("status"))
278
290
  ```
279
291
 
280
292
  Animation methods:
@@ -286,6 +298,8 @@ Animation methods:
286
298
 
287
299
  Animation examples:
288
300
 
301
+ Create an animation job:
302
+
289
303
  ```python
290
304
  import os
291
305
 
@@ -302,7 +316,6 @@ video = client.animation.create({
302
316
  },
303
317
  })
304
318
  print("animation.create:", video["id"], video.get("status"))
305
-
306
319
  ```
307
320
 
308
321
  Fetch and wait for an animation:
@@ -344,10 +357,13 @@ finished = client.animation.create_and_wait({
344
357
  },
345
358
  }, timeout_ms=WAIT_TIMEOUT_MS)
346
359
  print("animation.create_and_wait:", finished["id"], finished.get("status"))
347
-
348
360
  ```
349
361
 
350
- ## Errors
362
+ ## Error Handling
363
+
364
+ API errors include the HTTP status, parsed server response, and a readable
365
+ message. For example, a `429` response can include an error code and message
366
+ such as insufficient credits.
351
367
 
352
368
  ```python
353
369
  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.9"
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.9"
@@ -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.9"
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.9")
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