Python 入门(二)- 使用 FastAPI 快速生成后端 API 接口

前言

作为一名前端仔,一直想自己写点后端接口来进行一些功能的测试。结合前端 + 后端的视角,完整的走一遍整体的技术实现流程。既能巩固知识,又能融会贯通,达到真正搞懂的目的

比如 Token 鉴权,图片上传,大文件上传,Websocket 联调等。这些功能虽然做过很多次,可始终是浮于表面,只知道前端做了什么,至于传递参数调用接口之后的事情是一概不知。感觉前端只是一个切图仔 + API 调用侠,很难真正理解深层次的技术原理。所以我打算学点后端的东西,打通整个流程,真正的去理解它

我选择 Python 作为后端语言,UV 作为 Python 包和环境管理工具。想要学习 UV 入门教程请直接查阅我写的另一篇文章,本文不再赘述 UV 如何安装 Python 以及创建项目和虚拟环境等基础操作。

《Python 入门(一)- 用 UV 管理 Python》:juejin.cn/post/760585...

快来跟我一起学习吧!

1. FastAPI 介绍

1.1 FastAPI 是什么?

FastAPI 官网:fastapi.tiangolo.com/zh/

pypi 上的地址:pypi.org/project/fas...

简介:FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框架,使用标准的 Python 语法,不需要学习新的语法、特定库的方法或类等等

FastAPI 使用了一种用于构建 Python Web 框架和服务器的标准,称为 ASGI。FastAPI 本质上是一个 ASGI Web 框架

1.2 为什么选 FastAPI ?

Python 主流的 web 框架有 flask,Django 和 FastAPI,经过一番调研,最后我选择使用 FastAPI

有如下原因:

  • flask 太毛坯,Django 太重,并且两者的官网文档都太丑陋..(个人认为)

  • 官网文档简洁美观

  • 快速的开发 api 接口

  • 自动生成交互式 API 文档(Swagger UI 和 ReDoc)

2. FastAPI 安装使用和运行

2.1 安装 FastAPI

如何用 UV 创建 Python 项目就不演示了,创建项目后也不必特意创建和激活虚拟环境,UV 会在合适的时机智能的自动创建使用虚拟环境。关于 UV 的知识我已经在这篇文章内写的很清楚了: 《Python 入门(一)- 用 UV 管理 Python》:juejin.cn/post/760585...

在 Python 项目中安装 FastAPI

bash 复制代码
uv add "fastapi[standard]"

