返回博客

代码调用 gpt-image-2 生图 | OpenAI SDK 与 HTTP 双写法

人工智能6750
代码调用 gpt-image-2 生图 | OpenAI SDK 与 HTTP 双写法

系列导语 本文是【大模型API中转站】系列篇。本系列致力于用最低的成本、最清晰的方法,帮你打通多模型 API 的任督二脉。建议先收藏,随用随查。

上一篇我们用 WorkBuddy 零代码接入了 gpt-image-2,这一篇进阶到代码层:用 Python 直接调用 gpt-image-2 生图接口。给你两种写法——OpenAI 官方 SDK(最省心)和原生 HTTP(最透明),都走 4SAPI 中转,复制即可跑。


1. 开篇:我为什么需要这个方案

痛点:界面工具适合手动出图,但一旦要批量生成、接进自己的应用、做自动化流水线,就必须用代码调用 API。而直连官方依旧卡在注册、网络、外卡那几关,调试时一个超时就能耗掉你半天。

场景:你是一个国内开发者,想在自己的脚本或后端服务里调用 GPT 生图能力——比如电商批量出图、给文章自动配图、做一个生图小工具——需要一段稳定、能跑通的代码。

本文目标:给你一条"Python 代码 → 中转(4SAPI) → gpt-image-2"的可行通路,提供 SDK 与 HTTP 两套完整可运行代码,附响应解析、存图和错误处理。


2. 原理速览

请求流向:

你的 Python 代码
      │  POST /v1/images/generations
      │  (OpenAI 兼容格式 + Bearer 鉴权)

中转服务 4SAPI(国内可达)
      │  转发 + 鉴权 + 计费

gpt-image-2 生图模型
      │  返回图片(URL 或 base64)

原路回传 → 你的代码保存/使用

关键认知:生图走的是专用端点。 和对话接口(/v1/chat/completions)不同,生图用的是 /v1/images/generations。请求体的核心字段:

字段含义示例
model模型名称gpt-image-2
prompt生图提示词"a cat sitting on wooden floor"
n生成张数1
size图片尺寸(可选)"1024x1024"

因为 4SAPI 提供 OpenAI 兼容协议,所以你既可以直接用官方 openai SDK(只改 base_url),也可以用原生 HTTP 自己拼请求。下面两种都给。


3. 接入方案

准备工作:到 4SAPI 官网注册并获取 API Key。下面代码里所有 YOUR_4SAPI_KEY 都替换成你的真实密钥。强烈建议用环境变量存放,不要硬编码进代码。

bash
# 先把 Key 放进环境变量(推荐)
# Windows PowerShell:
setx OPENAI_API_KEY "你的4sapi密钥"
# macOS / Linux:
export OPENAI_API_KEY="你的4sapi密钥"

方案一:OpenAI 官方 SDK(推荐,最省心)

SDK 帮你处理了鉴权头、序列化、重试等细节,代码最干净。只需把 base_url 指向 4SAPI。

安装依赖:

bash
pip install openai

完整代码:

python
import os
import base64
from openai import OpenAI

# base_url 指向 4SAPI 中转,api_key 从环境变量读取
client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),   # 你的 4SAPI 密钥
    base_url="https://4sapi.com/v1",
)

resp = client.images.generate(
    model="gpt-image-2",
    prompt="a cat sitting on a wooden floor, warm light",
    n=1,
    size="1024x1024",
)

# 响应可能返回 url,也可能返回 base64(b64_json),两种都兼容处理
item = resp.data[0]

if getattr(item, "url", None):
    print("图片 URL:", item.url)
elif getattr(item, "b64_json", None):
    img_bytes = base64.b64decode(item.b64_json)
    with open("gpt_image_sdk.png", "wb") as f:
        f.write(img_bytes)
    print("已保存为 gpt_image_sdk.png")

说明images.generate 返回的 data 是一个列表,n 设为几就有几张。不同模型/参数下,结果可能是图片 url,也可能是 b64_json(base64 编码的图片),上面代码两种都做了兼容。

方案二:原生 HTTP 调用(最透明,无需 SDK)

不想装 SDK,或想完全掌控请求时用这种。这就是你给的那段代码,我补全了鉴权和说明:

python
import http.client
import json

conn = http.client.HTTPSConnection("4sapi.com")

