Python · Virtual Try-On API

Virtual Try-On API in Python

Kein pip install photta nötig — die Dokumentation empfiehlt offiziell die requests-Library. Ein 30-Zeilen-Wrapper lässt sich ohne Aufwand in Django, FastAPI, Celery-Worker oder Lambda-Handler integrieren.

Kurz zusammengefasst

Installieren Sie `requests`, laden Sie `PHOTTA_API_KEY` aus env, schreiben Sie einen `photta_request()` Wrapper, der `Authorization: Bearer photta_live_xxx` sendet und bei Nicht-2xx-Fehlern einen `PhottaError` wirft. Senden Sie dann einen POST an `/tryon/apparel` und pollen Sie `/tryon/apparel/:id` alle 3 Sekunden bis `data.status == 'completed'` — meist innerhalb von 1.5 bis 4 Minuten.

Aktualisiert · 2026-04-19

Ihr erster 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)

Was Sie erwartet

Typical completion

1–3min

2K / 4K credits

4 / 6

Styles

2

Batch-ready

yes

Funktionsweise

Virtual Try-On API in Python

Fünf Schritte, null Photta-spezifische Abhängigkeiten — requests deckt alles ab.

  1. 01

    Schritt 1

    Registrieren und Key generieren

    Gleicher Weg wie bei anderen Sprachen: ai.photta.app → Developers → Generate API key. Keys beginnen mit `photta_live_` und funktionieren für alle Photta-Endpunkte.

  2. 02

    Schritt 2

    Key aus env laden

    Setzen Sie `PHOTTA_API_KEY` in der Umgebung und lesen Sie ihn über `os.environ`. Laden Sie ihn in FastAPI oder Django einmalig beim Start in ein Settings-Modul. Den Key niemals im Quellcode oder der Git-History speichern.

  3. 03

    Schritt 3

    Einen Requests-Wrapper schreiben

    Eine 30-zeilige `photta_request()` Funktion übernimmt Base-URL, Authorization-Header, JSON-Serialisierung und Fehlerübersetzung. Das ist die einzige Abstraktion, die Sie brauchen, bis das Python SDK erscheint.

  4. 04

    Schritt 4

    Senden und pollen

    POST an `/tryon/apparel`, um eine Generations-ID zu erhalten, dann pollen Sie `/tryon/apparel/:id` im 3-Sekunden-Intervall. In Celery oder RQ sollten Sie den Poll-Loop über Tasks verteilen, damit ein 4-Minuten-Job keinen Worker blockiert.

  5. 05

    Schritt 5

    Ergebnis persistieren

    Die fertige Payload enthält `output_url` und `thumbnail_url`. Laden Sie die Bytes in Ihren eigenen Object-Storage (S3, GCS, Cloudflare R2) herunter, damit Ihr Produkt nicht langfristig vom Photta-CDN abhängig ist.

Code, End-to-End

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

Warum diese Struktur

Warum requests heute die richtige Wahl ist

  • 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

Was es nicht kann

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

Fragen anderer Entwickler

Questions other developers ask

Gibt es ein offizielles Photta Python SDK?+

Noch nicht. Die Roadmap priorisiert das Python SDK ab zehn zahlenden API-Kunden. Bis dahin ist der unterstützte Integrationsweg die requests-Library (synchron) oder httpx (async) — beide sind offiziell dokumentiert und funktionieren mit dem 30-Zeilen-Wrapper auf dieser Seite.

Welche Python-Versionen werden unterstützt?+

Python 3.9 und neuer. Der Wrapper nutzt Type Hints, F-Strings und die `str | None` Syntax (ab 3.10+). Bei 3.9 ersetzen Sie `str | None` durch `Optional[str]`. requests selbst unterstützt 3.8+, aber 3.9+ ist das praktische Minimum für moderne Photta-Projekte.

Sollte ich requests oder httpx verwenden?+

requests, wenn Sie nur wenige sequenzielle Aufrufe machen — es ist einfacher und meist schon vorhanden. httpx, wenn Sie Async-Concurrency (parallele Übermittlungen, Batch-Backfills) oder HTTP/2 benötigen. Der Wrapper ist in beiden Fällen minimal; tauschen Sie `requests.request` gegen `httpx.Client().request` aus, der restliche Code bleibt identisch.

Kann ich es aus Django aufrufen?+

Ja. Legen Sie den Wrapper in `services/photta.py` ab und importieren Sie ihn in einer View oder einem Celery-Task. Rufen Sie die API nicht direkt in einem synchronen Request-Handler auf, wenn der Job lange dauert — senden Sie den Job aus der View, geben Sie die ID zurück und pollen Sie im Hintergrund.

Wie polle ich aus einem Celery-Worker?+

Senden Sie den Job in einem Task und planen Sie dann einen Folgetask (via `apply_async(countdown=3)`), der einmal pollt und sich selbst neu einplant, bis der Job fertig ist oder ein Retry-Limit erreicht wird. Das hält Worker frei.

Wie signalisiert die API Fehler?+

Nicht-2xx-Antworten enthalten ein JSON mit einem `error`-Objekt: `type`, `code`, `message`, sowie `param` bei 400ern und `retry_after` bei 429ern. Der Wrapper auf dieser Seite wirft einen `PhottaError`, damit Aufrufer direkt auf den Statuscode reagieren können, ohne den Body manuell zu parsen.

Python · Virtual Try-On API

Account erstellen und API-Key erhalten

Installieren Sie `requests`, laden Sie `PHOTTA_API_KEY` aus env, schreiben Sie einen `photta_request()` Wrapper, der `Authorization: Bearer photta_live_xxx` sendet und bei Nicht-2xx-Fehlern einen `PhottaError` wirft. Senden Sie dann einen POST an `/tryon/apparel` und pollen Sie `/tryon/apparel/:id` alle 3 Sekunden bis `data.status == 'completed'` — meist innerhalb von 1.5 bis 4 Minuten.

Virtual Try-On API für Python — Photta | Photta