Python · Virtual Try-On API
Virtual Try-On API in Python
Er is geen pip install photta nodig — de Photta-documentatie beveelt officieel de requests-bibliotheek aan. Een wrapper van dertig regels sluit zonder gedoe aan op Django, FastAPI, Celery-workers en Lambda-handlers.
In één zin
Installeer `requests`, laad `PHOTTA_API_KEY` vanuit env, schrijf een `photta_request()` wrapper die `Authorization: Bearer photta_live_xxx` stuurt en een getypeerde `PhottaError` genereert bij niet-2xx responses. Doe vervolgens een POST naar `/tryon/apparel` en poll `/tryon/apparel/:id` elke 3 seconden totdat `data.status == 'completed'` — meestal binnen 1.5 tot 4 minuten.
Bijgewerkt · 2026-04-19
Je eerste verzoek
import time
from photta import photta_request, PhottaError
# 1. Submit the job
created = photta_request("POST", "/tryon/apparel", json={
"product_type": "dress",
"product_images": ["https://example.com/dress.jpg"],
"mannequin_id": "mnq_athena_ts",
"pose_id": "pose_standing_front",
"resolution": "2K",
"aspect_ratio": "3:4",
})
generation_id = created["data"]["id"]
# 2. Poll every 3 seconds. Upper bound: 120 attempts ≈ 6 minutes,
# comfortably above the documented 1.5–4 minute window.
for _ in range(120):
result = photta_request("GET", f"/tryon/apparel/{generation_id}")
status = result["data"]["status"]
if status == "completed":
print("Result:", result["data"]["output_url"])
break
if status == "failed":
raise RuntimeError(result["data"]["error_message"])
time.sleep(3)Wat je kunt verwachten
Typical completion
1–3min
2K / 4K credits
4 / 6
Styles
2
Batch-ready
yes
Hoe het werkt
Virtual Try-On API in Python
Vijf stappen, nul Photta-specifieke dependencies — requests dekt alles.
- 01
Stap 1
Meld je aan en genereer een sleutel
Zelfde pad als elke andere taal: ai.photta.app → Developers → Generate API key. Sleutels beginnen met `photta_live_` en werken voor elke Photta-mogelijkheid.
- 02
Stap 2
Laad de sleutel vanuit env
Stel `PHOTTA_API_KEY` in in de omgeving en lees deze uit via `os.environ`. In FastAPI of Django laad je dit eenmalig bij het opstarten in een settings-module. Plaats de sleutel niet in de broncode of publieke Git-geschiedenis.
- 03
Stap 3
Schrijf een requests-wrapper
Een `photta_request()` functie van dertig regels handelt de basis-URL, de Authorization header, JSON-serialisatie en fout-vertaling af. Dat is de enige abstractie die je nodig hebt totdat de Python SDK verschijnt.
- 04
Stap 4
Indienen en pollen
POST naar `/tryon/apparel` om een generatie-ID te krijgen, en poll vervolgens `/tryon/apparel/:id` met een interval van 3 seconden. In Celery of RQ breek je de poll-loop op over verschillende taken, zodat een taak van 4 minuten geen worker bezet houdt.
- 05
Stap 5
Sla het resultaat op
De voltooid-payload bevat `output_url` en `thumbnail_url`. Download de bytes naar je eigen object storage — S3, GCS, Cloudflare R2 — zodat je product niet afhankelijk is van Photta's CDN voor langdurige weergave.
Code, van begin tot eind
Copy, paste, done.
Four snippets — install prerequisites, wrap the REST call, submit + poll, then handle the errors that actually happen in production.
# Photta doesn't ship an official Python SDK yet — requests is the
# recommended path in the docs. Standard library urllib works too if
# you need zero dependencies.
pip install requests
# Store your API key in env (dotenv optional but convenient)
echo "PHOTTA_API_KEY=photta_live_xxxxx" >> .env# photta.py
import os
import requests
PHOTTA_BASE_URL = "https://ai.photta.app/api/v1"
class PhottaError(Exception):
def __init__(self, status: int, code: str, message: str, retry_after: int | None = None):
super().__init__(message)
self.status = status
self.code = code
self.retry_after = retry_after
def photta_request(method: str, path: str, **kwargs):
headers = {
"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}",
"Content-Type": "application/json",
**kwargs.pop("headers", {}),
}
response = requests.request(method, f"{PHOTTA_BASE_URL}{path}", headers=headers, **kwargs)
body = response.json()
if not response.ok:
err = body.get("error", {})
raise PhottaError(
status=response.status_code,
code=err.get("code", "unknown"),
message=err.get("message", response.reason),
retry_after=err.get("retry_after"),
)
return bodyimport time
from photta import photta_request, PhottaError
# 1. Submit the job
created = photta_request("POST", "/tryon/apparel", json={
"product_type": "dress",
"product_images": ["https://example.com/dress.jpg"],
"mannequin_id": "mnq_athena_ts",
"pose_id": "pose_standing_front",
"resolution": "2K",
"aspect_ratio": "3:4",
})
generation_id = created["data"]["id"]
# 2. Poll every 3 seconds. Upper bound: 120 attempts ≈ 6 minutes,
# comfortably above the documented 1.5–4 minute window.
for _ in range(120):
result = photta_request("GET", f"/tryon/apparel/{generation_id}")
status = result["data"]["status"]
if status == "completed":
print("Result:", result["data"]["output_url"])
break
if status == "failed":
raise RuntimeError(result["data"]["error_message"])
time.sleep(3)from photta import photta_request, PhottaError
import time
try:
photta_request("POST", "/tryon/apparel", json={ ... })
except PhottaError as err:
if err.status == 402:
# Out of credits — err.code == "insufficient_credits"
raise
elif err.status == 429:
# Rate-limited. Honour the Retry-After header.
time.sleep(err.retry_after or 30)
# then retry…
elif err.status >= 500:
# Server-side — retry with exponential backoff.
raise
else:
raiseWaarom deze vorm
Waarom requests vandaag de juiste keuze is
- Zero Photta-specific dependencies — `requests` is already in most Python projects
- Works anywhere Python runs: Django, FastAPI, Flask, Celery workers, Lambda, scripts
- The client wrapper is ~30 lines — paste it into `photta.py` and move on
- Pairs naturally with asyncio via `httpx` if you need parallel submission
Wat het niet doet
Honest caveats
- No official @photta/python SDK yet — REST + requests is the documented pattern
- No async fetch helper shipped; swap `requests` for `httpx` when you need concurrency
- Bearer token auth only — no OAuth client credentials yet
Vragen die andere developers stellen
Questions other developers ask
Is er een officiële Photta Python SDK?+
Nog niet. De Photta-roadmap geeft prioriteit aan de Python SDK zodra er tien betalende API-klanten live zijn. Tot die tijd is het ondersteunde integratiepad de requests-bibliotheek (synchroon) of httpx (asynchroon) — beide worden beschreven in de officiële documentatie en beide werken met de wrapper van dertig regels op deze pagina.
Welke Python versies worden ondersteund?+
Python 3.9 en later. De wrapper gebruikt type hints, f-strings en de `str | None` syntaxis, wat prima werkt op 3.10+. Op 3.9 vervang je `str | None` door `Optional[str]`. requests zelf ondersteunt officieel 3.8+, maar 3.9+ is het praktische minimum voor moderne Photta-projecten.
Moet ik requests of httpx gebruiken?+
requests als je een handvol opeenvolgende calls doet — het is eenvoudiger en zit al in de meeste codebases. httpx als je asynchrone gelijktijdigheid nodig hebt (parallelle indieningen, bulk-backfills) of HTTP/2. De wrapper is in beide gevallen klein; vervang `requests.request` door `httpx.Client().request` en de rest van de code blijft identiek.
Kan ik dit aanroepen vanuit Django?+
Ja. Plaats de wrapper in `services/photta.py`, importeer deze vanuit een view of een Celery-task. Roep de API niet aan binnen een synchrone request handler als de taak lang duurt — dien in vanuit de view, retourneer het generatie-ID en poll vanuit een achtergrondtaak of een Channels-consumer.
Hoe poll ik vanuit een Celery worker?+
Dien de taak in vanuit de ene task en plan vervolgens een vervolg-task in (via `apply_async(countdown=3)`) die eenmalig pollt en zichzelf opnieuw inplant totdat de taak is voltooid of een maximum aantal pogingen is bereikt. Dit houdt workers vrij en voorkomt langlopende taken die autoscalers verstoren.
Hoe signaleert de API fouten?+
Niet-2xx responses bevatten een JSON-body met een `error`-object: `type`, `code`, `message`, plus `param` bij 400s en `retry_after` bij 429s. De wrapper op deze pagina genereert een `PhottaError` die dit allemaal bevat, zodat je callers kunnen differentiëren op statuscode zonder de body zelf te hoeven parsen.
Python · Virtual Try-On API
Maak een account aan en ontvang een API-sleutel
Installeer `requests`, laad `PHOTTA_API_KEY` vanuit env, schrijf een `photta_request()` wrapper die `Authorization: Bearer photta_live_xxx` stuurt en een getypeerde `PhottaError` genereert bij niet-2xx responses. Doe vervolgens een POST naar `/tryon/apparel` en poll `/tryon/apparel/:id` elke 3 seconden totdat `data.status == 'completed'` — meestal binnen 1.5 tot 4 minuten.