HiAPI
ブログ

チュートリアル

HiAPI APIでflux-2-klein-4b/text-to-imageを呼び出す方法:curl、Python、そして動作するリクエスト

経済的な画像階層をパイプラインに組み込むための実践チュートリアル

Oct 31, 2026
平面玻璃风格封面图:数层半透明玻璃斜向叠压,把浅灰底场折射成冷蓝色带,构图安静克制。

flux-2-klein-4b/text-to-imageがコスト重視のワークロードに適している理由

すべての画像パイプラインがカタログ中で最も重いモデルを必要とするわけではありません。本番トラフィックの大部分は反復的なものです。商品画像、バリエーションプレビュー、商品リストのサムネイル、同じテンプレートから生成されるソーシャルカードなどです。こうした場面では、flux-2-klein-4b/text-to-image は意図的に軽量な階層として設計されています。最高水準の忠実度を少し犠牲にする代わりに、スループットと予測可能性を得るわけで、数千個の素材をスケジュールに沿って一括生成する場合には、これがたいてい正しいトレードオフです。

最も恩恵を受けるワークロードは2種類あります。

  • ECの商品画像。 通常、きれいな基本記述(「マットなセラミックマグ、350ml、ウォームグレー、白いシームレス背景に配置」など)があり、色・角度・構図をカバーする大量のレンダリングバリエーションを生成する必要があります。芸術的な表現力よりも一貫性が重要です。
  • 社内向けまたはロングテールの画面向けの一括生成。 カテゴリバナー、A/Bテスト用クリエイティブ、ドラフトリストのプレースホルダー画像など——こうした素材では、わずかな品質向上はより重い実行コストに見合いません。

キービジュアルや精細なテクスチャ、構図そのものが製品である場合は、より重い階層を選んでください。生成量、レイテンシ、1枚あたりのコストが意思決定を支配する場合は、flux-2-klein-4b/text-to-image を選んでください。本チュートリアルの残りでは、この階層をエンドツーエンドで使用します。リクエスト構造、curl呼び出し、Pythonヘルパー関数、アスペクト比戦略、そして非同期ライフサイクルです。

リクエスト送信前の準備

最初の呼び出しの前に、3つのことを確定する必要があります。

1. HiAPIからのAPIキー

HiAPIコンソールでキーを作成します。ここで説明するすべてのリクエストはこのキーで認証され、キーが唯一必要な資格情報です——モデルごとの個別登録手続きはありません。

2. キーをソース管理から遠ざける

他のあらゆる機密情報と同様に扱ってください。実績のある方法は次のとおりです。

export HIAPI_API_KEY="your-key-here"

その後、シェルとPythonで環境から読み取ります。絶対にコミットせず、dotfileローダーを使用する場合は .env を .gitignore に追加してください。キーが漏洩した場合は、履歴をクリーンアップしようとするのではなく、コンソールでローテーションしてください。

3. モデル識別子の確認

識別子文字列はリクエストボディでそのまま使用され、一部の構成ではURLにも現れます。

flux-2-klein-4b/text-to-image

正確にコピーしてください——4b と /text-to-image の接尾辞はどちらも名前の一部です。ここでのタイプミスは404や「unknown model」エラーの最も一般的な原因です。キーが環境にあり、識別子が確認できたら、ペイロードを構築できます。

flux-2-klein-4b/text-to-imageリクエストの構成

HiAPI上のテキスト生成画像リクエストは意図的に簡潔に保たれています。モデル識別子と生成パラメータのペイロードを提供し、モデルエンドポイントの構成方法に応じて、結果またはジョブハンドルが返されます。

最も重要なフィールド

  • model — 正確な識別子、flux-2-klein-4b/text-to-image。
  • prompt — 画像を説明する文字列。これは出力品質に最も影響するフィールドです。他の何かを変更する前に、ここに注力してください。
  • サイズまたはアスペクト比 — 出力のフレーミングを指定する方法。ハードコードされたピクセルペアではなく、アスペクト比形式の指定を優先してください。基盤となる解像度の挙動が変わっても安定しているからです。

レスポンスの形

レスポンスには2つの形態があり、クライアントは両方を処理する必要があります。

  1. 同期ペイロード — レスポンスに生成画像の位置(URL)が直接含まれます。
  2. 非同期ジョブペイロード — レスポンスにジョブ識別子とステータス(pending、processing、succeeded、failed が典型的なステータス)が含まれます。次にその識別子でステータスエンドポイントをポーリングし、終了状態に達してペイロードに出力位置が含まれるまで待ちます。

