从github上下载源码,或者pip install fastapi,然后在pycharm中import fastapi,就可以鼠标点击的方式进入源码阅读了。
注意,本文档不是源码的一部分,只是为了方便,将原来的README.md改为了OriginalREADME.md。
https://codeload.github.com/tiangolo/fastapi/zip/refs/tags/0.65.1
FastAPI是一个现代的Python Web框架,基于Starlette构建,用于构建API。它具有以下特点:
- 高性能:与NodeJS和Go相当,是最快的Python框架之一
- 快速开发:减少约40%的开发者人为错误
- 直观易用:支持Pydantic自动数据验证,提供优秀的编辑器支持
- 自动文档:自动生成交互式API文档(Swagger UI和ReDoc)
- 类型安全:完全兼容Python类型提示,与Pydantic深度集成
- 异步支持:原生支持异步请求处理
- 依赖注入:强大的依赖注入系统,支持yield清理资源
- OpenAPI支持:自动生成OpenAPI 3.0规范文档
- WebSocket支持:内置WebSocket支持
- 中间件支持:可集成Starlette中间件
FastAPI 0.65.1版本是早期版本,核心架构基于:
- Starlette:ASGI框架,处理HTTP请求/响应
- Pydantic:数据验证和序列化
- ujson/orjson:可选的高性能JSON库
本项目旨在通过中文注释帮助理解FastAPI的内部实现原理。
作为链接文件,将所有源码阅读中的点串起来。
- 预备知识
- Python基本语法
- 网络基础知识
- 推荐使用Pycharm,版本不限,但是我目前使用的是2020.3,打开文件夹,配置好Interpreter,安装好以下包:
starlettepydanticflipmypyflake8- ...
- 进入
fastapi文件夹下,然后打开__init__.py,可以看到最开始的注释,然后跟着注释跳转查看即可; - ...
- 阅读体验:
- 如果你用的是社区版,且在windows下,pycharm中默认注释是灰度的,不影响代码阅读,
可是如果我们主要看注释,可以稍微调整一下
- 进入Settings,然后Editor -> Color Scheme -> Language Defaults
- 然后在打开的页面中,待选框中第四行找到Comments,双击选择第三项Line comment
- 然后在右边Foreground旁边,点击后选择自己喜欢的颜色,最后确认。我选择蓝色,较为醒目。
- 按住Ctrl,同时鼠标点击想跳转的函数或者类,可以直接跳转;
- 如果你用的是社区版,且在windows下,pycharm中默认注释是灰度的,不影响代码阅读,
可是如果我们主要看注释,可以稍微调整一下
- 注释模板说明
- 概览:本文件作用;
- 全局变量:本文件的全局设置;
- 外部导入:导入模块、变量等的说明;
- 代码格式说明:简要有些不符合PEP8代码风格的地方;
- better-codes:heavily opinionated
- 代码逻辑:重点,可能会分散到源码各个部分说明。
- 因为源码中
#类型的注释非常少(仅在encoders中有两行),所以,基本可以认为#类型的注释就是额外加的源码阅读笔记; - 源码中的中文部分都是阅读源码的笔记(中文文档部分除外);
- 其中如果有出现英文,并且标注John的部分都是我自己进一步阅读和参考的笔记。
- .github:用于github相关的文件,相关的流程文档,提issue的模板,以及自动化的脚本等。
有兴趣的小伙伴可以看看action中的文件。其中的
FUNDING.yml被删除,不想引起误会; - docs:各个语言版本的教程文档,其中包含中文,见zh文件夹;
- docs_src:教程文档中有关代码实例的部分,实际文件在这里;
- fastapi:真正的源码所在文件夹,我的注释都将在这个文件夹下的各个文件中;
- pending_tests:测试用的脚本;
- scripts:各种脚本,含格式化代码,文档生成,发布,压缩等等,都是在linux类系统中可以直接执行的代码;
- test:用于框架测试的代码;
.flake8:一款辅助检测Python代码是否规范的工具,想用可以pip install flake8安装使用;.gitignore:本文件内容里的文件或文件夹,是无法被版本管理工具git跟踪到的;CONTRIBUTING.md:如果你想给fastapi框架贡献代码,可以到这里看看;LICENSE:使用的是MIT许可,MIT许可在开源社区是用的非常广泛的一种,具有非常大的自由度;mypy.ini:mypy在编译时向Python添加静态类型检查,使程序变得更加可维护,这里是其配置文件。 想用可以pip install mypy安装使用;OriginalREADME.md:源码自带的README.md,项目介绍文档;pyproject.toml:包管理工具,使用flip init生成,自行配置。根据官方文档PEP517和PEP518, 将来取代setup.py。这里的包指的是fastapi。- 使用方法:
python -m pip install .注意别漏掉后面的点(代表当前目录) - 其它:当我们安装
fastapi时,有以下的方式:pip install fastapipip install fastapi[all]这种方法中的all,如果查看pyproject.toml文件, 就会发现,是all = [...]中的模块;
- 使用方法:
README.md:此说明文件,非源码的一部分。
- 2021-5-31:建立此文档,准备源码阅读;
- 2026-04-11: 继续源码阅读工作,添加中文注释
- 已完成文件:init.py, applications.py, routing.py, param_functions.py, params.py, dependencies/utils.py, dependencies/models.py, responses.py, requests.py, websockets.py, background.py, exceptions.py, datastructures.py, encoders.py, utils.py
- 导出了17个主要接口,包括FastAPI、Request、Response等
- 使用别名导入,保持API稳定性
- DefaultPlaceholder模式:使用
Default类包装默认值,用于识别用户是否显式设置了响应类等参数,即使值为truthy也能被识别 - AsyncExitStack:在
__call__方法中使用异步上下文栈管理资源,支持依赖注入中的yield语法 - 自动路由注册:FastAPI在初始化时自动注册OpenAPI、Swagger UI和ReDoc的路由
- 依赖注入系统:通过
Dependant类收集端点的所有依赖,支持路径参数、查询参数、Header、Cookie、Body等 - 同步/异步处理:使用
asyncio.iscoroutinefunction判断端点是否为异步函数,同步函数会自动在线程池中运行 - 响应模型克隆:使用
secure_cloned_response_field防止Pydantic子模型继承导致敏感字段泄露 - 路由唯一ID:每个路由生成唯一的
unique_id,用于OpenAPI文档中的操作ID
- 统一参数声明:提供Path、Query、Header、Cookie、Body、Form、File、Depends、Security等函数
- 参数验证:所有函数都支持数值范围(gt/ge/lt/le)、字符串长度(min_length/max_length)、正则表达式(regex)等验证
- Header自动转换:Header函数默认将下划线转换为连字符(如X-Custom-Header)
- embed参数:Body函数支持embed参数,将单一参数嵌入JSON而非嵌套
- 继承体系:Path、Query、Header、Cookie继承自Param,Param继承自pydantic的FieldInfo
- Body/Form/File:Body继承自FieldInfo,Form和File继承自Body
- Depends/Security:Security继承自Depends,都用于依赖注入
- ParamTypes枚举:定义query、header、path、cookie四种参数类型
- SecurityRequirement:安全需求类,包含安全方案和OAuth2 scopes
- Dependant:依赖项核心类,包含所有参数信息
- cache_key:在创建时就计算好的缓存键,用于性能优化
- 递归结构:Dependant包含子Dependant列表,形成树形结构
- 依赖解析:通过
get_dependant函数解析函数签名,提取所有依赖参数 - 依赖缓存:使用cache_key实现依赖项结果的缓存,避免重复计算
- 依赖覆盖:通过
dependency_overrides_provider允许覆盖依赖项 - yield支持:支持依赖函数中使用yield进行资源清理(需要Python 3.7+)
- 特殊参数类型:自动识别Request、WebSocket、Response、BackgroundTasks等特殊参数
- 安全作用域:支持OAuth2 scopes的Security依赖
- 重导出starlette响应:直接导入starlette的响应类
- UJSONResponse:可选的ujson响应,性能优于标准json
- ORJSONResponse:可选的orjson响应,性能最佳
- 直接导入:Request和HTTPConnection直接导入自starlette
- 直接导入:WebSocket和WebSocketDisconnect直接导入自starlette
- 直接导入:BackgroundTasks直接导入自starlette
- HTTPException:继承自starlette,添加headers支持
- RequestValidationError:请求验证错误,继承自pydantic的ValidationError
- WebSocketRequestValidationError:WebSocket验证错误
- UploadFile:继承starlette的UploadFile,添加pydantic验证器
- DefaultPlaceholder:识别用户是否显式设置参数值(即使值为truthy)
- Default函数:工厂函数,创建DefaultPlaceholder
- jsonable_encoder:核心函数,支持BaseModel、Enum、Path等类型
- sqlalchemy_safe:默认过滤_sa开头的属性
- custom_encoder:支持自定义编码器
- get_path_param_names:使用正则提取路径参数
- create_response_field:创建pydantic字段
- create_cloned_field:克隆字段,防止敏感字段泄露
- generate_operation_id_for_path:生成OpenAPI操作ID
- get_value_or_default:处理DefaultPlaceholder优先级