Python SDK

v1.0.0

Official Python client with sync and async interfaces covering every DUAL API endpoint. Built on httpx with automatic retry, Pydantic models, and a typed error hierarchy.

Python ≥ 3.9httpxpydantic v2

Installation

pip install dual-sdk

Quick Start

example.py
import os
from dual_sdk import DualClient

client = DualClient(
    token=os.environ["DUAL_API_KEY"],
    auth_mode="api_key",
)

# Returns a typed Wallet model
wallet = client.wallets.me()
print(wallet.id, wallet.email)

# Returns PaginatedResponse[Template]
page = client.templates.list(limit=20)
for tmpl in page.items:
    print(tmpl.name)

# Mint an object via the Event Bus
result = client.event_bus.execute(
    action={"mint": {"template_id": "tmpl_abc123", "custom": {"name": "My First Token"}}}
)
print(result.action_id)

Async Support

Use AsyncDualClient for non-blocking I/O. Every method mirrors the sync API with await.

async_example.py
import asyncio
from dual_sdk import AsyncDualClient

async def main():
    async with AsyncDualClient(token=os.environ["DUAL_API_KEY"], auth_mode="api_key") as client:
        wallet = await client.wallets.me()
        templates = await client.templates.list(limit=20)

        # Concurrent requests
        import asyncio
        results = await asyncio.gather(
            client.objects.list(limit=10),
            client.templates.list(limit=10),
            client.organizations.list(limit=10),
        )

asyncio.run(main())

Configuration

The SDK supports custom timeouts, retry policies with exponential backoff, and base URL configuration.

config.py
from dual_sdk import DualClient

# API key auth (default)
client = DualClient(
    token=os.environ["DUAL_API_KEY"],
    auth_mode="api_key",
    base_url="https://gateway-48587430648.europe-west6.run.app",  # default
    timeout=10.0,       # seconds
    max_retries=3,      # retry on 429/5xx
    backoff=1.0,        # exponential backoff base
)

# JWT bearer token auth
jwt_client = DualClient(
    token=os.environ["DUAL_JWT"],
    auth_mode="bearer",
)

Error Handling

All API errors are raised as DualError subclasses with status, code, message, and full response body.

error_handling.py
from dual_sdk import DualClient, DualError, DualAuthError, DualRateLimitError

client = DualClient(token=os.environ["DUAL_API_KEY"], auth_mode="api_key")

try:
    wallet = client.wallets.me()
except DualAuthError as e:
    print(f"Auth failed [{e.status}]: {e.code}")
except DualRateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
except DualError as e:
    print(f"API error [{e.status}]: {e.message}")
    print("Details:", e.body)

Modules

The SDK provides 14 modules accessible via client.module_name. Each module has identical sync and async interfaces.

ModuleCoverageDescription
.wallets14 methodsLogin, registration, profile, token refresh, linked wallets
.templates7 methodsCRUD operations, search, variations
.objects9 methodsCreate, list, search, children, parents, activity
.organizations18 methodsOrg management, members, roles, invitations
.payments2 methodsPayment config, deposit listing
.storage5 methodsFile upload, metadata, template assets
.webhooks6 methodsCRUD, test endpoint
.notifications7 methodsMessages, message templates
.event_bus8 methodsActions, action types, batch execution
.faces6 methodsFace CRUD, by template lookup
.sequencer4 methodsBatch submission, checkpoints
.indexer7 methodsPublic API, stats, search
.api_keys3 methodsCreate, list, delete keys
.support4 methodsTicket management

View the full source on GitHub · 2,083 lines · 14 modules · sync + async

TypeScript SDK →