Python · API för virtuell try-on
API för virtuell try-on i Python
I en mening
Installera requests, läs in PHOTTA_API_KEY från env, skriv en photta()-wrapper som skickar Bearer-nyckeln och kastar ett typat PhottaError vid svar som inte är 2xx, gör sedan en POST till /api/v1/tryon/apparel och polla /api/v1/tryon/apparel/{id} var 3:e sekund tills status är completed.
- Typisk tid: 1.5–4 min
- Credits: 5 credits vid 2K · 6 credits vid 4K
- Bearbetning: asynkron, polling
- Gränser: 600 requests/min
- Autentisering: Bearer-nyckel
Varje siffra på den här sidan kommer från Photter API-dokumentationen · kontrollerad
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")I korthet
I korthet
- Endpoint
- POST /api/v1/tryon/apparel
- Autentisering
- Bearer API-nyckel
- Bearbetning
- Asynkron — polla status-endpointen
- Typisk tid
- 1.5–4 min
- Credits
- 5 credits vid 2K · 6 credits vid 4K
- Bildförhållanden
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- Indatagränser
- Upp till 10 MB per bild; JPEG, PNG, WebP
- Idempotent
- Nej
Hur det fungerar
Fem steg, noll Photta-specifika beroenden — requests täcker allt.
Steg 1
Skapa konto och generera en nyckel
Samma väg som för alla andra språk: ai.photta.app → Developers → Generate API key. Nycklar börjar med `photta_live_` och fungerar över alla Photta-capabilities.
Steg 2
Läs in nyckeln från env
Sätt `PHOTTA_API_KEY` i miljön och läs den via `os.environ`. I FastAPI eller Django, läs in den en gång vid uppstart i en settings-modul. Bädda inte in nyckeln i källkod eller publik Git-historik.
python3 -m pip install requests export PHOTTA_API_KEY="photta_live_xxxxx"Steg 3
Skriv en requests-wrapper
En trettioraders `photta_request()`-funktion hanterar bas-URL:en, Authorization-headern, JSON-serialisering och felöversättning. Det är den enda abstraktionen du behöver tills Python-SDK:t släpps.
# 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 bodySteg 4
Skicka och polla
Gör en POST till `/api/v1/tryon/apparel` för att få ett generations-ID, och polla sedan `/api/v1/tryon/apparel/{id}` med ett 3-sekundersintervall. I Celery eller RQ, dela upp poll-loopen över flera tasks så att ett jobb på flera minuter inte låser 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")Steg 5
Spara resultatet
Den färdiga payloaden innehåller `output_url` och `thumbnail_url`. Ladda ner byten till din egen objektlagring — S3, GCS, Cloudflare R2 — så att din produkt inte är bunden till Phottas CDN för långsiktig rendering.
Fel
- 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:
raiseGränser
- 600 anrop per minut per API-nyckel (Fast fönster; gränsen är densamma på alla planer)
- En 429 innehåller Retry-After: 30 sekunder
- Upp till 10 MB per bild
- Format: JPEG, PNG, WebP
- Samtidiga batcher per plan: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- Endast polling — API:et skickar inga webhooks.
Varför requests är rätt val idag
- Inget Photta-specifikt beroende — requests finns redan i de flesta Python-projekt
- Fungerar överallt där Python körs: Django, FastAPI, Flask, Celery-workers, Lambda, skript
- Klient-wrappern är på cirka trettio rader — klistra in den i photta.py och gå vidare
- Fungerar utmärkt med asyncio via httpx när du behöver parallella anrop
Vad det inte gör
- Inget officiellt Photta Python-paket än — REST med requests är det dokumenterade mönstret
- Polling är den enda signalen för slutförande; API:et skickar inga webhooks
- Endast Bearer-nyckel; det finns inget OAuth-flöde för client-credentials
Vanliga utvecklarfrågor
Finns det ett officiellt Photta Python-SDK?
Inte än. Den stödda integrationsvägen är biblioteket requests (synkront) eller httpx (asynkront) — båda kräver bara en tunn wrapper, och wrappern på den här sidan fungerar för alla capabilities.
Vilka Python-versioner stöds?
Python 3.9 och senare. Wrappern använder typannoteringar, f-strängar och syntaxen `str | None`, vilket fungerar fint i 3.10+. I 3.9 byter du ut `str | None` mot `Optional[str]`. requests i sig stöder officiellt 3.8+, men 3.9+ är det praktiska minimikravet för moderna Photta-projekt.
Bör jag använda requests eller httpx?
requests om du gör en handfull sekventiella anrop — det är enklare och finns redan i de flesta kodbaser. httpx om du behöver asynkron samtidighet (parallella anrop, massuppdateringar i efterhand) eller HTTP/2. Wrappern är minimal oavsett vilket; byt `requests.request` mot `httpx.Client().request` så förblir resten av koden identisk.
Kan jag anropa det från Django?
Ja. Lägg wrappern i `services/photta.py`, importera den från en view eller en Celery-task. Anropa inte API:et i en synkron request-handler om jobbet tar lång tid — skicka anropet från din view, returnera generations-ID:t och polla från en bakgrundstask eller en Channels-konsument.
Hur pollar jag från en Celery-worker?
Skicka jobbet från en task och schemalägg sedan en uppföljningstask (via `apply_async(countdown=3)`) som pollar en gång och schemalägger om sig själv tills jobbet är klart eller en maxgräns för retries nås. Detta håller workers lediga och undviker långkörande tasks som stör autoskalare.
Hur signalerar API:et fel?
Svar som inte är 2xx innehåller en JSON-body med ett `error`-objekt: `type`, `code`, `message`, samt `param` vid 400 och `retry_after` vid 429. Wrappern på den här sidan kastar ett `PhottaError` som innehåller alla dessa, så att dina anropare kan förgrena logiken baserat på statuskod utan att själva behöva parsa bodyn.
Relaterade sidor
Node.js
API för virtuell try-on i Node.js
Anropa Phottas aPI för virtuell try-on från en Node.js-backend med inbyggd fetch. Ingen SDK krävs: lagra din nyckel, skicka in jobbet, polla efter resultatet.
LäscURL
API för virtuell try-on med cURL
Anropa Phottas aPI för virtuell try-on direkt från skalet med cURL. Skicka, polla, ladda ner — alla kodavsnitt fungerar tillsammans med jq för skriptade pipelines.
LäsFunktioner
API för virtuell try-on för apparel
REST API som placerar kläder på AI-mannekänger. Asynkron, 1,5–4 minuters generering, 5 credits vid 2K, 6 vid 4K. Exempel för cURL, Node.js och Python.
LäsBygg
Bygg en virtuell try-on-funktion för din app
Ett heltäckande recept för att driftsätta en virtuell try-on-funktion med Photta API: ladda upp, skicka in, gör polling från en worker, rendera resultatet. TypeScript + server-only-mönster.
LäsBygg
Lägg till virtuell try-on i en iOS- eller Android-app
Så här lägger du till virtuell try-on med AI i en nativ iOS- eller Android-app med hjälp av Photta API: skicka aldrig nyckeln till enheten, använd din backend som proxy, spegla jobbstatus.
LäsSnabbstart
Första Photta-bilden på under fem minuter.
Skapa konto, generera en API-nyckel, kör ditt första cURL-anrop, polla tills det är klart, spara resultatet. Fem steg, dokumenterade från början till slut.
LäsReferens
Photta API-prissättning
Vad varje Photta API-endpoint kostar i credits i 2K och 4K, hur debitering och återbetalning fungerar, samt vilka endpoints som är gratis. Inget fast pris i pengar per bild.
Läs
Varje siffra på den här sidan kommer från Photter API-dokumentationen · kontrollerad
Testa API:et på fem minuter
Generera en Photta API-nyckel, klistra in cURL-kodfragmentet ovan, och du har din första bild på en modell innan kaffet har bryggts klart.
- 1.5–4 min
- 5 credits vid 2K · 6 credits vid 4K
- asynkron, polling
- 600 requests/min
- Bearer-nyckel