payload = json.dumps({
    "model": "gpt-image-2",
    "prompt": "cat",
    "n": 1
})

headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer YOUR_4SAPI_KEY',   # 注意 Bearer 前缀,换成你的真实密钥
    'Content-Type': 'application/json'
}

conn.request("POST", "/v1/images/generations", payload, headers)
res = conn.getresponse()
data = res.read()
text = data.decode("utf-8")
print(text)

# 把原始响应存成 json,方便后续解析/排查
with open("gpt_image_response.json", "w", encoding="utf-8") as f:
    f.write(text)

关键修正:你原代码里 'Authorization': '' 是空的,调用会直接返回 401。鉴权头必须是 Bearer + 你的密钥(Bearer 后有个空格),这是最容易踩的坑。

进阶:从 HTTP 响应里把图片真正存下来

上面只是存了原始 JSON。要拿到图片本体,再加一段解析:

python
import base64
import urllib.request

result = json.loads(text)
item = result["data"][0]

if "url" in item and item["url"]:
    # 返回的是图片链接,下载下来
    urllib.request.urlretrieve(item["url"], "gpt_image_http.png")
    print("已下载为 gpt_image_http.png")
elif "b64_json" in item and item["b64_json"]:
    # 返回的是 base64,解码写文件
    with open("gpt_image_http.png", "wb") as f:
        f.write(base64.b64decode(item["b64_json"]))
    print("已保存为 gpt_image_http.png")

第 4 步:运行并验证

把密钥填好后直接运行脚本。跑通的标志:


3.5 两种写法怎么选?常见报错排查

选型对比:

维度OpenAI SDK原生 HTTP
上手难度低,几行搞定中,要自己拼请求
依赖pip install openai仅标准库,零依赖
可控性一般高,请求全透明
适合场景业务开发、快速集成调试、嵌入受限环境、学习原理

一句话建议:日常开发用 SDK,排查问题或环境装不了依赖时用 HTTP。

常见报错:

现象原因解法
401 UnauthorizedAuthorization 为空、漏了 Bearer 前缀、Key 错头部填 Bearer 你的密钥,核对 Key
404 Not Found端点写错(用了 chat 路径)、模型名错生图用 /v1/images/generations,模型名 gpt-image-2
429 限流调用太频繁 / 额度耗尽加重试与退避,检查 4SAPI 余额
KeyError: 'data'响应是错误体而非正常结果先打印 text 看返回内容,按报错信息定位
图片打不开把 base64 当 URL 处理(或反之)用上文 url / b64_json 兼容写法
超时网络波动 / 中转排队设置超时与重试,持续异常联系中转站

排查口诀:先看 401(鉴权)、再看 404(端点/模型名)、最后看响应体


3.6 其他语言怎么调?(cURL / Node.js / Go)

协议是统一的,换语言只是换"拼请求"的写法。下面三段都走同一个端点 https://4sapi.com/v1/images/generations、同样的 Bearer 鉴权。

cURL(最快验证,先用它确认 Key 和端点没问题):

bash
curl https://4sapi.com/v1/images/generations \
  -H "Authorization: Bearer YOUR_4SAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "a cat sitting on a wooden floor",
    "n": 1
  }'

Node.js(用官方 openai SDK,和 Python 同款思路):

javascript
import OpenAI from "openai";
import fs from "fs";

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,   // 你的 4SAPI 密钥
  baseURL: "https://4sapi.com/v1",
});

const resp = await client.images.generate({
  model: "gpt-image-2",
  prompt: "a cat sitting on a wooden floor, warm light",
  n: 1,
  size: "1024x1024",
});

const item = resp.data[0];
if (item.url) {
  console.log("图片 URL:", item.url);
} else if (item.b64_json) {
  fs.writeFileSync("gpt_image_node.png", Buffer.from(item.b64_json, "base64"));
  console.log("已保存为 gpt_image_node.png");
}

Go(标准库,零第三方依赖):

go
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	payload := []byte(`{"model":"gpt-image-2","prompt":"a cat","n":1}`)
	req, _ := http.NewRequest("POST",
		"https://4sapi.com/v1/images/generations",
		bytes.NewBuffer(payload))
	req.Header.Set("Authorization", "Bearer YOUR_4SAPI_KEY")
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}

记住:无论哪种语言,端点、鉴权头、请求体字段都一样。换语言只是换语法外壳,协议层是同一套。


