零基础入门python45:FastAPI ASGI、应用对象与自动文档 零基础入门python45FastAPI ASGI、应用对象与自动文档一、上一篇课后练习讲解FastAPI 部分从本篇开始暂无前置练习。上一篇课后练习完整答案上一篇练习的要求已落实到下面完整文件先运行项目测试再用 curl 对照状态码和数据库持久化结果答案要点README 提供 check/migrate/test/runserver 全流程交付包删除缓存文件并保留迁移、环境示例和验收脚本。文件README.md完整参考答案文件完整文件README.md# Django Shop 验收 python manage.py check python manage.py migrate python manage.py test -v 2 python manage.py runserver 127.0.0.1:8000完整参考答案文件本篇对应的交付源码完整文件django-shop/shop/tests.pyfromdjango.contrib.authimportget_user_modelfromrest_framework.testimportAPITestCasefrom.modelsimportCategory,Order,ProductclassShopApiTest(APITestCase):defsetUp(self):self.userget_user_model().objects.create_user(usernamealice,passwordpassword123)categoryCategory.objects.create(name图书,slugbooks)self.productProduct.objects.create(categorycategory,namePython入门,slugpython,price59.00,stock5)deftest_products_are_public(self):responseself.client.get(/api/products/)self.assertEqual(response.status_code,200)self.assertEqual(response.data[0][name],Python入门)deftest_checkout_requires_login(self):responseself.client.post(/api/checkout/,{items:[{product_id:self.product.id,quantity:1}]},formatjson)self.assertEqual(response.status_code,403)deftest_session_cart_checks_stock(self):responseself.client.post(/api/cart/,{product_id:self.product.id,quantity:2},formatjson)self.assertEqual(response.status_code,201)self.assertEqual(response.data[str(self.product.id)],2)responseself.client.post(/api/cart/,{product_id:self.product.id,quantity:9},formatjson)self.assertEqual(response.status_code,400)deftest_checkout_creates_order_and_reduces_stock(self):self.client.force_authenticate(self.user)responseself.client.post(/api/checkout/,{items:[{product_id:self.product.id,quantity:2}]},formatjson)self.assertEqual(response.status_code,201)self.assertEqual(response.data[total_amount],118.00)self.product.refresh_from_db()self.assertEqual(self.product.stock,3)self.assertEqual(Order.objects.get().user,self.user)deftest_insufficient_stock_rolls_back_order(self):self.client.force_authenticate(self.user)responseself.client.post(/api/checkout/,{items:[{product_id:self.product.id,quantity:9}]},formatjson)self.assertEqual(response.status_code,400)self.assertEqual(Order.objects.count(),0)验收命令python -m pytest -qDjango 项目使用 python manage.py test。预期测试通过若失败先检查迁移、配置和事务回滚。二、本篇要解决的真实问题FastAPI 应用是 ASGI callable。main.py 负责组装路由health 接口是部署探针启动后 /docs 会根据类型注解生成 OpenAPI。三、请求是怎样走完整条链路的客户端请求 → 路由匹配 → Pydantic 校验 → Depends 注入用户/Session → SQLAlchemy 查询或业务服务 → 提交事务 → 响应模型序列化。每一步都有明确责任排错时按这个顺序定位。四、先看一个最小代码片段router.get(/api/health)defhealth():return{status:ok}这里的注释不是装饰它说明数据从哪里来、为什么不能相信客户端以及失败时系统应保持什么状态。五、完整文件代码app/main.py当前阶段完整文件fromfastapiimportFastAPI,Requestfromfastapi.responsesimportJSONResponsefrom.importai,articles,auth,extrasfrom.databaseimportBase,engine Base.metadata.create_all(engine)appFastAPI(titleBlog Community API,version2.0)app.include_router(auth.router);app.include_router(articles.router);app.include_router(ai.router);app.include_router(extras.router)app.get(/api/health)defhealth():return{status:ok}app.exception_handler(ValueError)defvalue_error_handler(request:Request,exc:ValueError):returnJSONResponse(status_code400,content{code:BAD_REQUEST,message:str(exc)})阅读方法先找路由函数再找它的 Depends、输入 schema、数据库操作和 response_model这五处合起来才是一个功能。六、安装、启动与验收..\..\.venv\Scripts\python.exe-m pip install-r requirements.txt..\..\.venv\Scripts\python.exe-m pytest-q..\..\.venv\Scripts\python.exe-m uvicorn app.main:app--reload打开/docs按顺序完成注册、登录、创建文章、分页查询、修改删除、评论点赞。错误请求必须看到明确状态码校验错误 422未登录 401无权限 403重复点赞 409。测试应全部通过。七、本篇验收清单能指出输入校验发生在哪个 schema。能解释 Session 何时提交、何时回滚。能用第二个用户验证资源隔离。能复现一个失败场景并说明原因。八、课后练习围绕“ASGI、应用对象与自动文档”新增一个测试用例写出请求、预期响应和断言下一篇开头会给出参考实现并继续使用本项目。五、把一次请求拆成可观察的链路FastAPI 只负责把 Python 函数接到 HTTP 上真正处理请求的是 ASGI 服务器。一次 GET /api/health 会经过 Uvicorn 接收字节流、Starlette 路由匹配、FastAPI 参数解析最后把字典编码为 JSON。参数类型错误发生在业务函数之前这就是为什么 /api/articles/abc 会得到 422。入口文件应该只负责装配应用和全局策略fromfastapiimportFastAPI,Requestfromfastapi.responsesimportJSONResponsefrom.importai,articles,auth,extrasfrom.databaseimportBase,engine# 课程演示用 create_all 让空目录可以运行生产环境应改为 Alembic upgrade head。Base.metadata.create_all(engine)appFastAPI(titleBlog Community API,version2.0)app.include_router(auth.router)app.include_router(articles.router)app.include_router(ai.router)app.include_router(extras.router)app.get(/api/health)defhealth()-dict[str,str]:只证明进程存活数据库深度检查应放在独立 ready 接口。return{status:ok}app.exception_handler(ValueError)defvalue_error_handler(request:Request,exc:ValueError):把业务层可预期错误转换成稳定的客户端契约。returnJSONResponse(status_code400,content{code:BAD_REQUEST,message:str(exc)}).venv\Scripts\python.exe-m uvicorn app.main:app--reload--port 8000 curl.exe-i http://127.0.0.1:8000/api/health curl.exe-i http://127.0.0.1:8000/api/articles/abc curl.exe-i http://127.0.0.1:8000/not-found预期分别是 200、422、404。若出现 Could not import module app.main确认当前目录是 fastapi-blog 根目录若端口占用换端口并同步修改请求地址。/docs 和 /openapi.json 能打开说明路由和模型已经被框架发现。六、当前项目中的完整文件对照阅读七、动手画出请求生命周期在纸上画四个框HTTP 请求、FastAPI 校验、路由函数、响应编码。把 /api/articles/abc 的 422 写在第二个框旁边说明它没有进入数据库把不存在路径的 404 写在路由匹配框旁边。这个图比死记状态码更有用因为以后换成 Django 或 Flask 仍然能沿用“请求在哪一层失败”的排查方法。建议给健康检查拆成 liveness 和 readinessliveness 只返回进程状态readiness 执行一次 SELECT 1 并在数据库不可用时返回 503。不要让 Kubernetes 因为一次数据库短暂抖动杀掉仍然健康的进程也不要把数据库异常伪装成 200。八、补充代码文件本篇结束完整模块文件本节不是代码片段而是本篇结束时该模块的完整版本。请先备份旧文件再整体替换替换后重新运行本篇命令和测试。阅读时重点看本篇新增的函数、事务边界和错误处理未涉及的代码先不要自行删减。app/main.pyfromfastapiimportFastAPI,Requestfromfastapi.responsesimportJSONResponsefrom.importai,articles,auth,extrasfrom.databaseimportBase,engine Base.metadata.create_all(engine)appFastAPI(titleBlog Community API,version2.0)app.include_router(auth.router);app.include_router(articles.router);app.include_router(ai.router);app.include_router(extras.router)app.get(/api/health)defhealth():return{status:ok}app.exception_handler(ValueError)defvalue_error_handler(request:Request,exc:ValueError):returnJSONResponse(status_code400,content{code:BAD_REQUEST,message:str(exc)})

