FastAPI教程III

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial
这部分暂无需求的没有记录,仅放置标题。

依赖项

安全性

中间件

你可以向FastAPI应用添加中间件。

”中间件“是一个函数,它在每个请求被特定的路径操作处理之前,以及在每个响应返回之前工作。

  • 它接收你的应用程序的每一个请求
  • 然后它可以对这个请求做一些事情或者执行任何需要的代码。
  • 然后它将请求传递给应用程序的其他部分(通过某种路径操作)。
  • 然后它获取应用程序生产的响应(通过某种路径操作)。
  • 它可以对该响应做些什么或者执行任何需要的代码。
  • 然后它返回这个响应

创建中间件

要创建中间件你可以在函数的顶部使用装饰器@app.middleware("http")

中间件参数接收如下参数:

  • request
  • 一个函数call_next,它将接收request作为参数。
  • 这个函数将request传递给相应的路径操作。
  • 然后它将返回由相应的路径操作生成的response
  • 然后你可以在返回response前进一步修改它。
import timefrom fastapi import FastAPI, Requestapp = FastAPI()@app.middleware("http")
async def add_process_time_header(request: Request, call_next):start_time = time.time()response = await call_next(request)process_time = time.time() - start_timeresponse.headers["X-Process-Time"] = str(process_time)return response

在这里插入图片描述

response的前和后

在任何路径操作收到request前,可以添加要和请求一起运行的代码。

也可以在响应生成但是返回之前添加代码。

例如你可以添加自定义请求头X-Process-Time包含以秒为单位的接收请求和生成响应的时间。

import timefrom fastapi import FastAPI, Requestapp = FastAPI()@app.middleware("http")
async def add_process_time_header(request: Request, call_next):start_time = time.time()response = await call_next(request)process_time = time.time() - start_timeresponse.headers["X-Process-Time"] = str(process_time)return response

其他中间件

可以在Advanced User Guide: Advanced Middleware关于中间件的教程。

下一节中会学习如何使用中间件处理CORS。

CORS(跨域资源共享)

CORS或者跨域资源共享指浏览器中运行的前端拥有与后端通信的JavaScript代码,而后端处于与前端不同的【源】的情况。

源是协议(httphttps)、域(myapp.comlocalhostlocalhost.tiangolo.com)以及端口(804438080)的组合。

因此,这些都是不同的源:

  • http://localhost
  • https://localhost
  • http://localhost:8000

即使它们都在localhost中,但是它们使用不同的协议或者端口,所以它们都是不同的[源]。

步骤

假设你的浏览器中有一个前端运行在http://localhost:8080,并且它的JavaScript正在尝试与运行在http://localhost的后端通信(因为我们没有指定端口,浏览器会采用默认的端口80)。

