title: FastAPI 学习手册
subtitle: FastAPI框架入门 基本使用, 模版渲染, form表单数据交互, 上传文件, 静态文件配置
date: 2020-06-16
author: NSX
catalog: true
tags:
- 技术
- 教程


在这篇教程里,我们会一起搭建一个用于生产环境的 FastAPI 服务器。写好之后,整个应用技术栈会是这样的:

2020-06-16-Python Web框架FastAPI - 图1

FastAPI 简介

官方文档:https://fastapi.tiangolo.com/

FastAPI是一种现代,快速(高性能)的Web框架,用于基于标准Python类型提示使用Python 3.6+构建API。

主要功能是:

  • 快速:非常高的性能,看齐NodeJS和Go。现有最快的Python框架之一。
  • 快速编码:将功能开发速度提高约200%至300%。
  • 更少的错误:减少约40%的人为错误(开发人员)。
  • 直观:强大的编辑器支持。完成无处不在。调试时间更少。
  • 简易:旨在易于使用和学习。减少阅读文档的时间。
  • :最小化代码重复。每个参数声明中的多个功能。更少的错误。
  • 健壮:获取可用于生产的代码。具有自动交互式文档。
  • 基于标准:基于(并完全兼容)API的开放标准:OpenAPI(以前称为Swagger)和JSON Schema

FastAPI 教程

FastAPI 基础学习

FastApi 基础学习(一) 概述

FastApi 基础学习(二) 开发环境安装及交互式API文档

FastApi 基础学习(三) Pydantic 做类型强制检查

FastAPI 基础学习(四) 路径参数

FastAPI 基础学习(五) 请求参数

FastAPI 基础学习(六) Request Body(I)

FastAPI 基础学习(七) Request Body(II)

FastAPI 基础学习(八) 参数附加信息 (一)

FastAPI 基础学习(九) 参数附加信息 (二)

FastAPI 基础学习(十) Pydantic复杂模型

FastAPI 基础学习(十一) 复杂数据类型

FastAPI 基础学习(十二) Cookie操作

FastAPI 基础学习(十三) Header操作

FastAPI 基础学习(十四) Response自定义状态码

FastAPI 基础学习(十五) 直接使用Request

FastAPI Response

FastAPI Response(一) Response模型

FastAPI Response(二) 直接返回Response对象

FastAPI Response(三) 定制化的Response

FastAPI Response(四) 高级定制的Response

FastAPI 中间件

FastAPI 中间件(一) 自定义中间件

FastAPI 中间件(二) 高级中间件

FastAPI 中间件(三) 跨域资源共享中间件

FastAPI 依赖注入系统

FastAPI 依赖注入系统(一) 简介

FastAPI 依赖注入系统(二) 依赖项类

FastAPI 依赖注入系统(三) 子依赖项

FastAPI 依赖注入系统(四) 基于路径操作装饰器的依赖项

FastAPI 依赖注入系统(五) 带有yield功能的依赖项

FastAPI 依赖注入系统(六) 可参数化的依赖项

FastAPI 安全机制

FastAPI 安全机制(一) 简介

FastAPI 安全机制(二) 基于OAuth2和JWT的Token认证机制(一)生成token

FastAPI 安全机制(三) 基于OAuth2和JWT的Token认证机制(二)用户登陆及验证

FastAPI 安全机制(四) OAuth2 scopes

FastAPI 数据库访问

FastAPI 数据库访问(一)使用SQLAlchemy访问关系数据库

FastAPI 数据库访问(二)使用SQLAlchemy异步访问关系数据库

FastAPI 进阶知识

FastAPI 进阶知识(一) 表单数据

FastAPI 进阶知识(二) JSON兼容编码

FastAPI 进阶知识(三) 错误处理

FastAPI 进阶知识(四) 后台任务

FastAPI 进阶知识(五) 子应用

FastAPI 进阶知识(六) 启动-关闭事件

FastAPI 进阶知识(七) 在Request中存储附加信息

FastAPI WebSockets

FastAPI WebSockets

FastAPI 工程管理

FastAPI 工程管理(一) 工程目录管理

FastAPI 工程管理(二) 工程设置

FastAPI 工程管理(三) 工程部署

FastAPI 工程管理(四) 工程示例

FastAPI异步 async/await

无论你是否使用async,FastAPI都会采用异步的方式处理。

但是,如果你定义了async函数,函数体却是同步的调用,将导致函数执行过程变成串行。

