minimax-sdk 0.1.0__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 (56) hide show
  1. minimax_sdk-0.1.0/.gitignore +17 -0
  2. minimax_sdk-0.1.0/PKG-INFO +595 -0
  3. minimax_sdk-0.1.0/README.md +563 -0
  4. minimax_sdk-0.1.0/pyproject.toml +51 -0
  5. minimax_sdk-0.1.0/src/minimax_sdk/__init__.py +125 -0
  6. minimax_sdk-0.1.0/src/minimax_sdk/_audio.py +156 -0
  7. minimax_sdk-0.1.0/src/minimax_sdk/_base.py +40 -0
  8. minimax_sdk-0.1.0/src/minimax_sdk/_http.py +716 -0
  9. minimax_sdk-0.1.0/src/minimax_sdk/_polling.py +184 -0
  10. minimax_sdk-0.1.0/src/minimax_sdk/client.py +303 -0
  11. minimax_sdk-0.1.0/src/minimax_sdk/exceptions.py +166 -0
  12. minimax_sdk-0.1.0/src/minimax_sdk/resources/__init__.py +0 -0
  13. minimax_sdk-0.1.0/src/minimax_sdk/resources/files.py +200 -0
  14. minimax_sdk-0.1.0/src/minimax_sdk/resources/image.py +188 -0
  15. minimax_sdk-0.1.0/src/minimax_sdk/resources/music.py +391 -0
  16. minimax_sdk-0.1.0/src/minimax_sdk/resources/speech.py +1545 -0
  17. minimax_sdk-0.1.0/src/minimax_sdk/resources/text.py +428 -0
  18. minimax_sdk-0.1.0/src/minimax_sdk/resources/video.py +649 -0
  19. minimax_sdk-0.1.0/src/minimax_sdk/resources/voice.py +386 -0
  20. minimax_sdk-0.1.0/src/minimax_sdk/types/__init__.py +51 -0
  21. minimax_sdk-0.1.0/src/minimax_sdk/types/files.py +26 -0
  22. minimax_sdk-0.1.0/src/minimax_sdk/types/image.py +24 -0
  23. minimax_sdk-0.1.0/src/minimax_sdk/types/music.py +13 -0
  24. minimax_sdk-0.1.0/src/minimax_sdk/types/speech.py +32 -0
  25. minimax_sdk-0.1.0/src/minimax_sdk/types/text.py +164 -0
  26. minimax_sdk-0.1.0/src/minimax_sdk/types/video.py +43 -0
  27. minimax_sdk-0.1.0/src/minimax_sdk/types/voice.py +46 -0
  28. minimax_sdk-0.1.0/tests/__init__.py +0 -0
  29. minimax_sdk-0.1.0/tests/conftest.py +50 -0
  30. minimax_sdk-0.1.0/tests/integration/__init__.py +0 -0
  31. minimax_sdk-0.1.0/tests/integration/conftest.py +12 -0
  32. minimax_sdk-0.1.0/tests/integration/outputs/image_base64.png +0 -0
  33. minimax_sdk-0.1.0/tests/integration/outputs/image_t2i.png +0 -0
  34. minimax_sdk-0.1.0/tests/integration/outputs/music_generated.mp3 +0 -0
  35. minimax_sdk-0.1.0/tests/integration/outputs/music_instrumental.mp3 +0 -0
  36. minimax_sdk-0.1.0/tests/integration/outputs/speech_async_generate.mp3 +0 -0
  37. minimax_sdk-0.1.0/tests/integration/test_files.py +104 -0
  38. minimax_sdk-0.1.0/tests/integration/test_image.py +89 -0
  39. minimax_sdk-0.1.0/tests/integration/test_music.py +105 -0
  40. minimax_sdk-0.1.0/tests/integration/test_speech.py +162 -0
  41. minimax_sdk-0.1.0/tests/integration/test_text.py +149 -0
  42. minimax_sdk-0.1.0/tests/integration/test_video.py +79 -0
  43. minimax_sdk-0.1.0/tests/integration/test_voice.py +127 -0
  44. minimax_sdk-0.1.0/tests/test_audio.py +170 -0
  45. minimax_sdk-0.1.0/tests/test_base.py +46 -0
  46. minimax_sdk-0.1.0/tests/test_client.py +276 -0
  47. minimax_sdk-0.1.0/tests/test_exceptions.py +176 -0
  48. minimax_sdk-0.1.0/tests/test_files.py +308 -0
  49. minimax_sdk-0.1.0/tests/test_http.py +1655 -0
  50. minimax_sdk-0.1.0/tests/test_image.py +285 -0
  51. minimax_sdk-0.1.0/tests/test_music.py +459 -0
  52. minimax_sdk-0.1.0/tests/test_polling.py +423 -0
  53. minimax_sdk-0.1.0/tests/test_speech.py +1461 -0
  54. minimax_sdk-0.1.0/tests/test_text.py +999 -0
  55. minimax_sdk-0.1.0/tests/test_video.py +558 -0
  56. minimax_sdk-0.1.0/tests/test_voice.py +458 -0
