Python · Virtual Try-On API

Virtual Try-On API на Python

Установка через pip не требуется — мы рекомендуем библиотеку requests. Обертка на 30 строк легко встраивается в Django, FastAPI, Celery и Lambda.

Суть

Установите `requests`, загрузите `PHOTTA_API_KEY` из env, создайте функцию `photta_request()` для отправки `Authorization: Bearer photta_live_xxx` и обработки ошибок, затем отправьте POST на `/tryon/apparel` и опрашивайте `/tryon/apparel/:id` каждые 3 секунды до `data.status == 'completed'`.

Обновлено · 2026-04-19

Ваш первый запрос

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)

Чего ожидать

Typical completion

1–3min

2K / 4K credits

4 / 6

Styles

2

Batch-ready

yes

Как это работает

Virtual Try-On API на Python

Пять шагов, ноль специфических зависимостей — requests достаточно.

  1. 01

    Шаг 1

    Зарегистрируйтесь и создайте ключ

    Тот же путь: ai.photta.app → Developers → Generate API key. Ключи `photta_live_` работают для всех возможностей Photta.

  2. 02

    Шаг 2

    Загрузите ключ из env

    Установите `PHOTTA_API_KEY` в окружении и читайте через `os.environ`. В FastAPI или Django загружайте его один раз при старте в настройки. Не храните ключ в коде или публичных репозиториях.

  3. 03

    Шаг 3

    Напишите обертку для requests

    Функция `photta_request()` на 30 строк управляет базовым URL, заголовками, JSON и трансляцией ошибок. Этого достаточно до выхода официального Python SDK.

  4. 04

    Шаг 4

    Отправка и опрос

    Выполните POST на `/tryon/apparel`, чтобы получить ID, затем опрашивайте `/tryon/apparel/:id` раз в 3 секунды. В Celery или RQ распределяйте проверку статуса между задачами, чтобы не занимать воркер на 4 минуты.

  5. 05

    Шаг 5

    Сохраните результат

    В ответе будут `output_url` и `thumbnail_url`. Скачайте изображение в свое хранилище (S3, GCS, Cloudflare R2), чтобы не зависеть от CDN Photta в будущем.

Код от и до

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

Почему такая структура

Почему requests — лучший выбор сейчас

  • 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

Чего он не делает

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 other developers ask

Есть ли официальный Photta Python SDK?+

Пока нет. Он появится, когда у API будет 10 платных клиентов. Сейчас стандартный путь — requests (синхронно) или httpx (асинхронно). Оба варианта работают с оберткой, представленной здесь.

Какие версии Python поддерживаются?+

Python 3.9 и выше. Код использует аннотации типов, f-строки и синтаксис `str | None` (3.10+). Для 3.9 замените его на `Optional[str]`. Сама библиотека requests поддерживает 3.8+, но 3.9+ рекомендуется для современных проектов.

Использовать requests или httpx?+

requests, если вы делаете последовательные вызовы — это проще. httpx, если нужна асинхронность (параллельная отправка, массовая обработка) или HTTP/2. Логика обертки почти идентична в обоих случаях.

Можно ли вызывать API из Django?+

Да. Поместите обертку в `services/photta.py`, импортируйте во view или задачу Celery. Не делайте долгих вызовов внутри синхронного обработчика запроса — создайте задачу, верните ID, и опрашивайте статус в фоне.

Как опрашивать из Celery?+

Создайте задачу для отправки, затем запланируйте повторную задачу (через `apply_async(countdown=3)`), которая проверяет статус один раз и переназначает себя до завершения или ошибки. Это освобождает воркеры и помогает автоскейлингу.

Как API сообщает об ошибках?+

Ответы 4xx/5xx содержат JSON с объектом `error`: `type`, `code`, `message`, а также `param` для 400 и `retry_after` для 429. Обертка на этой странице выбрасывает `PhottaError` со всеми деталями для удобной обработки.

Python · Virtual Try-On API

Создайте аккаунт и получите API-ключ

Установите `requests`, загрузите `PHOTTA_API_KEY` из env, создайте функцию `photta_request()` для отправки `Authorization: Bearer photta_live_xxx` и обработки ошибок, затем отправьте POST на `/tryon/apparel` и опрашивайте `/tryon/apparel/:id` каждые 3 секунды до `data.status == 'completed'`.

Virtual Try-On API для Python — Photta | Photta