Python · Virtual Try-On API

Virtual Try-On API trong Python

Không cần pip install photta — tài liệu Photta chính thức khuyến nghị sử dụng thư viện requests. Một wrapper 30 dòng có thể tích hợp vào Django, FastAPI, Celery workers và Lambda handlers mà không cần thủ tục phức tạp nào khác.

Tóm tắt trong một câu

Cài đặt `requests`, tải `PHOTTA_API_KEY` từ môi trường, viết một wrapper `photta_request()` để gửi `Authorization: Bearer photta_live_xxx` và raise lỗi `PhottaError` có kiểu dữ liệu cho các phản hồi không phải 2xx, sau đó POST tới `/tryon/apparel` và poll `/tryon/apparel/:id` mỗi 3 giây cho đến khi `data.status == 'completed'` — thường trong vòng 1.5 đến 4 phút.

Đã cập nhật · 2026-04-19

Yêu cầu đầu tiên của bạn

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)

Kỳ vọng gì

Typical completion

1.5–4min

2K / 4K credits

5 / 7

Jewelry types

4

Close-up mannequins

built-in

Cách hoạt động

Virtual Try-On API trong Python

Năm bước, không có thư viện phụ thuộc riêng của Photta — requests xử lý được tất cả.

  1. 01

    Bước 1

    Đăng ký và tạo key

    Cùng quy trình như mọi ngôn ngữ khác: ai.photta.app → Nhà phát triển → Tạo API key. Key bắt đầu bằng `photta_live_` và hoạt động trên mọi tính năng của Photta.

  2. 02

    Bước 2

    Tải key từ env

    Thiết lập `PHOTTA_API_KEY` trong môi trường và đọc nó qua `os.environ`. Trong FastAPI hoặc Django, hãy tải nó một lần khi khởi động vào một module settings. Đừng nhúng key vào mã nguồn hoặc lịch sử Git công khai.

  3. 03

    Bước 3

    Viết một requests wrapper

    Một hàm `photta_request()` dài 30 dòng để xử lý base URL, Authorization header, JSON serialization và chuyển đổi lỗi. Đó là lớp trừu tượng duy nhất bạn cần cho đến khi Python SDK ra mắt.

  4. 04

    Bước 4

    Gửi yêu cầu và poll

    POST tới `/tryon/apparel` để lấy ID tạo ảnh, sau đó poll `/tryon/apparel/:id` mỗi 3 giây. Trong Celery hoặc RQ, hãy chia vòng lặp poll qua các task để một tác vụ 4 phút không làm nghẽn worker.

  5. 05

    Bước 5

    Lưu trữ kết quả

    Payload hoàn tất bao gồm `output_url` và `thumbnail_url`. Tải dữ liệu vào kho lưu trữ đối tượng của riêng bạn — S3, GCS, Cloudflare R2 — để sản phẩm của bạn không bị ràng buộc vào CDN của Photta cho việc hiển thị lâu dài.

Code toàn quy trình

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

Tại sao lại có cấu trúc này

Tại sao requests là lựa chọn đúng đắn hiện nay

  • 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

Những gì nó không làm

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

Câu hỏi từ các nhà phát triển khác

Questions other developers ask

Có SDK Photta Python chính thức không?+

Chưa có. Lộ trình của Photta ưu tiên Python SDK khi có mười khách hàng API trả phí hoạt động. Cho đến lúc đó, lộ trình tích hợp được hỗ trợ là thư viện requests (đồng bộ) hoặc httpx (bất đồng bộ) — cả hai đều được ghi nhận trong tài liệu chính thức và hoạt động tốt với wrapper 30 dòng trên trang này.

Những phiên bản Python nào được hỗ trợ?+

Python 3.9 trở lên. Wrapper sử dụng type hints, f-strings và cú pháp `str | None`, hoạt động tốt trên 3.10+. Trên 3.9, hãy đổi `str | None` thành `Optional[str]`. Bản thân requests hỗ trợ chính thức 3.8+, nhưng 3.9+ là mức tối thiểu thực tế cho các dự án Photta hiện đại.

Nên dùng requests hay httpx?+

Sử dụng requests nếu bạn chỉ thực hiện một vài lệnh gọi tuần tự — nó đơn giản hơn và có sẵn trong hầu hết mã nguồn. Sử dụng httpx nếu bạn cần xử lý bất đồng bộ (gửi yêu cầu song song, nạp dữ liệu hàng loạt) hoặc HTTP/2. Wrapper đều rất nhỏ gọn; chỉ cần đổi `requests.request` thành `httpx.Client().request` và phần mã còn lại giữ nguyên.

Tôi có thể gọi từ Django không?+

Có. Đặt wrapper trong `services/photta.py`, import nó từ một view hoặc một Celery task. Đừng gọi API bên trong một trình xử lý yêu cầu đồng bộ nếu tác vụ kéo dài — hãy gửi yêu cầu từ view, trả về ID tạo ảnh, và poll từ một task chạy ngầm hoặc một Channels consumer.

Làm thế nào để poll từ một Celery worker?+

Gửi tác vụ từ một task, sau đó lên lịch một task tiếp theo (qua `apply_async(countdown=3)`) để thực hiện poll một lần và tự lên lịch lại cho đến khi tác vụ hoàn thành hoặc đạt ngưỡng thử lại tối đa. Điều này giúp các worker luôn rảnh và tránh các task chạy quá lâu gây ảnh hưởng đến hệ thống autoscaler.

API báo lỗi như thế nào?+

Các phản hồi không phải 2xx mang theo JSON body với đối tượng `error`: `type`, `code`, `message`, kèm theo `param` cho lỗi 400 và `retry_after` cho lỗi 429. Wrapper trên trang này raise một lỗi `PhottaError` chứa tất cả các thông tin này để bạn có thể xử lý theo mã trạng thái mà không cần tự parse body.

Python · Virtual Try-On API

Tạo tài khoản và lấy API key

Cài đặt `requests`, tải `PHOTTA_API_KEY` từ môi trường, viết một wrapper `photta_request()` để gửi `Authorization: Bearer photta_live_xxx` và raise lỗi `PhottaError` có kiểu dữ liệu cho các phản hồi không phải 2xx, sau đó POST tới `/tryon/apparel` và poll `/tryon/apparel/:id` mỗi 3 giây cho đến khi `data.status == 'completed'` — thường trong vòng 1.5 đến 4 phút.

Virtual Try-On API cho Python — Photta | Photta