然后,浏览器会向后端发送一个HTTPOPTIONS请求,如果后端发送适当的headers来授权来自这个不同源(http://localhost:8080)的通信,浏览器将允许前端的JavaScript向后端发送请求。

为此,后端必须有一个【允许的源】列表。

在这种情况下,它必须包含http://localhost:8080,前端才能正常工作。

通配符

也可以使用"*"声明这个列表,表示全部都是允许的。

但这仅允许某些类型的通信,不包括所有涉及凭据的内容:像Cookies以及那些使用Bearer令牌的授权headers等。

因此,为了一切都能正常工作,最好显式地指定允许的源。

使用CORSMiddleware

你可以在FastAPI应用中使用CORSMiddleware来配置它。

  • 导入CORSMiddleware
  • 创建一个允许的源列表(由字符串组成)。
  • 将其作为【中间件】添加到你的FastAPI应用中。

你也可以指定后端是否允许:

  • 凭证(授权headers,Cookies)等
  • 特定的HTTP方法(POSTPUT)或者使用通配符"*"允许所有方法。
  • 特定的HTTP headers或者使用通配符"*"允许所有headers。
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddlewareapp = FastAPI()origins = ["http://localhost.tiangolo.com","https://localhost.tiangolo.com","http://localhost","http://localhost:8080",
]app.add_middleware(CORSMiddleware,allow_origins=origins,allow_credentials=True,allow_methods=["*"],allow_headers=["*"],
)@app.get("/")
async def main():return {"message": "Hello World"}

默认情况下,这个CORSMiddleware实现所使用地默认参数较为保守,所以你需要显式地启用特定的源、方法或者headers,以便浏览器能够在跨域上下文中使用它们。

支持一下参数:

  • allow_origins-一个允许跨域请求的源列表。例如['https://example.org', 'https://www.example.org']。你可以使用 ['*'] 允许任何源。
  • allow_origin_regex - 一个正则表达式字符串,匹配的源允许跨域请求。例如 'https://.*\.example\.org'
  • allow_methods - 一个允许跨域请求的 HTTP 方法列表。默认为 ['GET']。你可以使用 ['*'] 来允许所有标准方法。
  • allow_headers - 一个允许跨域请求的 HTTP 请求头列表。默认为 []。你可以使用 ['*'] 允许所有的请求头。AcceptAccept-LanguageContent-Language 以及 Content-Type 请求头总是允许 CORS 请求。
  • allow_credentials - 指示跨域请求支持 cookies。默认是 False。另外,允许凭证时 allow_origins 不能设定为 ['*'],必须指定源。
  • expose_headers - 指示可以被浏览器访问的响应头。默认为 []
  • max_age - 设定浏览器缓存 CORS 响应的最长时间,单位是秒。默认为 600。

中间件响应两种特定类型的 HTTP 请求……

CORS 预检请求

这是些带有 OriginAccess-Control-Request-Method 请求头的 OPTIONS 请求。

在这种情况下,中间件将拦截传入的请求并进行响应,出于提供信息的目的返回一个使用了适当的 CORS headers 的 200400 响应。

简单请求

任何带有 Origin 请求头的请求。在这种情况下,中间件将像平常一样传递请求,但是在响应中包含适当的 CORS headers。

更多信息

更多关于CORS的信息,请查看Mozilla CORS文档。

SQL(关系型)数据库

更大的应用-多个文件

后台任务

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

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

包括这些例子:

  • 执行操作后发送的电子邮件通知:
    • 由于连接到电子邮件服务器并发送电子邮件往往很”慢“(几秒钟),您可以立即返回响应并在后台发送电子邮件通知。
  • 处理数据:
    • 例如,假设您收到的文件必须经过一个缓慢的过程,您可以返回一个”Accepted“(HTTP 202)响应并在后台处理它。

使用BackgroundTasks

首先导入BackgroundTasks并在路径操作函数中使用类型声明BackgroundTasks定义一个参数,FastAPI会创建一个BackgroundTasks类型的对象并作为该参数传入。

创建一个任务函数,创建要作为后台任务运行的函数。它只是一个可以接收参数的标准函数。它可以是async def或普通的def函数,FastAPI知道如何正确处理。在这种情况下,任务函数将写入一个文件(模拟发送电子邮件)。由于写操作不使用asyncawait,我们用普通的def定义函数。

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

.add_task()接收以下参数:

  • 在后台运行的任务函数(write_notification)。
  • 应按顺序传递给任务函数的任意参数序列(email)。
  • 应传递给任务函数的任意关键字参数(message="some notification")。
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}: {message}"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类型的参数:在路径操作函数里,在依赖中(可依赖),在子依赖中,等等。

FastAPI知道在每种情况下该做什么以及如何复用同一对象,因此所有后台任务被合并在一起并且随后在后台运行。

