Python · バーチャル試着 API

Python でのバーチャル試着 API

pip install photta は不要です。Photta のドキュメントでは公式に requests ライブラリを推奨しています。30行のラッパーがあれば、Django, FastAPI, Celery ワーカー, Lambda ハンドラーなどにそのまま組み込めます。

要約

`requests` をインストールし、環境変数から `PHOTTA_API_KEY` を読み込みます。`Authorization: Bearer photta_live_xxx` を送信し、2xx 以外で `PhottaError` を送出する `photta_request()` ラッパーを作成します。`/tryon/apparel` に POST し、`data.status == 'completed'` になるまで 3秒ごとに `/tryon/apparel/:id` をポーリングします(通常 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.5–4min

2K / 4K credits

5 / 7

Jewelry types

4

Close-up mannequins

built-in

仕組み

Python でのバーチャル試着 API

5ステップ、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 ラッパーを作成する

    ベースURL、Authorization ヘッダー、JSON シリアライズ、エラー変換を処理する 30行程度の `photta_request()` 関数を作成します。Python SDK がリリースされるまでは、この抽象化だけで十分です。

  4. 04

    ステップ 4

    送信とポーリング

    `/tryon/apparel` に POST して生成IDを取得し、3秒間隔で `/tryon/apparel/:id` をポーリングします。Celery や RQ を使用する場合、4分間のジョブでワーカーを占有しないよう、ポーリングループをタスク間で分割してください。

  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 のロードマップでは、有料 API ユーザーが10社に達した時点で Python SDK を優先的に開発する予定です。それまでは、requests ライブラリ(同期)または httpx(非同期)を使用した統合をサポートしています。このページの30行のラッパーはいずれでも動作します。

どの Python バージョンがサポートされていますか?+

Python 3.9 以降です。ラッパーは型ヒント、f-strings、`str | None` 構文を使用しており、3.10+ で最適に動作します。3.9 の場合は `str | None` を `Optional[str]` に置き換えてください。requests 自体は 3.8+ をサポートしていますが、現代的な Photta プロジェクトでは 3.9+ が実質的な最小要件です。

requests と httpx のどちらを使うべきですか?+

数個の連続したコールを行うだけなら、シンプルで普及している requests が適しています。非同期の並行処理(並列送信やバルク処理)や HTTP/2 が必要な場合は httpx を選択してください。ラッパーはどちらでもほぼ同じです。`requests.request` を `httpx.Client().request` に置き換えるだけで、残りのコードは維持できます。

Django から呼び出せますか?+

はい。`services/photta.py` にラッパーを配置し、View や Celery タスクからインポートしてください。ジョブが長い場合は同期 View 内で API を呼び出さず、View から送信して生成IDを返し、バックグラウンドタスクや Channels コンシューマーからポーリングしてください。

Celery ワーカーからポーリングするには?+

1つのタスクでジョブを送信し、その後、1回ポーリングしてジョブが未完了なら自身を再スケジュールする(`apply_async(countdown=3)` 使用)後続タスクを作成します。これにより、ワーカーを解放し続け、オートスケーラーを阻害する長時間実行タスクを回避できます。

API のエラーはどのように通知されますか?+

2xx 以外のレスポンスには `type`, `code`, `message` を含む JSON ボディが含まれ、400 では `param`、429 では `retry_after` が付与されます。このページのラッパーは、これらすべてを保持する `PhottaError` を送出するため、呼び出し側でボディを解析することなくステータスコードに応じた分岐が可能です。

Python · バーチャル試着 API

アカウントを作成してAPIキーを取得

`requests` をインストールし、環境変数から `PHOTTA_API_KEY` を読み込みます。`Authorization: Bearer photta_live_xxx` を送信し、2xx 以外で `PhottaError` を送出する `photta_request()` ラッパーを作成します。`/tryon/apparel` に POST し、`data.status == 'completed'` になるまで 3秒ごとに `/tryon/apparel/:id` をポーリングします(通常 1.5–4 分以内)。

Python 用バーチャル試着 API — Photta | Photta