FastAPI(37)- Middleware 中间件

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: FastAPI(37)- Middleware 中间件

什么是中间件


  • 就是一个函数,它在被任何特定路径操作处理之前处理每个请求,且在每个 response 返回之前被调用
  • 类似钩子函数

 

执行顺序

  1. 中间件会接收应用程序中的每个请求 Request
  2. 针对请求 Request 或其他功能,可以自定义代码块
  3. 再将请求 Request 传回路径操作函数,由应用程序的其余部分继续处理该请求
  4. 路径操作函数处理完后,中间件会获取到应用程序生成的响应 Response
  5. 中间件可以针对响应 Response 或其他功能,又可以自定义代码块
  6. 最后返回响应 Response 给客户端

 

Request

FastAPI 有提供 Request 模块,但其实就是 starlette 里面的 Request

 

Response

FastAPI 有提供 Response 模块,但其实就是 starlette 里面的 Response

 

中间件和包含 yield 的依赖项、Background task 的执行顺序

  1. 依赖项 yield 语句前的代码块
  2. 中间件
  3. 依赖项 yield 语句后的代码块
  4. Background task

 

创建中间件


import time
from fastapi import FastAPI, Request
@app.middleware("http")
# 必须用 async
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    # 必须用 await
    response = await call_next(request)
    process_time = time.time() - start_time
    # 自定义请求头
    response.headers["X-Process-Time"] = str(process_time)
    # 返回响应
    return response


中间件函数接收两个参数

  • request:Request 请求,其实就是 starlette 库里面的 Request
  • call_next:是一个函数,将 request 作为参数

 

call_next

  • 会将 request 传递给相应的路径操作函数
  • 然后会返回路径操作函数产生的响应,赋值给 response
  • 可以在中间件 return 前对 response 进行操作

 

实际栗子


import uvicorn
from fastapi import FastAPI, Request, Query, Body, status
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
@app.middleware("http")
# 必须用 async
async def add_process_time_header(request: Request, call_next):
    # 1、可针对 Request 或其他功能,自定义代码块
    print("=== 针对 request 或其他功能执行自定义逻辑代码块 ===")
    print(request.query_params)
    print(request.method)
    # 2、将 Request 传回给对应的路径操作函数继续处理请求
    # 必须用 await
    response = await call_next(request)
    # 4、接收到路径操作函数所产生的的 Response,记住这并不是返回值(return)
    # 5、可针对 Response 或其他功能,自定义代码块
    print("*** 针对 response 或其他功能执行自定义逻辑 ***")
    # 自定义请求头响应状态码
    response.headers["X-Process-Token"] = str("test_token_polo")
    response.status_code = status.HTTP_202_ACCEPTED
    # 6、最终返回 Response 给客户端
    return response
class User(BaseModel):
    name: str = None
    age: int = None
@app.post("/items/")
async def read_item(item_id: str = Query(...), user: User = Body(...)):
    # 3、收到请求,处理请求
    res = {"item_id": item_id}
    if user:
        res.update(jsonable_encoder(user))
    print("@@@ 执行路径操作函数 @@@", res)
    # 有没有 return 都不影响中间件接收 Response
    return res


重点

  • call_next 是一个函数,调用的就是请求路径对应的路径操作函数
  • 返回值是一个 Response 类型的对象

 

访问 /items ,控制台输出结果

=== 针对 request 或其他功能执行自定义逻辑代码块 ===

item_id=test

POST

@@@ 执行路径操作函数 @@@ {'item_id': 'test', 'name': 'string', 'age': 0}

*** 针对 response 或其他功能执行自定义逻辑 ***

 

从请求结果再看执行流程图

image.png

  • 黄色块就是业务代码啦
  • 红色线就是处理完 Request,准备返回 Response 了

 

正常传参的请求结果


image.png

相关文章
|
4天前
|
中间件 Python
中间件应用Django Middleware(Python)
【5月更文挑战第3天】中间件应用Django Middleware(Python)
37 6
中间件应用Django Middleware(Python)
|
4天前
|
缓存 前端开发 安全
Python web框架fastapi中间件的使用,CORS跨域详解
Python web框架fastapi中间件的使用,CORS跨域详解
|
5月前
|
小程序 中间件 PHP
laravel5.8(六)中间件(middleware)
中间件,第一次听到这个名字感觉好陌生,这是个啥呀,第三方插件?好像不是。之前也没有遇到过这个玩意啊。 之前使用到的thinkphp5.0以及Yii2.0框架都是没有中间件这一说的。 去thinkphp官网查了一下,要到thinkphp5.1.6才开始支持中间件。实现的方式基本上就是仿照laravel。 一:那么什么时中间件呢: HTTP 中间件提供了为过滤进入应用的 HTTP 请求提供了一套便利的机制。 例如,Laravel 内置了一个中间件来验证用户是否经过授权,如果用户没有经过授权,中间件会将用户重定向到登录页面,否则如果用户经过授权,中间件就会允许请求继续往前进入下一步操作。
50 0
|
7月前
|
中间件
如何开发一个 SAP UI5 Tools 的自定义中间件扩展 - Custom Middleware Extension
如何开发一个 SAP UI5 Tools 的自定义中间件扩展 - Custom Middleware Extension
82 1
|
存储 JSON 前端开发
彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07
前文再续,上一回我们完成了用户的登录逻辑,将之前用户管理模块中添加的用户账号进行账号和密码的校验,过程中使用图形验证码强制进行人机交互,防止账号的密码被暴力破解。本回我们需要为登录成功的用户生成Token,并且通过Iris的中间件(Middleware)进行鉴权操作。
彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07
|
中间件 数据库 Python
Django中间件Middleware简单使用
Django中间件Middleware简单使用
105 0
|
数据采集 中间件 Python
Python爬虫:Scrapy中间件Middleware和Pipeline
Python爬虫:Scrapy中间件Middleware和Pipeline
206 1
Python爬虫:Scrapy中间件Middleware和Pipeline
|
前端开发 中间件 API
通过thinkjs的middleware将less作为中间件进行处理
最近在折腾的时候又想写less了,但是换框架了,成了thinkjs,考虑到开发阶段一直编译编译less的情况..最终根据middleware的特点实现了一个超级简单的less中间件。
通过thinkjs的middleware将less作为中间件进行处理
|
中间件
FastAPI 学习之路(三十)中间件
FastAPI 学习之路(三十)中间件
FastAPI 学习之路(三十)中间件
|
中间件
如何查找SAP CRM通过中间件Middleware连接的远端ERP系统
如何查找SAP CRM通过中间件Middleware连接的远端ERP系统
如何查找SAP CRM通过中间件Middleware连接的远端ERP系统