Generate
Client Library

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.py
"""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.75

See Set a video's length for the supported counts, errors, and billing.

API reference

Please refer to the API Reference page.