Python SDK
v1.0.0Official 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-sdkQuick 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.
| Module | Coverage | Description |
|---|---|---|
.wallets | 14 methods | Login, registration, profile, token refresh, linked wallets |
.templates | 7 methods | CRUD operations, search, variations |
.objects | 9 methods | Create, list, search, children, parents, activity |
.organizations | 18 methods | Org management, members, roles, invitations |
.payments | 2 methods | Payment config, deposit listing |
.storage | 5 methods | File upload, metadata, template assets |
.webhooks | 6 methods | CRUD, test endpoint |
.notifications | 7 methods | Messages, message templates |
.event_bus | 8 methods | Actions, action types, batch execution |
.faces | 6 methods | Face CRUD, by template lookup |
.sequencer | 4 methods | Batch submission, checkpoints |
.indexer | 7 methods | Public API, stats, search |
.api_keys | 3 methods | Create, list, delete keys |
.support | 4 methods | Ticket management |
View the full source on GitHub · 2,083 lines · 14 modules · sync + async
TypeScript SDK →