Python Client
Submit and track tasks with the official MachGen Python client.
machgen-client is the official Python client. It wraps the
REST API with typed models, automatic uploads of local source
files, polling, and pushed status updates over server-sent events (SSE).
You can receive updates through a callback or block until the task finishes.
Python 3.11 or newer is required.
1. Install
pip install machgen-client 2. Provide your API key
By default the client reads your key (see
Get Started) from the MACHGEN_API_KEY environment
variable:
export MACHGEN_API_KEY="MGA_<key_id>:<secret>"from machgen.client import MachGenClient
with MachGenClient() as client:
...Or pass it explicitly - useful for multi-tenant code:
client = MachGenClient(api_key="MGA_<key_id>:<secret>")Required
If no key is supplied and MACHGEN_API_KEY is unset, the constructor raises a ValueError immediately - the client
never sends unauthenticated requests.
3. Examples
Each script submits a task, polls until it completes, and returns the asset
locator from result.task_output (keyed by output kind, e.g. image/video).
Tasks with input images
Some task types may involve input images like I2V (with optional last frame) and R2V.
Such tasks expect the field src_image_urls to be specified, which supports:
- local paths like
foo/bar.png- they are uploaded automatically on submission http(s)://URLs - they must be publicly accessible
For I2V the list is positional: entry 0 is the start frame, an optional entry
1 is the end frame (on models that support it - a second image otherwise returns
400). See Source images.
Refer to the examples below for different task types.
"""Text-to-video (T2V): generate a short clip from a text prompt."""
from __future__ import annotations
import time
from machgen.client import (
MachGenClient,
TaskInput,
TaskOutputType,
TaskStatus,
VideoConfig,
)
def run(client: MachGenClient) -> str:
task = TaskInput(
prompt="A red panda exploring a misty forest at dawn",
model="Wan2.2-A14B",
task_type="T2V",
video_config=VideoConfig(
duration_secs=5,
height=480,
aspect_ratio="16:9",
fps=16,
),
)
handle = client.submit_task(task)
result = client.get_task_state(handle)
while result.status not in (TaskStatus.COMPLETED, TaskStatus.FAILED):
time.sleep(2)
result = client.get_task_state(handle)
if result.status == TaskStatus.FAILED:
raise RuntimeError(f"Generation failed: {result.error_msg}")
assert result.task_output is not None
return result.task_output[TaskOutputType.VIDEO]
if __name__ == "__main__":
with MachGenClient() as client:
print(run(client))Waiting for results
submit_task returns a TaskHandle without waiting for completion. Pass
on_update to open a background SSE connection: the server pushes status
updates over this connection, and the client calls your callback as they arrive.
handle = client.submit_task(task, on_update=lambda state: print(state.status))
result = client.wait(handle, timeout=300.0)client.wait(handle) uses the same stream and blocks until the task reaches
COMPLETED or FAILED. It also opens an SSE connection when no callback is
supplied. The default timeout is 300 seconds; exceeding it raises TimeoutError
without cancelling the task.
For manual polling, client.get_task_state(handle) fetches the current status
once. Repeat that call as needed, as shown in the examples above. Polling alone
does not open an SSE connection.
Once the task has finished, client.get_task_billing(handle) returns what it
cost, the Generation Credit it earned back, and the net. Calling it earlier
raises httpx.HTTPStatusError with a 409 response, since the cost is not
final until the task completes or fails.
Once COMPLETED, client.download_asset(handle.task_id) returns the raw asset
bytes, or read the asset locator from result.task_output (keyed by output
kind) directly.
client.get_account() returns your balance together with how many of your
tasks are queued and running, if you want to pace submissions against your
account's concurrency limit.
Set a video's length
VideoConfig takes either duration_secs (whole seconds) or num_frames (a
frame count, on MiniMax-H3). The model renders the nearest frame count it
supports and returns it, with its exact length in seconds:
from machgen.client import MachGenClient, TaskInput, VideoConfig
task = TaskInput(
prompt="A red panda exploring a misty forest at dawn",
model="MiniMax-H3",
task_type="T2V",
video_config=VideoConfig(num_frames=90, height=768, aspect_ratio="16:9"), # 3.75s x 24
)
with MachGenClient() as client:
result = client.wait(client.submit_task(task))
print(result.metadata.num_frames, result.metadata.duration_secs) # 90 3.75See Set a video's length for the supported counts, errors, and billing.
API reference
Please refer to the API Reference page.