AI生图第2节:python对接gpt-image-2模型API生图

vibecoding提示词:

复制代码

这个是我的apikey:sk-1cdcb37af4bb729eab8983f3ea08f158c01737672581de07db6839bcf9d16545 这个是我的url地址:https://token.zhilu.online/v1 现在我需要gpt-image-2模型,来生成一个图片生成网站。 使用html+css+js即可,生成一个网页,调用这个模型,需要支持选择比例生成

复制代码
        "quality": payload.get("quality", "auto"),
        "n": int(payload.get("n", 1)),
        "output_format": str(payload.get("output_format", "png")).lower(),
    }

    if payload.get("background") and payload.get("background") != "auto":
        request_payload["background"] = payload["background"]

    if payload.get("output_compression") is not None:
        request_payload["output_compression"] = int(payload["output_compression"])

    if payload.get("moderation") is not None:
        request_payload["moderation"] = payload["moderation"]

    return request_payload


def item_value(item: Any, name: str) -> Any:
    if isinstance(item, dict):
        return item.get(name)
    return getattr(item, name, None)


class AppHandler(BaseHTTPRequestHandler):
    server_version = "ImageServer/1.0"

    def log_message(self, format: str, *args: Any) -> None:
        print(format % args, flush=True)

    def end_headers(self) -> None:
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "GET,POST,OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "Content-Type, Authorization")
        self.send_header("Cache-Control", "no-store")
        super().end_headers()

    def send_json(self, status_code: int, payload: dict[str, Any]) -> None:
        body = json.dumps(payload, ensure_ascii=True).encode("utf-8")
        self.send_response(status_code)
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def send_text(self, status_code: int, text: str) -> None:
        body = safe_text(text).encode("utf-8")
        self.send_response(status_code)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_OPTIONS(self) -> None:
        self.send_response(204)
        self.send_header("Content-Length", "0")
        self.end_headers()

    def do_GET(self) -> None:
        path = urlparse(self.path).path

        if path == "/health":
            self.send_json(
                200,
                {
                    "ok": True,
                    "mode": "python-http-server",
                    "base_url": CONFIG["base_url"] or None,
                    "model": CONFIG["model"],
                },
            )
            return

        filename = STATIC_FILES.get(path)
        if not filename:
            self.send_text(404, "Not Found")
            return

        target = ROOT / filename
        body = target.read_bytes()
        self.send_response(200)
        self.send_header(
            "Content-Type",
            MIME_TYPES.get(target.suffix.lower(), "application/octet-stream"),
        )
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_POST(self) -> None:
        path = urlparse(self.path).path

        if path != "/api/images/generations":
            self.send_text(405, "Method Not Allowed")
            return

        self.handle_generate()

    def handle_generate(self) -> None:
        if not CONFIG["api_key"]:
            self.send_json(500, {"error": {"message": "Missing API key in server.config.local.json."}})
            return

        if not CONFIG["base_url"]:
            self.send_json(500, {"error": {"message": "Missing base_url in server.config.local.json."}})
            return

        try:
            content_length = int(self.headers.get("Content-Length", "0"))
            raw = self.rfile.read(content_length).decode("utf-8")
            payload = json.loads(raw) if raw else {}
        except Exception:
            self.send_json(400, {"error": {"message": "Request body must be valid JSON."}})
            return

        validation_error = validate_payload(payload)
        if validation_error:
            self.send_json(400, {"error": {"message": validation_error}})
            return

        try:
            client = OpenAI(api_key=CONFIG["api_key"], base_url=CONFIG["base_url"])
            result = client.images.generate(**build_request_payload(payload))
            data = []
            for item in result.data:
                entry: dict[str, Any] = {}
                if item_value(item, "b64_json"):
                    entry["b64_json"] = item_value(item, "b64_json")
                if item_value(item, "url"):
                    entry["url"] = item_value(item, "url")
                data.append(entry)

            self.send_json(
                200,
                {
                    "created": item_value(result, "created"),
                    "data": data,
                },
            )
        except Exception as exc:
            status_code = int(getattr(exc, "status_code", 502) or 502)
            message = safe_text(getattr(exc, "message", None) or str(exc))
            body = getattr(exc, "body", None)

            if isinstance(body, dict):
                if isinstance(body.get("error"), dict) and body["error"].get("message"):
                    message = safe_text(body["error"]["message"])
                elif body.get("message"):
                    message = safe_text(body["message"])

            self.send_json(status_code, {"error": {"message": message}})


def main() -> None:
    address = ("127.0.0.1", CONFIG["port"])
    server = ThreadingHTTPServer(address, AppHandler)
    print(
        f"Server running at http://127.0.0.1:{CONFIG['port']} | model={CONFIG['model']}",
        flush=True,
    )
    server.serve_forever()


if __name__ == "__main__":
相关推荐
辞旧 lekkk1 小时前
【Redis初阶】常见数据类型
开发语言·数据库·c++·redis·学习·缓存·bootstrap
帅次1 小时前
Kotlin 与 Java 互操作:混合工程里的平台类型与 API 边界
java·开发语言·kotlin·suspend·nullable
ddshub_cc3 小时前
理解 Loop Engineering 与 AI 编程成本优化
大数据·人工智能·gpt·prompt·ai编程
dtq04243 小时前
C语言-结构体详解
c语言·开发语言·学习
梅雅达编程笔记3 小时前
编程启蒙|Scratch 转 Python 系列第9天:字典/哈希表积木双向对照(AI大模型参数配置表实战)
开发语言·人工智能·python·numpy·pandas
持力行3 小时前
C++与Java变量声明、定义及内存分配的核心区别
java·开发语言·c++
zhz52144 小时前
GIS项目中空间参考转换与MBTiles偏移:问题成因、解法与避坑
python·vue·gis
jinyishu_4 小时前
C++ 继承全解:从基础到高级特性
开发语言·c++
KaMeidebaby5 小时前
卡梅德生物技术快报|如何制备单克隆抗体:小众禽类靶点单抗制备实操流程:双载体抗原交叉筛选完整工艺记录
人工智能·python·深度学习·算法·机器学习
且陶陶º5 小时前
【LLM】Codex CLI 接入第三方大模型实践:实现 GLM / GPT 等多模型切换
gpt