検証できないパラメータを発明しないでください。フィールドがそのモデルの文書化されたリクエストの一部でない場合は、含めないでください——未知のフィールドは紛らわしい400エラーの2番目に一般的な原因です。model、prompt、アスペクト比から始め、まず1枚の画像を正常に取得してから、オプションのパラメータを1つずつ追加し、各変更後に出力を確認してください。

最初に動作するcurl呼び出し

以下はターミナルに貼り付けられる完全なリクエストです。HIAPI_API_KEY が上記のようにエクスポートされていることを前提としています。

curl -sS -X POST "https://api.hiapi.ai/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-2-klein-4b/text-to-image",
    "prompt": "Studio product photo of a matte ceramic mug, warm grey, soft diffused light, seamless white background, centered composition",
    "aspect_ratio": "1:1"
  }'

JSONフォーマッタ(| jq .)に通してレスポンスを読み取ります。画像URLが直接表示されるか、id と status を持つジョブオブジェクトが表示されます。

結果の解釈

  • 画像URLが得られた場合は、ブラウザで開いてください。キー、モデル識別子、プロンプトがすべて正常に機能していることが確認できます。
  • ジョブオブジェクトが得られた場合は、id を記録してください——後のセクションでポーリングします。

一般的な障害の診断

  • 401 / 403 — キーが欠落している、形式が誤っている、または Authorization: Bearer ヘッダーで渡されていません。curlを実行するシェルで環境変数が実際にエクスポートされているか確認してください。
  • 404 または「unknown model」 — 識別子が誤っています。正確に flux-2-klein-4b/text-to-image である必要があります。
  • 検証メッセージ付きの400 — 通常は prompt の欠落、サポートされていないパラメータ名、または受け入れられる集合にないアスペクト比です。ペイロードを3つのコアフィールドに絞り、再試行してください。
  • 429 — 階層で許可された速度より速くリクエストを送信しています。タイトなループで再試行するのではなく、バックオフを追加してください。

curlが正常に動作したら、Python版で問題が発生したときの比較対象となる、動作が確認済みのリクエストが得られます。

同じリクエストをPythonに移植する

Python版は同じペイロードを薄くラップしたものです。パイプラインの他の部分がHTTPロジックを繰り返さずに呼び出せるよう、関数として整理してください。

import os
import time
import requests

API_BASE = "https://api.hiapi.ai/v1"
MODEL = "flux-2-klein-4b/text-to-image"

def generate_image(prompt: str, aspect_ratio: str = "1:1") -> dict:
    """Submit a text-to-image job and return the parsed response."""
    api_key = os.environ["HIAPI_API_KEY"]
    payload = {
        "model": MODEL,
        "prompt": prompt,
        "aspect_ratio": aspect_ratio,
    }
    response = requests.post(
        f"{API_BASE}/images/generations",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        },
        json=payload,
        timeout=60,
    )
    if response.status_code >= 400:
        # Surface the server's message rather than a bare status code.
        raise RuntimeError(f"HiAPI error {response.status_code}: {response.text}")
    return response.json()

すぐに効果が出る習慣をいくつか挙げます。

  • キーはインポート時ではなく関数内で環境から読み取る ことで、同じモジュールをnotebook、スクリプト、スケジュールタスクで共通して使用できます。
  • ステータスコードを明示的に確認し、レスポンスボディを例外に含める こと。HiAPIの検証メッセージはどのフィールドが誤っているかを伝えます。裸の raise_for_status() はこれを隠してしまいます。
  • タイムアウトを設定する。 タイムアウトがないと、停滞した接続がワーカープロセスを無期限にハングさせる可能性があります。
  • ペイロードをdictのまま保持する ことで、文字列フォーマットを書き直すことなく、ログ記録、差分比較、オプションパラメータの拡張ができます。

次は最小限のドライバーです。

result = generate_image(
    "Studio product photo of a matte ceramic mug, warm grey, "
    "soft diffused light, seamless white background, centered composition"
)
print(result)

本番に耐えるアスペクト比の選択

アスペクト比は、下流システムがフレーミングを前提とするため、後工程で手戻りが最も発生しやすいパラメータです。リクエストごとではなく、画面ごとに決定してください。

実用的なマッピング

  • 正方形 (1:1) — マーケットプレイスのリスト、商品グリッド、アバター、サムネイル位置。ほとんどの商品タイルは正方形で、切り抜きの見栄えが悪いため、ECの安全なデフォルトです。
  • 縦長 (3:4 または 4:5) — ソーシャルフィードの位置やルックブック風の商品画像。ボトルや衣料など縦長の商品に、黒帯なしでスペースを提供します。
  • 横長 (16:9) — バナー、キービジュアル帯、メールヘッダー、動画サムネイル。

上流で比率を固定すべき理由

