Python · API Virtual Try-On

API Virtual Try-On di Python

Tidak perlu pip install photta — dokumentasi Photta secara resmi merekomendasikan library requests. Wrapper tiga puluh baris bisa langsung masuk ke Django, FastAPI, worker Celery, dan handler Lambda tanpa upacara tambahan.

Dalam satu kalimat

Instal `requests`, muat `PHOTTA_API_KEY` dari env, tulis wrapper `photta_request()` yang mengirimkan `Authorization: Bearer photta_live_xxx` dan memunculkan `PhottaError` pada respons non-2xx, lalu POST ke `/tryon/apparel` dan poll `/tryon/apparel/:id` setiap 3 detik hingga `data.status == 'completed'` — biasanya dalam 1.5 hingga 4 menit.

Diperbarui · 2026-04-19

Request pertama Anda

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)

Apa yang diharapkan

Typical completion

1.5–4min

2K / 4K credits

5 / 7

Aspect ratios

5

Product types

6

Cara kerja

API Virtual Try-On di Python

Lima langkah, nol dependensi khusus Photta — requests menangani segalanya.

  1. 01

    Langkah 1

    Daftar dan buat key

    Jalur yang sama dengan bahasa lain: ai.photta.app → Developers → Generate API key. Key dimulai dengan `photta_live_` dan berlaku untuk setiap kapabilitas Photta.

  2. 02

    Langkah 2

    Muat key dari env

    Set `PHOTTA_API_KEY` di lingkungan dan baca melalui `os.environ`. Di FastAPI atau Django, muat sekali saat booting ke modul settings. Jangan masukkan key di kode sumber atau riwayat Git publik.

  3. 03

    Langkah 3

    Tulis wrapper requests

    Fungsi `photta_request()` tiga puluh baris menangani base URL, header Authorization, serialisasi JSON, dan translasi error. Itu adalah satu-satunya abstraksi yang Anda butuhkan sampai SDK Python diluncurkan.

  4. 04

    Langkah 4

    Kirim dan poll

    POST ke `/tryon/apparel` untuk mendapatkan ID generasi, lalu poll `/tryon/apparel/:id` pada interval 3 detik. Di Celery atau RQ, pecah loop polling di seluruh task agar job 4 menit tidak menahan worker.

  5. 05

    Langkah 5

    Simpan hasilnya

    Payload yang selesai menyertakan `output_url` dan `thumbnail_url`. Unduh byte-nya ke penyimpanan objek Anda sendiri — S3, GCS, Cloudflare R2 — sehingga produk Anda tidak terikat pada CDN Photta untuk rendering jangka panjang.

Kode, ujung ke ujung

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

Mengapa pola ini

Mengapa requests adalah pilihan tepat saat ini

  • 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

Apa yang tidak bisa dilakukan

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

Pertanyaan pengembang lainnya

Questions other developers ask

Apakah ada SDK Python resmi Photta?+

Belum ada. Roadmap Photta memprioritaskan SDK Python setelah sepuluh pelanggan API berbayar aktif. Hingga saat itu, jalur integrasi yang didukung adalah library requests (sinkron) atau httpx (asinkron) — keduanya didokumentasikan secara resmi dan keduanya bekerja dengan wrapper tiga puluh baris di halaman ini.

Versi Python apa saja yang didukung?+

Python 3.9 dan versi lebih baru. Wrapper ini menggunakan type hints, f-strings, dan sintaks `str | None`, yang berjalan baik di 3.10+. Di 3.9, ganti `str | None` menjadi `Optional[str]`. requests sendiri secara resmi mendukung 3.8+, tetapi 3.9+ adalah minimum praktis untuk proyek Photta modern.

Haruskah saya menggunakan requests atau httpx?+

requests jika Anda melakukan beberapa panggilan sekuensial — ini lebih sederhana dan sudah ada di sebagian besar kode. httpx jika Anda butuh konkurensi asinkron (pengiriman paralel, bulk backfill) atau HTTP/2. Wrapper-nya tetap kecil untuk keduanya; cukup ganti `requests.request` dengan `httpx.Client().request` dan sisa kodenya tetap identik.

Bisakah saya memanggilnya dari Django?+

Ya. Tempatkan wrapper di `services/photta.py`, impor dari view atau task Celery. Jangan panggil API di dalam handler request sinkron jika job-nya lama — kirim dari view, kembalikan ID generasi, dan lakukan polling dari task latar belakang atau consumer Channels.

Bagaimana cara polling dari worker Celery?+

Kirim job dari satu task, lalu jadwalkan task lanjutan (via `apply_async(countdown=3)`) yang melakukan polling sekali dan menjadwalkan dirinya sendiri kembali hingga job selesai atau mencapai ambang batas retry maksimal. Ini menjaga worker tetap bebas dan menghindari task yang berjalan lama yang bisa mengganggu autoscaler.

Bagaimana API memberi sinyal error?+

Respons non-2xx membawa body JSON dengan objek `error`: `type`, `code`, `message`, plus `param` pada 400 dan `retry_after` pada 429. Wrapper di halaman ini memunculkan `PhottaError` yang membawa semua info ini sehingga pemanggil Anda bisa melakukan percabangan berdasarkan status code tanpa perlu mem-parsing body sendiri.

Python · API Virtual Try-On

Buat akun dan dapatkan API key

Instal `requests`, muat `PHOTTA_API_KEY` dari env, tulis wrapper `photta_request()` yang mengirimkan `Authorization: Bearer photta_live_xxx` dan memunculkan `PhottaError` pada respons non-2xx, lalu POST ke `/tryon/apparel` dan poll `/tryon/apparel/:id` setiap 3 detik hingga `data.status == 'completed'` — biasanya dalam 1.5 hingga 4 menit.

API Virtual Try-On untuk Python — Photta | Photta