读书笔记-《fastapi Web开发入门,进阶和实战》
1,框架对比
笔者在这里只是对比了fastapi和flask两种web框架,flask是基于多线程的,但因为GIL的存在会限制整个框架的性能,fastapi最大的亮点是其异步特性。据说是可以媲美nodejs和Go后台的性能。
多线程的不足是应对每一个请求都需要创建一个新的线程来应付处理。系统不能无限量创建线程和进程来处理。
协程,一种程序级别的IO调度,可以将它理解为对现有线程进行的一次分片任务处理,线程可以在代码块之间来回切换执行,而非逐行执行,因此能够支持更快的上下文切换,减少线程的创建开销和切换开销,从而大大提高了系统性能。
2,异步核心
asyncio是Python官方提供的用于构建协程的并发应用库,是FastAPI实现异步特性的重要组成部分。
asyncio的核心是Eventloop(事件循环),它以Eventloop为核心来实现协程函数结果的回调。它提供了相关协程任务的注册、取消、执行及回调等方法来实现并发
异步IO的本质是基于事件触发机制来实现异步回调。在IO处理上主要采用了IO复用机制来实现非阻塞操作,如在众多的Python Web框架中比较流行的tornado框架,就是比较早出现的一个非阻塞式服务器,它的出现就是为了应对C10K的问题处理。tornado之所以能解决C10K的问题,主要是受益于其非阻塞的方式和对epoll的运用,它每秒甚至可以处理数以千计的连接。这种异步非阻塞是在一个单线程内完成的。在一个线程内可以高效处理更多的IO任务,这就是异步IO的魅力所在。
3,总体特性
还有其他的特性介绍是
1,支持ASGI协议的web应用框架,同时兼容ASGI和WSGI
2,类型提示的特性,使用了Pydantic可以数据类型校验和模块响应
3,基于Pydantic模型的数据序列化反序列化
4,依赖注入系统
5,支持webSocket,GraphQL等
6,支持异步后台任务,可以方便对耗时的任务进行异步处理
7,支持服务进程启动和关闭事件回调监听
8,支持自定义相关中间件来处理请求和响应
9,开箱支持openAPI和Json Schema,可以自动生成交互式文档
10,使用uvloop模块,让原生标准的asyncio内置的事件循环更快
4,交互式文档
自动生成API可视化交互式文档虽然方便,但是在生产环境中开启此文档访问会带来安全隐患。
设置了docs_url=None和redoc_url=None,此时访问 http://127.0.0.1:8000/docs 的请求都会返回“Not Found”的提示
5,主从应用挂载
主应用挂载子应用的好处有:app独立管理;各自所属的API交互式文档是独立的,可以分开访问。
通过调用app.mount(subapp)进行主应用挂载子应用关联,设置子应用请求URL地址为/subapp
6,依赖注入机制
依赖注入的引入确实可以对独立组件进行分离和解耦,使各个组件之间相互独立。依赖项可以是函数(包括同步函数或协程函数)、类或任何实现了__call__()方法的对象
在FastAPI框架中,依赖注入机制通过声明函数参数来实现。依赖项可以在路径操作函数中使用,通过Depends函数来注入。
函数类型的依赖项可以是同步函数,也可以是协程函数,FastAPI框架会自动进行转换处理。
在多层嵌套依赖注入示例代码中同时定义了两个依赖项,但是在这种定义方式下,两个依赖项之间是存在依赖关系的。这种方式可实现全局依赖项的注入。需注意,通过这种方式注入的依赖项会作用到所有app的路由上,当有请求进来时,所有的路由都会自动执行所有的依赖项。
7,中间件
7.1,中间件概述
中间件的本质其实只是一个简单类。中间件遵循ASGI的规范。只要符合ASGI规范的中间件,都可以在FastAPI框架中进行拔插使用。它主要的处理场景是在视图函数收到请求和返回响应内容这一过程中执行一些特定逻辑的任务,所以有时候可以把它理解为所有视图函数的钩子。基于中间件的这种特性,人们可以总结中间件的适用场景:请求跨域处理、API限流限速、对接口进行监控、日志请求记录、IP白名单限制处理、请求权限的校验、请求缓存处理、认证和授权、压缩响应内容等。
7.2,跨域中间件
提供了CORSMiddleware中间件,下面用它来解决类似跨域请求的问题
添加完成跨域中间件,并设置允许发起跨域请求origins之后,当后端接收到前端发起的预校验请求时,发现当前请求来源的域名属于origins范围时开始放行,允许下一个请求继续发起,这样前端和后端API就可以完成真正的数据互通。
7.3,自定义中间件
通过继承BaseHTTPMiddleware来实现自定义的中间件
8,数据库
8.1,Python操作SQLite数据库
SQLite数据库是Python标准库的一部分,游标对象主要用于对数据库表进行DML相关处理。使用Python操作SQLite3数据库时,是通过传入原生SQL语句对数据进行操作的
8.2,SQLAlchemy库
利用SQLAlchemy可以快速设计数据库持久模型,高效设计数据库交互访问方式。
FastAPI框架的并发模式支持多线程和协程两种方式。通常,多线程方式意味着使用的多数是同步阻塞的数据库;而对于协程方式,则意味着需要使用支持异步操作的数据库
8.3,SQLModel库
SQLModel整合了Pydantic和SQLAlchemy,这样可以减少代码的重复量
8.4,aioredis使用
异步库aioredis,该库是支持asyncio的Redis客户端库,通过该库可以基于asyncio为Redis提供简单易用的接口
Redis天然支持发布订阅功能,在Redis中扮演发布者和订阅者的都是Redis客户端
在startup服务事件中创建Redis实例,并且把创建的实例放到全局app.state对象中。这样做的主要目的是方便在app.state获取该实例
9,安全认证
9.1,openAPI规范
基于标准HTTP的身份验证方案,常见的有HTTPBasic基本认证方案和HTTPDigest摘要认证方案等。
HTTPBasic基本认证是Web服务器和客户端之间最基础的HTTP认证方式。下面介绍它的具体认证流程。

