Python · Try-on-API til smykker
Try-on-API til smykker i Python
I én sætning
Installer requests, indlæs PHOTTA_API_KEY fra env, skriv en photta()-wrapper, der sender Bearer-nøglen og kaster en typet PhottaError ved ikke-2xx-svar, lav derefter POST til /api/v1/tryon/jewelry og poll /api/v1/tryon/jewelry/{id} hvert 3. sekund, indtil status er completed.
- Typisk tid: 1.5–4 min
- Credits: 5 credits ved 2K · 6 credits ved 4K
- Behandling: async, polling
- Grænser: 600 requests/min
- Autentifikation: Bearer key
Hvert tal på denne side stammer fra Photta API-dokumentationen · tjekket
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/jewelry \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
}')
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/jewelry/$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/jewelry", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
}),
});
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/jewelry/${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/jewelry",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
},
)
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/jewelry/{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 fortalt
Kort fortalt
- Endpoint
- POST /api/v1/tryon/jewelry
- Autentifikation
- Bearer API-nøgle
- Behandling
- Asynkron — poll status-endpointet
- Typisk tid
- 1.5–4 min
- Credits
- 5 credits ved 2K · 6 credits ved 4K
- Billedformater
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- Inputgrænser
- Op til 10 MB pr. billede; JPEG, PNG, WebP
- Idempotent
- Nej
Sådan virker det
Fem trin, nul Photta-specifikke afhængigheder — requests dækker det hele.
Trin 1
Tilmeld dig og generer en nøgle
Samme fremgangsmåde som for alle andre sprog: ai.photta.app → Developers → Generate API key. Nøgler starter med `photta_live_` og fungerer på tværs af alle Photta-capabilities.
Trin 2
Indlæs nøglen fra env
Sæt `PHOTTA_API_KEY` i miljøet og læs den via `os.environ`. I FastAPI eller Django indlæses den én gang ved opstart i et settings-modul. Undgå at indlejre nøglen i kildekode eller offentlig Git-historik.
python3 -m pip install requests export PHOTTA_API_KEY="photta_live_xxxxx"Trin 3
Skriv en requests-wrapper
En tredive linjers `photta_request()`-funktion håndterer base-URL'en, Authorization-headeren, JSON-serialisering og fejloversættelse. Det er den eneste abstraktion, du har brug for, indtil Python SDK'et udgives.
# 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 bodyTrin 4
Indsend og poll
Lav en POST til `/api/v1/tryon/jewelry` for at få et genererings-ID, og poll derefter `/api/v1/tryon/jewelry/{id}` med et interval på 3 sekunder. I Celery eller RQ bør du fordele poll-loopet over flere tasks, så et job på flere minutter ikke blokerer en worker.
import os, requests res = requests.post( "https://api.photta.app/api/v1/tryon/jewelry", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}, json={ "jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg", "jewelry_type": "necklace", "mannequin_id": "mnk_j9k1l2", "background": "soft window light on dark velvet", "resolution": "2K", "aspect_ratio": "3:4", "user_instruction": "Make the pendant 10% smaller." }, ) 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/jewelry/{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")Trin 5
Gem resultatet
Det færdige payload indeholder `output_url` og `thumbnail_url`. Download bytes til dit eget objektlager — S3, GCS, Cloudflare R2 — så dit produkt ikke er afhængigt af Phottas CDN til langsigtet rendering.
Fejl
- 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/jewelry", json={
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
})
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 anmodninger i minuttet pr. API-nøgle (Fast vindue; grænsen er den samme på alle planer)
- En 429 indeholder Retry-After: 30 sekunder
- Op til 10 MB pr. billede
- Formater: JPEG, PNG, WebP
- Samtidige batches pr. plan: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- Kun polling — API'et sender ingen webhooks.
Hvorfor requests er det rigtige valg i dag
- Ingen Photta-specifik afhængighed — requests findes allerede i de fleste Python-projekter
- Kører overalt, hvor Python kører: Django, FastAPI, Flask, Celery-workers, Lambda, scripts
- Klient-wrapperen er på omkring tredive linjer — indsæt den i photta.py, og kom videre
- Spiller sammen med asyncio via httpx, når du har brug for parallel indsendelse
Hvad den ikke gør
- Ingen officiel Photta Python-pakke endnu — REST med requests er det dokumenterede mønster
- Polling er det eneste signal om fuldførelse; API'et sender ingen webhooks
- Kun Bearer-nøgle; der findes intet OAuth client-credentials flow
Spørgsmål udviklere stiller
Findes der et officielt Photta Python SDK?
Ikke endnu. Den understøttede integrationsvej er requests-biblioteket (synkront) eller httpx (asynkront) — begge kræver kun en tynd wrapper, og wrapperen på denne side fungerer til enhver capability.
Hvilke Python-versioner understøttes?
Python 3.9 og nyere. Wrapperen bruger type hints, f-strings og `str | None`-syntaks, hvilket fungerer fint på 3.10+. På 3.9 udskiftes `str | None` med `Optional[str]`. requests understøtter officielt 3.8+, men 3.9+ er det praktiske minimum for moderne Photta-projekter.
Bør jeg bruge requests eller httpx?
requests hvis du foretager en håndfuld sekventielle kald — det er simplere og findes allerede i de fleste kodebaser. httpx hvis du har brug for async concurrency (parallelle indsendelser, bulk backfills) eller HTTP/2. Wrapperen er minimal i begge tilfælde; udskift `requests.request` med `httpx.Client().request`, og resten af koden forbliver identisk.
Kan jeg kalde den fra Django?
Ja. Placer wrapperen i `services/photta.py`, importér den fra et view eller en Celery-task. Kald ikke API'et inde i en synkron request-handler, hvis jobbet tager lang tid — indsend fra viewet, returnér genererings-ID'et, og poll fra en baggrundstask eller en Channels-consumer.
Hvordan poller jeg fra en Celery-worker?
Indsend jobbet fra én task, og planlæg derefter en opfølgende task (via `apply_async(countdown=3)`), der poller én gang og genplanlægger sig selv, indtil jobbet er færdigt, eller en grænse for max-retries nås. Dette holder workers ledige og undgår langvarige tasks, der forstyrrer autoscalers.
Hvordan signalerer API'et fejl?
Ikke-2xx-svar indeholder en JSON-body med et `error`-objekt: `type`, `code`, `message`, samt `param` ved 400-fejl og `retry_after` ved 429-fejl. Wrapperen på denne side kaster en `PhottaError`, der indeholder alle disse, så dine kaldere kan forgrene på statuskode uden selv at skulle parse bodyen.
Relaterede sider
Node.js
Try-on-API til smykker i Node.js
Kald Phottas try-on-API til smykker fra en Node.js-backend med indbygget fetch. Ingen SDK påkrævet: gem din nøgle, indsend jobbet, foretag polling for resultatet.
LæscURL
Try-on-API til smykker med cURL
Kald Phottas try-on-API til smykker direkte fra kommandolinjen med cURL. Indsend, poll, download — hvert kodestykke fungerer sammen med jq til scriptede pipelines.
LæsFunktioner
Try-on-API til smykker til halskæder, ringe, armbånd og øreringe
Placér halskæder, ringe, armbånd og øreringe på AI-modeller via REST. 5 credits ved 2K, indbyggede close-up-mannequiner, refleksionsbevidst rendering fra Photta-dokumentationen.
LæsByg
Byg en AI-produktfotograferingstjeneste
En playbook til stiftere om videresalg af Phottas virtuelle try-on-API som en white-label-SaaS: tenant-nøgler, batch-fanout, fakturering pr. credit, SLA-realiteter.
LæsHurtig start
Første Photta-billede på under fem minutter.
Opret en konto, generer en API-nøgle, kør dit første cURL-kald, foretag polling indtil det er fuldført, gem resultatet. Fem trin, dokumenteret fra start til slut.
LæsReference
Photta API-priser
Hvad hvert Photta API-endpoint koster i credits ved 2K og 4K, hvordan debitering og refundering fungerer, og hvilke endpoints der er gratis. Ingen faste pengepriser pr. billede.
Læs
Hvert tal på denne side stammer fra Photta API-dokumentationen · tjekket
Prøv API'et på fem minutter
Generér en Photta API-nøgle, indsæt cURL-kodestykket ovenfor, og du har dit første billede på en model, før kaffen er færdigbrygget.
- 1.5–4 min
- 5 credits ved 2K · 6 credits ved 4K
- async, polling
- 600 requests/min
- Bearer key