首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >把 Demo 从后端服务推进到可交付应用

把 Demo 从后端服务推进到可交付应用

原创
作者头像
dsy
发布2026-08-17 09:07:33
发布2026-08-17 09:07:33
720
举报

上篇给 build_request_id 写了测试,项目算「能跑、能验证」了。但启动还是一句:

代码语言:bash
复制
uv run uvicorn app.main:app --reload --port 8000

这等于还停留在「在我电脑上能跑」。换台机器、换个同事,环境对不上就跑不起来。今天就把这个 Demo 往「可运行、可演示、能分享」推一步。

今天做了五件事:Docker 化、简单前端、CORS、样例库、README。


一、Docker 化:把环境一起打包

Docker 解决的核心问题是:把 Python 版本、依赖、启动命令,打包成一个标准箱,到哪台机器都能原样开起来。类比集装箱——里面装什么只有你自己知道,但外面尺寸统一,吊上船就能走。

今天建了 Dockerfile.dockerignore,然后两条命令:

代码语言:bash
复制
docker build -t resume-analyzer-api .
docker run --env-file .env -p 8000:8000 resume-analyzer-api

有个坑必须记牢,写在 DockerfileCMD 里:

代码语言:dockerfile
复制
CMD ["uv", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

--host 0.0.0.0 不能省。容器有自己独立的网络命名空间,不绑这个地址,容器外面根本访问不到 FastAPI。


二、.env 绝不能打进镜像

.env 里有:

代码语言:env
复制
DEEPSEEK_API_KEY=...

一旦 COPY .env 进镜像,这镜像只要分享出去,密钥就跟着泄露了。

正确做法是镜像只装代码和环境,密钥运行时注入:

代码语言:bash
复制
docker run --env-file .env -p 8000:8000 resume-analyzer-api

一句话:镜像保存代码和环境,密钥在运行时注入


三、简单前端:给 API 一个普通用户入口

之前调接口只能用 curl 或 FastAPI 自带的 /docs。今天加了个最小页面:

代码语言:shell
复制
app/static/index.html

页面上有目标岗位输入框、简历文本框、开始分析按钮、结果展示区,靠:

代码语言:js
复制
fetch("/analyze_resume")

调后端。

意义很直接:结构化 API 终于有了一个不用看文档也能操作的入口。


四、让 FastAPI 自己托管前端

不用额外起一个 Web 服务器,FastAPI 直接把页面顶上来:

代码语言:python
复制
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles

app.mount("/static", StaticFiles(directory="app/static"), name="static")

@app.get("/")
def index() -> FileResponse:
    return FileResponse("app/static/index.html")

这样浏览器开 http://127.0.0.1:8000/ 就能看到页面。前后端同一个服务,部署省事。


五、CORS:前后端分开时的跨域

如果页面和 API 都来自 http://127.0.0.1:8000,同源,没跨域问题。但前端若跑在 http://127.0.0.1:5500,后端在 8000,虽然都在本机,端口不同,浏览器就判定为不同源,会拦请求。

规则很简单:协议、域名、端口,任意一个不同都算跨域

后端要显式放行:

代码语言:python
复制
from fastapi.middleware.cors import CORSMiddleware

origins = [
    "http://127.0.0.1:5500",
    "http://localhost:5500",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=False,
    allow_methods=["*"],
    allow_headers=["*"],
    expose_headers=["X-Request-ID"],
)

注意 expose_headers=["X-Request-ID"] —— 前面几篇辛辛苦苦加的 request_id,如果这里不暴露,前端 fetch 的响应头里读不到它,追踪闭环就断在最后一公里。


六、样例库:让 Demo 更好演示

给前端加了几个一键填充按钮:

  • 正常简历样例
  • 触发 422 样例
  • AI Agent 岗位样例

不用每次手敲文本。尤其「触发 422 样例」,一点就能验证之前写的 VALIDATION_ERROR + request_id + 错误结构是不是真的工作。Demo 从「能用」变成「容易演示」。


七、README:把代码变成可交付成果

最后写 README。它的作用是让未来的你或别人知道:项目是什么、怎么启动、怎么测试、怎么部署。

建议至少覆盖:

代码语言:shell
复制
项目简介
项目结构
环境变量
本地启动
Docker 启动
前端页面
API 示例
错误响应示例
运行测试
当前限制
学习总结

这一步的本质是把一堆代码,变成一个别人能理解和复用的项目。


八、这一篇想说清楚一件事

AI 应用不只是后端能调模型,还要能运行、能访问、能演示、能交付。

前面几篇攒的是内功:

代码语言:shell
复制
Agent 能力 / API 封装 / 错误响应 / 日志 / 测试

今天补的是外功:

代码语言:shell
复制
容器化 / 前端入口 / 跨域 / 样例演示 / 项目说明

能验证还不够,能交付才算完成。


九、完整的项目能力

到现在,这个 PydanticAI 简历分析 Demo 已经具备:

代码语言:shell
复制
结构化输出      Pydantic output_type
字段校验        field_validator
工具调用        Tool
Schema/Evidence 分层结构 + 原文溯源
API 封装        FastAPI
统一错误响应    HTTPException + error_detail
request_id 追踪 全局异常处理器
日志            logging
pytest 测试     test_utils
Docker 化       Dockerfile
简单前端        static/index.html
CORS 配置       CORSMiddleware
样例库          Demo 预设
README         交付说明

这已经是一个完整的小型 AI 工程闭环了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、Docker 化:把环境一起打包
  • 二、.env 绝不能打进镜像
  • 三、简单前端:给 API 一个普通用户入口
  • 四、让 FastAPI 自己托管前端
  • 五、CORS:前后端分开时的跨域
  • 六、样例库:让 Demo 更好演示
  • 七、README:把代码变成可交付成果
  • 八、这一篇想说清楚一件事
  • 九、完整的项目能力
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档