Python · Virtuel Try-On API

Virtuel Try-On API i Python

Ingen pip install photta er nødvendig — Photta-dokumentationen anbefaler officielt requests-biblioteket. En wrapper på tredive linjer kan indsættes i Django, FastAPI, Celery-workers og Lambda-handlere uden yderligere dikkedarer.

Kort fortalt

Installer `requests`, indlæs `PHOTTA_API_KEY` fra env, skriv en `photta_request()` wrapper, der sender `Authorization: Bearer photta_live_xxx` og kaster en typet `PhottaError` ved ikke-2xx responser, lav derefter en POST til `/tryon/apparel` og polle `/tryon/apparel/:id` hvert 3 sekund, indtil `data.status == 'completed'` — typisk inden for 1.5 til 4 minutter.

Opdateret · 2026-04-19

Din første request

PythonNode.jscURLcURL
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)

Hvad kan man forvente

Typical completion

1–3min

2K / 4K credits

4 / 6

Styles

2

Batch-ready

yes

Sådan virker det

Virtuel Try-On API i Python

Fem trin, nul Photta-specifikke afhængigheder — requests dækker det hele.

  1. 01

    Trin 1

    Opret dig og generer en nøgle

    Samme vej som alle andre sprog: ai.photta.app → Developers → Generate API key. Nøgler starter med `photta_live_` og virker på tværs af alle Photta-kapabiliteter.

  2. 02

    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 kan du indlæse den én gang ved opstart i et settings-modul. Indlejr ikke nøglen i kildekoden eller i offentlig Git-historik.

  3. 03

    Trin 3

    Skriv en requests-wrapper

    En `photta_request()` funktion på tredive linjer håndterer base-URL, Authorization-header, JSON-serialisering og fejl-oversættelse. Det er den eneste abstraktion, du har brug for, indtil Python SDK'et lander.

  4. 04

    Trin 4

    Indsend og polle

    POST til `/tryon/apparel` for at få et generations-ID, og polle derefter `/tryon/apparel/:id` med et interval på 3 sekunder. I Celery eller RQ bør du opdele polling-loopet over flere opgaver, så et job på 4 minutter ikke optager en worker.

  5. 05

    Trin 5

    Persistér resultatet

    Den færdige payload inkluderer `output_url` og `thumbnail_url`. Download bytes til din egen object storage — S3, GCS, Cloudflare R2 — så dit produkt ikke er bundet til Phottas CDN til langsigtet rendering.

Kode, ende-til-ende

Copy, paste, done.

Four snippets — install prerequisites, wrap the REST call, submit + poll, then handle the errors that actually happen in production.

01Use the battle-tested requests library
bash
# 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
02A 30-line client wrapper you can drop into any project
python
# 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 body
03Submit a try-on and poll until the result is ready
python
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)
04Handle 402 credit exhaustion and 429 rate limits
python
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:
        raise

Hvorfor denne struktur

Hvorfor requests er det rigtige valg i dag

  • 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

Hvad det ikke gør

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

Spørgsmål fra andre udviklere

Questions other developers ask

Findes der en officiel Photta Python SDK?+

Ikke endnu. Phottas roadmap prioriterer Python SDK'et, når ti betalende API-kunder er aktive. Indtil da er den understøttede integrationsvej requests-biblioteket (synkront) eller httpx (asynkront) — begge er dokumenteret i den officielle dokumentation, og begge fungerer med wrapperen på denne side.

Hvilke Python-versioner understøttes?+

Python 3.9 og senere. Wrapperen bruger type hints, f-strings og `str | None` syntaks, hvilket fungerer fint på 3.10+. På 3.9 skal `str | None` erstattes med `Optional[str]`. requests selv understøtter officielt 3.8+, men 3.9+ er det praktiske minimum for moderne Photta-projekter.

Skal 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 asynkron samtidighed (parallelle indsendelser, bulk-backfills) eller HTTP/2. Wrapperen er lille uanset hvad; skift `requests.request` ud med `httpx.Client().request`, og resten af koden forbliver identisk.

Kan jeg kalde det fra Django?+

Ja. Læg wrapperen i `services/photta.py`, og importer den fra en view eller en Celery-opgave. Kald ikke API'et inde i en synkron request-handler, hvis jobbet er langt — indsend fra view'et, returner generations-ID'et, og polle fra en baggrundsopgave eller en Channels-consumer.

Hvordan poller jeg fra en Celery-worker?+

Indsend jobbet fra én opgave, og planlæg derefter en opfølgende opgave (via `apply_async(countdown=3)`), der poller én gang og planlægger sig selv igen, indtil jobbet er færdigt eller en grænse for max-retries nås. Dette holder workers ledige og undgår langvarige opgaver, der forstyrrer autoscalere.

Hvordan signalerer API'et fejl?+

Ikke-2xx responser indeholder en JSON-body med et `error`-objekt: `type`, `code`, `message`, plus `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 sig på statuskoden uden selv at skulle parse body.

Python · Virtuel Try-On API

Opret en konto og hent en API-nøgle

Installer `requests`, indlæs `PHOTTA_API_KEY` fra env, skriv en `photta_request()` wrapper, der sender `Authorization: Bearer photta_live_xxx` og kaster en typet `PhottaError` ved ikke-2xx responser, lav derefter en POST til `/tryon/apparel` og polle `/tryon/apparel/:id` hvert 3 sekund, indtil `data.status == 'completed'` — typisk inden for 1.5 til 4 minutter.

Virtuel Try-On API til Python — Photta | Photta