3.7 进阶:能上生产的批量生成(重试 + 退避 + 限流)

前面的代码是"能跑通",真要批量出图还得加三件套:超时、重试退避、并发限流。下面是一个可直接复用的 Python 封装,循环出图时单张失败不会拖垮整批。

python
import os
import time
import base64
import random
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url="https://4sapi.com/v1",
    timeout=60,          # 单次请求超时(秒)
)

def generate_one(prompt, filename, max_retries=4):
    """生成单张图,带指数退避重试。成功返回 True。"""
    for attempt in range(max_retries):
        try:
            resp = client.images.generate(
                model="gpt-image-2",
                prompt=prompt,
                n=1,
                size="1024x1024",
            )
            item = resp.data[0]
            if getattr(item, "b64_json", None):
                with open(filename, "wb") as f:
                    f.write(base64.b64decode(item.b64_json))
            elif getattr(item, "url", None):
                import urllib.request
                urllib.request.urlretrieve(item.url, filename)
            print(f"[OK] {filename}")
            return True
        except Exception as e:
            # 指数退避 + 随机抖动,避免被限流时一起重试
            wait = (2 ** attempt) + random.random()
            print(f"[重试 {attempt+1}/{max_retries}] {e}{wait:.1f}s 后再试")
            time.sleep(wait)
    print(f"[FAIL] {filename} 最终失败")
    return False

# 批量任务:提示词 → 文件名
tasks = [
    ("a cat sitting on a wooden floor", "cat_01.png"),
    ("a dog running on grass", "dog_01.png"),
    ("a cup of coffee on a desk", "coffee_01.png"),
]

ok = 0
for prompt, filename in tasks:
    if generate_one(prompt, filename):
        ok += 1
    time.sleep(1)   # 简单限流:每张之间停 1 秒,按额度调整

print(f"完成 {ok}/{len(tasks)} 张")

这段代码做对了几件事:

想再快可以上并发(concurrent.futures 线程池),但务必同时配合限流和退避,否则很容易被中转或上游限流挡回来。


3.8 提示词怎么写,出图才稳

同样的模型,提示词差一点,出图质量天差地别。几条实用经验:

对比示例:

text
弱提示词:cat
强提示词:a fluffy orange tabby cat sitting on a light wooden floor,
         photorealistic, warm afternoon light, shallow depth of field,
         no text, no watermark

后者出图的可控性和成品率明显更高。


3.9 真实落地场景

这套调用能力接进业务后,常见的三类用法:

  1. 批量商品图 / 配图:电商或内容平台,按商品/文章标题批量生成配图,用 3.7 的批量封装跑一个列表即可。
  2. 应用内"一键生图"功能:把调用封装成后端接口,前端传 prompt、后端返图片,做成你 App 里的生图按钮。
  3. 自动化内容流水线:和定时任务结合,比如每天为新发布的文章自动配一张题图,全程无人工。

接进后端时记得:Key 只放服务端,绝不下发到前端;前端调你自己的接口,由后端去调中转,这样既安全又能统一做限流和计费。


3.10 调用参数速查表

参数必填说明
model模型名,固定 gpt-image-2
prompt生图提示词,建议英文 + 细节
n生成张数,默认 1
size尺寸,如 1024x1024,以模型支持为准
response_format部分实现支持指定 urlb64_json

不同中转/模型版本支持的参数略有差异,拿不准时先用 cURL 打一发,看返回里有哪些字段最直接。


4. 成本与风险提示


5. 总结与系列导航

一句话总结:想用代码调用 gpt-image-2 生图,记住三件事——

  1. 端点POST https://4sapi.com/v1/images/generations
  2. 鉴权:请求头 Authorization: Bearer 你的密钥(别忘了 Bearer 和那个空格)
  3. 两种写法:要省心用 OpenAI SDK(改 base_url 即可),要透明用原生 HTTP

SDK 适合快速集成进业务,HTTP 适合调试和受限环境。两套代码都已给全,复制改 Key 即可跑。

常见疑问(FAQ)

如果你有更优雅的封装或批量调用姿势,欢迎在评论区分享,我会挑选优质思路补充进系列。

标签:gpt-image-24SAPIPython实战API教程自动化出图

推荐阅读

探索更多前沿洞察与行业干货。