Python · API de Try-On Virtual
API de Try-On Virtual en Python
No hace falta un pip install photta — la documentación oficial de Photta recomienda la librería requests. Un wrapper de treinta líneas se integra en Django, FastAPI, workers de Celery y handlers de Lambda sin más ceremonia.
En una frase
Instala `requests`, carga `PHOTTA_API_KEY` desde env, escribe un wrapper `photta_request()` que envíe `Authorization: Bearer photta_live_xxx` y lance un `PhottaError` tipado en respuestas no-2xx, luego haz un POST a `/tryon/apparel` y sondea `/tryon/apparel/:id` cada 3 segundos hasta que `data.status == 'completed'` — típicamente en 1.5 a 4 minutos.
Actualizado · 2026-04-19
Tu primera solicitud
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)Qué esperar
Typical completion
1.5–4min
2K / 4K credits
5 / 7
Aspect ratios
5
Product types
6
Cómo funciona
API de Try-On Virtual en Python
Cinco pasos, cero dependencias específicas de Photta — requests cubre todo.
- 01
Paso 1
Regístrate y genera una clave
La misma ruta que para cualquier otro lenguaje: ai.photta.app → Desarrolladores → Generar API key. Las claves comienzan con `photta_live_` y funcionan en todas las capacidades de Photta.
- 02
Paso 2
Carga la clave desde env
Configura `PHOTTA_API_KEY` en el entorno y léela mediante `os.environ`. En FastAPI o Django, cárgala una vez al inicio en un módulo de configuración. No incrustes la clave en el código fuente ni en el historial público de Git.
- 03
Paso 3
Escribe un wrapper de requests
Una función `photta_request()` de treinta líneas gestiona la URL base, el header Authorization, la serialización JSON y la traducción de errores. Esa es la única abstracción que necesitas hasta que llegue el SDK de Python.
- 04
Paso 4
Enviar y sondear
POST a `/tryon/apparel` para obtener un ID de generación, luego sondea `/tryon/apparel/:id` en un intervalo de 3 segundos. En Celery o RQ, rompe el bucle de sondeo entre tareas para que un trabajo de 4 minutos no bloquee a un worker.
- 05
Paso 5
Persistir el resultado
El payload completado incluye `output_url` y `thumbnail_url`. Descarga los bytes en tu propio almacenamiento de objetos — S3, GCS, Cloudflare R2 — para que tu producto no esté atado al CDN de Photta para el renderizado a largo plazo.
Código, de punta a punta
Copy, paste, done.
Four snippets — install prerequisites, wrap the REST call, submit + poll, then handle the errors that actually happen in production.
# 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# 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 bodyimport 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)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:
raisePor qué esta estructura
Por qué requests es la elección correcta hoy
- 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
Qué no hace
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
Preguntas de otros desarrolladores
Questions other developers ask
¿Existe un SDK oficial de Photta para Python?+
Aún no. El roadmap de Photta prioriza el SDK de Python una vez que haya diez clientes de pago de la API activos. Hasta entonces, la ruta de integración soportada es la librería requests (síncrona) o httpx (asíncrona) — ambas están documentadas en la documentación oficial y funcionan con el wrapper de treinta líneas de esta página.
¿Qué versiones de Python están soportadas?+
Python 3.9 y posteriores. El wrapper usa sugerencias de tipo (type hints), f-strings y sintaxis `str | None`, que funciona bien en 3.10+. En 3.9 cambia `str | None` por `Optional[str]`. requests soporta oficialmente 3.8+, pero 3.9+ es el mínimo práctico para proyectos modernos de Photta.
¿Debo usar requests o httpx?+
requests si vas a realizar unas pocas llamadas secuenciales — es más simple y ya está en la mayoría de los proyectos. httpx si necesitas concurrencia asíncrona (envíos paralelos, cargas masivas) o HTTP/2. El wrapper es pequeño de cualquier forma; cambia `requests.request` por `httpx.Client().request` y el resto del código se mantiene idéntico.
¿Puedo llamarlo desde Django?+
Sí. Pon el wrapper en `services/photta.py`, impórtalo desde una vista o una tarea de Celery. No llames a la API dentro de un handler de solicitud síncrono si el trabajo es largo — envíalo desde la vista, devuelve el ID de generación y sondea desde una tarea en segundo plano o un consumidor de Channels.
¿Cómo realizo el polling desde un worker de Celery?+
Envía el trabajo desde una tarea y luego programa una tarea de seguimiento (vía `apply_async(countdown=3)`) que sondee una vez y se reprograme a sí misma hasta que el trabajo se complete o alcance un límite de reintentos. Esto mantiene a los workers libres y evita tareas de larga duración que afecten a los autoescaladores.
¿Cómo señala los errores la API?+
Las respuestas que no son 2xx llevan un cuerpo JSON con un objeto `error`: `type`, `code`, `message`, además de `param` en los 400 y `retry_after` en los 429. El wrapper de esta página lanza un `PhottaError` que contiene todo esto para que tus llamadores puedan decidir según el status code sin analizar el cuerpo ellos mismos.
Python · API de Try-On Virtual
Crea una cuenta y obtén una API key
Instala `requests`, carga `PHOTTA_API_KEY` desde env, escribe un wrapper `photta_request()` que envíe `Authorization: Bearer photta_live_xxx` y lance un `PhottaError` tipado en respuestas no-2xx, luego haz un POST a `/tryon/apparel` y sondea `/tryon/apparel/:id` cada 3 segundos hasta que `data.status == 'completed'` — típicamente en 1.5 a 4 minutos.