野生流动开发者文档
图片生成调用

FLUX.2 [klein] 4B 图片生成

使用耐久 Job API 生成 FLUX.2 PNG 图片并安全下载产物。

FLUX.2 [klein] 4B 是野生流动的首方文本生成图片模型,精确运行版本为 black-forest-labs/FLUX.2-klein-4B。请求使用中英文提示词,成功后生成 PNG 图片。当前目录价格为 ¥0.05 / 张;实时可用状态和最终账单以模型广场与控制台为准。

图片生成可能经历排队、模型准备和生成,因此使用耐久 Job,并在成功后单独下载产物。 下面的示例包含提交、等待和下载步骤。需要了解重试时,可查看任务与结果文件。

快速调用

以下命令适用于 macOS / Linux,需要 Python 3 和 cURL。每次新任务生成新的幂等键,重试同一任务时保留原键。

先获取 API Key,并为这次业务请求生成一个稳定且唯一的幂等键:

export WILDFLOW_API_KEY="替换为控制台生成的密钥"
export WILDFLOW_IDEMPOTENCY_KEY="$(python3 -c 'import uuid; print(uuid.uuid4())')"

提交任务:

curl --fail-with-body --silent --show-error -D response-headers.txt -X POST https://api.wildflow.cn/v1/jobs \
  -H "Authorization: Bearer $WILDFLOW_API_KEY" \
  -H "Idempotency-Key: $WILDFLOW_IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "FLUX.2 [klein] 4B",
    "parameters": {
      "prompt": "一只熊猫在竹林中阅读,柔和自然光,电影感构图",
      "width": 1024,
      "height": 1024,
      "num_inference_steps": 4,
      "guidance_scale": 1.0,
      "seed": 42
    }
  }' \
  --output operation.json

首次接收成功返回 HTTP 202,响应头 Location 指向 /v1/jobs/{operation_id}。重复提交相同 API Key、 幂等键和请求正文会返回原 Operation;同一幂等键配合不同请求会返回 409。

参数

参数必需允许值说明
prompt是非空,最多 20,000 字节图片内容、场景、光线、色彩与构图描述
width否256–2048整数且必须是 8 的倍数
height否256–2048整数且必须是 8 的倍数
num_inference_steps否1–100推理步数;更多步数通常需要更长时间
guidance_scale否0–20提示词引导强度
seed否0–9223372036854775807固定随机种子便于复现同一参数组合

提示词可以按“主体、场景、光线、色彩、构图、风格”的顺序组织。模型生成的文字、复杂手部和精细界面 元素可能不稳定,重要文字建议在生成后使用排版工具叠加。

轮询与下载

先完成上面的提交步骤,确认已生成 operation.json。然后设置下载文件名:

export RESULT_FILE="result.png"
export RESULT_MEDIA_TYPE="image/png"

下面的命令使用 Python 3,读取上一步保存的 operation.json,等待任务完成后下载结果。等待超过两小时会停止;再次执行本段会继续查询原任务,不会重新提交。

python3 - <<'PY'
import hashlib
import json
import os
import time
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
from pathlib import Path
from urllib.error import HTTPError
from urllib.parse import quote
from urllib.request import Request, urlopen

base = "https://api.wildflow.cn"
headers = {"Authorization": "Bearer " + os.environ["WILDFLOW_API_KEY"]}
operation = json.loads(Path("operation.json").read_text())
operation_id = operation["id"]
status_url = base + "/v1/jobs/" + quote(operation_id, safe="")
output = Path(os.environ["RESULT_FILE"])
expected_media_type = os.environ["RESULT_MEDIA_TYPE"]
deadline = time.monotonic() + 7200

def pause(value):
    try:
        seconds = float(value)
    except (TypeError, ValueError):
        try:
            seconds = (parsedate_to_datetime(value) - datetime.now(timezone.utc)).total_seconds()
        except (TypeError, ValueError, OverflowError):
            seconds = 3
    seconds = max(1, seconds)
    if time.monotonic() + seconds >= deadline:
        raise SystemExit("等待超时。保留 operation.json,稍后重新执行本段继续查询。")
    time.sleep(seconds)

while time.monotonic() < deadline:
    try:
        with urlopen(Request(status_url, headers=headers), timeout=60) as response:
            status = json.load(response)
            retry_after = response.headers.get("Retry-After", "3")
    except HTTPError as error:
        if error.code in (429, 503):
            pause(error.headers.get("Retry-After", "3"))
            continue
        raise SystemExit(f"查询失败:HTTP {error.code}。保留原任务,检查错误后继续查询。")

    state = status["state"]
    print("任务状态:", state, flush=True)
    if state == "succeeded":
        artifacts = status.get("artifacts", [])
        if not artifacts:
            raise SystemExit("任务成功但缺少结果文件,请保留任务 ID 并联系支持。")
        artifact = artifacts[0]
        if artifact["media_type"] != expected_media_type:
            raise SystemExit("结果格式与预期不同,请检查任务和模型。")
        download_url = base + "/v1/artifacts/" + quote(artifact["id"], safe="") + "/content"
        temporary = output.with_name(output.name + ".part")
        digest = hashlib.sha256()
        size = 0
        with urlopen(Request(download_url, headers=headers), timeout=60) as response:
            with temporary.open("wb") as file:
                while chunk := response.read(1024 * 1024):
                    file.write(chunk)
                    digest.update(chunk)
                    size += len(chunk)
        if size != artifact["size_bytes"] or digest.hexdigest() != artifact["sha256"]:
            raise SystemExit("文件校验失败,保留原任务并重新执行本段下载。")
        temporary.replace(output)
        print("已保存:", output)
        break
    if state not in ("queued", "running", "submitting"):
        raise SystemExit(f"任务已停止:{state}。请保留任务 ID;不要换幂等键重复提交。")
    pause(retry_after)
else:
    raise SystemExit("等待超时。保留 operation.json,稍后继续查询原任务。")
PY

网络中断时可重新执行本段。failed、cancelled、recovery_required 或未知状态会停止下载;需要帮助时查看任务恢复说明。

下载后可核对 size_bytes、sha256 以及元数据中的宽高。如果任务仍在排队或执行,请继续轮询,不要 更换幂等键重复创建图片任务。

错误与恢复

统一错误和恢复原则见任务与结果文件。FLUX.2 还应重点检查:

  • 400 invalid_request:检查模型全名、提示词和参数范围;
  • 401 / 403:检查 API Key、额度和令牌允许的模型范围;
  • 409 idempotency_conflict:同一幂等键已经绑定了不同请求;
  • 429 / 503:按响应中的 Retry-After 等待后有限重试;
  • recovery_required:结果或账务状态需要平台恢复,不要自动创建第二个付费任务。

提交包含真人肖像、品牌、版权作品或其他受保护内容前,请确认自己具有相应权利;不得生成违法、欺骗性 或侵害他人权益的内容。不要在日志、前端代码或问题截图中记录完整 API Key。

相关文档

获取 API Key · 价格与计费 · 常见问题