Skip to content

johntheprime/fastapi-notes

Repository files navigation

FastAPI框架的源码阅读(0.65.1版本)

从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,安装好以下包:
    • starlette
    • pydantic
    • flip
    • mypy
    • flake8
    • ...
  • 进入fastapi文件夹下,然后打开__init__.py,可以看到最开始的注释,然后跟着注释跳转查看即可;
  • ...
  • 阅读体验:
    • 如果你用的是社区版,且在windows下,pycharm中默认注释是灰度的,不影响代码阅读, 可是如果我们主要看注释,可以稍微调整一下
      • 进入Settings,然后Editor -> Color Scheme -> Language Defaults
      • 然后在打开的页面中,待选框中第四行找到Comments,双击选择第三项Line comment
      • 然后在右边Foreground旁边,点击后选择自己喜欢的颜色,最后确认。我选择蓝色,较为醒目。
    • 按住Ctrl,同时鼠标点击想跳转的函数或者类,可以直接跳转;
  • 注释模板说明
    • 概览:本文件作用;
    • 全局变量:本文件的全局设置;
    • 外部导入:导入模块、变量等的说明;
    • 代码格式说明:简要有些不符合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.inimypy 在编译时向 Python 添加静态类型检查,使程序变得更加可维护,这里是其配置文件。 想用可以pip install mypy安装使用;
  • OriginalREADME.md:源码自带的README.md,项目介绍文档;
  • pyproject.toml:包管理工具,使用flip init生成,自行配置。根据官方文档PEP517和PEP518, 将来取代setup.py。这里的包指的是fastapi。
    • 使用方法:python -m pip install . 注意别漏掉后面的点(代表当前目录)
    • 其它:当我们安装fastapi时,有以下的方式:
      • pip install fastapi
      • pip install fastapi[all] 这种方法中的all,如果查看pyproject.toml文件, 就会发现,是all = [...] 中的模块;
  • README.md:此说明文件,非源码的一部分。

参考资料

PROGRESS

  • 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

有趣的事实 (Interesting Facts)

init.py (入口文件)

  • 导出了17个主要接口,包括FastAPI、Request、Response等
  • 使用别名导入,保持API稳定性

applications.py

  • DefaultPlaceholder模式:使用Default类包装默认值,用于识别用户是否显式设置了响应类等参数,即使值为truthy也能被识别
  • AsyncExitStack:在__call__方法中使用异步上下文栈管理资源,支持依赖注入中的yield语法
  • 自动路由注册:FastAPI在初始化时自动注册OpenAPI、Swagger UI和ReDoc的路由

routing.py

  • 依赖注入系统:通过Dependant类收集端点的所有依赖,支持路径参数、查询参数、Header、Cookie、Body等
  • 同步/异步处理:使用asyncio.iscoroutinefunction判断端点是否为异步函数,同步函数会自动在线程池中运行
  • 响应模型克隆:使用secure_cloned_response_field防止Pydantic子模型继承导致敏感字段泄露
  • 路由唯一ID:每个路由生成唯一的unique_id,用于OpenAPI文档中的操作ID

param_functions.py

  • 统一参数声明:提供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而非嵌套

params.py (参数类定义)

  • 继承体系: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四种参数类型

dependencies/models.py (依赖注入数据模型)

  • SecurityRequirement:安全需求类,包含安全方案和OAuth2 scopes
  • Dependant:依赖项核心类,包含所有参数信息
  • cache_key:在创建时就计算好的缓存键,用于性能优化
  • 递归结构:Dependant包含子Dependant列表,形成树形结构

dependencies/utils.py (依赖注入系统核心)

  • 依赖解析:通过get_dependant函数解析函数签名,提取所有依赖参数
  • 依赖缓存:使用cache_key实现依赖项结果的缓存,避免重复计算
  • 依赖覆盖:通过dependency_overrides_provider允许覆盖依赖项
  • yield支持:支持依赖函数中使用yield进行资源清理(需要Python 3.7+)
  • 特殊参数类型:自动识别Request、WebSocket、Response、BackgroundTasks等特殊参数
  • 安全作用域:支持OAuth2 scopes的Security依赖

responses.py (响应类)

  • 重导出starlette响应:直接导入starlette的响应类
  • UJSONResponse:可选的ujson响应,性能优于标准json
  • ORJSONResponse:可选的orjson响应,性能最佳

requests.py (请求类)

  • 直接导入:Request和HTTPConnection直接导入自starlette

websockets.py (WebSocket类)

  • 直接导入:WebSocket和WebSocketDisconnect直接导入自starlette

background.py (后台任务)

  • 直接导入:BackgroundTasks直接导入自starlette

exceptions.py (异常类)

  • HTTPException:继承自starlette,添加headers支持
  • RequestValidationError:请求验证错误,继承自pydantic的ValidationError
  • WebSocketRequestValidationError:WebSocket验证错误

datastructures.py (数据结构)

  • UploadFile:继承starlette的UploadFile,添加pydantic验证器
  • DefaultPlaceholder:识别用户是否显式设置参数值(即使值为truthy)
  • Default函数:工厂函数,创建DefaultPlaceholder

encoders.py (JSON编码器)

  • jsonable_encoder:核心函数,支持BaseModel、Enum、Path等类型
  • sqlalchemy_safe:默认过滤_sa开头的属性
  • custom_encoder:支持自定义编码器

utils.py (工具函数)

  • get_path_param_names:使用正则提取路径参数
  • create_response_field:创建pydantic字段
  • create_cloned_field:克隆字段,防止敏感字段泄露
  • generate_operation_id_for_path:生成OpenAPI操作ID
  • get_value_or_default:处理DefaultPlaceholder优先级

About

fastapi source code analysis(zh-cn) 基于fastapi 0.65.1源码

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages