Python SDK
Use synchronous or asynchronous Python clients to validate videos, manage projects, and export files.
indream-client 1.1.0 supports Python 3.10 or later. It includes synchronous and asynchronous clients, typed responses, uploads, export polling and cancellation, and webhook verification.
Install
python -m pip install indream-client==1.1.0
curl --fail --output editor-state.json https://docs.indream.ai/examples/editor-state.jsonValidate and export
Save this as quick_start.py beside the downloaded sample. Replace the API-key placeholder and run it on your server.
import json
from pathlib import Path
from indream import IndreamClient
editor_state = json.loads(Path("editor-state.json").read_text())
with IndreamClient(api_key="<YOUR_API_KEY>") as client:
validation = client.editor.validate(editor_state)
if not validation.valid:
raise ValueError(validation.errors)
created = client.exports.create({
"editorState": editor_state,
"stateSchemaVersion": "v1",
"ratio": "16:9",
"scale": 1,
"fps": 30,
"format": "mp4",
"filename": "hello-indream.mp4",
})
print("Export:", created.task_id)
completed = client.exports.wait(created.task_id, timeout=600, poll_interval=2)
print(completed.status, completed.output_url)python quick_start.pyDownload the file from the completed task's output_url and save a copy if you need to retain it. Exports explains task states, output settings, and cancellation.
JSON request fields keep their API names, such as stateSchemaVersion. Typed Python response attributes use snake case, such as task_id, filename, export_phase, and billed_standard_seconds.
Use the asynchronous client
import asyncio
import json
from pathlib import Path
from indream import AsyncIndreamClient
async def main() -> None:
editor_state = json.loads(Path("editor-state.json").read_text())
async with AsyncIndreamClient(api_key="<YOUR_API_KEY>") as client:
created = await client.exports.create({
"editorState": editor_state,
"stateSchemaVersion": "v1",
"ratio": "16:9",
"scale": 1,
"fps": 30,
"format": "mp4",
})
completed = await client.exports.wait(created.task_id, timeout=600)
print(completed.output_url)
asyncio.run(main())Use the context managers to close the client's connections even when a request fails.
Save a project and upload a file
The following calls assume client is open and editor_state contains the sample:
project = client.projects.create({
"title": "Product introduction",
"editorState": editor_state,
"stateSchemaVersion": "v1",
})
asset = client.uploads.upload(
Path("hero.png").read_bytes(),
filename="hero.png",
content_type="image/png",
project_id=project.project_id,
)
print(asset.asset_id)To save a changed draft, call client.projects.sync(project.project_id, {"editorState": editor_state, "stateSchemaVersion": "v1"}). To export the saved draft, call client.projects.create_export(project.project_id, output_settings).
An uploaded asset needs a corresponding asset and item in editor state before it appears in the video. See Assets.
Track and cancel work
client.exports.get(task_id) returns the current task. client.exports.list(page_size=20) returns items and next_page_cursor. Pass that cursor as page_cursor to continue.
client.exports.wait returns a completed task. Failure or cancellation raises APIError with TASK_TERMINAL_FAILURE. A wait timeout raises TimeoutError and leaves the server task running. To cancel it, call client.exports.cancel(task_id).
Handle request errors
Catch APIError or its subclasses AuthError, ValidationError, and RateLimitError. Inspect the problem's error code before choosing a recovery action. An API-key usage cap is not temporary throttling.
Set timeout for individual HTTP requests and max_retries for eligible transient failures. The client does not automatically repeat uploads or arbitrary writes. For an export that may be retried, pass a stable idempotency_key and keep its payload unchanged.
See Errors and retries for quota, validation, and permission failures.
Verify a webhook
Use verify_export_webhook_request with the exact raw body and received headers, then validate the parsed JSON with ExportWebhookEvent:
import json
from indream import verify_export_webhook_request
from indream.types import ExportWebhookEvent
def parse_event(raw_body: str, headers: dict[str, str], webhook_secret: str):
if not verify_export_webhook_request(
webhook_secret=webhook_secret,
raw_body=raw_body,
headers=headers,
max_skew_seconds=300,
):
raise ValueError("Invalid webhook signature.")
return ExportWebhookEvent.model_validate(json.loads(raw_body))Read Webhooks for event types and durable delivery handling.
Source and issues: indream-client-python on GitHub. Package: indream-client on PyPI.
Last updated on