更大的应用 - 多个文件

假设文件结构如下:
在这里插入图片描述

.
├── app                  # 「app」是一个 Python 包
│   ├── __init__.py      # 这个文件使「app」成为一个 Python 包
│   ├── main.py          # 「main」模块,例如 import app.main
│   ├── dependencies.py  # 「dependencies」模块,例如 import app.dependencies
│   └── routers          # 「routers」是一个「Python 子包」
│   │   ├── __init__.py  # 使「routers」成为一个「Python 子包」
│   │   ├── items.py     # 「items」子模块,例如 import app.routers.items
│   │   └── users.py     # 「users」子模块,例如 import app.routers.users
│   └── internal         # 「internal」是一个「Python 子包」
│       ├── __init__.py  # 使「internal」成为一个「Python 子包」
│       └── admin.py     # 「admin」子模块,例如 import app.internal.admin

APIRouter

假设专门用于处理用户逻辑的文件是位于 /app/routers/users.py 的子模块

你可以使用 APIRouter 为该模块创建路径操作。

然后你可以使用它来声明路径操作。

from fastapi import APIRouterrouter = APIRouter()@router.get("/users")
async def read_users():return [{"username": "Rick"}, {"username": "Morty"}]@router.get("/users/me", tags=["users"])
async def read_user_me():return {"username": "fakecurrentuser"}@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):return {"username": username}

依赖项

我们将需要一些在应用程序的好几个地方所使用的依赖项。因此,我们将它们放在它们自己的 dependencies 模块(app/dependencies.py)中

from fastapi import Header, HTTPExceptionasync def get_token_header(x_token: str = Header()):if x_token != "fake-super-secret-token":raise HTTPException(status_code=400, detail="X-Token header invalid")async def get_query_token(token: str):if token != "jessica":raise HTTPException(status_code=400, detail="No Jessica token provided")

其他使用 APIRouter 的模块

假设你在位于 app/routers/items.py 的模块中还有专门用于处理应用程序中「item」的端点。

我们知道此模块中的所有路径操作都有相同的:

  • 路径 prefix:/items。
  • tags:(仅有一个 items 标签)。
  • 额外的 responses。
  • dependencies:它们都需要我们创建的 X-Token 依赖项。

因此,我们可以将其添加到 APIRouter 中,而不是将其添加到每个路径操作中

我们还可以添加一个 tags 列表和额外的 responses 列表,这些参数将应用于此路由器中包含的所有路径操作。

我们可以添加一个 dependencies 列表,这些依赖项将被添加到路由器中的所有路径操作中,并将针对向它们发起的每个请求执行/解决。

我们仍然可以添加更多将会应用于特定的路径操作的 tags,以及一些特定于该路径操作的额外 responses

from fastapi import APIRouter, Depends, HTTPExceptionfrom ..dependencies import get_token_headerrouter = APIRouter(prefix="/items",tags=["items"],dependencies=[Depends(get_token_header)],responses={404: {"description": "Not found"}}, # 当 API 端点可能返回 404 错误时,在文档中显示 "Not found" 的描述
)fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}@router.get("/")
async def read_items():return fake_items_db@router.get("/{item_id}")
async def read_item(item_id: str):if item_id not in fake_items_db:raise HTTPException(status_code=404, detail="Item not found")return {"name": fake_items_db[item_id]["name"], "item_id": item_id}@router.put("/{item_id}", tags=["custom"], responses={403: {"description": "Operation forbidden"}})
async def update_item(item_id: str):if item_id != "plumbus":raise HTTPException(status_code=403, detail="You can only update the plumbus")return {"item_id": item_id, "name": "The Great Plumbus"}

FastAPI 主体

from fastapi import Depends, FastAPIfrom .dependencies import get_query_token, get_token_header
from .routers import items, users
from .internal import adminapp = FastAPI(dependencies=[Depends(get_query_token)]) # 声明全局依赖# 加入路由
app.include_router(users.router)
app.include_router(items.router)
app.include_router(admin.router,prefix="/admin",tags=["admin"],dependencies=[Depends(get_token_header)],responses={418: {"description": "I'm a teapot"}},  # 示例响应
)@app.get("/")
async def root():return {"message": "Hello World"}