レンダリング時にAPIをたまたま呼び出すコードが比率を選択すると、商品カタログの半分が正方形、半分が縦長になり、修正のために再生成のコストが発生します。代わりに、比率をコンテンツモデルにエンコードしてください——決定的に比率へマッピングされる surface や placement フィールド——そしてそのフィールドから生成します。切り抜きを許容できる位置には1:1を使用し、固定レイアウトの位置にはレイアウトが要求する比率を使用してください。

同じ規律はプロンプトにも当てはまります。フレーミングのヒント(「中央配置の構図」、「商品全体がフレーム内に収まる」、「左側にコピー用の余白」)は、その場限りの呼び出しごとの文字列ではなく、プロンプトテンプレートに含めてください。テンプレートにより、1000枚の生成画像が同じパイプラインから出てきたように見え、まさにそれが商品カタログに必要なことです。

注意点が1つあります。すべてのモデルがすべての比率を受け入れるわけではありません。選択した比率を1回送信して成功を確認してから、バッチ全体に展開してください。

非同期ジョブを完了までポーリングする

flux-2-klein-4b/text-to-image が画像ではなくジョブハンドルを返す場合は、状態機械として扱ってください。流れは次のとおりです。送信 → ジョブIDを受信 → ステータスをポーリング → 終了状態 → 出力を読み取る。

def wait_for_job(job_id: str, timeout_s: int = 300, interval_s: int = 2) -> dict:
    api_key = os.environ["HIAPI_API_KEY"]
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        response = requests.get(
            f"{API_BASE}/jobs/{job_id}",
            headers={"Authorization": f"Bearer {api_key}"},
            timeout=30,
        )
        response.raise_for_status()
        job = response.json()
        status = job.get("status")
        if status == "succeeded":
            return job
        if status == "failed":
            raise RuntimeError(f"Job {job_id} failed: {job.get('error')}")
        time.sleep(interval_s)
    raise TimeoutError(f"Job {job_id} did not finish in {timeout_s}s")

各状態の処理

  • pending / processing — 待機を続けます。短い間隔で開始し、長いキューの間にステータスエンドポイントへ頻繁に負荷をかけないよう、穏やかなバックオフ(例えば、睡眠時間を上限まで増やす)を検討してください。
  • succeeded — ペイロードに出力位置が含まれるようになりました。ただちにポーリングを停止してください。
  • failed — 盲目的に再試行しないでください。エラーメッセージを記録してください。プロンプトやパラメータの問題である場合、同じリクエストを再送信しても同じように失敗します。

停止すべき時を知る

ループは常に実時間の期限で制約してください。永遠にポーリングするワーカープロセスはリークしたワーカープロセスです。タイムアウト時には、手動確認のためにジョブIDを公開してください——ジョブが後で成功した場合でも、出力を取得できます。バッチの場合は、画像ごとに送信と待機を直列化するのではなく、複数のジョブを並行実行して一緒にポーリングしてください。

出力のダウンロードと保存

生成された画像は、ジョブまたは生成レスポンス内の取得可能な位置に現れます。サーバー側で取得し、その後自分で永続化してください——返されたURLを商品ページにホットリンクしないでください。それは配信成果物であり、ストレージ層ではないからです。

def download_image(url: str, path: str) -> str:
    response = requests.get(url, timeout=120)
    response.raise_for_status()
    with open(path, "wb") as f:
        f.write(response.content)
    return path

予測可能な命名スキームを使用する

images/{surface}/{sku}/{variant}-{ratio}.png のようなパスは3つのものを提供します。素材が商品ごとに自然にグループ化され、画面がどのフレーミングを要求したかを示し、ファイル名の比率によって予期しない重複が明らかになります。同じSKUのバリエーションを再生成する場合は、プロンプトの短いハッシュをファイル名に含めてください——そうすれば再実行が、比較したい以前の試行を静かに上書きすることはありません。

ループを閉じる

ジョブIDを保存したファイルと一緒に記録してください。マニフェスト、データベース行、または付随ファイルに記録します。下流システムが画像の品質が低いと報告したとき、ジョブIDがあれば元のプロンプトとパラメータを取得できます。コンテンツアドレス方式のファイル名と組み合わせることで、保存された素材からそれを生成した正確なリクエストまで遡れる再現可能な監査証跡が得られます。

送信、ポーリング、ダウンロードをつなげれば、flux-2-klein-4b/text-to-image はパイプライン内の普通の1ステップになります。作業をキューに入れ、期限付きでポーリングし、安定した名前で保存する。そこから先のスケーリングは、新しいコードではなく、並行性とテンプレートの問題にすぎません。

永続的なAIアーティファクトで開発を始める

APIキーを取得して、タスクベースの1つのAPIで画像・動画・音声モデルを呼び出せます。

APIドキュメントを読む