Python · Virtual Try-On API

Virtual Try-On API in Python

Non serve nessun pip install photta — la documentazione raccomanda ufficialmente la libreria requests. Un wrapper di trenta righe si integra in Django, FastAPI, Celery e Lambda senza complicazioni.

In una frase

Installa requests, carica PHOTTA_API_KEY da env, scrivi un wrapper photta_request() che invia Authorization: Bearer photta_live_xxx e solleva una PhottaError tipizzata per risposte non-2xx, quindi POST su /tryon/apparel e polling di /tryon/apparel/:id ogni 3 secondi finché data.status == 'completed' — solitamente tra 1.5 e 4 minuti.

Aggiornato · 2026-04-19

La tua prima richiesta

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)

Cosa aspettarsi

Typical completion

1–3min

2K / 4K credits

4 / 6

Styles

2

Batch-ready

yes

Come funziona

Virtual Try-On API in Python

Cinque step, zero dipendenze specifiche di Photta — requests copre tutto.

  1. 01

    Step 1

    Registrati e genera una chiave

    Stesso percorso degli altri linguaggi: ai.photta.app → Developers → Generate API key. Le chiavi iniziano con photta_live_ e funzionano per ogni funzionalità Photta.

  2. 02

    Step 2

    Carica la chiave da env

    Imposta PHOTTA_API_KEY nell'ambiente e leggila tramite os.environ. In FastAPI o Django, caricala all'avvio in un modulo settings. Non inserire la chiave nel codice sorgente o nella cronologia Git pubblica.

  3. 03

    Step 3

    Scrivi un wrapper per requests

    Una funzione photta_request() di trenta righe gestisce URL base, header Authorization, serializzazione JSON e traduzione degli errori. È l'unica astrazione necessaria finché non uscirà l'SDK Python.

  4. 04

    Step 4

    Invia e polling

    POST su /tryon/apparel per ottenere un ID generazione, poi polling di /tryon/apparel/:id ogni 3 secondi. In Celery o RQ, dividi il loop di polling tra i task per non bloccare un worker per 4 minuti.

  5. 05

    Step 5

    Salva il risultato

    Il payload completato include output_url e thumbnail_url. Scarica i byte nel tuo storage (S3, GCS, Cloudflare R2) in modo che il tuo prodotto non dipenda dalla CDN di Photta a lungo termine.

Codice, 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

Perché questa struttura

Perché requests è la scelta giusta oggi

  • 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

Cosa non fa

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

Domande frequenti degli sviluppatori

Questions other developers ask

Esiste un SDK Python ufficiale di Photta?+

Non ancora. La roadmap di Photta prioritizza l'SDK Python una volta raggiunti i dieci clienti API paganti. Fino ad allora, il percorso supportato è la libreria requests (sincrona) o httpx (asincrona) — entrambe documentate e compatibili con il wrapper in questa pagina.

Quali versioni di Python sono supportate?+

Python 3.9 e successivi. Il wrapper usa type hints, f-strings e la sintassi str | None, corretta su 3.10+. Su 3.9 sostituisci str | None con Optional[str]. requests supporta ufficialmente 3.8+, ma 3.9+ è il minimo pratico per progetti Photta moderni.

Dovrei usare requests o httpx?+

requests se effettui poche chiamate sequenziali — è più semplice e già presente in molti progetti. httpx se hai bisogno di concorrenza asincrona (invii paralleli, backfill massivi) o HTTP/2. Il wrapper è simile; sostituisci requests.request con httpx.Client().request e il resto del codice rimane identico.

Posso chiamarla da Django?+

Sì. Inserisci il wrapper in services/photta.py, importalo in una view o un task Celery. Non chiamare l'API dentro un handler di richiesta sincrono se il job è lungo — invia dalla view, restituisci l'ID generazione e gestisci il polling in background via task o consumer Channels.

Come effettuo il polling da un worker Celery?+

Invia il job da un task, poi pianifica un task successivo (via apply_async(countdown=3)) che controlla lo stato una volta e si ripianifica finché il job non è completato o raggiunge il limite di tentativi. Questo mantiene i worker liberi ed evita task a lunga esecuzione che disturbano l'autoscaling.

Come vengono segnalati gli errori dall'API?+

Le risposte non-2xx includono un body JSON con un oggetto error: type, code, message, oltre a param per i 400 e retry_after per i 429. Il wrapper in questa pagina solleva una PhottaError con questi dati per permetterti di gestire i vari codici di stato senza parsare il body manualmente.

Python · Virtual Try-On API

Crea un account e ottieni una API key

Installa requests, carica PHOTTA_API_KEY da env, scrivi un wrapper photta_request() che invia Authorization: Bearer photta_live_xxx e solleva una PhottaError tipizzata per risposte non-2xx, quindi POST su /tryon/apparel e polling di /tryon/apparel/:id ogni 3 secondi finché data.status == 'completed' — solitamente tra 1.5 e 4 minuti.

Virtual Try-On API per Python — Photta | Photta