Skip to main content

Decart Python SDK

A Python SDK for Decart's models.

Installation

Using UV

uv add decart

Using pip

pip install decart

Documentation

For complete documentation, guides, and examples, visit: https://docs.platform.decart.ai/sdks/python

Quick Start

Image Editing (Process API)

import asyncio
import os
from decart import DecartClient, models

async def main():
    async with DecartClient(api_key=os.getenv("DECART_API_KEY")) as client:
        # Edit an image
        result = await client.process({
            "model": models.image("lucy-image-2"),
            "prompt": "Apply a painterly oil-on-canvas look while preserving the composition",
            "data": open("input.png", "rb"),
        })

        with open("output.png", "wb") as f:
            f.write(result)

asyncio.run(main())

Video Editing (Queue API)

For video editing jobs, use the queue API to submit jobs and poll for results:

async with DecartClient(api_key=os.getenv("DECART_API_KEY")) as client:
    # Submit and poll automatically
    result = await client.queue.submit_and_poll({
        "model": models.video("lucy-clip"),
        "prompt": "Restyle this footage with anime shading and vibrant neon highlights",
        "data": open("input.mp4", "rb"),
        "on_status_change": lambda job: print(f"Status: {job.status}"),
    })

    if result.status == "completed":
        with open("output.mp4", "wb") as f:
            f.write(result.data)
    else:
        print(f"Job failed: {result.error}")

Or manage the polling manually:

async with DecartClient(api_key=os.getenv("DECART_API_KEY")) as client:
    # Submit the job
    job = await client.queue.submit({
        "model": models.video("lucy-clip"),
        "prompt": "Add cinematic teal-and-orange grading and gentle film grain",
        "data": open("input.mp4", "rb"),
    })
    print(f"Job ID: {job.job_id}")

    # Poll for status
    status = await client.queue.status(job.job_id)
    print(f"Status: {status.status}")

    # Get result when completed
    if status.status == "completed":
        data = await client.queue.result(job.job_id)
        with open("output.mp4", "wb") as f:
            f.write(data)

Client tokens

Create short-lived client tokens on your backend and hand the signed token to your frontend. Its claims (service_tier, allowed models and origins, expiry, ...) are signed into the JWT, so your backend can verify and read them offline instead of round-tripping to the platform. Verification needs the verify extra (pip install "decart[verify]", adds PyJWT + cryptography):

from decart import DecartClient, TokenVerifyError, verify_client_token

async with DecartClient(api_key=os.getenv("DECART_API_KEY")) as client:
    token = await client.tokens.create(expires_in=300, metadata={"service_tier": 0})

    verified = await client.tokens.verify(token.token)  # or: await verify_client_token(token.token)
    verified.service_tier  # 0
    verified.pool          # "free" for tier 0, else "paid"
    verified.user_id, verified.organization_id, verified.api_key_id, verified.expires_at

verify checks the Ed25519 signature against the platform JWKS (https://platform.decart.ai/api/auth/jwks, fetched once and cached), plus exp, iss and aud. It raises TokenVerifyError on a tampered, expired or foreign token. It is offline JWKS verification, unrelated to the gateway's online POST /v1/verify. To inspect a token without verifying it, client.tokens.decode(token) / decode_client_token(token) returns the same fields, untrusted. The SDK is async-only; from sync code use asyncio.run(verify_client_token(token)).

Realtime fast mode

Realtime sessions accept an optional speed on RealtimeConnectOptions, alongside resolution. Fast mode (speed="fast") serves the session from a higher-compute tier for lower latency and higher throughput; output quality is unchanged. It is currently available for lucy-2.5 / lucy-latest, lucy-vton-3.5, and lucy-vton-3.6 / lucy-vton-latest (lucy-vton-latest currently resolves to lucy-vton-3.6), in the US region only, and is billed at 2x the standard realtime rate for those models. Other models ignore the option (the SDK emits a warning). Omit it (the default) for standard mode.

from decart import DecartClient, models
from decart.realtime import RealtimeClient, RealtimeConnectOptions

client = DecartClient(api_key=os.getenv("DECART_API_KEY"))
realtime = await RealtimeClient.connect(
    base_url=client.realtime_base_url,
    api_key=client.api_key,
    local_track=local_track,
    options=RealtimeConnectOptions(
        model=models.realtime("lucy-2.5"),
        on_remote_stream=on_remote_stream,
        speed="fast",  # omit for standard mode
    ),
)

Each model definition lists the speed tiers it advertises via ModelDefinition.supported_speeds (for example models.realtime("lucy-2.5").supported_speeds == ("fast",)). See the realtime docs for the full realtime API.

Development

Setup with UV

# Clone the repository
git clone https://github.com/decartai/decart-python
cd decart-python

# Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install all dependencies (including dev dependencies)
uv sync --all-extras

# Run tests
uv run pytest

# Run linting
uv run ruff check decart/ tests/ examples/

# Format code
uv run black decart/ tests/ examples/

# Type check
uv run mypy decart/

Common Commands

# Install dependencies
uv sync --all-extras

# Run tests with coverage
uv run pytest --cov=decart --cov-report=html

# Run examples
uv run python examples/process_video.py
uv run python examples/realtime_synthetic.py

# Update dependencies
uv lock --upgrade

Test UI

The SDK includes an interactive test UI built with Gradio for quickly testing all SDK features without writing code.

# Install Gradio
pip install gradio

# Run the test UI
python test_ui.py

Then open http://localhost:7860 in your browser.

The UI provides tabs for:

  • Image Editing - Image-to-image edits
  • Video Editing - Video-to-video edits
  • Video Restyle - Restyle videos using text prompts or reference images
  • Tokens - Create short-lived client tokens

Enter your API key at the top of the interface to start testing.

Publishing a New Version

The package is automatically published to PyPI when you create a GitHub release.

Automated Release

Use the release script to automate the entire process:

python release.py

The script will:

  1. Display the current version
  2. Prompt for the new version
  3. Update pyproject.toml
  4. Commit and push changes
  5. Create a GitHub release with release notes

The GitHub Actions workflow will automatically build, test, and publish to PyPI.

License

MIT

Metadata

Release files for decart 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for decart 0.2.2
File Size Uploaded
decart-0.2.2.tar.gz 189.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for decart 0.2.2
File Interpreter ABI Platform
decart-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 230.9 kB

Release files / decart-0.2.2.tar.gz

Download URL decart-0.2.2.tar.gz
Size 189.3 kB
Tags Source
SHA-256 checksum
How to use checksums
da8f5a1bcdafddf310b16924f8544ee8db0378c7c5a4d09018bb891e4f391fd0
BLAKE2b-256 checksum
How to use checksums
5c5a3e5f44ec1824d8584d622c268918e5c604518cf635f493f019b294d88c33
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / decart-0.2.2-py3-none-any.whl

Download URL decart-0.2.2-py3-none-any.whl
Size 41.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
70cdc96c2cbb3e4903fa306fb91cd9bff6c3f869e3d4c7b704b313229bbd83ae
BLAKE2b-256 checksum
How to use checksums
428aa91f0d2bd6e73d3e8800ff6aa4664c895d3aca9feab99e95648e44626856
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.3

2 release files

This release

0.2.2 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.39

2 release files

0.0.38

2 release files

0.0.36

2 release files

0.0.35

2 release files

0.0.34

2 release files

0.0.30

2 release files

0.0.29

2 release files

0.0.25

2 release files

0.0.23

2 release files

0.0.22

2 release files

0.0.21

2 release files

0.0.20

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page