async使用指导:

  • 如果这个请求比较慢,比如连接数据库读取数据、文件IO、rpc调用等一般加上async,我想普通项目里大部分请求都会多多少少跟数据库打交道,所以加的往往比较多;
  • 求稳不求快的,那就定义为普通函数 def (因为它可以采用多线程的方式解决)
  • 分不清加不加就不加,毕竟async是要开销的。如果定义了async函数,里面却是同步的调用,那么这将慢的是灾难!;

异步编程:

Asynchronous Code之所以称为“异步”,是因为计算机/程序不必与速度较慢的任务“同步”,而是在等待中去执行其它工作。文中作者详细列举了相对于cpu和内存操作来说,慢的多的操作如下:

  • 网络通信
  • 文件读写
  • 远程api调用如rpc调用
  • 数据库操作和查询

异步是相对同步编程来说的,在执行顺序上并没有改变。实际效果就是同一台机器如果有比较多的慢操作使用异步编程可以提高吞吐率。这里再吐槽一下,大部分语言比如python、csharp、go等的async都是协程实现的,只有java是线程实现的。代价:进程>线程>协程,java不是不能用协程来实现完全是因为历史包袱,线程相对也不会丢失太多的性能。

异步实验代码

  1. from fastapi import FastAPI
  2. import time
  3. import asyncio
  4. import os
  5. app = FastAPI()
  6. @app.get("/async_slowest")
  7. async def async_slowest():
  8. time.sleep(1)
  9. return {"message": "异步模式,但是同步执行sleep函数,执行过程是串行的"}
  10. @app.get("/async_sleep_in_thread")
  11. async def async_sleep_in_thread():
  12. loop = asyncio.get_event_loop()
  13. await loop.run_in_executor(None, time.sleep, 1)
  14. return {"message": "线程池中运行sleep函数"}
  15. @app.get("/async_sleep")
  16. async def async_sleep():
  17. await asyncio.sleep(1)
  18. return {"message": "异步模式,且异步执行sleep函数"}
  19. @app.get("/sync")
  20. def sync_sleep():
  21. time.sleep(1)
  22. return {"message": "同步模式,但是FastAPI会放在线程池中运行,所以很快"}

我们用ab工具,总量100,并发100进行测试。

这4个函数,最慢的就是第一个async_slowest。我们可以看到,它几乎是一个接一个的串联输出。原因是:fastapi框架会将async函数会放到event loop中运行。如果函数没有运行或有await,则其他函数无法运行。所以这里是一个串联的效果,总时间需要100s

为了解决这个问题,第二个函数引入了一个线程池中去运行,所以不会出现阻塞。这个函数,1秒可以全部运行完。

第三个函数是最正宗的实现。它使用异步的sleep取代了原版同步的sleep。这也是最快的实现。1秒可以运行完

第四个函数是唯一一个不是async的普通函数。它的运行时间是多少呢?我的电脑是3秒运行完!为什么?这就是fastapi精彩的地方。前面提到,async函数会放到event loop中执行。那么,普通的函数会放到哪里呢?答案是,放到thread pool中。那么为什么是3秒呢。这是因为我的电脑是逻辑8核。线程池的默认配置是核数*5,所以是40线程。我的测试是100个并发,所以一共是3秒完成。40->40->20

FastAPI vs. Flask

二者的区别在哪?

  1. FastAPI是最快的Python框架之一,其性能比Flask高出300%以上:
    2020-06-16-Python Web框架FastAPI - 图2
    在总体延迟和吞吐量方面,FastAPI都更具优势!
  2. 对异步具有本机支持
    Flask(专为诸如Gunicorn之类的WSGI服务器设计)不具有本地异步支持;而FastAPI建立在ASGI服务器Uvicorn的基础上,使运行异步事件循环(对传入请求进行计数)变得容易。
  3. 转换成本低
    就语法而言,它在设计上与Flask非常相似,从Flask到FastAPI的最初过渡只需要极少的重写量

参考

fastapi.2020-06-16-Python Web框架FastAPI - 图3

fastapi教程翻译(搬运自用)

FastAPI框架入门 基本使用, 模版渲染, form表单数据交互, 上传文件, 静态文件配置

How can I prevent “307 Temporary Redirect” while accessing FastAPI via an Android Emulator on local machine #731

当碰到URL结尾包含斜杠“/”这种情况,会让客户端重定向到相应没有尾斜杠的URI(也有可能会返回301 - 用来资源重定向)

FastAPI项目实战