HTTPDigest摘要认证是为了弥补HTTPBasic基本认证存在的缺陷而被设计出来的,它的主要作用是避免用户密码在网络层传输。整个HTTPDigest摘要认证过程和Baise认证大体一致,只是在进行质询回传时有所区别.

9.2,APIKey的特定密钥
APIKey认证鉴权方案是一种基于读取前端提交固定关键key值来进行比对校验的一种方式。FastAPI框架提供的基于APIKey的特定密钥方案主要有APIKeyHeader、APIKeyQuery、APIKeyCookie这3种。
3种方案的使用流程基本是一致的:
1)实例化特定鉴权类型。例如,APIKeyHeader方案要求客户端在请求头中携带一个API Key字段,服务端通过检查该字段的值来验证客户端身份。在使用过程中,只需要实例化APIKeyHeader类的实例对象,在实例化时指定对应API Key的名称和可选的描述信息即可。
2)通过声明一个依赖项来读取客户端传入的key值,然后将其和服务端的key值进行对比,如果两个值匹配,则进行正常访问,否则抛出异常。
9.3,基于OAuth2的授权机制颁发
OAuth是一种开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站、移动应用或者桌面应用上存储的受保护的资源。OAuth 2是授权协议,而非认证协议,它没有提供完善的身份认证功能。
JWT
JWT本质是一个字符串,但是这个字符串主要由Header(头部)、Payload(载荷)、Singnature(签证)3个部分组成。Header是对JWT元数据的描述,它是JSON对象。Payload(载荷)也是JSON对象,包含JWT信息中需要传递的主体数据,又称其为有效载荷。Singnature是签证信息,通过指定的secret密钥和HMACSHA256哈希算法对两个组成部分的数据进行加密后生成的。HMACSHA256哈希算法可以确保数据不会被篡改。
密码模式
密码模式(Password Grant)是允许用户使用用户名和密码来直接向授权服务器请求访问令牌,而不需要进行授权码的获取和交换的一种授权方式。
授权码模式
授权码模式(Authorization Code Grant)适用于客户端需要访问用户受保护资源的场景,是需要用户参与授权过程的一种授权方式。在授权码模式中,客户端将用户重定向到授权服务器,用户登录并授权客户端访问其受保护的资源,授权服务器将授权码发送给客户端。客户端使用授权码向授权服务器请求访问令牌,授权服务器验证授权码的有效性后,直接向客户端返回访问令牌。
10,API测试
使用PyTest进行检测,或者使用FastAPI自带的API测试工具TestClient工具和HttpX的异步单元测试
11,生产环境部署详解
服务部署推荐使用 Gunicorn + Uvicorn
Uvicorn是一个基于asyncio、高效、轻量级的Python ASGI(Asynchronous Server Gateway Interface)服务器。某个worker进程崩溃或者异常终止时,master进程会自动重新启动一个新的worker工作进程来代替它,从而确保系统服务的持续稳定运行。
Gunicorn可以作为反向代理服务器来接收客户端请求,并将请求转发给Uvicorn服务器处理。而Uvicorn则是一个异步框架,可以处理高并发的请求
服务进程管理推荐使用 Supervisor
反向代理推荐使用 OpenRestry
可持续集成推荐使用 Gogs + Drone
错误信息收集推荐使用 Sentry
跨服务链路统计推荐使用 Jaeger SDK
各个服务节点之间的调用均采用了链路埋点的方式,调用请求过程通过对应的TraceID将服务节点串联起来,

浙公网安备 33010602011771号