> ## Documentation Index
> Fetch the complete documentation index at: https://dripart-chore-sync-comfy-api-v2-spec-2b9c2cf.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Comfy SDK

> 独自のアプリケーションからComfyUIワークフローを実行するための公式PythonおよびTypeScript SDK

<Warning>
  **ベータ。** SDKと、それらが呼び出すComfy API v2は`0.1.x`です。APIの形状は、確定する前にまだ変更される可能性があります。今が、間違っていることを私たちに伝えるのに最もコストのかからない時期です。[フィードバック](#フィードバック)を参照してください。
</Warning>

Comfy SDKを使用すると、アプリケーションでComfyUIワークフローを実行し、結果を受け取ることができます。ワークフローを送信すると、ComfyUIがそれを実行し、出力をダウンロードできます。同じコードが、Comfy Cloudまたは自分でホストするComfyUIインスタンスに対して実行されます。変更されるのはベースURLのみです。

SDKは、[Comfy API v2](/ja/api-reference/v2/overview)のクライアントです。これは、長期的にサポートする予定のバージョン管理されたHTTP APIです。ComfyUIの新しいリリースでも、それに基づいて構築された統合が壊れることはありません。

この方法で人々が構築するもの:

* BlenderやKritaなど、別のアプリケーション内でコンテンツを生成するプラグイン
* ユーザーに代わって生成を実行するコンシューマー向けアプリ
* バッチパイプライン。たとえば、ビデオの全フレームに1つのワークフローを実行するなど
* 同時に多くのワークフローを処理する必要があるバックエンドサービス

<Note>
  これらのSDKは、ComfyUIを**外部から**操作します。**ComfyUIの内部で**実行されるカスタムノードやフロントエンド拡張機能を記述している場合は、代わりに[カスタムノードの開発](/ja/custom-nodes/overview)を参照してください。これらは別のAPIセットです。
</Note>

## インストール

<CodeGroup>
  ```bash Python theme={null}
  pip install comfy-sdk
  ```

  ```bash TypeScript theme={null}
  npm i @comfyorg/sdk
  ```
</CodeGroup>

Python 3.10 以降。Node 22 以降。

## クイックスタート

入力画像をアップロードし、ワークフローを実行して、結果をディスクに書き込みます。

<CodeGroup>
  ```python Python theme={null}
  from comfy_sdk import Comfy

  # Comfy Cloud
  client = Comfy(api_key="comfyui-...")

  wf = client.workflows.from_file("workflow_api.json")

  asset = client.assets.from_file("photo.png")
  wf.set_input("10", "image", asset)

  job = client.run(wf)
  for output in job.get_outputs("9"):
      output.to_file(output.name)
  ```

  ```typescript TypeScript theme={null}
  import { Comfy } from "@comfyorg/sdk";

  // Comfy Cloud
  const client = new Comfy({ apiKey: "comfyui-..." });

  const wf = await client.workflows.fromFile("workflow_api.json");

  const asset = client.assets.fromFile("photo.png");
  wf.setInput("10", "image", asset);

  const job = await client.run(wf);
  await job.getOutputs("9")[0].toFile("out.png");
  ```
</CodeGroup>

`workflow_api.json` は、[API 形式](/ja/development/api-development/workflow-api-format)で保存されたワークフローです。`"10"` と `"9"` はそのファイル内のノード ID です。入力画像が送り込まれるノードと、結果を取得したい出力ノードを指します。

アセットハンドルは遅延評価されます。`photo.png` はローカルでハッシュ化され、サーバーがそのバイトをまだ保持していない場合にのみアップロードされます。そのため、同じ入力を使用して再実行してもコストはかかりません。

`run()` はジョブを送信し、ターミナル状態に達するまで待機します。実行中に他の作業を行うには、代わりに `submit()` を使用し、[イベントストリーム](#ジョブの実行を監視する)を監視してください。

代わりに自分の ComfyUI に対して実行するには、`COMFY_BASE_URL` を設定してキーを削除します。以下を参照してください。

## ベースURLの選択

| 接続先             | Base URL                             | APIキー                      |
| --------------- | ------------------------------------ | -------------------------- |
| **Comfy Cloud** | `https://cloud.comfy.org` (デフォルト)    | 必須                         |
| **サーバーレスデプロイ**  | `https://<deployment>.run.comfy.app` | 必須                         |
| **ご自身のComfyUI** | `http://127.0.0.1:8189` (ローカルプロキシ)   | デフォルトでは不要。オプションの静的ベアラートークン |

ベースURLはコンストラクタ引数ではなく、`COMFY_BASE_URL`環境変数から取得されます:

```bash theme={null}
export COMFY_BASE_URL="https://<deployment>.run.comfy.app"  # serverless
export COMFY_BASE_URL="http://127.0.0.1:8189"               # self-hosted proxy
```

この変数はクライアントが構築されるたびに読み取られ、`http(s)` URLである必要があります。未設定または空白の場合はComfy Cloudを意味します。したがって、クライアント自体はどこでも同じです:

<CodeGroup>
  ```python Python theme={null}
  client = Comfy(api_key="comfyui-...")
  ```

  ```typescript TypeScript theme={null}
  const client = new Comfy({ apiKey: "comfyui-..." });
  ```
</CodeGroup>

<Note>
  初期ビルドからアップグレードしますか? `Comfy("<url>", "<key>")`は、`COMFY_BASE_URL`を設定した`Comfy(api_key="<key>")`になりました。`api_key`はキーワード専用引数なので、以前の位置引数での呼び出しは、URLをキーとして静かに読み取るのではなく、`TypeError`を発生させます。
</Note>

### Comfy Cloud

そのまま動作します。[APIキー](/ja/development/api-development/getting-an-api-key)を作成し、クライアントに渡します。

<Note>
  APIアクセスには有料のComfy Cloudサブスクリプションが必要です。無料プランには含まれません。同時に実行できるジョブ数はプランによって異なります。[Cloud API概要](/ja/development/cloud/overview#並列実行（同時ジョブ）)をご覧ください。
</Note>

### サーバーレスデプロイ

[開発者プラットフォーム](https://platform.comfy.org)を通じてデプロイしたワークフローには、専用のエンドポイントが割り当てられます。`COMFY_BASE_URL`をそのエンドポイントに指定し、Comfy Cloudとまったく同じようにAPIキーを使用します。このガイドのすべてが同じように機能します。

サーバーレスデプロイはピン留めされた1つのワークフローを実行するため、`get_workflow()`は実行されたグラフ（`format: "api"`）を返します。

### ご自身のComfyUI

ベータ期間中、v2 APIは[comfy-api-proxy](https://github.com/Comfy-Org/comfy-api-proxy)によって提供されます。これは、ComfyUIと一緒に動作する小規模なオープンソースサービスです。

```bash theme={null}
pip install comfy-api-proxy
comfy-api-proxy
```

デフォルトでは、`127.0.0.1:8188`のComfyUIをプロキシし、`127.0.0.1:8189`でv2 APIを提供します。いずれかを変更するには、`--comfyui`と`--port`を使用します。

次に、`COMFY_BASE_URL="http://127.0.0.1:8189"`を設定します。認証はデフォルトでは不要です。プロキシに静的ベアラートークンを設定している場合は、そのトークンをSDKのAPIキーとして渡します: `Comfy(api_key="...")`。プロキシはデフォルトではループバックにのみバインドします。インストール環境にモデルファイルもアップロードしたい場合は、`--comfyui-base-dir /path/to/ComfyUI`を指定して実行してください。

プロキシは暫定対策です。v2 APIが安定すれば、ComfyUIコアに組み込まれ、プロキシは不要になります。

## ジョブの実行を監視する

`job.events()` は、ジョブの状態のライブストリームを提供します。ノードとステップの進捗、プレビューフレーム、各出力がコミットされた瞬間のデータを取得できます。接続が切断された場合は、自動的に再接続されます。

<CodeGroup>
  ```python Python theme={null}
  from comfy_sdk import Progress, Preview, OutputReady, StatusChange

  job = client.submit(wf)

  for event in job.events():
      match event:
          case Progress() as p:
              print(f"{p.value:.0%} {p.message}")
          case Preview() as pv:
              image = pv.to_pil()
          case OutputReady() as o:
              o.output.to_file(f"partial/{o.output.name}")
          case StatusChange(status="succeeded"):
              break

  result = job.result()
  ```

  ```typescript TypeScript theme={null}
  const job = await client.submit(wf);

  for await (const event of job.events()) {
    switch (event.kind) {
      case "progress":
        console.log(event.value);
        break;
      case "outputReady":
        await event.output.toFile(`${event.output.name}`);
        break;
      case "statusChange":
        if (event.status === "succeeded") break;
    }
  }
  ```
</CodeGroup>

`Preview.to_pil()` にはオプションの Pillow extra が必要です: `pip install "comfy-sdk[pil]"`。

`result()` は、完了したジョブを返します。実行に失敗した場合は、ノードレベルの詳細情報を含む `JobFailed` を送出します。完全なイベントカタログについては、お使いの言語の [SDK README](#リファレンス) を参照してください。

ストリームはライブフィードであり、再生可能なログではありません。進捗を表示するためのものであり、結果の取得に依存するためのものではありません。ジョブのポーリングこそが信頼できる情報源であり、`run()`、`wait()`、`result()` は自動的にポーリングにフォールバックします。理由については、[設計ノート](/ja/development/api-development/sdks-design#まずポーリング、進捗はストリームで) を参照してください。

## 出力を生成元のワークフローまで遡る

出力には、それを生成したジョブのIDが保持されています。そのため、サイドテーブルを保持しなくても、ファイルから逆方向に遡ることができます。

<CodeGroup>
  ```python Python theme={null}
  output = job.outputs[0]
  output.job_id          # the job that produced this file
  ```

  ```typescript TypeScript theme={null}
  const output = job.outputs[0];
  output.jobId; // the job that produced this file
  ```
</CodeGroup>

同じIDは、単体で取得したアセットにも付いています。後で見つけたファイルでも、そのジョブまで遡れます。アップロードしたアセットには生成元のジョブがないため、この値は`None`（TypeScriptでは`undefined`）になります。

ジョブから、その背後にあるワークフローを取得できます。これは、このプロセス内で送信したものではなく、IDで再水和されたジョブでも機能します。

<CodeGroup>
  ```python Python theme={null}
  wf = job.get_workflow()

  if wf.format == "save":
      ...  # the workflow as authored, canvas layout and Note nodes intact
  else:
      ...  # the executed API-format graph
  ```

  ```typescript TypeScript theme={null}
  const wf = await job.getWorkflow();

  if (wf.format === "save") {
    // the workflow as authored, canvas layout and Note nodes intact
  } else {
    // the executed API-format graph
  }
  ```
</CodeGroup>

**常に`format`で分岐してください。** 返ってくる形状は、ジョブがどのように送信されたかによって決まり、リクエストごとに制御できるものではありません。

| `format` | 取得できるもの                                                   | ケース                                            |
| -------- | --------------------------------------------------------- | ---------------------------------------------- |
| `save`   | ジョブが実行されたバージョンの作成時ワークフロー。キャンバスレイアウトとNoteなどのエディタ専用ノードを含みます | Comfy Cloudエディタから送信されたジョブ。ワークフローバージョンが固定されています |
| `api`    | 実行されたグラフ。エディタ専用の構成要素は除去され、Get/Setノードは展開されています             | その他すべて（今日これらのSDKを通じて送信されるすべてのジョブを含みます）         |

SDKを通じて送信したジョブは常に`api`を返します。v2送信にはバージョン固定フィールドがまだないためです。この動作は将来変更されます。判別子が用意されているのは、コード側の変更が不要になるようにするためです。

## SDK が現在対応している範囲

最初のバージョンは、1つのことをきちんと行います。ワークフローを実行して結果を取得することです。

* **アセット:** ファイル、バイト、ストリーム、または URL から入力ハンドルを作成します。ハンドルは遅延評価され、コンテンツアドレス方式のため、同じ入力で再実行しても再アップロードされません。
* **送信:** API 形式のグラフを送信します。送信は冪等であり、キューが満杯の場合も、限られた予算内で自動的に再試行されます。
* **実行:** `wait()` でポーリングするか、`events()` でリアルタイムの進捗を追跡します。
* **出力:** ディスクに書き込む、メモリにバッファリングする、バイト範囲を取得する、または短期間有効なダウンロード URL を取得します。
* **トレーサビリティ:** すべての出力には、それを生成したジョブの ID が含まれ、ジョブからその背後にあるワークフローを取得することもできます。
* **アセットの削除:** アップロードしたアセットを、ハンドルまたは ID で削除します。
* **エラー:** 生のステータスコードではなく、`JobFailed`、`Unauthorized`、`InsufficientCredits`、`QueueFull` などの型付き例外。
* **キャンセル:** 実行中のジョブをキャンセルできます。TypeScript では、任意の呼び出しで `AbortSignal` も受け付けます。

Python には、同期 `Comfy` クライアントと、同じインターフェースを持つ `AsyncComfy` クライアントの両方が用意されています。TypeScript は非同期のみです。

このバージョンには含まれないもの: 保存したワークフローの管理、モデルライブラリ、ノードのイントロスペクション、名前付きワークフローパラメータ。[設計ノート](/ja/development/api-development/sdks-design#最初のバージョンの範囲) では、なぜ API サーフェスがこのように小さく始まるのかを説明しています。

## リファレンス

SDK の README は、各言語の完全なリファレンスです。認証、アセット、エラー、および低レベルのエスケープハッチを含みます。

<CardGroup cols={2}>
  <Card title="Python SDK" icon="python" href="https://github.com/Comfy-Org/comfy-python-sdk">
    <code>comfy-sdk</code> を PyPI で公開。同期・非同期クライアント。
  </Card>

  <Card title="TypeScript SDK" icon="js" href="https://github.com/Comfy-Org/comfy-typescript-sdk">
    <code>@comfyorg/sdk</code> を npm で公開。型付き・非同期、低レベルクライアントを備えています。
  </Card>

  <Card title="Comfy API v2 リファレンス" icon="code" href="/ja/api-reference/v2/overview">
    両方のSDKの基盤となるHTTP API。任意の言語から直接使用できます。
  </Card>

  <Card title="設計ノート" icon="compass" href="/ja/development/api-development/sdks-design">
    このAPIが存在する理由、既存のComfyUI APIとの関係、今後の予定。
  </Card>
</CardGroup>

## フィードバック

これは意図的に`0.1.x`です。メソッド名、クライアントの形状、イベントカタログ、エラーの分類体系、実際のアセット操作の使用感は、すべてまだ変更コストが低く、今後数週間でサーフェスを固定する予定です。その後、「長期的にサポートします」という言葉は、もはや修正できないことを意味するようになります。

使いにくい点、期待していたのに見つからなかったもの、回避策で対応せざるを得なかったことをお知らせください。[私たちのDiscord](https://discord.com/invite/comfyorg)の`#developer-platform`チャンネルがその場所です。

別の言語のファーストパーティSDKが必要な場合は、そこでその旨をお伝えください。両方のSDKは同じ文書化されたHTTP契約に基づいているため、今日の時点であらゆる言語がAPIと通信できますが、どこに需要があるのかを把握したいと考えています。
