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.
- minimax_sdk-0.1.0/.gitignore +17 -0
- minimax_sdk-0.1.0/PKG-INFO +595 -0
- minimax_sdk-0.1.0/README.md +563 -0
- minimax_sdk-0.1.0/pyproject.toml +51 -0
- minimax_sdk-0.1.0/src/minimax_sdk/__init__.py +125 -0
- minimax_sdk-0.1.0/src/minimax_sdk/_audio.py +156 -0
- minimax_sdk-0.1.0/src/minimax_sdk/_base.py +40 -0
- minimax_sdk-0.1.0/src/minimax_sdk/_http.py +716 -0
- minimax_sdk-0.1.0/src/minimax_sdk/_polling.py +184 -0
- minimax_sdk-0.1.0/src/minimax_sdk/client.py +303 -0
- minimax_sdk-0.1.0/src/minimax_sdk/exceptions.py +166 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/__init__.py +0 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/files.py +200 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/image.py +188 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/music.py +391 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/speech.py +1545 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/text.py +428 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/video.py +649 -0
- minimax_sdk-0.1.0/src/minimax_sdk/resources/voice.py +386 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/__init__.py +51 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/files.py +26 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/image.py +24 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/music.py +13 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/speech.py +32 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/text.py +164 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/video.py +43 -0
- minimax_sdk-0.1.0/src/minimax_sdk/types/voice.py +46 -0
- minimax_sdk-0.1.0/tests/__init__.py +0 -0
- minimax_sdk-0.1.0/tests/conftest.py +50 -0
- minimax_sdk-0.1.0/tests/integration/__init__.py +0 -0
- minimax_sdk-0.1.0/tests/integration/conftest.py +12 -0
- minimax_sdk-0.1.0/tests/integration/outputs/image_base64.png +0 -0
- minimax_sdk-0.1.0/tests/integration/outputs/image_t2i.png +0 -0
- minimax_sdk-0.1.0/tests/integration/outputs/music_generated.mp3 +0 -0
- minimax_sdk-0.1.0/tests/integration/outputs/music_instrumental.mp3 +0 -0
- minimax_sdk-0.1.0/tests/integration/outputs/speech_async_generate.mp3 +0 -0
- minimax_sdk-0.1.0/tests/integration/test_files.py +104 -0
- minimax_sdk-0.1.0/tests/integration/test_image.py +89 -0
- minimax_sdk-0.1.0/tests/integration/test_music.py +105 -0
- minimax_sdk-0.1.0/tests/integration/test_speech.py +162 -0
- minimax_sdk-0.1.0/tests/integration/test_text.py +149 -0
- minimax_sdk-0.1.0/tests/integration/test_video.py +79 -0
- minimax_sdk-0.1.0/tests/integration/test_voice.py +127 -0
- minimax_sdk-0.1.0/tests/test_audio.py +170 -0
- minimax_sdk-0.1.0/tests/test_base.py +46 -0
- minimax_sdk-0.1.0/tests/test_client.py +276 -0
- minimax_sdk-0.1.0/tests/test_exceptions.py +176 -0
- minimax_sdk-0.1.0/tests/test_files.py +308 -0
- minimax_sdk-0.1.0/tests/test_http.py +1655 -0
- minimax_sdk-0.1.0/tests/test_image.py +285 -0
- minimax_sdk-0.1.0/tests/test_music.py +459 -0
- minimax_sdk-0.1.0/tests/test_polling.py +423 -0
- minimax_sdk-0.1.0/tests/test_speech.py +1461 -0
- minimax_sdk-0.1.0/tests/test_text.py +999 -0
- minimax_sdk-0.1.0/tests/test_video.py +558 -0
- minimax_sdk-0.1.0/tests/test_voice.py +458 -0
|
@@ -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
|
+
[](https://pypi.org/project/minimax-sdk/)
|
|
38
|
+
[](https://pypi.org/project/minimax-sdk/)
|
|
39
|
+
[](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)
|