当前位置: 首页 > news >正文

部署Qwen-Image,通过API返回可访问的图像URL

在这里插入图片描述
场景:当我们在本地部署了图像生成模型Qwen-Image的API服务之后,常见的API响应返回可能是生成图像的base64编码,或者二进制流。这种方式是将图像数据通过API直接返回给用户。而很多场景下,我们希望API能直接返回一个生成图像的URL。这个帖子将介绍,如何在服务器上,将生成的图像保存到指定目录,并将该目录开放可访问。

实现方式:FastAPI完成图像生成的调用,将生成图像保存到指定路径,返回URL;Nginx实现静态资源映射,将指定路径开放访问。

调整FastAPI

基于前面的部署,调整FastAPI启动脚本:

from fastapi import FastAPI
from pydantic import BaseModel
import requests
import copy
import json
import os
import urllib.parse
import time
from fastapi import HTTPException, Header
import base64
API_KEY = "12345"# ---------------- 配置 ----------------
COMFYUI_API_URL = "http://127.0.0.1:8188"  # ComfyUI API 地址
WORKFLOW_FILE = "image_qwen_image_api.json"  # 固定 workflow 文件
OUTPUT_DIR = "output_images"
POLL_INTERVAL = 1  # 秒STATIC_DIR = "/var/www/static"  # 存储图片的目录
SERVER_BASE_URL = "http://server_ip:9001"  # 对外访问的服务器地址os.makedirs(OUTPUT_DIR, exist_ok=True)# ---------------- 读取 workflow ----------------
with open(WORKFLOW_FILE, "r", encoding="utf-8") as f:base_workflow = json.load(f)# ---------------- 请求体定义 ----------------
class GenerateRequest(BaseModel):positive: strnegative: str = ""height: int = 512  # -1 表示随机width: int = 512# ---------------- FastAPI 实例 ----------------
app = FastAPI(title="ComfyUI API Server")# ---------------- 生成接口 ----------------
@app.post("/generate")
def generate(req: GenerateRequest, x_api_key: str = Header(None)):if x_api_key != API_KEY:raise HTTPException(status_code=401, detail="Invalid API Key")workflow = copy.deepcopy(base_workflow)# 替换 workflow 中的 prompt 和 seedworkflow["6"]["inputs"]["text"] = req.positiveworkflow["7"]["inputs"]["text"] = req.negative  workflow["58"]["inputs"]["width"] = req.widthworkflow["58"]["inputs"]["height"] = req.height# 提交任务到 ComfyUI APIresp = requests.post(f"{COMFYUI_API_URL}/prompt", json={"prompt": workflow})resp.raise_for_status()prompt_id = resp.json()["prompt_id"]images_base64 = []while True:history = requests.get(f"{COMFYUI_API_URL}/history/{prompt_id}").json()if prompt_id in history:outputs = history[prompt_id].get("outputs", {})for node_id, output_data in outputs.items():if "images" in output_data:for img in output_data["images"]:filename = img["filename"]subfolder = img.get("subfolder", "")filetype = img.get("type", "png")img_url = (f"{COMFYUI_API_URL}/view"f"?filename={urllib.parse.quote(filename)}"f"&subfolder={urllib.parse.quote(subfolder)}"f"&type={urllib.parse.quote(filetype)}")img_data = requests.get(img_url).content# 保存到指定路径下save_path = os.path.join(STATIC_DIR, filename)with open(save_path, "wb") as f:f.write(img_data)# 返回的URLpublic_url = f"{SERVER_BASE_URL}/static/{filename}"img_b64 = base64.b64encode(img_data).decode("utf-8")images_base64.append(img_b64)if images_base64:breaktime.sleep(POLL_INTERVAL)return {"prompt_id": prompt_id, "image_url": public_url}

其中STATIC_DIR = "/var/www/static"即指定的保存生成图像的路径,也是将开放访问的目录,SERVER_BASE_URL = "http://server_ip:9001"则是配置的url,包括服务器ip和端口。调用API将返回{'prompt_id': 'xxx', 'image_url': 'http://server_ip:9001/static/image.png'}

配置Nginx

下面配置Nginx实现静态资源映射。新建一个配置文件:

sudo nano /etc/nginx/conf.d/static_files.conf

在该文件中写入:

server {listen 9001; # 端口server_name _; # _为默认匹配所有 Hostlocation /static/ { # alias /var/www/static/; # 这里是指定开放访问的目录,建议选择这个,不会存在权限问题autoindex off;  # 是否开启目录浏览# 若开启,用户可访问static下所有文件,否则,只能访问当前文件}
}

重启Nginx:sudo systemctl reload nginx,检查Nginx是否正常工作:sudo nginx -t
到此为止,用户可以通过http://server_ip:9001/static/image.png访问你存放在/var/www/static/目录下的文件了。这部分和图像生成API无关,只是将返回方式改成了url。

注意:Nginx使用的端口注意不能和FastAPI冲突,否则Nginx启动不了。当你在浏览器中打http://server_ip:9001/static/image.png,如果显示403 Forbidden,则要么是指定的访问目录存在权限问题,建议用上面的目录;或者是配置文件里路径没写完整,最后的/不能忘。

http://www.dtcms.com/a/333045.html

相关文章:

  • 以下是对智能电梯控制系统功能及系统云端平台设计要点的详细分析,结合用户提供的梯控系统网络架构设计和系统软硬件组成,分点论述并补充关键要点:
  • 一文打通 AI 知识脉络:大语言模型等关键内容详解
  • 铨林接纸机学习记录1
  • AI智能文档生成系统需求规格说明书
  • Linux 进程、线程与 exec/系统调用详解
  • MySQL中的字符串函数
  • PowerShell 格式化系统完全掌握(下):自定义列/格式字符串/对齐与宽度 + 实战模板
  • 抗日胜利80周年 | HTML页面
  • 智和信通全栈式运维平台落地深圳某学院,赋能运维管理提质提效
  • TCP传输层协议(4)
  • 微信实名认证组件
  • 二十四、Mybatis-基础操作-删除(预编译SQL)
  • SAP ALV导出excel 报 XML 错误的 /xl/sharedStrings.xml
  • Android协程的用法大全
  • 汽车电子:现代汽车的智能核心
  • Unity_数据持久化_Json
  • 使用原生css实现word目录样式,标题后面的...动态长度并始终在标题后方(生成点线)
  • 第七十章:告别“手写循环”噩梦!Trainer结构搭建:PyTorch Lightning让你“一键炼丹”!
  • Codeforces Deque工艺
  • 用 FreeMarker 动态构造 SQL 实现数据透视分析
  • STM32学习笔记12-串口数据包收发FlyMcuST-LINK Utility
  • Shortest Routes II(Floyd最短路)
  • 管家婆辉煌系列试用版/期限说明
  • Shader开发(十三)理解片元插值
  • 淘米自动签到脚本
  • 大气负氧离子自动监测站:解密空气的科技密码
  • 有红帽认证证书可以0元置换华为openEuler-HCIA/HCIP认证
  • OpenSCA开源社区每日安全漏洞及投毒情报资讯|13th Aug. , 2025
  • MyBatis StatementHandler核心原理详解
  • Nginx反向代理Tomcat实战指南