Python · API d'essayage virtuel

API d'essayage virtuel en Python

Pas besoin de pip install photta — la documentation Photta recommande officiellement la bibliothèque requests. Un wrapper de trente lignes s'intègre dans Django, FastAPI, Celery et Lambda sans aucune cérémonie supplémentaire.

En une phrase

Installez `requests`, chargez `PHOTTA_API_KEY` depuis l'environnement, écrivez un wrapper `photta_request()` qui envoie `Authorization: Bearer photta_live_xxx` et lève une exception `PhottaError` typée, puis effectuez un POST sur `/tryon/apparel` et interrogez `/tryon/apparel/:id` toutes les 3 secondes jusqu'à `data.status == 'completed'` — généralement sous 1.5 à 4 minutes.

Mis à jour · 2026-04-19

Votre première requête

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)

À quoi s'attendre

Typical completion

1–3min

2K / 4K credits

4 / 6

Styles

2

Batch-ready

yes

Comment ça marche

API d'essayage virtuel en Python

Cinq étapes, zéro dépendance spécifique à Photta — requests gère tout.

  1. 01

    Étape 1

    S'inscrire et générer une clé

    Même parcours que pour les autres langages : ai.photta.app → Développeurs → Générer une clé API. Les clés commencent par `photta_live_` et fonctionnent pour toutes les capacités Photta.

  2. 02

    Étape 2

    Charger la clé depuis l'environnement

    Définissez `PHOTTA_API_KEY` dans l'environnement et lisez-la via `os.environ`. Dans FastAPI ou Django, chargez-la au démarrage dans un module de configuration. N'intégrez pas la clé dans le code source ou l'historique Git.

  3. 03

    Étape 3

    Écrire un wrapper requests

    Une fonction `photta_request()` de trente lignes gère l'URL de base, l'en-tête Authorization, la sérialisation JSON et la traduction des erreurs. C'est la seule abstraction requise en attendant le SDK Python.

  4. 04

    Étape 4

    Soumettre et interroger

    POST sur `/tryon/apparel` pour obtenir un ID de génération, puis interrogez `/tryon/apparel/:id` toutes les 3 secondes. Dans Celery ou RQ, répartissez le polling sur plusieurs tâches pour ne pas bloquer un worker pendant 4 minutes.

  5. 05

    Étape 5

    Persister le résultat

    Le payload complété inclut `output_url` et `thumbnail_url`. Téléchargez les octets dans votre propre stockage (S3, GCS, Cloudflare R2) pour ne pas lier votre produit au CDN de Photta sur le long terme.

Code, de bout en bout

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

Pourquoi cette structure

Pourquoi requests est le bon choix aujourd'hui

  • 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

Ce qu'il ne fait pas

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

Questions fréquentes des développeurs

Questions other developers ask

Existe-t-il un SDK Python Photta officiel ?+

Pas encore. La roadmap Photta priorise le SDK Python une fois que dix clients API payants seront actifs. D'ici là, l'intégration recommandée passe par requests (synchrone) ou httpx (asynchrone) — les deux sont documentés et compatibles avec le wrapper fourni.

Quelles versions de Python sont supportées ?+

Python 3.9 et plus. Le wrapper utilise les type hints, les f-strings et la syntaxe `str | None` (Python 3.10+). Pour 3.9, remplacez `str | None` par `Optional[str]`. requests supporte officiellement 3.8+, mais 3.9+ est le minimum conseillé pour les projets Photta modernes.

Dois-je utiliser requests ou httpx ?+

requests si vous effectuez quelques appels séquentiels — c'est plus simple et déjà présent dans la plupart des projets. httpx si vous avez besoin de concurrence asynchrone (soumissions parallèles, traitement de masse) ou de HTTP/2. Le wrapper est minimaliste dans les deux cas ; remplacez `requests.request` par `httpx.Client().request` et le reste du code demeure identique.

Puis-je l'appeler depuis Django ?+

Oui. Placez le wrapper dans `services/photta.py` et importez-le depuis une vue ou une tâche Celery. Ne faites pas d'appels API longs dans un handler synchrone — soumettez depuis la vue, renvoyez l'ID de génération, et interrogez via une tâche de fond ou un consumer Channels.

Comment interroger depuis un worker Celery ?+

Soumettez la tâche depuis un premier worker, puis planifiez une tâche de suivi (via `apply_async(countdown=3)`) qui interroge une fois et se replanifie elle-même jusqu'à complétion ou échec. Cela libère les workers et évite les tâches trop longues.

Comment l'API signale-t-elle les erreurs ?+

Les réponses hors 2xx contiennent un corps JSON avec un objet `error` : `type`, `code`, `message`, ainsi que `param` pour les 400 et `retry_after` pour les 429. Le wrapper sur cette page lève une `PhottaError` contenant ces données pour faciliter la gestion des erreurs.

Python · API d'essayage virtuel

Créer un compte et obtenir une clé API

Installez `requests`, chargez `PHOTTA_API_KEY` depuis l'environnement, écrivez un wrapper `photta_request()` qui envoie `Authorization: Bearer photta_live_xxx` et lève une exception `PhottaError` typée, puis effectuez un POST sur `/tryon/apparel` et interrogez `/tryon/apparel/:id` toutes les 3 secondes jusqu'à `data.status == 'completed'` — généralement sous 1.5 à 4 minutes.

API d'essayage virtuel pour Python — Photta | Photta