QuickBot text-to-image-using-imagen3 后端实战:用 FastAPI 搭建 Imagen3 文本生成图像服务
【免费下载链接】generative-aiSample code and notebooks for Generative AI on Google Cloud, with Gemini Enterprise Agent Platform项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai
本篇文章以 QuickBot 模板集中的text-to-image-using-imagen3后端为对象,完整讲解如何基于 FastAPI + Vertex AI Imagen3 构建一个可独立运行、可部署到 Cloud Run 的文本生成图像 API 服务。你将掌握从虚拟环境搭建、gcloud 凭据配置、环境变量注入,到 uvicorn 本地启动、核心路由与并行图像生成实现的完整链路,同时了解仓库内配套的测试与代码规范体系。
一、模板定位:QuickBot 前后端分离架构
QuickBot 是一组"开箱即用"的应用模板,每个模板都可以独立部署到 Cloud Run,并与用户默认的 Google Cloud 认证凭据直接联通。依据模板复杂度,它会按需在你的 Google Cloud 项目中创建多或少资源。text-to-image-using-imagen3是其中专攻文本生成图像的模板,其统一架构为:
- frontend/:一个 Angular 应用,负责交互界面;
- backend/:一个 FastAPI Python 应用,负责图像生成与 API 服务。
本文聚焦后端部分,即 backend/README.md 所描述的内容。仓库根目录的 README.md 提供了整体项目介绍,后端的具体文件清单如下(均已存在于仓库中):
backend/ ├── main.py # FastAPI 应用入口与 CORS 配置 ├── requirements.txt # Python 依赖 ├── local.env # 本地环境变量样例 ├── Dockerfile # 容器镜像构建与 gunicorn 启动命令 ├── pyproject.toml # pytest/覆盖率配置 ├── pylintrc # pylint 规则配置 ├── pytest.ini ├── src/ │ ├── controller/search.py # /api/search 路由控制器 │ ├── model/search.py # Pydantic 请求/响应模型 │ └── service/search.py # ImagenSearchService 图像生成服务 └── tests/test_search.py # 控制器与服务层测试二、环境准备:创建虚拟环境并安装依赖
后端是标准的 Python 工程,第一步在backend/目录内创建虚拟环境并安装依赖。原文档给出的命令流程如下:
# 检查是否已处于虚拟环境中 pip -V # 若尚未激活,则创建并激活虚拟环境 python3 -m venv .venv source .venv/bin/activate pip3 install -r requirements.txtVS Code 提示:VS Code 可能无法自动识别你的虚拟环境。此时按
Ctrl + Shift + P,选择Python: Select Interpreter,再选择Enter interpreter path...,手动指向本后端目录下的.venv/bin/python即可。
从 requirements.txt 可以看到依赖分为几层:Web 框架(fastapi~=0.111.1、uvicorn~=0.17.0、gunicorn)、Google Cloud 客户端库(google-cloud-aiplatform==1.69.0、google-genai==0.8.0、google-cloud-speech==2.27.0、google-cloud-bigquery、google-cloud-discoveryengine等),以及开发工具(pylint、black、pytest、pytest-cov、pytest-watch)。其中google-genai是调用 Imagen3 / Gemini 图像生成的核心 SDK。
三、配置 gcloud 凭据
要让后端通过 Vertex AI 调用 Imagen3,必须让本机具备可用的 Google Cloud 身份。原文档的凭据检查与配置命令:
# 查看当前登录账号与项目配置 gcloud auth list gcloud config list # 登录并绑定项目 gcloud auth login gcloud config set project <your project id> gcloud auth application-default set-quota-project <your project id> # 再次验证 gcloud auth list gcloud config listgcloud auth application-default login会生成 Application Default Credentials(ADC),后端运行时将通过google.auth.default()自动读取该凭据;set-quota-project用于为 ADC 显式指定配额项目。从源码看,src/service/search.py 中正是这样取用身份并构建 Vertex AI 客户端的:
_, PROJECT_ID = google.auth.default() LOCATION = "us-central1" client = genai.Client( vertexai=True, project=PROJECT_ID, location=LOCATION )四、注入环境变量
后端通过环境变量区分运行环境并决定 CORS 策略。仓库中的 local.env 内容如下:
export ENVIRONMENT=development export FRONTEND_URL=http://localhost:4200macOS / Windows(以及 Linux 上的 zsh)
在backend/目录下直接 source 该文件:
. ./local.envLinux(bash)
由于 bash 默认不解析.local.env中的export(文件无 shebang),需要打开.venv/bin/activate,在PATH导出之后追加环境变量:
_OLD_VIRTUAL_PATH="$PATH" PATH="$VIRTUAL_ENV/bin:$PATH" export PATH # Quickbot env variables export ENVIRONMENT=development export FRONTEND_URL=http://localhost:4200配置完成后运行env检查变量是否生效。
环境变量在后端代码中的作用
查看 main.py 的configure_cors实现,可以看到这两个变量的确切语义:
ENVIRONMENT=development:CORS 放行所有来源(allow_origins=["*"]),方便本地前端http://localhost:4200跨域调试;ENVIRONMENT=production:必须同时提供FRONTEND_URL,CORS 仅放行该前端地址;若缺失会抛出ValueError提示;- 传入其他取值会抛出
Invalid ENVIRONMENT异常。
在容器化场景中,Dockerfile 也默认注入了ENVIRONMENT="development"与FRONTEND_URL="http://localhost:4200",并通过docker-compose.yml把本机 ADC 挂载进容器,实现"开箱即用"的本地开发。
五、运行后端服务
本地开发模式
配置好环境后,用 uvicorn 启动并开启热重载:
uvicorn main:app --reload --port 8080启动后:
- 访问根路径
http://localhost:8080/会返回字符串You are calling Quick Bot Backend(见 main.py); - 访问
/api/version返回v0.0.1; - 图像生成接口为
POST /api/search。
容器 / Cloud Run 模式
生产部署采用 gunicorn + Uvicorn worker,见 Dockerfile 的启动指令:
gunicorn main:app --workers=4 --worker-class=uvicorn.workers.UvicornWorker \ --timeout=36000 --bind=0.0.0.0:8080镜像基于python:3.11-alpine,暴露 8080 端口;4 个 worker 配合长超时(36000 秒),是为图像生成这种耗时请求设计的配置。若想用 Docker Compose 一键启动前后端,可参考仓库根目录的 docker-compose.yml(详细步骤见 根 README)。
六、核心实现剖析:Imagen3 图像生成服务
理解了如何运行后,我们来深挖"图像生成"这条主链路,它由三层组成。
1. 路由层:POST /api/search
src/controller/search.py 定义了一个前缀为/api/search的APIRouter,其search端点接收CreateSearchRequest,解出 5 个参数后交给ImagenSearchService:
term:用户提示词;generation_model:图像生成模型;aspect_ratio:宽高比;number_of_images:生成张数;image_style:风格。
控制器对异常做了分层处理:ValueError映射为 400,其余异常映射为 500,保证接口错误信息可读。
2. 模型层:Pydantic 校验与响应结构
src/model/search.py 用 Pydantic 做了严格的入参约束,这是保证调用 Vertex AI 不出错的关键:
- 生成模型白名单(
GenerationModelOptionalLiteral):imagen-4.0-ultra-generate-exp-05-20、imagen-3.0-generate-001、imagen-3.0-fast-generate-001、imagen-3.0-generate-002、imagegeneration@006、imagegeneration@005、imagegeneration@002; - 宽高比白名单(
AspectRatioLiteral):1:1、9:16、16:9、3:4、4:3; - 风格白名单(
ImageStyleLiteral):Modern、Realistic、Vintage、Monochrome、Fantasy、Sketch; - 张数范围:
number_of_images限制在 1~4(Field(ge=1, le=4)); - 提示词校验:
term最大长度 150,且通过field_validator拒绝空串或纯空白输入。
响应模型SearchResponse由gemini_results与imagen_results两组ImageGenerationResult组成,每个结果包含enhanced_prompt(增强后的提示词)、rai_filtered_reason(安全过滤原因)以及image(gcs_uri、mime_type、encoded_imagebase64 编码)。所有字段采用 camelCase 别名输出(to_camel),与前端 Angular 模型天然对齐。
3. 服务层:Imagen 与 Gemini 并行生成
src/service/search.py 的generate_images是核心逻辑,它同时发起两条生成链路并通过asyncio.gather(..., return_exceptions=True)并行执行:
Imagen 链路(_generate_with_imagen):构造带风格的提示词Make the image with a style '{image_style}'. The user prompt is: {term},然后调用:
await asyncio.to_thread( client.models.generate_images, model=generation_model, prompt=prompt_imagen, config=types.GenerateImagesConfig( number_of_images=number_of_images, aspect_ratio=aspect_ratio, enhance_prompt=True, # 自动增强提示词 safety_filter_level="BLOCK_MEDIUM_AND_ABOVE", person_generation="DONT_ALLOW", # 禁止生成人物 ), )这里有两个值得注意的实现细节:
- 同步 SDK 调用被包进
asyncio.to_thread,避免阻塞事件循环; - 对
imagen-4.0-ultra-generate-exp-05-20这一模型做了特判:每次调用只生成 1 张图,需要 N 张图就并发发起 N 次调用(见 src/service/search.py),这与该模型单次调用限制有关;其他 Imagen 模型则单次请求直接生成number_of_images张。
Gemini 链路(_generate_with_gemini):使用gemini-2.0-flash-preview-image-generation模型,通过response_modalities=["TEXT", "IMAGE"]请求图文多模态输出,按所需张数循环调用generate_content,并从响应中筛选inline_data.mime_type以image/开头的部分作为图片,同时拼接候选文本作为enhanced_prompt,还兼容了prompt_feedback.blocked的安全拦截信息。
最终两类结果合并为一个SearchResponse返回,前端可同时展示 Imagen 与 Gemini 两组生成图。
七、辅助能力:语音输入接口
除了图像生成,后端还提供了一个语音转文本端点/api/audio_chat(main.py)。它接收UploadFile音频,通过google.cloud.speech的SpeechClient发起长语音识别(long_running_recognize),配置了en-US、48kHz 采样率、单声道,并开启词级置信度与时间偏移,识别结果作为文本返回。这让用户可以在前端用语音输入提示词,再走图像生成链路。
八、用测试验证接口行为
仓库在 tests/test_search.py 提供了完整的接口与服务层测试,值得作为开发时的参照:
- 用
MagicMock构造模拟的google.genai.Client,并注入 4 张带 base64 占位数据的GenerateImagesResponse; TestSearchController.test_search_endpoint使用 FastAPI 的TestClient对POST /api/search发起真实请求,同时 monkeypatch 掉认证与ImagenSearchService,断言返回 200、结果数量为 4,并逐字段校验enhancedPrompt、gcsUri、mimeType、encodedImage与 base64 编码一致;TestImagenSearchService.test_imagen_search_service直接测试服务层,断言返回的是ImageGenerationResult列表且CustomImageResult.encoded_image正确。
运行测试(依赖 pyproject.toml 中配置的--cov覆盖率收集,输出 lcov 格式):
pytest九、代码风格与提交规范
为保证多人协作质量,后端遵循 Google Python Style Guide,配套工具为pylint与black;前端(Angular)则使用 Google TypeScript Style Guide 的gts。具体操作如下。
后端(Python)
- 确保依赖已安装(
requirements.txt中已包含pylint与black):
pip install pylint black # 或 pip install -r requirements.txt配置
pylint:仓库backend/下已提供 pylintrc(若从零开始可用pylint --generate-rcfile > .pylintrc生成后再按需修改)。执行 lint 检查:
pylint . # 或指定模块:pylint your_module_name- 用 black 统一格式化(每行 80 字符):
python -m black . --line-length=80前端(TypeScript)
在前端目录下初始化gts并在tsconfig.json中扩展其默认配置:
{ "extends": "./node_modules/gts/tsconfig-google.json" }然后分别运行 lint 与自动修复:
npm run lint # 即 gts lint npm run fix # 即 gts fix提交信息
建议遵循 Angular Commit Message Guidelines,保持提交信息清晰、可追溯。
十、小结
text-to-image-using-imagen3后端展示了一条完整的"FastAPI + Vertex AI Imagen3"生产化路径:通过local.env/ 环境变量管理 CORS 与运行环境,通过 Pydantic Literal 白名单约束模型、比例、风格与张数,通过asyncio.to_thread+asyncio.gather并发驱动 Imagen3 与 Gemini 双模型生成,并以 gunicorn + Uvicorn 支撑 Cloud Run 部署,配合 pytest 测试与 pylint/black 规范。无论你是想快速复刻一个文本生成图像 API,还是准备把它容器化部署到 Cloud Run,这份模板的每一层实现都值得直接参考。
【免费下载链接】generative-aiSample code and notebooks for Generative AI on Google Cloud, with Gemini Enterprise Agent Platform项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考