standard\] 在 Python 里被称为 "Extra"(额外选项),它告诉 UV 除了安装 FastAPI 核心库外,还要把标准可选依赖一起安装 UV 解析 fastapi 的 Extra (standard) 声明,发现其包含了 uvicorn、pydantic、httptools 等子依赖。详见官网介绍:[fastapi.tiangolo.com/zh/#depende...](https://link.juejin.cn?target=https%3A%2F%2Ffastapi.tiangolo.com%2Fzh%2F%23dependencies "https://fastapi.tiangolo.com/zh/#dependencies") UV 会自动下载并利用硬链接将它们安装到项目的 .venv 中 并同步更新 pyproject.toml(声明依赖) ![2.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/dc676842540ee1731a801ce43a6990bc.webp) 和 uv.lock(锁定精确版本)。 ![3.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/c18059b7dda672acd93f216faa99d6a6.webp) ### 2.2 使用 FastAPI 创建一个名为 `main.py` 的文件,其中包含 FastAPI 的导入以及创建 get 请求接口,完整内容如下: ```python from fastapi import FastAPI app = FastAPI() @app.get("/") async def read_root(): return {"Hello": "World"} @app.get("/items/{item_id}") async def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} ``` ### 2.3 运行 FastAPI ```bash uv run fastapi dev main.py ``` ![4.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/883e75a19b5b7760fa22bdc765cb8aad.webp) * `uv run`:自动定位 .venv 环境(自动寻找当前目录或上级目录的 pyproject.toml 文件所在目录中的 .venv),用这个虚拟环境运行命令 * `fastapi dev`:FastAPI 官方 CLI,内部启动 uvicorn 服务器,默认监听 8000 端口,并自动开启 Reload(热部署) 模式(代码改了服务器自动重启)。默认运行在 [http://127.0.0.1:8000,并自动生成交互式文档](https://link.juejin.cn?target=http%3A%2F%2F127.0.0.1%3A8000%25EF%25BC%258C%25E5%25B9%25B6%25E8%2587%25AA%25E5%258A%25A8%25E7%2594%259F%25E6%2588%2590%25E4%25BA%25A4%25E4%25BA%2592%25E5%25BC%258F%25E6%2596%2587%25E6%25A1%25A3 "http://127.0.0.1:8000%EF%BC%8C%E5%B9%B6%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E4%BA%A4%E4%BA%92%E5%BC%8F%E6%96%87%E6%A1%A3") ### 2.4 交互式 API 文档 此时 fastapi 会自动生成两个交互式 API 文档,能在浏览器中直接调用和测试你的 API Swagger UI:[http://127.0.0.1:8000/docs](https://link.juejin.cn?target=http%3A%2F%2F127.0.0.1%3A8000%2Fdocs "http://127.0.0.1:8000/docs") ![5.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/1823b990a69820d0e449e3b008b0908a.webp) 点击 `Try it out` ![5.1.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/6f8eaf192a217512aa3e7e51225caa0d.webp) 点击 `Execute` ![5.2.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/133a998a165874711964dd11c37f8700.webp) 成功获取到接口返回内容 ![5.3.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/fe361596b802dd1c4756bed14c286180.webp) 修改接口返回内容,将 World 改为闲云一鹤 ![5.4.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/c24f05a1a5013dd167aea07d8a621a08.webp) 再次点击 Execute,可以看到接口返回值同步更新了,`说明热部署功能已开启`,不需要重启服务就能自动更新内容(注意,如果更改了接口字段或者新增接口需要刷新文档页面) ![5.5.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/d00f430aedcfdbc7acc25cbd5d377c19.webp) ReDoc:[http://127.0.0.1:8000/redoc](https://link.juejin.cn?target=http%3A%2F%2F127.0.0.1%3A8000%2Fredoc "http://127.0.0.1:8000/redoc") 这是访问 redoc 文档 ![5.6.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/72d8849bb08727d7b07e27d98afb0611.webp) ## 3. vscode 配置 ### 3.1 VSCode 安装 Python 扩展,检查语法错误 Python 是一个对于格式要求极其严格的语言,如果缩进或者一些格式错误,会报错导致无法运行 ![6.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/6380f725239d827b54de10b869845743.webp) 这里我故意在 `app = FastAPI()` 前面加上几个空格,产生了缩进错误,运行失败 ![7.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/234ad251828e8711138c83115f98cc4e.webp) `在 VS Code 里安装 Python 扩展`,它会自动帮你检查语法错误 ![8.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/269e41151006dc2acaae58d1f61d19ab.webp) 不符合规范以及语法错误的地方,会标红提示 ![9.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/6348862c693877c896c395b984473517.webp) ### 3.2 安装 Ruff + VSCode 配置 实现保存代码自动格式化 我们可以将配置再进一步优化,保存后让编辑器帮你自动格式化代码,就像前端的 eslint 和 prettier 强烈推荐 Ruff,它是一个用 rust 编写的,速度极快(比 Flake8 和 Black 快 10-100 倍)的 python 代码检查和格式化工具;并且 Ruff 和 uv 都是同一家公司(Astral)开发的 #### 3.2.1 第一步:项目集成 (The Tooling) 在你的项目终端运行,这会把 Ruff 记录在你的开发依赖中: ```bash uv add --dev ruff ``` ![10.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/b5acf01877cb3b6cb7fe971fa1f7fc16.webp) 安装后会在 pyproject.toml 文件中添加 ruff 依赖 ![11.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/645b1c21ad7cbafaf1b854a1fa735644.webp) 并且在 uv.lock 文件中锁定了 ruff 版本 ![12.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/ac9ff3ddcafc6673793ce8536d459211.webp) #### 3.2.2 第二步:VSCode 安装 Ruff 扩展 `在 VS Code 扩展市场搜索并安装 Ruff` (作者是 Astral Software)。 ![13.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/eb7eaad852544fefb677755d2e1cfd7c.webp) #### 3.2.3 第三步:配置 VS Code 用户设置 (User Settings) ```json { // 设置 Python 文件的默认格式化程序为 Ruff "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true, "editor.codeActionsOnSave": { // 自动修复可修复的错误(比如多余的空格、没用的 import) "source.fixAll.ruff": "explicit", // 自动对 import 语句进行排序 "source.organizeImports.ruff": "explicit" } }, // 让 Ruff 插件优先使用你项目里 uv add 安装的那个版本 "ruff.importStrategy": "fromEnvironment" } ``` ![14.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/5371d576756fd779a562235c7be74920.webp) 建议用户区和工作区都配置,这样无论是你个人在电脑创建多个 Python 项目,还是团队合作让别人 git clone 你的项目时,都能确保拥有同样的格式化配置! tip: `记得提醒同事装插件`:配置是有了,但如果同事没装 VS Code 的 Ruff 插件,配置是不会生效的 下面测试保存代码自动格式化的配置是否生效 将下面的代码复制到 main.py 文件中,然后保存 ```python import time, datetime def hello(): x=1; y=2; print('hello world!',x + y) ``` 这是格式化后的代码 ```python def hello(): x = 1 y = 2 print("hello world!", x + y) ``` 自动完成了下面的操作: 1. 自动删除已导入却未使用的库:time, datetime 2. 缩进从两个空格变成了四个空格 3. x和y赋值,等号前后去掉了空格,并且后面去掉了多余的分号 4. 'hello world!' 单引号也变成了双引号,并且逗号后面加上了空格 ### 3.3 忽略 ` __pycache__` 文件夹 前面运行 uv run fastapi dev main.py 后项目根目录下新增了一个 ` __pycache__` 文件夹,并且里面新增了一个 `main.cpython-313.pyc` 文件 这是 Python 自己生成的"编译缓存"。运行 main.py 时,它会把代码编译成更快执行的字节码(.pyc 文件),然后存到 ` __pycache__` 文件夹里。 下次运行如果你没改代码,Python 跳过编译过程直接读这个缓存文件,启动速度会更快一点 千万不要将它们提交到仓库,因为这是临时文件、每台电脑都会自己生成,提交上去完全没用 在项目根目录创建一个 `.gitignore` 文件,写上 ` __pycache__` ![15.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/f4c74e111e1a2596d48dafef6b907dad.webp) ` __pycache__` 文件可以随便删除,没有任何坏影响,只是下次启动时 Python 需要重新编译一下,启动时间会稍微长那么零点几秒 ## 4. 路由 ### 4.1 定义 路由是 url 地址和处理函数之间的映射关系,它决定了当用户访问某个网址时,服务器应该执行哪段代码来返回结果 人话就是路由 = 装饰器 ➕ 函数 用装饰器装饰函数,当请求路径的时候,执行路由对应的函数 ### 4.2 完整代码 ```python from fastapi import FastAPI app = FastAPI() @app.get("/") async def read_root(): return {"Hello": "掘金-闲云一鹤"} @app.get("/song") async def get_song(): return {"门前大桥下": "游过一群鸭"} ``` ### 4.3 代码讲解 上面代码中 `app` 是 FastApi 实例 `get` 是请求方法 `/` 是请求路径 `@app.get("/")` 组成了`装饰器` `read_root()` 是函数 `return {"Hello": "掘金-闲云一鹤"}` 是函数的响应结果 访问路由查看效果 ![16.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/4878fb761ad01e7eed1815845dd87d87.webp) 输入不同的路由,返回不同的接口 ![17.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/9ec0217d887835b0f0481d44bb53a174.webp) ## 5. 参数 ### 5.1 参数介绍 * 什么是参数? 参数就是客户端发送请求时附带的额外信息和指令 参数的作用是让同一个接口能根据不同的输入参数,返回不同的输出结果,实现接口的动态交互 * 参数类型 参数分为: 路径参数,查询参数,请求体参数 ### 5.2 路径参数 #### 5.2.1 定义 路径参数出现在 Url 路径的后面,例如:`/user/{name}` 路径参数用于指向唯一的,特定的资源,方法为 `GET` 完整代码: ```python from fastapi import FastAPI app = FastAPI() @app.get("/users/{id}") async def get_user(id: int, name: str | None = None): return {"id": id, "name": name} ``` Request URL 示例: ```json http://127.0.0.1:8000/users/6?name=xyyh ``` Response body 示例: ```json { "id": 6, "name": "xyyh" } ``` ![18.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/5ed4a36d13725450597987f947989d0a.webp) #### 5.2.2 类型注解 类型注解用于给参数添加额外的信息和校验,比如限制 ID 的范围值。 如果只限制参数的类型,就用 Python 的原生注解,比如 `id: int` 或者 `name: str` 如果有额外的限制,比如范围值和长度限制等,就需要用到 `Path` 注解,Path 函数需要先导入再使用 完整代码: ```python from fastapi import FastAPI, Path app = FastAPI() @app.get("/users/{id}") async def get_user( id: int = Path(..., gt=0, lt=101, description="用户ID,取值范围1-100"), name: str | None = None, ): return {"msg": f"这是一个用户接口, id为{id}, 姓名为{name}"} ``` 其中 `...` 表示必填,`gt` 表示值必须大于此值,`lt` 表示值必须小于此值 具体以及更多用法请查阅 FastAPI 官方文档:[fastapi.tiangolo.com/zh/referenc...](https://link.juejin.cn?target=https%3A%2F%2Ffastapi.tiangolo.com%2Fzh%2Freference%2Fparameters%2F%3Fh%3Dgt%23fastapi.Path "https://fastapi.tiangolo.com/zh/reference/parameters/?h=gt#fastapi.Path") Request URL 示例: ```json http://127.0.0.1:8000/users/6?name=xyyh ``` Response body 示例: ```json { "msg": "这是一个用户接口, id为6, 姓名为xyyh" } ``` 我故意将 ID 输入为不符合范围内的值,它提醒我输入值应大于0 ![19.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/426745ff90fe325537685fca2ebc1ecc.webp) 输入正常范围的 ID 值,接口正常返回 ![20.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/a4e6131ef95eb8df8aa1080b38839b50.webp) ### 5.3 查询参数 #### 5.3.1 定义 查询参数出现在 Url 路径的后面,紧跟一个问号,然后通过 `key=value` 形式展示参数,如果有多个参数中间用 `& 符号`进行拼接,例如:`user?name=张三&age=18` 查询参数用于对数据进行过滤,排序,分页等操作,方法为 `GET` 完整代码: ```python from fastapi import FastAPI app = FastAPI() # 查询用户列表 page: 当前页, size:每页条数 @app.get("/users/user_list") async def get_user_list(page: int = 1, size: int = 10): return {"msg": f"这是查询用户列表的接口, 当前为{page}页, 每页条数为{size}"} ``` `=` 号后面直接赋值,表示默认值 Request URL 示例: ```json http://127.0.0.1:8000/users/user_list?page=1&size=10 ``` Response body 示例: ```json { "msg": "这是查询用户列表的接口, 当前为1页, 每页条数为10" } ``` ![21.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/35698185d93aa6cd46422b011d126cea.webp) #### 5.3.2 类型注解 与路径参数相同,查询参数也支持 python 原生注解 与路径参数不同(路径参数使用 `Path` 注解),查询参数需要使用 `Query` 来做类型注解,同样需要先引入再使用 完整代码: ```python from fastapi import FastAPI, Query app = FastAPI() # 查询用户列表 page: 当前页, size:每页条数 @app.get("/users/user_list") async def get_user_list( page: int = Query(1, ge=1, description="当前页码,必须大于等于1"), size: int = Query(10, ge=1, le=100, description="每页条数必须在1-100之间"), ): return {"msg": f"这是查询用户列表的接口, 当前为{page}页, 每页条数为{size}"} ``` Request URL 示例: ```json http://127.0.0.1:8000/users/user_list?page=1&size=10 ``` Response body 示例: ```json { "msg": "这是查询用户列表的接口, 当前为1页, 每页条数为10" } ``` 将页码和每页条数输入不符合范围内的值,也正常收到了提示 ![22.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/1795f9dc33d2f91cd4de4f50ffa85350.webp) 输入正常范围的值,接口正常返回 ![23.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/d80723a287fb94c1a9d500c5ea120264.webp) ### 5.4 请求体参数 #### 5.4.1 定义 请求体参数出现在 http 请求的消息体(body)中, 请求体参数用于创建,更新资源,携带大量数据,如 json,方法为 `POST`,`PUT` 等 在 http 协议中,一个完整的请求由三部分组成: 1. 请求行:包含方法,url,协议版本 2. 请求头:元数据信息(content-type,authorization等) 3. 请求体:实际要发送的数据内容 完整代码: ```python from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() # 用户注册 class User(BaseModel): username: str password: str @app.post("/users/register") async def register_user(user: User): # 在这里可以添加用户注册的逻辑,例如将用户信息保存到数据库 return {"msg": f"用户 {user.username} 注册成功!"} ``` Request URL 示例: ```json http://127.0.0.1:8000/users/register ``` Response body 示例: ```json { "msg": "用户 掘金-闲云一鹤 注册成功!" } ``` ![24.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/214cc08b6bef2b82ea451e6a41b5bde6.webp) ![25.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/8009b562f0800c4dc0cb99798b33da39.webp) #### 5.4.2 类型注解 请求体参数可以用 python 原生注解或者 `Field` 注解 要先导入 `Field` 函数,用法跟 Path 和 Query 差不多 完整代码: ```python from fastapi import FastAPI from pydantic import BaseModel, Field app = FastAPI() # 用户注册 class User(BaseModel): username: str = Field(default="掘金-闲云一鹤", description="用户名") password: str = Field( ..., min_length=6, max_length=20, description="密码,长度必须在6到20之间" ) @app.post("/users/register") async def register_user(user: User): # 在这里可以添加用户注册的逻辑,例如将用户信息保存到数据库 return {"msg": f"用户 {user.username} 注册成功!"} ``` 密码长度必须在6到20之间,我输入三位数 ![26.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/47a11799106b5a4ac5d590944522ad7b.webp) 提示我长度不够 ![27.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/4962609ad894bd2d346cdc1cc230cc2f.webp) 输入六位数密码,正常提交接口 ![28.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/cc3cb3257d47965faddff58af2b7a6bd.webp) ## 5. 响应 默认情况下,FastAPI 会将代码中的 Python 对象(字典,列表,pydantic 模型等),自动转换为 json 响应格式(JSONResponse) FastAPI 内置的响应类型有:JSONResponse(json格式),HTMLResponse(HTML 内容),PlainTextResponse(纯文本),FileResponse(文件下载),StreamingResponse(流式响应),RedirectResponse(重定向) 如果想要接口返回其他的响应格式,需要手动设置,下面将详细介绍如何使用不同的响应 ## 5.1 HTMLResponse 响应 HTMLResponse 用于返回 HTML 内容 HTMLResponse 响应的 content-type 值为:`text/html; charset=utf-8` 完整代码: ```python from fastapi import FastAPI from fastapi.responses import HTMLResponse app = FastAPI() @app.get("/", response_class=HTMLResponse) async def get_html(): return """ 闲云一鹤

这是一个简单的HTML响应

我是掘金-闲云一鹤

欢迎访问我的掘金主页:https://juejin.cn/user/729731452122382

""" ``` 浏览器访问可查看渲染效果:[http://127.0.0.1:8000/](https://link.juejin.cn?target=http%3A%2F%2F127.0.0.1%3A8000%2F "http://127.0.0.1:8000/") ![29.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/316323636a7b6b4bfc0e9f08208f2f2a.webp) ## 5.2 FileResponse 响应 FileResponse 用于返回文件下载 FileResponse 响应的 content-type 值为:`content-type: image/jpeg` 完整代码: ```python from fastapi import FastAPI from fastapi.responses import FileResponse app = FastAPI() @app.get("/file") async def get_file(): file_path = "./img/壁纸.jpg" return FileResponse( file_path, ) ``` 浏览器访问可查看图片:[http://127.0.0.1:8000/file](https://link.juejin.cn?target=http%3A%2F%2F127.0.0.1%3A8000%2Ffile "http://127.0.0.1:8000/file") ![30.png](https://oss.xyyzone.com/jishuzhan/article/2027284674733735938/b2d4a79fb21e4f83bc0a2a337dbab07d.webp) ## 5.3 自定义响应数据的格式 可以理解为提前定义了接口的数据字段以及类型,如果接口返回的数据字段以及类型不符合提前定义的值,就会报错。前端仔表示感觉很像前端的 Typescript 完整代码: ```python from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str description: str = None price: float tax: float = None @app.post("/items/") async def create_item(item: Item): return item ``` ## 5.4 处理异常响应 FastAPI 通过 `HTTPException` 来处理异常 完整代码: ```python from fastapi import FastAPI, HTTPException app = FastAPI() @app.get("/users/{id}") async def get_user(id: int): # 这里模拟一个用户ID列表,实际应用中可以从数据库中查询 id_list = [1, 2, 3, 4, 5] if id not in id_list: raise HTTPException(status_code=404, detail="用户不存在") return { "id": id, } ``` 如果输入的 ID 值不在 id_list 中,就会抛出错误: `{ "detail": "用户不存在" }` ## 6. 中间件 ### 6.1 定义 * 中间件是一个在每次请求进入 FastAPI 应用时都会被执行的函数 * 中间件的作用是为每个请求添加统一的处理逻辑(记录日志,身份认证,跨域,设置响应头,性能监控等) * 它在请求到达实际的路径操作(路由处理函数)之前运行,并且在响应返回给客户端之前再运行一次 * 多个中间件的执行顺序是,从下到上 ### 6.2 使用 完整代码: ```python from fastapi import FastAPI app = FastAPI() @app.get("/") async def read_root(): return {"Hello": "World"} @app.middleware("http") async def middleware1(request, call_next): print("中间件-1: 开始处理请求.") response = await call_next(request) print("中间件-1: 请求处理完成.") return response @app.middleware("http") async def middleware2(request, call_next): print("中间件-2: 开始处理请求.") response = await call_next(request) print("中间件-2: 请求处理完成.") return response ``` 调用接口后,返回 json 数据 ```json { "Hello": "World" } ``` 并且 vscode 终端打印结果: ```json 中间件-2: 开始处理请求. 中间件-1: 开始处理请求. 中间件-1: 请求处理完成. 中间件-2: 请求处理完成. ``` ## 7. 依赖注入 ### 7.1 定义 * 作用:使用依赖注入系统来共享通用逻辑,减少代码重复 * 依赖项:可重用的组件(函数/类),负责提供某种功能或数据 * 注入:FastAPI 自动帮你调用依赖项,并将结果"注入"到路径操作函数中 * 使用场景:处理请求参数,共享业务逻辑,共享数据库连接,安全和认证 ### 7.2 使用 完整代码: ```python from fastapi import Depends, FastAPI, Query app = FastAPI() # 依赖项:公共分页 async def common_page_and_size( page: int = Query(1, ge=1, description="当前页码,必须大于等于1"), size: int = Query(10, ge=1, le=100, description="每页条数必须在1-100之间"), ): return {"msg": f"这是查询用户列表的接口, 当前为{page}页, 每页条数为{size}"} @app.get("/users/user_list") async def get_user_list(pagination: dict = Depends(common_page_and_size)): return pagination ``` ## 8. ORM ### 8.1 定义 ORM(Object-RelationalMapping,对象关系映射) 是一种编程技术,用于在面向对象编程语言和关系型数据库之间建立映射。它允许开发者通过操作对象的方式与数据库进行交互 ,而无需直接编写复杂的 SQL 语句 ORM 工具有:SQLALchemy ORM,Django ORM,Tortoise ORM 具体的操作以及如何连接数据库,放在下一篇文章来写吧,如果有人看的话

相关推荐
Rockbean2 小时前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek
曲幽3 小时前
FastAPI + Ollama 实战:搭一个能查天气的AI助手
python·ai·lora·torch·fastapi·web·model·ollama·weatherapi
用户60648767188964 小时前
国内开发者如何接入 Claude API?中转站方案实战指南(Python/Node.js 完整示例)
人工智能·python·api
只与明月听4 小时前
RAG深入学习之Chunk
前端·人工智能·python
用户8356290780516 小时前
自动化文档处理:Python 批量提取 PDF 图片
后端·python
多恩Stone1 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ4022054961 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
百锦再1 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
QQ5110082851 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php