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.videos—create,run,wait,getclient.assets—create,get,list,delete,wait_activeclient.faces—enroll,enroll_assetclient.files—create_upload,uploadclient.webhooks—verify
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9cca59eec5bde379677f6f0d0d6617a4feb90488799fdbd20a6bbf6570ef00a8
|
|
| MD5 |
47c74ecc95aa382cc234768a71b9b01d
|
|
| BLAKE2b-256 |
fb7697846e1e18c6f9c04023b42073095f258818100183da832c07d67af4ebc6
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f4d4755d16b416bafc38170001fcdc7c6a9c681226be442ff4f88acd1f33506
|
|
| MD5 |
c65ffd706f4bd5eff3f41991032029ff
|
|
| BLAKE2b-256 |
9e9c943b0723082fcfd1abc57d38b443d40f5fe9efb720ed9a00c5d3dea86d06
|