from typing import Annotated, Unionfrom 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: Union[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"}

该示例中,信息会在响应发出之后被写到log.txt文件。

如果请求中有查询,它将在后台任务中写入日志。

然后另一个在路径操作函数生成的后台任务会使用路径参数email写入一条信息。
在这里插入图片描述

元数据和文档URL

静态文件

测试

感谢 Starlette,测试FastAPI 应用轻松又愉快。

它基于 HTTPX, 而HTTPX又是基于Requests设计的,所以很相似且易懂。

有了它,你可以直接与FastAPI一起使用 pytest。

使用TestClient

要使用TestClient,先要安装httpx(例pip install httpx

  • 导入TestClient
  • 通过传入你的FastAPI应用创建一个TestClient
  • 创建名字以test_开头的函数(这是标准的pytest约定)。
  • 像使用httpx那样使用TestClient对象。
  • 为你需要检查的地方用标准的Python表达式写个简单的assert语句(重申,标准的pytest)。
from fastapi import FastAPI
from fastapi.testclient import TestClientapp = FastAPI()@app.get("/")
async def read_main():return {"msg": "Hello World"}client = TestClient(app)def test_read_main():response = client.get("/")assert response.status_code == 200assert response.json() == {"msg": "Hello World"}

在这里插入图片描述

分离测试

在实际应用中,你可能会把你的测试放在另一个文件里。

您的FastAPI应用程序也可能由一些文件/模块组成等等。

FastAPI app文件

假设你有一个像更大的应用中所描述的文件结构:

.
├── app
│   ├── __init__.py
│   └── main.py

main.py文件中你有一个FastAPI app:

from fastapi import FastAPIapp = FastAPI()@app.get("/")
async def read_main():return {"msg": "Hello World"}

测试文件

然后你会有一个包含测试的文件test_main.py。app可以像Python包那样存在(一样是目录,但有个__init__.py文件):

.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py

因为这文件在同一个包中,所以你可以通过相对导入从main模块(main.py)导入app对象:

from fastapi.testclient import TestClientfrom .main import appclient = TestClient(app)def test_read_main():response = client.get("/")assert response.status_code == 200assert response.json() == {"msg": "Hello World"}

然后测试代码和之前一样的。

测试:扩展示例

现在让我们扩展这个例子,并添加更多细节,看下如何测试不同部分。

扩展后的FastAPI app文件

让我们继续之前的文件结构:

.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py

假设现在包含FastAPI app的文件main.py有些其他路径操作。

有个GET操作会返回错误。

有个POST操作会返回一些错误。

所有路径操作都需要一个X-Token头。

from typing import Annotatedfrom fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModelfake_secret_token = "coneofsilence"fake_db = {"foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"},"bar": {"id": "bar", "title": "Bar", "description": "The bartenders"},
}app = FastAPI()class Item(BaseModel):id: strtitle: strdescription: str | None = None@app.get("/items/{item_id}", response_model=Item)
async def read_main(item_id: str, x_token: Annotated[str, Header()]):if x_token != fake_secret_token:raise HTTPException(status_code=400, detail="Invalid X-Token header")if item_id not in fake_db:raise HTTPException(status_code=404, detail="Item not found")return fake_db[item_id]@app.post("/items/", response_model=Item)
async def create_item(item: Item, x_token: Annotated[str, Header()]):if x_token != fake_secret_token:raise HTTPException(status_code=400, detail="Invalid X-Token header")if item.id in fake_db:raise HTTPException(status_code=400, detail="Item already exists")fake_db[item.id] = itemreturn item

扩展后的测试文件

然后您可以使用扩展后的测试更新test_main.py

from fastapi.testclient import TestClientfrom .main import appclient = TestClient(app)def test_read_item():response = client.get("/items/foo", headers={"X-Token": "coneofsilence"})assert response.status_code == 200assert response.json() == {"id": "foo","title": "Foo","description": "There goes my hero",}def test_read_item_bad_token():response = client.get("/items/foo", headers={"X-Token": "hailhydra"})assert response.status_code == 400assert response.json() == {"detail": "Invalid X-Token header"}def test_read_nonexistent_item():response = client.get("/items/baz", headers={"X-Token": "coneofsilence"})assert response.status_code == 404assert response.json() == {"detail": "Item not found"}def test_create_item():response = client.post("/items/",headers={"X-Token": "coneofsilence"},json={"id": "foobar", "title": "Foo Bar", "description": "The Foo Barters"},)assert response.status_code == 200assert response.json() == {"id": "foobar","title": "Foo Bar","description": "The Foo Barters",}def test_create_item_bad_token():response = client.post("/items/",headers={"X-Token": "hailhydra"},json={"id": "bazz", "title": "Bazz", "description": "Drop the bazz"},)assert response.status_code == 400assert response.json() == {"detail": "Invalid X-Token header"}def test_create_existing_item():response = client.post("/items/",headers={"X-Token": "coneofsilence"},json={"id": "foo","title": "The Foo ID Stealers","description": "There goes my stealer",},)assert response.status_code == 409assert response.json() == {"detail": "Item already exists"}

每当你需要客户端在请求中传递信息,但你不知道如何传递时,你可以通过搜索(谷歌)如何用httpx做,或者是用requests做,毕竟HTTPX的设计是基于Requests的设计的。

接着只需在测试中同样操作。

示例:

  • 传一个路径或查询参数,添加到URL上。
  • 传一个JSON体,传一个Python对象(例如一个dict)到参数json
  • 如果你需要发送Form Data而不是JSON,使用data参数。
  • 要发送headers,传dictheaders参数。
  • 对于cookies,传dictcookies参数。

关于如何传数据给后端的更多信息(使用httpxTestClient),请查阅HTTPX文档。

运行起来

之后,你只需要安装pytest,他会自动检测文件和测试,执行测试,然后向你报告结果。

调试

你可以在编辑器中连接调试器,例如使用Visual Studio Code或PyCharm。

调用uvicorn

在你的FastAPI应用中直接导入uvicorn并运行:

import uvicorn
from fastapi import FastAPIapp = FastAPI()@app.get("/")
def root():a = "a"b = "b" + areturn {"hello world": b}if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)

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

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