假设你的组织为你提供了 app/internal/admin.py 文件。

它包含一个带有一些由你的组织在多个项目之间共享的管理员路径操作的 APIRouter。

对于此示例,它将非常简单。但是假设由于它是与组织中的其他项目所共享的,因此我们无法对其进行修改,以及直接在 APIRouter 中添加 prefix、dependencies、tags 等

可是我们仍然希望在包含 APIRouter 时设置一个自定义的 prefix,以便其所有路径操作以 /admin 开头,我们希望使用本项目已经有的 dependencies 保护它,并且我们希望它包含自定义的 tags 和 responses。

我们可以通过将这些参数传递给 app.include_router() 来完成所有的声明,而不必修改原始的 APIRouter

查看自动化的 API 文档

现在,使用 app.main 模块和 app 变量运行 uvicorn
在这里插入图片描述

后台任务

你可以定义在返回响应后运行的后台任务。

这对需要在请求之后执行的操作很有用,但客户端不必在接收响应之前等待操作完成。

使用 BackgroundTasks

创建要作为后台任务运行的函数。

它只是一个可以接收参数的标准函数。

它可以是 async def 或普通的 def 函数,FastAPI 知道如何正确处理。

然后在你的 路径操作函数 里,用 .add_task() 方法将任务函数传到 后台任务 对象中

from email import message
from fastapi import BackgroundTasks, FastAPIapp = FastAPI()def write_notification(email: str, message = ""):with open("log.txt", mode="w") as email_file:content = f"notification for {email} with message: {message}\n" email_file.write(content)@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks):background_tasks.add_task(write_notification,email, message="some notification")return {"message": "Notification sent in the background"}

依赖注入

使用 BackgroundTasks 也适用于依赖注入系统,你可以在多个级别声明 BackgroundTasks 类型的参数:在 路径操作函数 里,在依赖中(可依赖),在子依赖中,等等。

from tkinter import NO
from typing import Annotatedfrom fastapi import BackgroundTasks, Depends, FastAPIapp = FastAPI()def write_log(message: str):with open("log.txt", mode="a") as log:log.write(message)def get_query(background_tasks: BackgroundTasks, q: str | None = None):if q:message = f"found query: {q}\n"background_tasks.add_task(write_log, message)return q@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks, q: Annotated[str, Depends(get_query)]
):message = f"message to {email}\n"background_tasks.add_task(write_log, message)return {"message": "Message sent"}

运行程序,此时设置q为3
在这里插入图片描述

元数据和文档 URL

API 元数据

你可以在设置 OpenAPI 规范和自动 API 文档 UI 中使用的以下字段:
在这里插入图片描述

from fastapi import FastAPIdescription = """
ChimichangApp API helps you do awesome stuff. 🚀## ItemsYou can **read items**.## UsersYou will be able to:* **Create users** (_not implemented_).
* **Read users** (_not implemented_).
"""app = FastAPI(title="ChimichangApp API",description=description,summary="Deadpool's favorite app. Nuff said.",version="0.0.1",terms_of_service="http://example.com/terms/",contact={"name": "Deadpoolio the Amazing","url": "http://x-force.example.com/contact/","email": "dp@x-force.example.com",},license_info={"name": "Apache 2.0","url": "https://www.apache.org/licenses/LICENSE-2.0.html",},
)@app.get("/items/")
async def read_items():return [{"name": "Katana"}]

运行程序,查看API文档
在这里插入图片描述

标签元数据

创建标签元数据并把它传递给 openapi_tags 参数,将 tags 参数和路径操作(以及 APIRouter)一起使用,将其分配给不同的标签:

from fastapi import FastAPItags_metadata = [{"name": "users","description": "Operations with users. The **login** logic is also here.",},{"name": "items","description": "Manage items. So _fancy_ they have their own docs.","externalDocs": {"description": "Items external docs","url": "https://fastapi.tiangolo.com/",},},
]app = FastAPI(openapi_tags=tags_metadata)@app.get("/users/", tags=["users"])
async def get_users():return [{"name": "Harry"}, {"name": "Ron"}]@app.get("/items/", tags=["items"])
async def get_items():return [{"name": "wand"}, {"name": "flying broom"}]

