Python · 虚拟试穿 API

Python 虚拟试穿 API

无需 pip install photta —— Photta 文档正式推荐使用 requests 库。一个 30 行的封装即可无缝接入 Django、FastAPI、Celery worker 和 Lambda 函数。

一句话介绍

安装 `requests`,从环境加载 `PHOTTA_API_KEY`,编写一个发送 `Authorization: Bearer photta_live_xxx` 的 `photta_request()` 封装函数,并在非 2xx 响应时抛出 `PhottaError`。随后 POST 到 `/tryon/apparel` 并每 3 秒轮询一次 `/tryon/apparel/:id` 直至 `data.status == 'completed'` —— 通常在 1.5 到 4 分钟内完成。

已更新 · 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

工作原理

Python 虚拟试穿 API

五个步骤,无需 Photta 特有依赖 —— requests 涵盖一切。

  1. 01

    步骤 1

    注册并生成密钥

    路径与其他语言一致:ai.photta.app → Developers → Generate API key。密钥以 `photta_live_` 开头,通用所有 Photta 功能。

  2. 02

    步骤 2

    从环境加载密钥

    在环境中设置 `PHOTTA_API_KEY` 并通过 `os.environ` 读取。在 FastAPI 或 Django 中,启动时将其加载到配置模块中。不要将密钥嵌入源码或公共 Git 历史。

  3. 03

    步骤 3

    编写 requests 封装函数

    一个 30 行的 `photta_request()` 函数即可处理基础 URL、Authorization 请求头、JSON 序列化和错误转换。在 Python SDK 上线前,这是您唯一需要的抽象。

  4. 04

    步骤 4

    提交并轮询

    向 `/tryon/apparel` 发送 POST 获取任务 ID,然后以 3 秒间隔轮询 `/tryon/apparel/:id`。在 Celery 或 RQ 中,应将轮询逻辑拆分到多个任务中,以免单个 4 分钟的任务长期占用 worker。

  5. 05

    步骤 5

    持久化结果

    完成后的数据包含 `output_url` 和 `thumbnail_url`。将字节流下载到您自己的对象存储(S3, GCS, Cloudflare R2)中,这样您的产品展示就不会长期绑定在 Photta 的 CDN 上。

端到端代码

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 吗?+

目前还没有。Photta 路线图优先考虑在达到 10 个付费 API 客户后发布 Python SDK。在此之前,官方支持的集成路径是 requests 库(同步)或 httpx(异步) —— 两者在文档中均有记载,且均适配本页面的 30 行封装代码。

支持哪些 Python 版本?+

Python 3.9 及更高版本。封装代码使用了类型提示、f-string 和 `str | None` 语法,这在 3.10+ 中表现完美。在 3.9 中请将 `str | None` 替换为 `Optional[str]`。requests 本身支持 3.8+,但 3.9+ 是现代 Photta 项目的实际最低要求。

我该用 requests 还是 httpx?+

如果您只是进行少量顺序调用,请使用 requests —— 它更简单且大多项目已内置。如果您需要异步并发(并行提交、批量回填)或 HTTP/2,请选择 httpx。两者的封装逻辑非常相似;只需将 `requests.request` 替换为 `httpx.Client().request`,其余代码保持不变。

我可以在 Django 中调用它吗?+

可以。将封装函数放在 `services/photta.py` 中,从 view 或 Celery 任务中导入。如果任务耗时较长,请勿在同步请求处理器内阻塞调用 API —— 而应在 view 中提交,返回任务 ID,并在后台任务或 Channels consumer 中进行轮询。

如何在 Celery worker 中进行轮询?+

从一个任务提交生成请求,然后调度一个后续任务(通过 `apply_async(countdown=3)`),该任务执行一次轮询,并在任务未完成且未达到最大重试次数前持续自我调度。这能保持 worker 空闲,避免因长时任务导致自动扩缩容失效。

API 如何返回错误?+

非 2xx 响应包含 JSON 格式的 `error` 对象:`type`、`code`、`message`,400 错误还会附带 `param`,429 错误附带 `retry_after`。本页面的封装函数会抛出包含这些信息的 `PhottaError`,方便调用者根据状态码进行逻辑分支处理,无需手动解析请求体。

Python · 虚拟试穿 API

创建账户并获取 API 密钥

安装 `requests`,从环境加载 `PHOTTA_API_KEY`,编写一个发送 `Authorization: Bearer photta_live_xxx` 的 `photta_request()` 封装函数,并在非 2xx 响应时抛出 `PhottaError`。随后 POST 到 `/tryon/apparel` 并每 3 秒轮询一次 `/tryon/apparel/:id` 直至 `data.status == 'completed'` —— 通常在 1.5 到 4 分钟内完成。

Python 虚拟试穿 API — Photta | Photta