相关文章

PyCharm 2024.1 版本更新亮点:智能编程,高效协作

目录 1. 前言2. 更新内容2.1 智能编码体验2.1.1 Hugging Face 文档预览2.1.2 全行代码补全 2.2 提升编辑器体验2.2.1 粘性行功能2.2.2 编辑器内代码审查 2.3 全新终端体验(测试版)2.3.1 新终端 Beta 2.4 智能助手(特定版本和专业用户&#xf…

短视频矩阵系统:打造品牌影响力的新方式

一、短视频矩阵概念 短视频营销革命:一站式解决策略!短视频矩阵系统是一款专为企业营销设计的高效工具,旨在通过整合和优化众多短视频平台资源,为企业呈现一个全面的短视频营销策略。该系统致力于协助企业以迅速且高效的方式制作…

小白学webgl合集-WebGL中给图片添加背景

一.实现效果 二.逻辑 为了在WebGL中给图片添加背景&#xff0c;主要的逻辑步骤包括初始化WebGL上下文、编写和编译着色器、创建和绑定缓冲区、加载和配置纹理以及绘制场景。以下是代码逻辑的详细说明&#xff1a; 1. 获取WebGL上下文 首先&#xff0c;通过获取<canvas>…

WEB与低代码:B/S架构在开发中的应用与优势

在互联网迅猛发展的今天&#xff0c;WEB应用已经成为人们日常生活和工作中不可或缺的一部分。随着技术的进步和需求的多样化&#xff0c;开发高效、灵活且易于维护的WEB应用变得尤为重要。B/S架构&#xff08;Browser/Server Architecture&#xff09;作为一种常见的WEB应用架构…

天天生鲜数据库设计

目录 1、用户表2、商品表SKU和SPU的概念区分3、商品表改进4、redis实现购物车模块&#xff0c;redis保存用户最近浏览记录5、订单表 设计表时&#xff0c;出现一对多的情况&#xff0c;可以将对应的“多”单独拿出来重新设计一个表 1、用户表 &#xff08;灰色的部分不存在表…

MySQL之如何处理超大分页

如何处理MySQL超发分页&#xff1f; 可以使用覆盖索引解决 【点击进入】 MySQL超大分页处理 在数据量较大时&#xff0c;如果使用limit分页查询&#xff0c;在查询时&#xff0c;越往后&#xff0c;分页查询效率会越低。 示例&#xff1a; select * from user limit 900000…

仓库管理系统带万字文档基于spingboot vue的前后端分离仓库管理系统java项目java课程设计java毕业设计

文章目录 仓库管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档&#xff08;9.9&#xffe5;带走&#xff09; 仓库管理系统 一、项目演示 仓库管理系统 二、项目介绍 基于spingboot和vue的前后端分离仓库管…

华测视频RTK,AR实景导航

华测导航视频测量RTK技术,通过融合卫星导航、惯导与视频摄影测量算法,让“所见即所测”成为现实,让测量工作变得更加智能、高效。 视频测量RTK:智能测绘的新里程碑 华测RTK的性能和广泛应用,在市场中获得了用户的认可,平均每10位用户中即有6位推荐。其视频测量功能通过引入自动…

如何用GPT开发一个基于 GPT 的应用?

原文发自博客&#xff1a;GPT应用开发小记 如何开发一个基于 GPT 的应用&#xff1f;答案就在问题里&#xff0c;那就是用 GPT 来开发基于 GPT 的应用。本文以笔者的一个开源项目 myGPTReader 为例&#xff0c;分享我是如何基于 GPT 去开发这个系统的&#xff0c;这个系统的功能…

【Django】网上蛋糕项目商城-关键字搜索,商品详情功能

概念 上文中已经实现热销和新品的商品列表功能&#xff0c;本文篇幅中实现关键字搜索商品&#xff0c;将商品加入购物车&#xff0c;以及查看商品的详情信息等功能 关键字搜索实现步骤 在head.html头部页面中&#xff0c;鼠标移动至搜索图标会显示隐藏的搜索框进行输入关键信…

吉利银河L6(官方小订送的3M) 对比 威固vk70+ks15

吉利送的号称价值2000的3M效果 撕膜重贴 威固vk70ks15 之后的效果 // 忘记测反射的热量了 可以验证金属膜是反射热而不是吸热 金属膜 手机GPS还能用吗 亲测 能用 太阳能总阻隔率 3M貌似20%出头 威固前档55% 侧后挡高一点不超过60% 夏天真实太阳发热能量 即阻隔率55%到60% …

使用Visual Studio Code记笔记

因为学习需要&#xff0c;记笔记是很有必要的&#xff0c;平常发CSDN&#xff08;都让CSDN是很棒的哈&#xff09;&#xff0c;后来使用VS Code的时候发现了很多插件&#xff0c;觉得做笔记还是相对不错的&#xff0c;主要用到的还是Markdown 主要设计的插件包括&#xff1a; …

PL/SQL入门到实践

一、什么是PL/SQL PL/SQL是Procedural Language/Structured Query Language的缩写。PL/SQL是一种过程化编程语言&#xff0c;运行于服务器端的编程语言。PL/SQL是对SQL语言的扩展。PL/SQL结合了SQL语句和过程性编程语言的特性&#xff0c;可以用于编写存储过程、触发器、函数等…

Hallo:分级音频驱动视觉合成肖像动画

团队&#xff1a;百度&#xff08;王井东大佬&#xff09;&#xff0c;复旦&#xff0c;瑞士ETH&#xff0c;南大 文章目录 概要介绍相关工作整体架构流程技术名词解释层次音频驱动的视觉合成训练和推理训练实验设置讨论社会风险和缓解措施小结 概要 肖像图像动画领域&#x…

如何修改PDF文档的作者名称?

要修改一个 PDF 文档的作者名称&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. **使用 Adobe Acrobat**&#xff08;如果有&#xff09;&#xff1a; - Adobe Acrobat 是一个功能强大的 PDF 编辑工具&#xff0c;支持修改文档属性信息&#xff0c;包括作者名称。打开…

一个用于自动复制文本的小工具:Auto_Copy

自动复制工具 这是一个在 Windows 上用于自动复制选中文本到剪贴板的小工具。该工具还允许通过右键单击粘贴剪贴板内容。 灵感来源: 在使用Mobaxterm时,我注意到其软件中具备选中即自动复制和右键直接粘贴的功能。但是,这种选中自动复制的功能仅在软件内部有效。由于这一功能…

什么是无头浏览器?

简而言之&#xff0c;无头浏览器是没有图形用户界面 &#xff08;GUI&#xff09; 的 Web 浏览器。GUI 包括用户与之交互的数字元素&#xff0c;例如按钮、图标和窗口。但是&#xff0c;关于无头浏览器&#xff0c;您需要了解的还有很多。 在本文中&#xff0c;您将了解什么是…

Go语言环境安装 第一个Go程序

Go下载地址 哪个能用用哪个。 https://go.dev/ https://golang.google.cn/&#xff08;Golang官网的官方镜像&#xff09; Windows 使用.msi安装包安装 下载msi文件 安装 双击运行go1.22.4.windows-amd64.msi Next 勾选I accept the terms in the License Agreement&…

Webpack: 持久化缓存大幅提升构建性能

概述 缓存是一种应用非常广泛性能优化技术&#xff0c;在计算机领域几乎无处不在&#xff0c;例如&#xff1a;操作系统层面 CPU 高速缓存、磁盘缓存&#xff0c;网路世界中的 DNS 缓存、HTTP 缓存&#xff0c;以及业务应用中的数据库缓存、分布式缓存等等。 那自然而然的&am…

路径规划 | 基于蜣螂优化算法的栅格地图机器人路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 路径规划 | 基于蜣螂优化算法的栅格地图机器人路径规划&#xff08;Matlab&#xff09; 1.利用蜣螂算法DBO优化栅格地图机器人路径规划&#xff0c;效果如图所示&#xff0c;包括迭代曲线图、栅格地图等等&#xff5e…