Skip to main content

Official RunMux Python SDK — video generation (Seedance 2.0) and the face asset library, with submit-and-wait helpers so you never hand-roll polling.

Project description

runmux

Official Python SDK for RunMux — generate video with Seedance 2.0 and manage the face asset library, without hand-rolling polling loops or the multi-step face upload.

Synchronous and Pythonic: construct one client, call resource methods with keyword arguments, get plain dicts back.

Install

pip install runmux

Requires Python 3.9+ (built on httpx).

Quickstart — text to video (one call)

import os
from runmux import RunmuxClient

client = RunmuxClient(api_key=os.environ["RUNMUX_API_KEY"])

# run() submits the job AND waits for the result — no polling code on your side.
video = client.videos.run(
    model="seedance-2-0-mini",
    prompt="a diamond necklace rotating on black velvet, soft highlights, product ad",
    resolution="480p",
    duration=5,
)

print(video["url"])  # downloadable result (expires ~1h unless you pass ttl)

The API key falls back to the RUNMUX_API_KEY environment variable, so RunmuxClient() works when that variable is set.

Prefer to manage polling yourself? Use create() then wait():

job = client.videos.create(model="seedance-2-0-mini", prompt="...")
done = client.videos.wait(job["id"])

Putting a person in the video (faces)

Raw human faces cannot be sent to the model directly. faces.enroll() runs the whole flow — register, wait until active, return the ready-to-use asset:// reference:

# Use an ordinary (non-celebrity) face photo.
asset_uri = client.faces.enroll(url="https://your-cdn.com/model.jpg")

video = client.videos.run(
    model="seedance-2-0-mini",
    prompt="Image 1 wearing the necklace, smiling at the camera",
    image_url=asset_uri,  # or reference_images=[asset_uri]
)

Even simpler — let RunMux enroll the face for you in one shot:

video = client.videos.run(
    model="seedance-2-0-mini",
    prompt="Image 1 wearing the necklace",
    image_url="https://your-cdn.com/model.jpg",
    auto_enroll_faces=True,
)

If a face is rejected (e.g. a celebrity / copyrighted likeness), the call raises a RunmuxError whose message explains why — switch to an ordinary face photo.

Image-to-video, batches, and inputs

# Product image as the first frame:
client.videos.run(
    model="seedance-2-0-mini",
    prompt="the ring rotates",
    frame_images=["https://cdn/ring.jpg"],
)

# Several variations at once (number_results 1–4) returns a list:
variations = client.videos.run(
    model="seedance-2-0-mini", prompt="...", number_results=3
)

# Upload a local file, then reference it:
with open("ring.png", "rb") as f:
    file_url = client.files.upload(f.read(), "image/png")

frame_images entries may be plain URL/asset:// strings, or dicts with an explicit frame, e.g. {"image": "https://cdn/ring.jpg", "frame": "first"}.

Webhooks

Submit with webhook_url to get the result POSTed to you, then verify the signature against the raw request body:

ok = client.webhooks.verify(
    payload=raw_request_body,                 # the raw string body, not re-serialized
    signature=request.headers.get("x-runmux-signature"),
    secret=os.environ["RUNMUX_WEBHOOK_SECRET"],
)

The signature scheme is sha256=<hex> where the hex is HMAC-SHA256(raw_body, secret); comparison is constant-time.

Errors

Every non-2xx response (and any failed job/asset) raises a RunmuxError with .code, .status, and .request_id for precise branching and support.

from runmux import RunmuxError

try:
    client.videos.run(model="seedance-2-0-mini", prompt="...")
except RunmuxError as exc:
    print(exc.code, exc.status, exc.request_id)

API surface

  • client.videoscreate, run, wait, get
  • client.assetscreate, get, list, delete, wait_active
  • client.facesenroll, enroll_asset
  • client.filescreate_upload, upload
  • client.webhooksverify

Wire field names

You pass clean Python snake_case keyword arguments; the SDK maps them to the exact field names the API expects. For example image_url, reference_images, auto_enroll_faces, and number_results are sent as-is, while output_type, output_format, output_quality, and upload_endpoint are sent as their camelCase wire equivalents. Pass idempotency_key to dedup retries — it is sent as the Idempotency-Key header, not a body field.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

runmux-0.1.0.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

runmux-0.1.0-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

Details for the file runmux-0.1.0.tar.gz.

File metadata

  • Download URL: runmux-0.1.0.tar.gz
  • Upload date:
  • Size: 11.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for runmux-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9cca59eec5bde379677f6f0d0d6617a4feb90488799fdbd20a6bbf6570ef00a8
MD5 47c74ecc95aa382cc234768a71b9b01d
BLAKE2b-256 fb7697846e1e18c6f9c04023b42073095f258818100183da832c07d67af4ebc6

See more details on using hashes here.

File details

Details for the file runmux-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: runmux-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for runmux-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5f4d4755d16b416bafc38170001fcdc7c6a9c681226be442ff4f88acd1f33506
MD5 c65ffd706f4bd5eff3f41991032029ff
BLAKE2b-256 9e9c943b0723082fcfd1abc57d38b443d40f5fe9efb720ed9a00c5d3dea86d06

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page