Skip to main content

Installation

pip install framelane

Quick start

Upload local media via POST /v1/uploads first, then pass the returned source_url below.
import os
import framelane

client = framelane.Framelane(api_key=os.environ["FRAMELANE_API_KEY"])

# Submit a render
render = client.renders.create(
    width=1920,
    height=1080,
    duration=10.0,
    frame_rate=30,
    output_format="mp4",
    elements=[
        {
            "type": "video",
            "id": "clip1",
            "source_url": os.environ["SOURCE_URL"],
            "time": 0,
            "in_point": 0,
            "out_point": 10,
        }
    ],
)

# Wait for completion
completed = client.renders.wait_for_completion(render.id)
print(completed.output.url)

API coverage

ResourceMethods
client.renderscreate, get, list, cancel, download, wait_for_completion
client.taskscreate, get, list, cancel, download, wait_for_completion
client.webhookscreate, get, list, update, delete, test, rotate_secret
client.api_keyscreate, list, revoke
client.workspaceget, get_usage, update, delete

Webhook signature verification

from framelane import verify_webhook_signature
from flask import Flask, request

app = Flask(__name__)

@app.post("/hooks/framelane")
def handle_webhook():
    is_valid = verify_webhook_signature(
        raw_body=request.data,
        signature=request.headers.get("Framelane-Signature"),
        secret=os.environ["FRAMELANE_WEBHOOK_SECRET"],
    )
    if not is_valid:
        return "Invalid signature", 400

    event = request.json
    # handle event...
    return "", 200

Async support

import asyncio
import framelane

async def main():
    client = framelane.AsyncFramelane(api_key=os.environ["FRAMELANE_API_KEY"])
    render = await client.renders.create(...)
    completed = await client.renders.wait_for_completion(render.id)
    print(completed.output.url)

asyncio.run(main())