@@ -0,0 +1,17 @@
1
+ .env
2
+ .firecrawl/
3
+ __pycache__/
4
+ *.pyc
5
+ *.pyo
6
+ .ruff_cache/
7
+ .pytest_cache/
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+ .venv/
12
+ uv.lock
13
+ .coverage
14
+ .claude/
15
+ .DS_Store
16
+ python/tests/integration/outputs/
17
+ docs/specs/
@@ -0,0 +1,595 @@
1
+ Metadata-Version: 2.4
2
+ Name: minimax-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for MiniMax multimodal APIs
5
+ Project-URL: Homepage, https://github.com/tsen1220/minimax-sdk
6
+ Project-URL: Repository, https://github.com/tsen1220/minimax-sdk
7
+ Project-URL: Documentation, https://github.com/tsen1220/minimax-sdk#readme
8
+ Author: Ken Tseng
9
+ License-Expression: MIT
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: httpx>=0.27
22
+ Requires-Dist: pydantic>=2.0
23
+ Requires-Dist: websockets>=12.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
26
+ Requires-Dist: pytest-cov>=6.0; extra == 'dev'
27
+ Requires-Dist: pytest>=8.0; extra == 'dev'
28
+ Requires-Dist: python-dotenv>=1.0; extra == 'dev'
29
+ Requires-Dist: respx>=0.22; extra == 'dev'
30
+ Requires-Dist: ruff>=0.8; extra == 'dev'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # MiniMax SDK for Python
34
+
35
+ Python SDK for [MiniMax](https://platform.minimax.io/) multimodal APIs -- Text, Speech, Voice, Video, Image, Music, and File management.
36
+
37
+ [![PyPI version](https://img.shields.io/pypi/v/minimax-sdk.svg)](https://pypi.org/project/minimax-sdk/)
38
+ [![Python](https://img.shields.io/pypi/pyversions/minimax-sdk.svg)](https://pypi.org/project/minimax-sdk/)
39
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
40
+
41
+ ## Table of Contents
42
+
43
+ - [Installation](#installation)
44
+ - [Quick Start](#quick-start)
45
+ - [Configuration](#configuration)
46
+ - [Resources](#resources)
47
+ - [Text](#text----clienttext)
48
+ - [Speech](#speech----clientspeech)
49
+ - [Voice](#voice----clientvoice)
50
+ - [Video](#video----clientvideo)
51
+ - [Image](#image----clientimage)
52
+ - [Music](#music----clientmusic)
53
+ - [Files](#files----clientfiles)
54
+ - [Async Support](#async-support)
55
+ - [Error Handling](#error-handling)
56
+ - [License](#license)
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install minimax-sdk
62
+ ```
63
+
64
+ **Requirements:** Python 3.10+
65
+
66
+ ## Quick Start
67
+
68
+ ```python
69
+ from minimax_sdk import MiniMax
70
+
71
+ client = MiniMax(api_key="your-api-key")
72
+
73
+ # Text generation
74
+ result = client.text.create(
75
+ model="MiniMax-M2.7",
76
+ messages=[{"role": "user", "content": "Hello"}],
77
+ max_tokens=1024,
78
+ )
79
+
80
+ # Text-to-Speech
81
+ audio = client.speech.tts(text="Hello world", model="speech-2.8-hd")
82
+ audio.save("hello.mp3")
83
+
84
+ # Generate an image
85
+ result = client.image.generate(prompt="A cat on the moon", model="image-01")
86
+ print(result.image_urls)
87
+
88
+ # Generate a video (auto-polls until complete)
89
+ result = client.video.text_to_video(prompt="A sunrise over the ocean", model="MiniMax-Hailuo-2.3")
90
+ print(result.download_url)
91
+ ```
92
+
93
+ ## Configuration
94
+
95
+ ### Constructor Parameters
96
+
97
+ ```python
98
+ client = MiniMax(
99
+ api_key="...", # required (or set MINIMAX_API_KEY env var)
100
+ base_url="https://api.minimax.io", # API base URL
101
+ timeout_connect=5.0, # connection timeout (seconds)
102
+ timeout_read=600.0, # read timeout (seconds)
103
+ timeout_write=600.0, # write timeout (seconds)
104
+ timeout_pool=600.0, # pool timeout (seconds)
105
+ max_retries=2, # auto-retry on server/rate-limit errors
106
+ poll_interval=5.0, # async task polling interval (seconds)
107
+ poll_timeout=600.0, # async task max wait time (seconds)
108
+ )
109
+ ```
110
+
111
+ ### Environment Variables
112
+
113
+ Only `api_key` and `base_url` support environment variables. All other settings use constructor parameters with built-in defaults.
114
+
115
+ | Environment Variable | Default | Description |
116
+ |---------------------|---------|-------------|
117
+ | `MINIMAX_API_KEY` | *(required)* | Your MiniMax API key |
118
+ | `MINIMAX_BASE_URL` | `https://api.minimax.io` | API base URL |
119
+
120
+ ```bash
121
+ export MINIMAX_API_KEY="your-api-key"
122
+ ```
123
+
124
+ ```python
125
+ from minimax_sdk import MiniMax
126
+
127
+ # Reads MINIMAX_API_KEY from environment automatically
128
+ client = MiniMax()
129
+ ```
130
+
131
+ ## Resources
132
+
133
+ ### Text -- `client.text`
134
+
135
+ Uses MiniMax's Anthropic-compatible endpoint (`/anthropic/v1/messages`). Supports models: `MiniMax-M2.7`, `MiniMax-M2.5`, `MiniMax-M2.1`, `MiniMax-M2`, and their highspeed variants.
136
+
137
+ #### Basic Text Generation
138
+
139
+ ```python
140
+ result = client.text.create(
141
+ model="MiniMax-M2.7",
142
+ messages=[{"role": "user", "content": "Hello"}],
143
+ max_tokens=1024,
144
+ )
145
+ # MiniMax models may return ThinkingBlocks before TextBlocks
146
+ for block in result.content:
147
+ if block.type == "text":
148
+ print(block.text)
149
+ ```
150
+
151
+ #### With System Prompt
152
+
153
+ ```python
154
+ result = client.text.create(
155
+ model="MiniMax-M2.7",
156
+ messages=[{"role": "user", "content": "Explain quantum computing"}],
157
+ max_tokens=1024,
158
+ system="You are a physics professor. Explain concisely.",
159
+ temperature=0.7,
160
+ )
161
+ ```
162
+
163
+ #### Streaming
164
+
165
+ ```python
166
+ for event in client.text.create_stream(
167
+ model="MiniMax-M2.7",
168
+ messages=[{"role": "user", "content": "Write a short poem"}],
169
+ max_tokens=512,
170
+ ):
171
+ if event.type == "content_block_delta" and event.delta.type == "text_delta":
172
+ print(event.delta.text, end="", flush=True)
173
+ ```
174
+
175
+ #### Tool Use (Function Calling)
176
+
177
+ ```python
178
+ result = client.text.create(
179
+ model="MiniMax-M2.7",
180
+ messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
181
+ max_tokens=1024,
182
+ tools=[{
183
+ "name": "get_weather",
184
+ "description": "Get current weather for a location",
185
+ "input_schema": {
186
+ "type": "object",
187
+ "properties": {"location": {"type": "string"}},
188
+ "required": ["location"],
189
+ },
190
+ }],
191
+ )
192
+
193
+ for block in result.content:
194
+ if block.type == "tool_use":
195
+ print(f"Call {block.name} with {block.input}")
196
+ ```
197
+
198
+ #### Extended Thinking
199
+
200
+ ```python
201
+ result = client.text.create(
202
+ model="MiniMax-M2.7",
203
+ messages=[{"role": "user", "content": "Solve: what is 127 * 389?"}],
204
+ max_tokens=4096,
205
+ thinking={"type": "enabled", "budget_tokens": 2048},
206
+ )
207
+
208
+ for block in result.content:
209
+ if block.type == "thinking":
210
+ print(f"Thinking: {block.thinking}")
211
+ elif block.type == "text":
212
+ print(f"Answer: {block.text}")
213
+ ```
214
+
215
+ ### Speech -- `client.speech`
216
+
217
+ #### Synchronous TTS
218
+
219
+ ```python
220
+ audio = client.speech.tts(
221
+ text="Hello world",
222
+ model="speech-2.8-hd",
223
+ voice_setting={"voice_id": "English_expressive_narrator", "speed": 1.0},
224
+ audio_setting={"format": "mp3", "sample_rate": 32000},
225
+ )
226
+ audio.save("output.mp3")
227
+ ```
228
+
229
+ #### Streaming TTS
230
+
231
+ ```python
232
+ for chunk in client.speech.tts_stream(text="Hello world", model="speech-2.8-hd"):
233
+ player.write(chunk)
234
+ ```
235
+
236
+ #### WebSocket (Real-Time, Multi-Turn)
237
+
238
+ ```python
239
+ with client.speech.connect(
240
+ model="speech-2.8-hd",
241
+ voice_setting={"voice_id": "English_expressive_narrator"},
242
+ ) as conn:
243
+ audio = conn.send("Hello, how are you?")
244
+ audio.save("chunk1.mp3")
245
+ audio = conn.send("I'm doing great.")
246
+ audio.save("chunk2.mp3")
247
+ ```
248
+
249
+ #### Long-Text Async TTS (up to 100K characters)
250
+
251
+ The high-level `async_generate` method creates a task, polls until completion, and returns the result with a download URL:
252
+
253
+ ```python
254
+ result = client.speech.async_generate(
255
+ text="Very long text...",
256
+ model="speech-2.8-hd",
257
+ voice_setting={"voice_id": "English_expressive_narrator"},
258
+ )
259
+ print(result.download_url)
260
+ ```
261
+
262
+ For lower-level control, use `async_create` and `async_query` separately:
263
+
264
+ ```python
265
+ task = client.speech.async_create(
266
+ text="Very long text...",
267
+ model="speech-2.8-hd",
268
+ voice_setting={"voice_id": "English_expressive_narrator"},
269
+ )
270
+ task_id = task["task_id"]
271
+
272
+ # Poll manually
273
+ status = client.speech.async_query(task_id)
274
+ ```
275
+
276
+ ### Voice -- `client.voice`
277
+
278
+ > **Note:** `voice.clone` and `voice.design` require a [pay-as-you-go](https://platform.minimax.io/user-center/basic-information/interface-key) account with sufficient balance. They are not covered by the Token Plan. `voice.list` and `voice.delete` work with any account.
279
+
280
+ #### Clone a Voice
281
+
282
+ ```python
283
+ file_info = client.voice.upload_audio("reference.mp3")
284
+ result = client.voice.clone(file_id=file_info.file_id, voice_id="my-custom-voice")
285
+ ```
286
+
287
+ #### Design a Voice from Description
288
+
289
+ ```python
290
+ result = client.voice.design(
291
+ prompt="A warm, friendly male narrator",
292
+ preview_text="Hello, welcome to our show.",
293
+ )
294
+ result.trial_audio.save("preview.mp3")
295
+ print(result.voice_id) # use this in TTS calls
296
+ ```
297
+
298
+ #### List and Delete Voices
299
+
300
+ ```python
301
+ voices = client.voice.list(voice_type="voice_cloning")
302
+ client.voice.delete(voice_id="my-custom-voice", voice_type="voice_cloning")
303
+ ```
304
+
305
+ ### Video -- `client.video`
306
+
307
+ All high-level video methods automatically poll until the generation task completes and return a `VideoResult` with a temporary download URL.
308
+
309
+ #### Text to Video
310
+
311
+ ```python
312
+ result = client.video.text_to_video(
313
+ prompt="A cat playing piano",
314
+ model="MiniMax-Hailuo-2.3",
315
+ duration=6,
316
+ resolution="1080P",
317
+ )
318
+ print(result.download_url)
319
+ ```
320
+
321
+ #### Image to Video
322
+
323
+ ```python
324
+ result = client.video.image_to_video(
325
+ first_frame_image="https://example.com/photo.jpg",
326
+ prompt="The scene comes alive",
327
+ model="MiniMax-Hailuo-2.3",
328
+ )
329
+ ```
330
+
331
+ #### First and Last Frame to Video
332
+
333
+ ```python
334
+ result = client.video.frames_to_video(
335
+ last_frame_image="https://example.com/end.jpg",
336
+ first_frame_image="https://example.com/start.jpg",
337
+ model="MiniMax-Hailuo-02",
338
+ )
339
+ ```
340
+
341
+ #### Subject Reference Video
342
+
343
+ ```python
344
+ result = client.video.subject_to_video(
345
+ subject_reference=[{"type": "character", "image": ["https://example.com/face.jpg"]}],
346
+ prompt="A person waving at the camera",
347
+ model="S2V-01",
348
+ )
349
+ ```
350
+
351
+ #### Low-Level Control
352
+
353
+ ```python
354
+ task = client.video.create(model="MiniMax-Hailuo-2.3", prompt="...")
355
+ status = client.video.query(task["task_id"])
356
+ ```
357
+
358
+ ### Image -- `client.image`
359
+
360
+ #### Text to Image
361
+
362
+ ```python
363
+ result = client.image.generate(
364
+ prompt="A futuristic city at sunset",
365
+ model="image-01",
366
+ aspect_ratio="16:9",
367
+ n=3,
368
+ )
369
+ print(result.image_urls)
370
+ ```
371
+
372
+ #### Image to Image (with Subject Reference)
373
+
374
+ ```python
375
+ result = client.image.generate(
376
+ prompt="A woman in a garden",
377
+ model="image-01",
378
+ subject_reference=[{"type": "character", "image_file": "https://example.com/face.jpg"}],
379
+ )
380
+ ```
381
+
382
+ #### Additional Parameters
383
+
384
+ ```python
385
+ result = client.image.generate(
386
+ prompt="...",
387
+ model="image-01",
388
+ response_format="base64", # "url" (default) or "base64"
389
+ width=1024, # explicit dimensions (mutually exclusive with aspect_ratio)
390
+ height=768,
391
+ seed=42, # reproducibility
392
+ n=2, # number of images
393
+ prompt_optimizer=True, # let the API optimize the prompt
394
+ )
395
+ ```
396
+
397
+ ### Music -- `client.music`
398
+
399
+ #### Generate Music
400
+
401
+ ```python
402
+ audio = client.music.generate(
403
+ model="music-2.5+",
404
+ prompt="Indie folk, melancholic mood",
405
+ lyrics="[Verse]\nWalking down the empty road\n[Chorus]\nBut I know the sun will rise",
406
+ )
407
+ audio.save("song.mp3")
408
+ ```
409
+
410
+ #### Generate with Streaming
411
+
412
+ ```python
413
+ chunks = []
414
+ for chunk in client.music.generate_stream(
415
+ model="music-2.5+",
416
+ prompt="Lo-fi hip hop beats",
417
+ is_instrumental=True,
418
+ ):
419
+ chunks.append(chunk)
420
+ ```
421
+
422
+ #### Generate Lyrics First, Then Music
423
+
424
+ ```python
425
+ lyrics = client.music.generate_lyrics(
426
+ mode="write_full_song",
427
+ prompt="A cheerful summer love song",
428
+ )
429
+ print(lyrics.lyrics)
430
+
431
+ audio = client.music.generate(model="music-2.5+", lyrics=lyrics.lyrics)
432
+ audio.save("summer.mp3")
433
+ ```
434
+
435
+ #### Instrumental Music
436
+
437
+ ```python
438
+ audio = client.music.generate(
439
+ model="music-2.5+",
440
+ prompt="Lo-fi hip hop beats",
441
+ is_instrumental=True,
442
+ )
443
+ ```
444
+
445
+ ### Files -- `client.files`
446
+
447
+ ```python
448
+ # Upload a file
449
+ file_info = client.files.upload("audio.mp3", purpose="voice_clone")
450
+
451
+ # List files by purpose
452
+ files = client.files.list(purpose="voice_clone")
453
+
454
+ # Retrieve file metadata (includes a temporary download URL)
455
+ info = client.files.retrieve(file_id="123")
456
+ print(info.download_url)
457
+
458
+ # Download raw file content
459
+ content = client.files.retrieve_content(file_id="123")
460
+
461
+ # Delete a file
462
+ client.files.delete(file_id="123", purpose="voice_clone")
463
+ ```
464
+
465
+ ## Async Support
466
+
467
+ Every resource method has an async counterpart via `AsyncMiniMax`. The API is identical -- just add `await`:
468
+
469
+ ```python
470
+ import asyncio
471
+ from minimax_sdk import AsyncMiniMax
472
+
473
+ async def main():
474
+ client = AsyncMiniMax(api_key="your-api-key")
475
+
476
+ # Text generation
477
+ result = await client.text.create(
478
+ model="MiniMax-M2.7",
479
+ messages=[{"role": "user", "content": "Hello"}],
480
+ max_tokens=1024,
481
+ )
482
+
483
+ # Streaming text
484
+ async for event in client.text.create_stream(
485
+ model="MiniMax-M2.7",
486
+ messages=[{"role": "user", "content": "Hello"}],
487
+ max_tokens=1024,
488
+ ):
489
+ if event.type == "content_block_delta" and event.delta.type == "text_delta":
490
+ print(event.delta.text, end="")
491
+
492
+ # All methods are awaitable
493
+ audio = await client.speech.tts(text="Hello", model="speech-2.8-hd")
494
+ audio.save("hello.mp3")
495
+
496
+ result = await client.video.text_to_video(
497
+ prompt="A sunrise over the ocean",
498
+ model="MiniMax-Hailuo-2.3",
499
+ )
500
+ print(result.download_url)
501
+
502
+ # Async context manager support
503
+ async with AsyncMiniMax(api_key="your-api-key") as client:
504
+ result = await client.image.generate(prompt="A cat", model="image-01")
505
+
506
+ # Async WebSocket
507
+ async with client.speech.connect(
508
+ model="speech-2.8-hd",
509
+ voice_setting={"voice_id": "English_expressive_narrator"},
510
+ ) as conn:
511
+ audio = await conn.send("Hello!")
512
+ audio.save("hello.mp3")
513
+
514
+ # Async streaming music
515
+ async for chunk in client.music.generate_stream(
516
+ model="music-2.5+",
517
+ prompt="Ambient electronic",
518
+ is_instrumental=True,
519
+ ):
520
+ process(chunk)
521
+
522
+ await client.close()
523
+
524
+ asyncio.run(main())
525
+ ```
526
+
527
+ Both `MiniMax` and `AsyncMiniMax` support context managers for automatic resource cleanup:
528
+
529
+ ```python
530
+ # Sync
531
+ with MiniMax(api_key="your-api-key") as client:
532
+ audio = client.speech.tts(text="Hello", model="speech-2.8-hd")
533
+
534
+ # Async
535
+ async with AsyncMiniMax(api_key="your-api-key") as client:
536
+ audio = await client.speech.tts(text="Hello", model="speech-2.8-hd")
537
+ ```
538
+
539
+ ## Error Handling
540
+
541
+ All exceptions inherit from `MiniMaxError` and carry structured error information:
542
+
543
+ - `code` -- the MiniMax API status code
544
+ - `message` -- human-readable error description
545
+ - `trace_id` -- request trace identifier for debugging
546
+
547
+ ### Exception Hierarchy
548
+
549
+ | Exception | Description |
550
+ |----------------------------|---------------------------------------------------|
551
+ | `MiniMaxError` | Base class for all SDK errors |
552
+ | `AuthError` | Invalid API key (codes 1004, 2049) |
553
+ | `RateLimitError` | Rate limit exceeded; auto-retried first |
554
+ | `InsufficientBalanceError` | Account balance too low (codes 1008, 2056) |
555
+ | `ContentSafetyError` | Content safety violation (base class) |
556
+ | `InputSafetyError` | Input triggered safety filter (code 1026) |
557
+ | `OutputSafetyError` | Output triggered safety filter (code 1027) |
558
+ | `InvalidParameterError` | Invalid request parameters |
559
+ | `APITimeoutError` | Server-side request timeout (code 1001) |
560
+ | `PollTimeoutError` | SDK-side polling timeout (task did not complete) |
561
+ | `ServerError` | Server-side error, typically retryable |
562
+ | `VoiceError` | Base class for voice-related errors |
563
+ | `VoiceCloneError` | Voice cloning failed |
564
+ | `VoiceDuplicateError` | Duplicate voice clone attempt |
565
+ | `VoicePermissionError` | Voice access denied |
566
+
567
+ ### Example
568
+
569
+ ```python
570
+ from minimax_sdk import MiniMax, RateLimitError, ContentSafetyError, AuthError, APITimeoutError, MiniMaxError
571
+
572
+ client = MiniMax(api_key="your-api-key")
573
+
574
+ try:
575
+ result = client.video.text_to_video(prompt="...", model="MiniMax-Hailuo-2.3")
576
+ except RateLimitError:
577
+ # Auto-retried up to max_retries times before being raised
578
+ print("Rate limited after all retries")
579
+ except ContentSafetyError:
580
+ # Input or output content violated safety policy
581
+ print("Content safety violation")
582
+ except AuthError:
583
+ # Invalid API key
584
+ print("Authentication failed")
585
+ except APITimeoutError:
586
+ # Server-side timeout
587
+ print("Request timed out")
588
+ except MiniMaxError as e:
589
+ # Catch-all for any MiniMax error
590
+ print(f"Error {e.code}: {e.message} (trace_id={e.trace_id})")
591
+ ```
592
+
593
+ ## License
594
+
595
+ [MIT](../LICENSE)