チュートリアル
hiapi API で recraft-v4-styles-pro/text-to-image を呼び出す方法:curl と Python
このエンドポイントが行うことと、使うべきタイミング
recraft-v4-styles-pro/text-to-image はテキストプロンプトを画像に変換しますが、その際立った特徴はスタイル認識にあります。プロンプトの文言だけに頼るのではなく、スタイル参照によって結果の視覚言語を導くことができます。出力が1回や2回の生成で見栄えするだけでなく、多数の生成を通じて一貫した感覚を保つ必要がある場合に実用的な選択肢です。
開発者は次のような場面でよくこれを使います:
- ブランド一貫性のある素材——キービジュアル、ソーシャルカード、広告バリエーションがすべて同じ視覚体系に収まる必要があります。
- 製品・マーケティングのモックアップ——プロンプトを繰り返し調整し、スタイルを固定して、ブランドに合致するバリエーション群を生成します。
- パイプラインのステップ——生成をより大きな自動化の一段階として扱い、保存済みの画像を別のサービスが消費します。
以下のすべてのコード例の書き方を決定づける特性が一つあります:画像生成は非同期です。リクエストはタスクを送信してすぐに返ります;画像は後から現れます。送信ステップとポーリングステップを書き、それらを二つの独立した関心事として扱う必要があります。
hiapi の認証情報とリクエスト基盤を準備する
すべての呼び出しは hiapi の統一されたエンドポイント界面を経由するため、最初のリクエストの前に三つのものを用意する必要があります:
- API キー——hiapi アカウントから取得します。他の機密情報と同様に扱い、環境変数から読み込み、共有する可能性のあるスクリプトにハードコードしないでください。
- モデル識別子——リリース時と完全に一致させる必要があります:
recraft-v4-styles-pro/text-to-image。 - HTTP をサポートするツール——探索用の
curl、および永続化が関わるあらゆる場面用の HTTP ライブラリ。
export HIAPI_API_KEY="your-key-here"
早めに内面化しておくべき約束事:
- JSON リクエストボディを送信する際は
Content-Type: application/jsonを使用します。 - bearer token ヘッダーで認証します。
- モデル id、プロンプト、スタイル参照はペイロード内のそれぞれ独立したフィールドとして扱い、すべてを一つの文字列に詰め込まないでください——そうすればポーリングステップとログがより理解しやすくなります。
正確なリクエストヘッダー名、ベース URL、現在のフィールド定義については、このモデルの hiapi API リファレンスドキュメントを参照してください;このチュートリアルは呼び出しの形態として、リファレンスドキュメントは名称の権威ある情報源として扱ってください。
動作する curl リクエスト
以下は送信呼び出しです。これを三つの層として理解してください:トランスポート、認証、リクエストボディ。
curl -sS -X POST "$HIAPI_BASE_URL/generate" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "recraft-v4-styles-pro/text-to-image",
"prompt": "minimalist product photo of a ceramic mug on a linen surface, soft daylight",
"style_references": []
}'
行ごとの説明:
-X POST——取得ではなく、タスクを送信します。Authorization: Bearer ...——トークンは環境変数から取得するため、このコマンドはターミナルに安全に貼り付けられ、変数を除けば安全に共有できます。-d '{...}'——JSON リクエストボディ。modelは正確な識別子です。promptはシーンを記述する自由テキストです。style_referencesはスタイル制御のマウントポイントであり、次に議論します。-sS——進捗バーを静かにするが、エラーは依然表示するため、失敗した呼び出しが見えます。
成功したレスポンスは画像ではなく確認応答です:タスクの識別子とステータスが得られます。その識別子を記録してください——ポーリングに必要な唯一のハンドルです。対話的に探索している場合は、レスポンスを JSON フォーマッタに通すとタスク id とステータスがより目立つようになります。
スタイル参照をプロンプトとともに渡す
メンタルモデルは単純です:プロンプトは何を、スタイル参照はどのように見えるべきかを説明します。ペイロード内でそれらを分離しておけば柔軟性を保てます——同じプロンプトを複数のスタイルセットで再実行して結果を比較できます。
{
"model": "recraft-v4-styles-pro/text-to-image",
"prompt": "ceramic mug on a linen surface, soft daylight",
"style_references": [
"https://your-bucket.example.com/styles/mug-ref-01.jpg",
"https://your-bucket.example.com/styles/mug-ref-02.jpg"
]
}
実用的なアドバイス:
- 参照なしから始める。 まず素のプロンプトで実行します。次に参照を一つ追加して違いを観察し、それから二つ追加します。一度に一箇所だけ変える方が、最初の試行でスタイルセット全体を使うよりもはるかに多くの情報をもたらします。
- 参照をアクセス可能に保つ。 サービスが確実に取得できる場所——公開バケットや十分な有効期間のある署名 URL——にホストし、数分で失効するリンクは使わないでください。
- セットを調和させる。 相互に一貫した参照(類似の照明、パレット、テクスチャ)は、モデルが矛盾を調停する必要がある寄せ集めよりも安定した結果を生む傾向があります。
- 参照をバージョン管理する。 それらを安定したキーの下に保存してください。来月出力に問題が生じたとき、その時どの参照ファイルが使われたかを正確に知る必要があります。
このモデルの hiapi リファレンスドキュメントを参照して、スタイル参照が URL、アップロードされたリソース、または名前付きプリセットのいずれの形式で渡されるのか、またその数と形式にどのような制限があるのかを確認してください。
Python での同じ呼び出し
curl 呼び出しは直接変換できます。小さな関数にカプセル化すれば、パイプラインの段階として再利用できます。
import os
import requests
HIAPI_BASE_URL = os.environ["HIAPI_BASE_URL"]
HIAPI_API_KEY = os.environ["HIAPI_API_KEY"]
def submit_generation(prompt: str, style_references: list[str] | None = None) -> str:
"""テキストから画像へのタスクを送信し、タスク id を返す。"""
payload = {
"model": "recraft-v4-styles-pro/text-to-image",
"prompt": prompt,
"style_references": style_references or [],
}
response = requests.post(
f"{HIAPI_BASE_URL}/generate",
headers={
"Authorization": f"Bearer {HIAPI_API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=30,
)
response.raise_for_status()
data = response.json()
return data["job_id"]
設計上の注意:
- 常にタイムアウトを設定する。 無限にハングする送信は、クラッシュと同様にワーカープロセスを効果的にブロックします。
raise_for_status()は非 2xx レスポンスをキャッチしてログに記録できる例外に変換し、不正な形式のレスポンスボディのまま黙って続行しないようにします。- id のみを返す。 タスク id は送信とポーリングの間の契約です。レスポンスの残りの部分を呼び出しコードから除外すれば、次のセクションがより簡単に書けます。
hiapi リファレンスドキュメントで実際のレスポンスフィールド名を確認し、data["job_id"] を適宜調整してください——フィールドの命名は、この記事の例と最も異なる可能性がある部分です。
タスクの完了状態をポーリングする
生成には時間がかかります。固定間隔でポーリングし、終端状態で停止し、最終的には諦めます。
import time
def wait_for_job(job_id: str, timeout: float = 300, interval: float = 3) -> dict:
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
response = requests.get(
f"{HIAPI_BASE_URL}/jobs/{job_id}",
headers={"Authorization": f"Bearer {HIAPI_API_KEY}"},
timeout=30,
)
response.raise_for_status()
job = response.json()
status = job["status"]
if status == "succeeded":
return job
if status == "failed":
raise RuntimeError(f"Job {job_id} failed: {job.get('error')}")
time.sleep(interval)
raise TimeoutError(f"Job {job_id} did not finish within {timeout}s")
あまり明白でない部分:
- 二つではなく三つの結果。 保留中、成功、失敗です。認識されないステータスはすべて保留中として扱い、ログを一行記録してください——そうすれば新たに追加されたステータスがワーカープロセスをクラッシュさせません。
- 待機全体に一つの期限を使用する。
time.monotonic()の期限は時計調整の影響を受けませんが、壁時計時間の算術はそうではありません。 - 頻繁にリクエストしない。 画像生成では、各チェック間の数秒で十分です。より速くポーリングする必要がある場合は、間隔を短縮するのではなく、試行間にバックオフを入れます。
- タイムアウトを強制する。 決して終了しないタスクは、コンテナが強制終了されるまで実行し続けるループではなく、アラートを発するエラーとして振る舞うべきです。
大量のタスクを実行する場合は、各タスクのためにタイトループでポーラーを生成するのではなく、バッチで送信し、イベントループやスレッドプールを使用して間隔をずらしながら並行してポーリングしてください。
出力をダウンロードして保存する
完了したタスクは画像参照、通常は URL を返します。これらのリンクには時間制限がある可能性があるため、速やかにダウンロードしてください。
def save_image(job: dict, path: str) -> None:
url = job["output"]["image_url"]
for attempt in range(3):
try:
with requests.get(url, stream=True, timeout=60) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return
except requests.RequestException:
if attempt == 2:
raise
time.sleep(2 ** attempt)
本番環境で採用する価値のある実践:
- ストリーミングダウンロード。 生成された画像は小さくありません;理由なく完全にメモリにロードするのは無駄です。
- 一時パスに書き込み、その後リネームする。 書き込み途中でのクラッシュは、パイプラインが有効な画像を期待する場所に切り詰められたファイルを残すべきではありません。
- 生成ではなくダウンロードを再試行する。 不安定なバケット取得の再試行は安価です;生成の浪費はそうではありません。再試行回数を制限し、指数バックオフを使用してください。
- タスク id をファイルと一緒に永続化する。 画像がどこから来たのかと誰かが尋ねたとき、答えはログを探し回るのではなく、一度のクエリで済むべきです。
オブジェクトストレージの場合は、open() を SDK のストリーミングアップロードに置き換え、同じ再試行の外殻を保ちます。
エラー、再試行、コストの妥当性チェック
最初に遭遇する失敗モードと、それぞれの処理方法:
- 401 / 認証エラー——キーが欠落、誤記、またはスクリプトを実行するシェルにエクスポートされていません。ペイロードに触れる前に環境を確認してください。
- 4xx 検証エラー——通常はモデル id の誤記、
promptの欠落、または不正な形式のスタイル参照です。レスポンスボディを逐語的に記録してください;検証メッセージはここで最速の修正手段です。 - 429 / レート制限——即座に再試行するのではなく、ジッター付きバックオフを使用します。送信関数の前にキューを設置することが再試行の嵐に勝ります。
- タスクタイムアウト——ポーリング期限が発動しました。再送信するかどうかを意図的に決定してください;盲目的な再送信は成功率を上げずに支出を倍にします。
- 一時的なネットワークエラー——上限付きの指数バックオフで送信とダウンロードを再試行します。ダウンロードの失敗は自由に再試行し、生成は慎重に再試行します。
コスト規律を実用的な観点から:
- 課金はモデルが実際に実行した作業に従うため、失敗したタスクと放棄されたバッチは隠れたコストです。後で使用量を計算できるよう、すべての送信をプロンプトハッシュとタスク id とともに記録してください。
- 可能な限り安価なプロンプトで反復する。 小規模で高速な実行で文言とスタイル参照を調整してから、大規模バッチに投入してください。
- 重複排除。 同じプロンプトとスタイルセットが二度リクエストされた場合、最初の結果を独自のキャッシュから提供してください。
- ワーカープロセスにハードな同時実行上限を追加する。 制限を引き上げる方が、予期しない請求を説明するよりも簡単です。
送信、ポーリング、保存を三つの独立したテスト可能な関数として扱えば、このエンドポイントはあらゆるパイプラインにきれいに組み込めます。正確なフィールド名、ステータス、現在の価格については、統合前に hiapi の recraft-v4-styles-pro/text-to-image モデルページを確認してください。
関連記事
すべての記事を見る →-
チュートリアル
HiAPI API で hailuo-2.3-fast/image-to-video を呼び出す方法:curl と Python の実践
高速・低コストな画像から動画へのティアにおける最初の実行可能なリクエスト — モデル ID から MP4 のダウンロードまで
-
チュートリアル
HiAPI APIでhailuo-2.3/text-to-videoを呼び出す方法:curl、Python、実行可能なリクエスト例
-
チュートリアル
HiAPI で Kandinsky 6.0 Pro のテキストto動画を使用する:curl と Python チュートリアル
リクエスト優先の実践デモ:プロンプトから動画クリップへの呼び出しを構築し、リクエストを送信し、完了状態をポーリングし、結果をダウンロードする