运行程序,打开docs文档
在这里插入图片描述
每个标签元数据字典的顺序也定义了在文档用户界面显示的顺序。

例如按照字母顺序,即使 users 排在 items 之后,它也会显示在前面,因为我们将它的元数据添加为列表内的第一个字典。

文档 URLs

你可以配置两个文档用户界面,包括:

  • Swagger UI:服务于 /docs。
    • 可以使用参数 docs_url 设置它的 URL。
    • 可以通过设置 docs_url=None 禁用它。
  • ReDoc:服务于 /redoc。
    • 可以使用参数 redoc_url 设置它的 URL。
    • 可以通过设置 redoc_url=None 禁用它。
from fastapi import FastAPIapp = FastAPI(docs_url="/documentation", redoc_url=None)@app.get("/items/")
async def read_items():return [{"name": "Foo"}]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917880.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917880.shtml
英文地址,请注明出处:http://en.pswp.cn/news/917880.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个示例mcp agent功能的交互式框架

https://github.com/whym3/Deepseek_MCPDeepseek_MCP https://github.com/whym3/Deepseek_MCP Deepseek_MCP是一个演示mcp agent的框架,基于Flask开发,支持在浏览器采用交互方式与deepseek及agent对话。需要注册外部Deepseek api,不支持本地…

nodejs 基础知识-2

模块的暴露和导入 编写date.js module.exports.echo 导出的名称 module.exports.echo function echo(){ return Date.now(); } 编写 index.js const echoDate require(‘./date.js’) 在index引入 console.log(echoDate.echo()); //调用 开发一个自定义模块 exports.forma…

递归推理树(RR-Tree)系统:构建认知推理的骨架结构

