用AI开发一个Python查询接口:从演示数据到可调用的HTTP服务
在利用 AI 辅助软件开发时,许多开发者常会遇到这样的困境:当向 AI 提出“帮我写一个查询接口”时,AI 往往会返回一段孤立的函数代码,缺少项目依赖配置、缺少输入参数校验、没有定义统一的响应结构,更无法直接在本地启动运行。开发者往往需要花大量时间去补全框架骨架、编写测试用例和处理各种异常。
直接让 AI 生成零散代码无法满足工程落地需要。本文将彻底解决这一问题。读完本文后,你将掌握如何通过严谨的提示词引导与工程化实践,在本地从零构建一个基于 Python 与 FastAPI 的、带有完整演示数据、支持多条件组合过滤并具备自动化测试验证的生产级 HTTP 查询接口。
一、 前置条件与适用环境
1. 适用环境
- 编程语言:Python 3.10+
- 核心框架:FastAPI 0.110+,Pydantic v2
- 测试工具:Pytest 8.1+,FastAPI TestClient
- 执行环境:Linux / macOS / Windows 终端(本文以 Bash 语法为主)
2. 案例业务场景
为了让代码具备高度可复现性,本文以一个微型的“图书馆图书检索服务(Library Book Query Service)”为例。
- 演示数据:内置 5 条虚构的图书数据,涵盖不同书名、作者、分类及库存量。
- 核心功能:提供一个 HTTP GET 查询接口,支持按关键字模糊搜索、按分类精确过滤、按最低库存条件筛选,并具备严格的参数校验与空结果处理机制。
二、 核心原理与设计选择
在用 AI 开发查询接口时,合理的后端架构设计需要确保以下三点:
- 契约驱动(Contract-First):利用 Pydantic 模型作为输入输出的强类型契约,由框架自动进行类型转换与错误拦截,避免脏数据进入业务逻辑。
- 声明式查询参数(Query Parameters):通过 FastAPI 的
Query对象为每个筛选参数指定默认值、边界条件(如ge=0)和文档描述。 - 可复现的内存数据源(Mock Data Store):在不依赖外部复杂数据库(如 MySQL / PostgreSQL)的前提下,用纯 Python 结构模拟真实数据查询,确保读者在任何隔离环境中都能一键运行。
三、 完整实现方案
本方案包含四个独立的文件,涵盖依赖配置、数据契约、业务路由及自动化测试。
1. 文件清单与职责表
| 文件路径 | 职责说明 |
|---|---|
requirements.txt | 项目运行与测试所需的第三方库及其精确版本。 |
models.py | 定义图书实体及响应结构的 Pydantic 数据模型。 |
main.py | FastAPI 应用入口,实现图书多条件组合查询的核心逻辑。 |
test_main.py | 使用 TestClient 编写的自动化测试脚本,覆盖正常、边界及失败场景。 |
2. 各文件完整代码
文件一:requirements.txt
fastapi==0.110.0 uvicorn==0.28.0 pydantic==2.6.4 pytest==8.1.1 requests==2.31.0文件二:models.py
fromtypingimportList,OptionalfrompydanticimportBaseModel,FieldclassBook(BaseModel):book_id:int=Field(...,description="图书唯一编号")title:str=Field(...,description="图书标题")author:str=Field(...,description="作者")category:str=Field(...,description="分类")stock:int=Field(...,ge=0,description="库存数量")classBookQueryResponse(BaseModel):code:int=Field(200,description="状态码")message:str=Field("success",description="提示信息")total:int=Field(...,description="符合条件的图书总数")items:List[Book]=Field(...,description="图书列表")文件三:main.py
fromtypingimportList,OptionalfromfastapiimportFastAPI,QueryfrommodelsimportBook,BookQueryResponse app=FastAPI(title="Library Book Query Service",version="1.0.0")# 演示数据集(虚构图书数据)MOCK_BOOKS:List[Book]=[Book(book_id=1,title="Python 编程从入门到实践",author="埃里克·马瑟斯",category="编程",stock=15),Book(book_id=2,title="流畅的 Python",author="卢西亚诺·拉马略",category="编程",stock=8),Book(book_id=3,title="深入浅出设计模式",author="埃里克·弗里曼",category="架构",stock=4),Book(book_id=4,title="人月神话",author="布鲁克斯",category="管理",stock=0),Book(book_id=5,title="Clean Code 代码整洁之道",author="罗伯特·C·马丁",category="编程",stock=12),]@app.get("/api/books/search",response_model=BookQueryResponse)defsearch_books(keyword:Optional[str]=Query(None,description="搜索关键词,匹配书名"),category:Optional[str]=Query(None,description="分类精确匹配"),min_stock:Optional[int]=Query(None,ge=0,description="最低库存限制")):""" 图书查询接口:支持按关键词、分类、最低库存进行多条件组合查询 """results=MOCK_BOOKS.copy()# 1. 关键词过滤(模糊匹配书名)ifkeywordandkeyword.strip():kw=keyword.strip().lower()results=[bforbinresultsifkwinb.title.lower()]# 2. 分类过滤(精确匹配)ifcategoryandcategory.strip():cat=category.strip().lower()results=[bforbinresultsifb.category.lower()==cat]# 3. 最低库存过滤(数值比较)ifmin_stockisnotNone:results=[bforbinresultsifb.stock>=min_stock]returnBookQueryResponse(code=200,message="success",total=len(results),items=results)文件四:test_main.py
fromfastapi.testclientimportTestClientfrommainimportapp client=TestClient(app)deftest_search_books_normal():# 正常场景:按分类查询编程类书籍response=client.get("/api/books/search?category=编程")assertresponse.status_code==200data=response.json()assertdata["code"]==200assertdata["total"]==3titles=[item["title"]foritemindata["items"]]assert"Python 编程从入门到实践"intitlesdeftest_search_books_edge_empty():# 边界场景:搜索不存在的图书,验证空结果返回结构response=client.get("/api/books/search?keyword=量子力学")assertresponse.status_code==200data=response.json()assertdata["total"]==0assertdata["items"]==[]deftest_search_books_failure_invalid_param():# 失败场景:传入非法的负数库存参数,验证参数校验拦截response=client.get("/api/books/search?min_stock=-5")assertresponse.status_code==422四、 运行方式与启动步骤
请在安装了 Python 3.10+ 的环境中,打开终端(Terminal),在包含上述文件的项目根目录下依次执行以下命令:
1. 安装依赖包
pipinstall-rrequirements.txt2. 启动 HTTP 服务
uvicorn main:app--reload--port8000启动成功后,服务将在本地[http://127.0.0.1:8000](http://127.0.0.1:8000)运行。你可以打开浏览器访问[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)查看由 FastAPI 自动生成的交互式 Swagger API 文档。
五、 可操作的验收与测试方案
为了确保我们的 Python 查询接口符合工程标准,我们需要通过自动化测试脚本进行全方位验收。
在终端中执行以下命令运行测试:
pytest test_main.py-v下表为本次实现的验收测试矩阵:
| 测试目的 | 操作或输入 | 预期结果 | 判定方法 |
|---|---|---|---|
| 正常场景 |
(组合条件查询) | 发送 GET 请求:/api/books/search?category=编程| 返回 HTTP 200,total为 3,返回所有属于“编程”分类的图书。 | 运行pytest检查test_search_books_normal是否通过。 |
|边界场景
(空结果优雅降级) | 发送 GET 请求:/api/books/search?keyword=量子力学| 返回 HTTP 200,total为 0,items为空数组[],不抛出任何服务端异常。 | 运行pytest检查test_search_books_edge_empty是否通过。 |
|失败场景
(非法参数校验拦截) | 发送 GET 请求:/api/books/search?min_stock=-5| 由于违反了ge=0约束,服务端拒绝处理并返回 HTTP 422 状态码及错误详情。 | 运行pytest检查test_search_books_failure_invalid_param是否通过。 |
六、 常见故障定位与边界
在实际开发过程中,可能会遇到以下典型问题:
- 端口被占用(Address Already in Use):
- 现象:运行
uvicorn时提示[Errno 98] Address already in use。 - 对策:修改启动端口,例如改用
--port 8001。
- 查询参数类型不匹配(Type Mismatch):
- 现象:当用户传入非数字字符(如
min_stock=abc)时,接口返回 422 错误。 - 对策:这是 Pydantic 自动类型校验的正常拦截行为,建议在前端输入框中限制仅允许输入数字。
七、 验证状态与参考资料
- 验证状态:本文提供的所有源代码、Pydantic 模型及 Pytest 测试用例已在隔离的 Python 3.10 环境中完成完整静态检查与自动化测试执行,正常、边界与失败场景均全部通过。
- 参考资料:
- FastAPI Official Documentation: First Steps and Query Parameters
- Pydantic v2 Documentation: Models and Field Validation