Python · Virtuell try-on API
Virtuell try-on API i Python
I én setning
Installer requests, last inn PHOTTA_API_KEY fra env, skriv en photta()-wrapper som sender Bearer-nøkkelen og kaster en typet PhottaError ved ikke-2xx-responser, send deretter POST til /api/v1/tryon/apparel og poll /api/v1/tryon/apparel/{id} hvert 3. sekund til status er completed.
- Typisk tidsbruk: 1.5–4 min
- Credits: 5 credits ved 2K · 6 credits ved 4K
- Prosessering: asynkron, polling
- Grenser: 600 forespørsler/min
- Autentisering: Bearer-nøkkel
Hvert tall på denne siden er hentet fra dokumentasjonen for Photta-API-et · verifisert
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": true,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')
# $ID is data.id from the POST response. Poll every 3 seconds until status is "completed" or "failed".
for i in $(seq 1 120); do
RESULT=$(curl -s "https://api.photta.app/api/v1/tryon/apparel/$ID" -H "Authorization: Bearer $PHOTTA_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.data.status')
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && echo "generation failed" && exit 1
sleep 3
done
echo "$RESULT" | jq -r '.data.output_url'const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": true,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
}),
});
const { data } = await res.json(); // data.id, data.status
async function waitFor(id) {
for (let attempt = 0; attempt < 120; attempt++) {
const res = await fetch(`https://api.photta.app/api/v1/tryon/apparel/${id}`, { headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}` } });
const { data } = await res.json();
if (data.status === "completed") return data.output_url;
if (data.status === "failed") throw new Error(data.error_message ?? "generation failed");
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error("timed out after 6 minutes");
}import os, requests
res = requests.post(
"https://api.photta.app/api/v1/tryon/apparel",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": True,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
},
)
data = res.json()["data"] # data["id"], data["status"]
import time
def wait_for(job_id):
for _ in range(120):
res = requests.get(f"https://api.photta.app/api/v1/tryon/apparel/{job_id}", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"})
data = res.json()["data"]
if data["status"] == "completed":
return data["output_url"]
if data["status"] == "failed":
raise RuntimeError(data.get("error_message", "generation failed"))
time.sleep(3)
raise TimeoutError("timed out after 6 minutes")Kort oppsummert
Kort oppsummert
- Endepunkt
- POST /api/v1/tryon/apparel
- Autentisering
- Bearer API-nøkkel
- Prosessering
- Asynkron – poll status-endepunktet
- Typisk tidsbruk
- 1.5–4 min
- Credits
- 5 credits ved 2K · 6 credits ved 4K
- Bildeformater
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- Inndatagrenser
- Opptil 10 MB per bilde; JPEG, PNG, WebP
- Idempotent
- Nei
Slik fungerer det
Fem trinn, null Photta-spesifikke avhengigheter — requests dekker alt.
Trinn 1
Registrer deg og generer en nøkkel
Samme fremgangsmåte som alle andre språk: ai.photta.app → Developers → Generate API key. Nøkler starter med `photta_live_` og fungerer på tvers av alle Photta-capabilities.
Trinn 2
Last inn nøkkelen fra env
Sett `PHOTTA_API_KEY` i miljøet og les den via `os.environ`. I FastAPI eller Django laster du den inn én gang ved oppstart i en innstillingsmodul. Ikke bygg inn nøkkelen i kildekode eller offentlig Git-historikk.
python3 -m pip install requests export PHOTTA_API_KEY="photta_live_xxxxx"Trinn 3
Skriv en requests-wrapper
En trettilinrers `photta_request()`-funksjon håndterer base-URL-en, Authorization-headeren, JSON-serialisering og feiloversettelse. Det er den eneste abstraksjonen du trenger inntil Python-SDK-en lanseres.
# photta.py — one helper for every endpoint import os, requests BASE = "https://api.photta.app/api/v1" class PhottaError(Exception): def __init__(self, status, error, retry_after=None): super().__init__(error.get("message", "request failed")) self.status, self.type, self.retry_after = status, error.get("type"), retry_after def photta(method, path, **kwargs): res = requests.request(method, BASE + path, headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}, timeout=30, **kwargs) body = res.json() if not res.ok: raise PhottaError(res.status_code, body.get("error", {}), res.headers.get("Retry-After")) return bodyTrinn 4
Send inn og poll
Gjør en POST til `/api/v1/tryon/apparel` for å hente en generasjons-ID, og poll deretter `/api/v1/tryon/apparel/{id}` med 3 sekunders intervall. I Celery eller RQ bør du dele opp polling-løkken på tvers av oppgaver, slik at en jobb som tar flere minutter ikke blokkerer en worker.
import os, requests res = requests.post( "https://api.photta.app/api/v1/tryon/apparel", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}, json={ "product_type": "top", "product_images": [ "https://cdn.yourstore.com/products/shirt-front.jpg" ], "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg", "product_category": "t_shirt", "mannequin_id": "mnk_f3a9b1", "pose_id": "pose_c2d4e5", "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg", "lock_background": True, "resolution": "2K", "aspect_ratio": "3:4", "body_size": "M", "expression": "neutral", "user_instruction": "Keep the collar pattern crisp and centered." }, ) data = res.json()["data"] # data["id"], data["status"] import time def wait_for(job_id): for _ in range(120): res = requests.get(f"https://api.photta.app/api/v1/tryon/apparel/{job_id}", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}) data = res.json()["data"] if data["status"] == "completed": return data["output_url"] if data["status"] == "failed": raise RuntimeError(data.get("error_message", "generation failed")) time.sleep(3) raise TimeoutError("timed out after 6 minutes")Trinn 5
Lagre resultatet permanent
Den fullførte payloaden inkluderer `output_url` og `thumbnail_url`. Last ned rådataene til din egen objektlagring — S3, GCS, Cloudflare R2 — slik at produktet ditt ikke er låst til Phottas CDN for langsiktig visning.
Feil
- 400
invalid_request_error - The request is malformed or contains invalid parameters.
- 401
authentication_error - The API key is missing, invalid, or expired.
- 402
insufficient_credits_error - Your account does not have enough credits.
- 404
not_found_error - The requested resource does not exist.
- 409
conflict_error - The request conflicts with current state — e.g. your concurrent-batch cap is reached.
- 429
rate_limit_error - Too many requests. Slow down and retry.Retry-After: 30
- 500
api_error - An internal server error occurred. Retry later.
try:
photta("POST", "/tryon/apparel", json={
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": True,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
})
except PhottaError as e:
if e.status == 402:
print("insufficient_credits_error: top up before retrying")
elif e.status == 429:
time.sleep(int(e.retry_after or 30))
else:
raiseGrenser
- 600 forespørsler per minutt per API-nøkkel (Fast tidsvindu; grensen er lik for alle abonnementer)
- En 429 inneholder Retry-After: 30 sekunder
- Opptil 10 MB per bilde
- Formater: JPEG, PNG, WebP
- Samtidige batcher per abonnement: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- Kun polling – API-et sender ikke webhooks.
Hvorfor requests er det rette valget i dag
- Ingen Photta-spesifikke avhengigheter — requests finnes allerede i de fleste Python-prosjekter
- Fungerer overalt hvor Python kjører: Django, FastAPI, Flask, Celery-workers, Lambda, skript
- Klient-wrapperen er på rundt tretti linjer — lim den inn i photta.py og gå videre
- Fungerer sømløst med asyncio via httpx når du trenger parallell innsending
Hva den ikke gjør
- Ingen offisiell Photta Python-pakke ennå — REST med requests er det dokumenterte mønsteret
- Polling er det eneste signalet på fullføring; API-et sender ikke webhooks
- Kun Bearer-nøkkel; det finnes ingen OAuth client-credentials-flyt
Spørsmål utviklere stiller
Finnes det en offisiell Photta Python-SDK?
Ikke ennå. Den støttede integrasjonsmåten er requests-biblioteket (synkront) eller httpx (asynkront) — begge krever bare en tynn wrapper, og wrapperen på denne siden fungerer for alle funksjoner.
Hvilke Python-versjoner støttes?
Python 3.9 og nyere. Wrapperen bruker type hints, f-strenger og `str | None`-syntaks, som fungerer fint på 3.10+. På 3.9 bytter du ut `str | None` med `Optional[str]`. requests i seg selv støtter offisielt 3.8+, men 3.9+ er det praktiske minimumskravet for moderne Photta-prosjekter.
Bør jeg bruke requests eller httpx?
requests hvis du gjør en håndfull sekvensielle kall — det er enklere og finnes allerede i de fleste kodebaser. httpx hvis du trenger asynkron samtidighet (parallelle innsendinger, backfills i bulk) eller HTTP/2. Wrapperen er minimal uansett; bytt ut `requests.request` med `httpx.Client().request`, så forblir resten av koden identisk.
Kan jeg kalle den fra Django?
Ja. Legg wrapperen i `services/photta.py`, og importer den fra et view eller en Celery-oppgave. Ikke kall API-et direkte i en synkron request-handler hvis jobben tar lang tid — send inn fra viewet, returner generasjons-ID-en, og poll fra en bakgrunnsoppgave eller en Channels-consumer.
Hvordan poller jeg fra en Celery-worker?
Send inn jobben fra én oppgave, og planlegg deretter en oppfølgingsoppgave (via `apply_async(countdown=3)`) som poller én gang og planlegger seg selv på nytt inntil jobben er fullført eller grensen for maks antall forsøk nås. Dette holder workers ledige og unngår langvarige oppgaver som forstyrrer autoskalering.
Hvordan signaliserer API-et feil?
Ikke-2xx-responser returnerer en JSON-body med et `error`-objekt: `type`, `code`, `message`, i tillegg til `param` på 400-feil og `retry_after` på 429-feil. Wrapperen på denne siden kaster en `PhottaError` som inneholder alle disse, slik at kallende kode kan forgrene på statuskode uten å parse bodyen manuelt.
Relaterte sider
Node.js
Virtuell try-on API i Node.js
Kall Phottas virtuell try-on API fra en Node.js-backend med native fetch. Ingen SDK nødvendig: lagre nøkkelen din, send inn jobben, poll etter resultatet.
LescURL
Virtuell try-on API med cURL
Kall Phottas virtuell try-on API direkte fra kommandolinjen med cURL. Send inn, poll, last ned — alle kodesnutter kan kombineres med jq for skriptede pipelines.
LesFunksjoner
Virtuell try-on API for klær
REST API som plasserer klær på AI-mannequiner. Asynkront, 1,5–4 minutters generering, 5 credits i 2K, 6 i 4K. Eksempler for cURL, Node.js og Python.
LesBygg
Bygg en virtuell try-on-funksjon for appen din
Ende-til-ende-oppskrift for å lansere en virtuell try-on-funksjon med Photta API: last opp, send inn, poll fra en worker, vis resultatet. TypeScript + mønstre kun for server.
LesBygg
Legg til virtuell try-on i en iOS- eller Android-app
Hvordan legge til AI-basert virtuell try-on i en nativ iOS- eller Android-app ved hjelp av Photta-API-et: aldri inkluder nøkkelen i appen, rute via backend, speil jobbstatus.
LesHurtigstart
Første Photta-bilde på under fem minutter.
Registrer deg, generer en API-nøkkel, kjør ditt første cURL-kall, utfør polling til det er fullført, lagre resultatet. Fem trinn, dokumentert fra start til slutt.
LesReferanse
Photta API-priser
Hva hvert Photta API-endepunkt koster i credits ved 2K og 4K, hvordan trekk og refusjoner fungerer, og hvilke endepunkter som er gratis. Ingen pengepris per bilde.
Les
Hvert tall på denne siden er hentet fra dokumentasjonen for Photta-API-et · verifisert
Prøv API-et på fem minutter
Generer en Photta API-nøkkel, lim inn cURL-kodesnutten ovenfor, og du har ditt første bilde på modell før kaffen er ferdig traktet.
- 1.5–4 min
- 5 credits ved 2K · 6 credits ved 4K
- asynkron, polling
- 600 forespørsler/min
- Bearer-nøkkel