Skip to content

Commit b077061

Browse files
authored
feat: add first SDK implementation (#1)
* feat: add basic SDK * fix: cancellation, file i/o, simplifications * chore: include py.typed file in wheel distribution * feat: add realtime * chore: add uv for dependency management * add gh workflow * fix formatting * fix python 3.9 * chore: support python 3.13 * chore: update license format in pyproject.toml * chore: test with python 3.14 * realtime: remove logs * fix p1 comments * feat: integrate aiofiles for asynchronous file handling and update dependencies * style: apply black formatting * style: remove unused imports (ruff) * fix: update examples to use context manager and match refactored API * style: apply black formatting to examples * docs: update README examples to use DecartClient with context manager * chore: cleanups according to cr
1 parent 64f1e4b commit b077061

31 files changed

+6832
-0
lines changed

.github/workflows/ci.yml

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint:
11+
name: Lint & Format Check
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Install UV
17+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
18+
19+
- name: Add UV to PATH
20+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
21+
22+
- name: Set up Python 3.12
23+
run: uv python install 3.12
24+
25+
- name: Install dependencies
26+
run: uv sync --all-extras
27+
28+
- name: Check formatting with Black
29+
run: uv run black --check decart_sdk/ tests/ examples/
30+
31+
- name: Lint with Ruff
32+
run: uv run ruff check decart_sdk/ tests/ examples/
33+
34+
- name: Type check with MyPy
35+
run: uv run mypy decart_sdk/
36+
continue-on-error: true # Don't fail on type errors yet
37+
38+
test:
39+
name: Test Python ${{ matrix.python-version }}
40+
runs-on: ubuntu-latest
41+
strategy:
42+
matrix:
43+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
44+
45+
steps:
46+
- uses: actions/checkout@v4
47+
48+
- name: Install UV
49+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
50+
51+
- name: Add UV to PATH
52+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
53+
54+
- name: Set up Python ${{ matrix.python-version }}
55+
run: uv python install ${{ matrix.python-version }}
56+
57+
- name: Install dependencies
58+
run: uv sync --all-extras
59+
60+
- name: Run tests
61+
run: uv run pytest tests/ -v --cov=decart_sdk --cov-report=xml --cov-report=term
62+
63+
- name: Upload coverage to Codecov
64+
uses: codecov/codecov-action@v4
65+
if: matrix.python-version == '3.12'
66+
with:
67+
file: ./coverage.xml
68+
flags: unittests
69+
name: codecov-umbrella
70+
fail_ci_if_error: false
71+
72+
test-examples:
73+
name: Test Examples (Syntax Check)
74+
runs-on: ubuntu-latest
75+
steps:
76+
- uses: actions/checkout@v4
77+
78+
- name: Install UV
79+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
80+
81+
- name: Add UV to PATH
82+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
83+
84+
- name: Set up Python 3.12
85+
run: uv python install 3.12
86+
87+
- name: Install dependencies
88+
run: uv sync --all-extras
89+
90+
- name: Check examples for syntax errors
91+
run: |
92+
echo "Checking examples compile without syntax errors..."
93+
uv run python -m py_compile examples/process_video.py
94+
uv run python -m py_compile examples/process_image.py
95+
uv run python -m py_compile examples/realtime_synthetic.py
96+
uv run python -m py_compile examples/realtime_file.py
97+
echo "✅ All examples have valid syntax"
98+
99+
# Note: Examples require DECART_API_KEY to actually run
100+
# They are only syntax-checked in CI
101+
102+
build:
103+
name: Build Package
104+
runs-on: ubuntu-latest
105+
needs: [lint, test]
106+
steps:
107+
- uses: actions/checkout@v4
108+
109+
- name: Install UV
110+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
111+
112+
- name: Add UV to PATH
113+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
114+
115+
- name: Set up Python 3.12
116+
run: uv python install 3.12
117+
118+
- name: Build package
119+
run: uv build
120+
121+
- name: Check package
122+
run: |
123+
uv run pip install twine
124+
uv run twine check dist/*
125+
126+
- name: Upload artifacts
127+
uses: actions/upload-artifact@v4
128+
with:
129+
name: dist
130+
path: dist/

.gitignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
23+
# Virtual environments
24+
venv/
25+
env/
26+
ENV/
27+
.venv/
28+
.venv
29+
30+
# UV
31+
.python-version
32+
33+
# IDEs
34+
.vscode/
35+
.idea/
36+
*.swp
37+
*.swo
38+
*~
39+
40+
# Testing
41+
.pytest_cache/
42+
.coverage
43+
htmlcov/
44+
.tox/
45+
46+
# Type checking
47+
.mypy_cache/
48+
.dmypy.json
49+
dmypy.json
50+
51+
# OS
52+
.DS_Store
53+
Thumbs.db
54+
55+
# Project specific
56+
*.mp4
57+
*.mov
58+
*.png
59+
*.jpg
60+
*.jpeg

README.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Decart Python SDK
2+
3+
A Python SDK for Decart's models.
4+
5+
## Installation
6+
7+
### Using UV
8+
9+
```bash
10+
uv pip install decart-sdk
11+
```
12+
13+
### Using pip
14+
15+
```bash
16+
pip install decart-sdk
17+
```
18+
19+
## Documentation
20+
21+
For complete documentation, guides, and examples, visit:
22+
**https://docs.platform.decart.ai/sdks/python**
23+
24+
## Quick Start
25+
26+
### Process Files
27+
28+
```python
29+
import asyncio
30+
import os
31+
from decart_sdk import DecartClient, models
32+
33+
async def main():
34+
async with DecartClient(api_key=os.getenv("DECART_API_KEY")) as client:
35+
# Generate a video from text
36+
result = await client.process({
37+
"model": models.video("lucy-pro-t2v"),
38+
"prompt": "A cat walking in a lego world",
39+
})
40+
41+
# Save the result
42+
with open("output.mp4", "wb") as f:
43+
f.write(result)
44+
45+
asyncio.run(main())
46+
```
47+
48+
### Video Transformation
49+
50+
```python
51+
async with DecartClient(api_key=os.getenv("DECART_API_KEY")) as client:
52+
# Transform a video file
53+
with open("input.mp4", "rb") as video_file:
54+
result = await client.process({
55+
"model": models.video("lucy-pro-v2v"),
56+
"prompt": "Anime style with vibrant colors",
57+
"data": video_file,
58+
"enhance_prompt": True,
59+
})
60+
61+
# Save the result
62+
with open("output.mp4", "wb") as f:
63+
f.write(result)
64+
```
65+
66+
## Development
67+
68+
### Setup with UV
69+
70+
```bash
71+
# Clone the repository
72+
git clone https://github.com/decartai/decart-python
73+
cd decart-python
74+
75+
# Install UV
76+
curl -LsSf https://astral.sh/uv/install.sh | sh
77+
78+
# Install all dependencies (including dev dependencies)
79+
uv sync --all-extras
80+
81+
# Run tests
82+
uv run pytest
83+
84+
# Run linting
85+
uv run ruff check decart_sdk/
86+
87+
# Format code
88+
uv run black decart_sdk/ tests/ examples/
89+
90+
# Type check
91+
uv run mypy decart_sdk/
92+
```
93+
94+
### Common Commands
95+
96+
```bash
97+
# Install dependencies
98+
uv sync --all-extras
99+
100+
# Run tests with coverage
101+
uv run pytest --cov=decart_sdk --cov-report=html
102+
103+
# Run examples
104+
uv run python examples/process_video.py
105+
uv run python examples/realtime_synthetic.py
106+
107+
# Update dependencies
108+
uv lock --upgrade
109+
```
110+
111+
## License
112+
113+
MIT

decart_sdk/__init__.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from .client import DecartClient
2+
from .errors import (
3+
DecartSDKError,
4+
InvalidAPIKeyError,
5+
InvalidBaseURLError,
6+
InvalidInputError,
7+
ModelNotFoundError,
8+
ProcessingError,
9+
WebRTCError,
10+
)
11+
from .models import models, ModelDefinition
12+
from .types import FileInput, ModelState, Prompt
13+
14+
try:
15+
from .realtime import (
16+
RealtimeClient,
17+
RealtimeConnectOptions,
18+
ConnectionState,
19+
)
20+
21+
REALTIME_AVAILABLE = True
22+
except ImportError:
23+
REALTIME_AVAILABLE = False
24+
RealtimeClient = None # type: ignore
25+
RealtimeConnectOptions = None # type: ignore
26+
ConnectionState = None # type: ignore
27+
28+
__version__ = "0.0.1"
29+
30+
__all__ = [
31+
"DecartClient",
32+
"DecartSDKError",
33+
"InvalidAPIKeyError",
34+
"InvalidBaseURLError",
35+
"InvalidInputError",
36+
"ModelNotFoundError",
37+
"ProcessingError",
38+
"WebRTCError",
39+
"models",
40+
"ModelDefinition",
41+
"FileInput",
42+
"ModelState",
43+
"Prompt",
44+
]
45+
46+
if REALTIME_AVAILABLE:
47+
__all__.extend(
48+
[
49+
"RealtimeClient",
50+
"RealtimeConnectOptions",
51+
"ConnectionState",
52+
]
53+
)

0 commit comments

Comments
 (0)