相关新闻

最新新闻

多智能体自发协调失控?关键节点的人类介入机制

多智能体自发协调失控?关键节点的人类介入机制

前一阵子在项目里调一个多智能体协作流程,我让三个智能体分别负责数据抽取、格式转换和报告生成。刚开始跑的时候,每个智能体看起来都尽职尽责:抽取的智能体说抽到了字段,转换的智能体说格式已对齐,报告智能体输出了一…

2026/9/2 8:53:15
2026年GEO服务商怎么选?GEO服务商TOP10企业评估与测评

2026年GEO服务商怎么选?GEO服务商TOP10企业评估与测评

开篇导读什么是GEO服务商?GEO,即生成式引擎优化(Generative Engine Optimization),其服务商是一类专门帮助企业在人工智能大模型生态中提升数字可见度与认知权重的专业机构。与传统的SEO侧重于让用户在搜索中“找到”品…

2026/9/2 8:53:15
Matlab实现f-k域地震数据处理:原理、掩膜设计与实战避坑

Matlab实现f-k域地震数据处理:原理、掩膜设计与实战避坑

简介:本资源是一份面向地震学研究者与地球物理方向MATLAB初学者的F-K(傅里叶-克尔斯特拉)谱分析工具包,用于高效提取地震序列的频散特征并反演地下结构。压缩包仅含1个核心MATLAB脚本文件(fk.m)&#xff0c…

2026/9/2 8:53:15
Keras中Transformer因果掩码实现:解决时间序列预测信息泄露

Keras中Transformer因果掩码实现:解决时间序列预测信息泄露

在时间序列预测任务中,Transformer 架构因其强大的序列建模能力而备受关注。然而,直接将为自然语言处理设计的 Transformer 应用于时间序列预测,尤其是在多步预测场景下,会引入一个关键问题:信息泄露。未来的信息会“穿…

2026/9/2 8:53:15
Fast-WAM 深度解析:世界动作模型真的需要推理时的未来想象吗?

Fast-WAM 深度解析:世界动作模型真的需要推理时的未来想象吗?

1. 引言:从 VLA 到 WAM 的范式跃迁 在具身智能领域,如何让机器人理解物理世界并做出合理决策,一直是核心难题。过去两年,视觉-语言-动作模型(VLA)凭借大规模预训练和端到端推理的优势,成为机器…

2026/9/2 8:53:15
ADB脚本自动化:无需Root实现安卓设备批量控制与任务调度

ADB脚本自动化:无需Root实现安卓设备批量控制与任务调度

这次我们来看一个基于 ADB 调试的创意项目。ADB(Android Debug Bridge)是 Android 开发者最熟悉的工具之一,通常用于安装应用、抓取日志、调试系统。但它的能力远不止于此。通过一系列 ADB 命令的组合,我们可以实现很多自动化、批…

2026/9/2 8:48:15