Lightweight async Python SDK for the Fotor OpenAPI
Project description
fotor-sdk
Lightweight, async-first Python SDK for the Fotor OpenAPI. Generate images and videos with a single API key -- no MCP server, no S3, no internal services required.
Installation
pip install fotor-sdk
Or install from GitHub:
pip install git+https://github.com/fotor-ai/fotor-sdk.git
For local development:
git clone https://github.com/fotor-ai/fotor-sdk.git
cd fotor-sdk
pip install -e .
CLI
After installation, the fotor command is available. Set your API key first:
export FOTOR_OPENAPI_KEY="your-api-key"
Generate images and videos:
fotor credits
fotor text2image --prompt "A diamond kitten on velvet, studio lighting"
fotor image2image --image ./ref-1.png ./ref-2.png --prompt "Turn these into an e-commerce product photo"
fotor bg-remove --image ./product.jpg
fotor upscale --image ./product.jpg --ratio 2
fotor text2video --prompt "A cinematic sunset over the ocean"
fotor image2video --image ./cover.png --prompt "Slow camera push-in"
Image inputs may be local files or http:// / https:// URLs. Local files are
uploaded through Fotor's signed upload flow before the task runs. CLI output is
JSON containing task status and result_url. For multi-image commands, pass
the images after a single --image, separated by spaces.
For image-to-image generation with multiple reference images, use image2image
and put all references after one --image:
fotor image2image \
--image ./reference-1.png ./reference-2.jpg https://example.com/reference-3.png \
--prompt "Use these references to create a polished product photo" \
--model gpt-image-2 \
--aspect-ratio 1:1 \
--resolution 2k
The older repeated form is still accepted:
fotor image2image --image ./reference-1.png --image ./reference-2.jpg --prompt "Use both references"
Run multiple SDK task specs concurrently from a JSON file:
[
{
"task_type": "text2image",
"tag": "cat",
"params": {
"prompt": "A diamond kitten on velvet, studio lighting",
"model_id": "gpt-image-2",
"aspect_ratio": "1:1",
"resolution": "2k"
}
},
{
"task_type": "text2video",
"tag": "sunset",
"params": {
"prompt": "A cinematic sunset over the ocean",
"model_id": "doubao-seedance-2-0-260128",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"audio_enable": false
}
}
]
fotor batch --file tasks.json --concurrency 5
Quick Start
Single Task
import asyncio
import os
from fotor_sdk import FotorClient, text2image
async def main():
client = FotorClient(api_key=os.environ["FOTOR_OPENAPI_KEY"])
result = await text2image(
client,
prompt="A diamond kitten on velvet, studio lighting",
model_id="seedream-4-5-251128",
resolution="2k",
aspect_ratio="1:1",
)
print(result.result_url)
asyncio.run(main())
Parallel Batch with Progress
import asyncio
import os
from fotor_sdk import FotorClient, TaskRunner, TaskSpec
async def main():
client = FotorClient(api_key=os.environ["FOTOR_OPENAPI_KEY"])
runner = TaskRunner(client, max_concurrent=5)
specs = [
TaskSpec("text2image", {"prompt": "A cat", "model_id": "seedream-4-5-251128"}, tag="cat"),
TaskSpec("text2image", {"prompt": "A dog", "model_id": "seedream-4-5-251128"}, tag="dog"),
TaskSpec("text2video", {"prompt": "Sunset", "model_id": "kling-v3", "duration": 5}, tag="sunset"),
]
def on_progress(total, completed, failed, in_progress, latest):
print(f" {completed + failed}/{total} done, latest: {latest.metadata.get('tag')}")
results = await runner.run(specs, on_progress=on_progress)
for r in results:
print(f"{r.metadata.get('tag')}: {r.status.name} -> {r.result_url}")
asyncio.run(main())
Configuration
| Environment Variable | Required | Default | Description |
|---|---|---|---|
FOTOR_OPENAPI_KEY |
Yes | -- | Your Fotor OpenAPI key |
FOTOR_OPENAPI_ENDPOINT |
No | https://api-b.fotor.com |
API base URL |
Available Task Functions
| Function | Description |
|---|---|
text2image() |
Generate image from text |
image2image() |
Edit / multi-reference generation |
image_upscale() |
2x or 4x upscale |
background_remove() |
Remove background |
text2video() |
Generate video from text |
single_image2video() |
Animate a single image |
start_end_frame2video() |
Interpolate between two frames |
multiple_image2video() |
Video from multiple images |
Core Classes
FotorClient
FotorClient(
api_key: str,
endpoint: str = "https://api-b.fotor.com",
poll_interval: float = 2.0,
max_poll_seconds: float = 1200,
)
Methods:
await create_task(path, payload) -> task_idawait get_task_status(task_id) -> TaskResultawait get_credits() -> dictawait wait_for_task(task_id) -> TaskResultawait submit_and_wait(path, payload) -> TaskResultsubmit_and_wait_sync(path, payload) -> TaskResultget_credits_sync() -> dict
TaskRunner
TaskRunner(client: FotorClient, max_concurrent: int = 5)
await run(specs, on_progress=None) -> list[TaskResult]run_sync(specs, on_progress=None) -> list[TaskResult]
TaskResult
TaskResult(task_id, status, result_url, error, elapsed_seconds, metadata)
result.success # True when COMPLETED with a result_url
TaskSpec
TaskSpec(task_type: str, params: dict, tag: str = "")
Error Handling
from fotor_sdk import FotorAPIError
try:
result = await text2image(client, prompt="...", model_id="bad-model")
except FotorAPIError as e:
print(f"API error: {e} code={e.code}")
For batch runs, failed tasks appear in results with status=FAILED and the
error field populated. The runner never raises on individual task failures.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fotor_sdk-0.1.10.tar.gz.
File metadata
- Download URL: fotor_sdk-0.1.10.tar.gz
- Upload date:
- Size: 25.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ae14b756017c0ecabfdce622df01bc2e0bf5bf686f00e374a5b577dafc5219f
|
|
| MD5 |
adb5c334c722bb57cff1d8bcaf689081
|
|
| BLAKE2b-256 |
42c0f3bbb71166ae0e6e2280dd248fbd18d098680cf12f326dea2c55e0c7c10e
|
File details
Details for the file fotor_sdk-0.1.10-py3-none-any.whl.
File metadata
- Download URL: fotor_sdk-0.1.10-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2b098c6dda3e66d00c6a2795067a1be793e81d5ab27af2b50a394624ce01e73
|
|
| MD5 |
113467a4a1c71307e5ec66db12673a9b
|
|
| BLAKE2b-256 |
a28a217cc520c3b59209a5df4fd519917e19ef952d1dd115fb824aff03a9a74d
|