探索基于三维评估的动态推理系统如何实现智能决策与知识演化引言 在复杂问题求解领域(如战略决策或科学探索),人类思维的递归本质为AI系统设计提供了重要启发。我设计并实现的递归推理树(Recursive Reasoning Tree, RR-Tree&#…

《动手学深度学习》读书笔记—9.5机器翻译与数据集

本文记录了自己在阅读《动手学深度学习》时的一些思考,仅用来作为作者本人的学习笔记,不存在商业用途。 语言模型是自然语言处理的关键, 而机器翻译是语言模型最成功的基准测试。 因为机器翻译正是将输入序列转换成输出序列的 序列转换模型&a…

Mysql进行操作时锁的具体行为

场景一:单个事务更新一条存在的数据 假设有表 user (id PK, name, age),数据:[id1, nameAlice, age25] 你的 SQL: UPDATE user SET age 26 WHERE id 1; 底层动作: 事务 A (主动方) 发起更新请求。Lock Manager 介入&…

人工智能领域、图欧科技、IMYAI智能助手2025年7月更新月报

IMYAI 平台 2025 年 7 月重要功能更新与优化汇总 2025年07月31日更新 细节优化: 修复了移动端提交后自动弹出侧边栏的BUG。优化对话高级配置界面,增加滚动条并固定高度,避免内容超出屏幕。音乐生成界面的人声选择新增“合唱”选项&#xff…

HTTP 与 HTTPS 的区别深度解析:从原理到实践

HTTP 和 HTTPS 是现代 Web 开发中不可或缺的协议,它们决定了浏览器与服务器之间数据传输的方式。HTTPS 作为 HTTP 的安全版本,在安全性、性能和用户体验上都有显著提升。本文将通过万字篇幅,结合图表和代码示例,详细剖析 HTTP 与 …

STM32F407VET6学习笔记11:smallmodbus_(多从机)创建新的slave从机

今日记录一些smallmodbus 创建新的slave 从机 的过程,以及使用的关键点. 目录 创建新的从机对应操作函数与buffer 创建新的从机线程与操作代码: slave使用的要点: 完整的slave代码: 能正常通信: 创建新的从机对应操作函…

【论文阅读】Transformer Feed-Forward Layers Are Key-Value Memories

Transformer Feed-Forward Layers Are Key-Value Memories 原文摘要 研究背景与问题: 前馈层占Transformer模型参数总量的2/3,但其功能机制尚未得到充分研究 核心发现:提出前馈层实质上是键值存储系统 键:这里的键与训练数据中出…

昇思+昇腾开发板:DeepSeek-R1-Distill-Qwen-1.5B 模型推理部署与 JIT 优化实践

目录 引言 模型推理部署 环境准备 安装 MindSpore 查看当前 mindspore 版本 安装 MindNLP 模型与分词器加载 导入必要的库 加载分词器 加载模型 对话功能实现 设置系统提示词 构建对话历史输入 推理函数实现 交互界面实现 推理JIT优化 基础环境安装 JIT 优化配置…

用phpstudy安装php8.2后报错:意思是找不到php_redis.dll拓展时

1.地址:https://pecl.php.net/package/redis/6.2.0/windows 2.下载3.解压后复制php_redis.dll到phpstudy_pro\Extensions\php\php8.2.9nts\ext目录 4.打开php.ini,加上 extension_dir “D:\software\phpstudy_pro\Extensions\php\php8.2.9nts\ext”

开源列式分布式数据库clickhouse

这里写自定义目录标题开源列式OLAP数据库clickhouseclickhouse使用 ClickHouse 的场景如何理解行式存储和列式存储clickhouse-go开源列式OLAP数据库clickhouse OLAP (分析型):专为快速扫描、聚合、分析海量数据设计。OLTP (事务型):专为处理大量短事务&…

Java Stream API 详解(Java 8+)

1. Stream 操作分类Stream 操作分为两类:中间操作(Intermediate Operations)返回新的 Stream,可以链式调用(如 filter, map, sorted, distinct)。惰性求值:只有遇到终止操作时才会执行。终止操作…

「源力觉醒 创作者计划」_文心大模型4.5系列开源模型, 从一行代码到一个生态:聊聊开源战略那些事儿,顺便扯扯文心大模型 4.5 的使用心得

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录从一行…

算法专题(二)回文链表

1、源代码class Solution {public boolean isPalindrome(ListNode head) {ListNode fasthead,slowhead; //快慢指针都在头结点//快指针走2步,慢指针走一步。//双数快指针最后是null,单数快指针下一位是nullwhile(fast!null && fast.next!null){f…

2025《艾诺提亚失落之歌》逆向工程解包尝试

前言 想开发一下光明之魂,看能不能解包《艾诺提亚失落之歌》的模型。 之前写了(https://blog.csdn.net/weixin_42875245/article/details/148616547?spm1001.2014.3001.5501) 沿用这个思路进行逆向工程解包。 文章目录请添加图片描述前言…

JVM 03 类加载机制

JVM 将字节码二进制流加载到内存称为类加载。 什么时候加载类 new 实例化对象。而对象所属类还没被加载。读取/设置类的静态非常量字段,常量字段在常量池。调用类的静态方法。类初始化,优先初始化父类。虚拟机启动时,先加载用户指定的主类。 …

STM32H7+FreeRTOS+LwIP移植EtherCAT开源主站SOEM

代码下载什么的就不多说了,直接看需要移植修改的代码。 1、osal.c修改 /******************************************************************************* * *** **** *** *** …

VijosOJ:中文信息学竞赛的二十年开源之路

VijosOJ:中文信息学竞赛领域的老牌开源在线判题系统 在中文编程教育与信息学竞赛的发展历程中,在线判题系统(OJ)扮演了至关重要的角色。它们不仅是选手训练的 “战场”,更是知识传递与社区交流的枢纽。VijosOJ&#x…

QPainter::CompositionMode解析

基本概念目标(Destination):已经存在的像素。源(Source):要绘制的新像素。组合模式:决定源和目标如何混合。总结SourceOver:源绘制在目标之上。DestinationOver:目标绘制在源之上。Clear:二者重叠区域被清空…