当前位置: 首页 > news >正文

FastAPI -- 第二弹(响应模型、状态码、路由APIRouter、后台任务BackgroundTasks)

响应模型

添加响应模型

from typing import Anyfrom fastapi import FastAPI
from pydantic import BaseModel, EmailStrapp = FastAPI()class UserIn(BaseModel):username: strpassword: stremail: EmailStrfull_name: str | None = Noneclass UserOut(BaseModel):username: stremail: EmailStrfull_name: str | None = None# 通过 response_model 设置返回模型
@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn) -> Any:return user

模型的其他操作

继承 & 解包

from fastapi import FastAPI
from pydantic import BaseModel, EmailStrapp = FastAPI()# 定义一个 Base
# 包含公共属性,比如 id create_time update_time 等
class UserBase(BaseModel):username: stremail: EmailStrfull_name: str | None = None# 继承 Base
class UserIn(UserBase):password: str# 继承 Base
class UserOut(UserBase):pass# 继承 Base
class UserInDB(UserBase):hashed_password: strdef fake_password_hasher(raw_password: str):return "supersecret" + raw_passworddef fake_save_user(user_in: UserIn):hashed_password = fake_password_hasher(user_in.password)# 解包# user_in = UserIn(username="john", password="secret", email="john.doe@example.com")# **user_in.dict() ==> #		username = user_dict["username"],#	    password = user_dict["password"],#	    email = user_dict["email"],#	    full_name = user_dict["full_name"], user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)print("User saved! ..not really")return user_in_db@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):user_saved = fake_save_user(user_in)return user_saved

组合模型 (Union & dict)

union

union:组合多个模型,但返回值只能是一个模型的实例

from typing import Unionfrom fastapi import FastAPI
from pydantic import BaseModelapp = FastAPI()class BaseItem(BaseModel):description: strtype: strclass CarItem(BaseItem):type: str = "car"class PlaneItem(BaseItem):type: str = "plane"size: intitems = {"item1": {"description": "All my friends drive a low rider", "type": "car"},"item2": {"description": "Music is my aeroplane, it's my aeroplane","type": "plane","size": 5,},"item3": [{"description": "item3_1 Music is my aeroplane, it's my aeroplane","type": "plane","size": 5,},{"description": "item3_2 Music is my aeroplane, it's my aeroplane","type": "plane","size": 5,},]
}# Union[PlaneItem, CarItem, list[PlaneItem]],。。。。]
# 允许返回 Union 的多种类型中的 一种
@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem,list[PlaneItem]])
async def read_item(item_id: str):return items[item_id]
dict

response_model=dict ,
response_model=dict[str, list] ,
response_model=list …

dict 有点类似于 any, 但又比 any 更具体一些
比如 any 可以是 list 也可以是 dict, 但 dict 只能是 dict 不能是 list
比如 dict 可以是 dict[str, list], dict[int, list] 等,但 dict[str, list] 只能是 dict[str, list]

from fastapi import FastAPIapp = FastAPI()# 测试 Any
@app.get("/test_any/")
async def read_keyword_weights():# return {"foo": 2.3, "bar": 3.4}return [1, 2, 3]# 测试 dict
@app.get("/test_dict/", response_model=dict)
async def read_keyword_weights():return {"foo": 2.3, "bar": [1, 2, 3]}# 测试 dict[str, float]
@app.get("/test_dict_str_float/", response_model=dict[str, float])
async def read_keyword_weights():return {"foo": 2.3, "bar": 3.4}# return {"foo": 2.3, "bar": [1, 2, 3]}

响应状态码

from enum import IntEnum
from http import HTTPStatusfrom fastapi import FastAPI, statusapp = FastAPI()# 通过 http模块的 HTTPStatus 类,
# 我们可以很方便的使用一些常见的状态码,如下
@app.get("/items/http_status", status_code=HTTPStatus.OK)
def test_status_code():return "hallow world HTTPStatus"# 通过 fastapi 的 status 模块,
# 我们可以很方便的使用一些常见的状态码,如下
@app.get("/items/status", status_code=status.HTTP_201_CREATED)
def test_status_code():return "hallow world status"# 也可以直接使用数字
@app.get("/items/num", status_code=201)
def test_status_code():return "hallow world num"

顺便记一下,可以仿照 HTTPStatus 的写法,自定义状态码。
注意:自定义状态码是放到 响应体 里的,放到 status_code 后面有可能会报错哦


# 自定义的状态码
class MyHTTPStatus(IntEnum):    def __new__(cls, value, phrase, description=''):obj = int.__new__(cls, value)obj._value_ = valueobj.phrase = phraseobj.description = descriptionreturn objCode200000 = 200000, 'OK', 'Request fulfilled, document follows'# client errorCode400000 = (400000, 'Bad Request','Bad request syntax or unsupported method')# 响应体示例
# {
#     "code": 200000,
#     "message": "OK",
#     "data": {
#         "name": "张三"
#     }
# }

From表单

from fastapi import FastAPI, Formapp = FastAPI()# 和 Boday Query 类似,Form 也是从 fastapi 导入
# username: str = Form()
@app.post("/login/")
async def login(username: str = Form(), password: str = Form()):return {"username": username}

上传文件 (File, UploadFile)

from fastapi import FastAPI, File, UploadFileapp = FastAPI()@app.post("/files/")
async def create_file(file: bytes = File()):return {"file_size": len(file)}# 和前面的可选参数类似,如果 file 是可选的可以使用如下的方式声明
# file: UploadFile | None = None
# 多文件上传
# files: list[UploadFile]
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):return {"filename": file.filename}

UploadFile 与 bytes 相比有更多优势:

  • 使用 spooled 文件
    • 存储在内存的文件超出最大上限时,FastAPI 会把文件存入磁盘
  • 这种方式更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存
  • 可获取上传文件的元数据
  • 自带 file-like async 接口
  • 暴露的 Python SpooledTemporaryFile 对象,可直接传递给其他预期「file-like」对象的库。

UploadFile

UploadFile 的属性
  • filename:上传文件名字符串(str),例如, myimage.jpg;
  • content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),例如,image/jpeg;
  • file: SpooledTemporaryFile( file-like 对象)。其实就是 Python文件,可直接传递给其他预期 file-like 对象的函数或支持库。
UploadFile 支持以下 async 方法
  • write(data):把 data (str 或 bytes)写入文件;
  • read(size):按指定数量的字节或字符(size (int))读取文件内容;
  • seek(offset):移动至文件 offset (int)字节处的位置
    • 例如,await myfile.seek(0) 移动到文件开头, 执行 await myfile.read() 后,需再次读取已读取内容时,这种方法特别好用;
  • close():关闭文件

依赖项

声明依赖项

  • 提高代码的复用性
from typing import Unionfrom fastapi import Depends, FastAPIapp = FastAPI()# 为查询接口设置一些公共参数
async def common_parameters(q: Union[str, None] = None, skip: int = 0, limit: int = 100
):return {"q": q, "skip": skip, "limit": limit}# 通过 Depends 声明依赖项
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):return commons@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):return commons

APIRouter

相当于 Flask 的 Blueprints

目录结构

.
├── 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
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")
app/routers/items.py
from fastapi import APIRouter, Depends, HTTPException# 可以使用相对路径进行导入操作
# 但个人不推荐这样操作
from ..dependencies import get_token_header# 定义 APIRouter(定义模块 / 定义蓝图)
router = APIRouter(prefix="/items",tags=["items"],dependencies=[Depends(get_token_header)],responses={404: {"description": "Not found"}},
)fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}# prefix + path
# api ==》 /items/
@router.get("/")
async def read_items():return fake_items_db# prefix + path
# api ==》 /items/{item_id}
@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 item: plumbus")return {"item_id": item_id, "name": "The great Plumbus"}
app/main.py
from fastapi import Depends, FastAPIfrom .dependencies import get_query_token, get_token_header
from .internal import admin# 导入模块路由
from .routers import items, usersapp = 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 Bigger Applications!"}

后台任务 BackgroundTasks

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: BackgroundTasks# 然后通过 background_tasks.add_task ,添加为后台任务# 并没有看到 background_tasks 创建,# 应该是 FastAPI 会创建一个 BackgroundTasks 类型的对象并作为该参数传入background_tasks.add_task(write_notification, email, message="some notification")return {"message": "Notification sent in the background"}

到此结  DragonFangQy 2024.07.13

相关文章:

FastAPI -- 第二弹(响应模型、状态码、路由APIRouter、后台任务BackgroundTasks)

响应模型 添加响应模型 from typing import Anyfrom fastapi import FastAPI from pydantic import BaseModel, EmailStrapp FastAPI()class UserIn(BaseModel):username: strpassword: stremail: EmailStrfull_name: str | None Noneclass UserOut(BaseModel):username: s…...

案例 | 人大金仓助力山西政务服务核心业务系统实现全栈国产化升级改造

近日,人大金仓支撑山西涉企政策服务平台、政务服务热线联动平台、政务网、办件中心等近30个政务核心系统完成全栈国产化升级改造,推进全省通办、跨省通办、综合业务受理、智能审批、一件事一次办等业务的数字化办结进程,为我国数字政务服务提…...

如何用python写接口

如何用python写接口?具体步骤如下:  1、实例化server 2、装饰器下面的函数变为一个接口 3、启动服务 开发工具和流程: python库:flask 》实例化server:server flask.Flask(__name__) 》server.route(/index,met…...

轻量级可扩展易航网址引导系统源码V2.45

由于现在网站行业的不稳定,导致很地址频繁更换,不仅是网站,联系QQ,加群链接等需要更换时,好不容易发展的客户会因为找不到您新的网站地址而流失,有了引导页以后就可以安心地宣传无需担心客户丢失的问题。 …...

解决ESLint和Prettier冲突的问题

在配置了ESLint的项目中使用Prettier进行格式化可能会出现冲突,不如Prettier配置了使用双引号,ESLint配置了单引号,当然可以一个一个改成一样的配置,但是比较麻烦。我发现可以直接使用ESLint的规则进行格式化。在VSCode配置过程如…...

C判断一个点在三角形上

背景 鼠标操作时,经常要判断是否命中显示控件,特开发此算法快速判断。 原理 三角形三等分点定理是指在任意三角形ABC中,可以找到三个点D、E和F,使得线段AD、BE和CF均等分三角形ABC。 这意味着三个等分点分别位于三个边界上&…...

物业系统自主研发接口测试框架

1、自主研发框架整体设计 1.1、什么是测试框架? 在了解什么是自动化测试框架之前,先了解一下什么叫框架?框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架…...

手机和电脑通过TCP传输

一.工具 手机端:网络调试精灵 电脑端:野火网络调试助手 在开始通信之前,千万要查看一下电脑的防火墙是否关闭,否则可能会无法通信 在开始通信之前,千万要查看一下电脑的防火墙是否关闭,否则可能会无法通信…...

Git 在commit后,撤销commit

1. 撤销已经add,但是没有commit的问题 git reset HEAD 2. 撤销已经commit,但是没有push到远端的文件(仅撤销commit 保留add操作) 撤销上一次的提交 git reset --soft HEAD^windows 系统使用提示 more,需要多加一个…...

多模态大模型 - MM1

1. 摘要 本文主要通过分析模型结构和数据选择讨论如何构建一个好的多模态大模型(MLLM),并同时提出了MM1模型,包括30B dense版本和64B的MoE版本。 具体贡献: 模型层面:影响效果的重要性排序为:…...

FPGA设计之跨时钟域(CDC)设计篇(2)----如何科学地设计复位信号?

1、复位是干嘛的? 时钟信号和复位信号应该是一个数字系统最重要和最常用的两个信号了。时钟的重要性大家都懂,没有时钟整个系统就无法同步,自然也就谈不上运行了。那么复位(reset)到底是干嘛的? 所有的数字系统在上电的时候都会进行复位,这样才能确保该系统的初始运行状…...

GPS北斗标准时钟同步服务器结构是什么?安徽京准

GPS北斗标准时钟同步服务器结构是什么?安徽京准 GPS北斗标准时钟同步服务器结构是什么?安徽京准 电厂时钟同步系统组成及配置 随着计算机和网络通信技术的飞速发展,火电厂热工自动化系统数字化、网络化的时代已经到来。一方面它为控制和信息系…...

9.5 栅格图层符号化多波段彩色渲染

文章目录 前言多波段彩色渲染QGis设置为多波段彩色二次开发代码实现多波段彩色 总结 前言 介绍栅格图层数据渲染之多波段彩色渲染说明:文章中的示例代码均来自开源项目qgis_cpp_api_apps 多波段彩色渲染 以“3420C_2010_327_RGB_LATLNG.tif”数据为例&#xff0c…...

力扣第九题

回文数 提示: 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 代码展示&#…...

鞭炮插画:成都亚恒丰创教育科技有限公司

鞭炮插画:年味里的绚烂记忆 在岁末年初的温柔时光里,总有一抹色彩,能瞬间唤醒沉睡的年味——那便是鞭炮插画中跃动的红与金,成都亚恒丰创教育科技有限公司 它们不仅仅是纸与墨的交织,更是情感与记忆的桥梁&#xff0c…...

python 循环

循环 while语句 for语句 循环控制语句 break 立即退出循环。 continue 跳过当前循环的剩余部分,并开始下一次迭代。 else for 和 while 循环都可以有一个可选的 else 子句,当循环正常结束时执行。 嵌套 占位符pass pass 是一个空操作语句。当你需要在代…...

映美精黑白相机IFrameQueueBuffer转halcon的HObject

映美精黑白相机&#xff0c;用wpfhalcon开发取图 1.到官网下载&#xff0c;开发包 1sdk 2c开发例子 3c#开发例子 引入TIS.Imaging.ICImagingControl35.dll 3.ICImagingControl使用这个类控制相机 /// <summary> /// 相机控制 /// </summary> public ICImagingC…...

Linux的load(负载)

负载(load)是Linux机器的一个重要指标&#xff0c;直观了反应了机器当前的状态。 在Linux系统中&#xff0c;系统负载是对当前CPU工作量的度量&#xff0c;被定义为特定时间间隔内运行队列中的平均线程数。 Linux的负载高&#xff0c;主要是由于CPU使用、内存使用、10消…...

杜比全景声——空间音频技术

什么是杜比&#xff1f;是否是标清、高清、超清之上的更清晰的格式&#xff1f;杜比全景声 和传统多声道立体声的差别&#xff1f;杜比全景声音频的渲染方式&#xff1f;车载平台上杜比技术的应用&#xff1f; 杜比技术的起源 杜比实验室&#xff08;Dolby Laboratories&…...

C 语言指针进阶

1.0 指针的定义 指针是内存中一个最小单元的编号&#xff08;内存单元的编号称之为地址【地址就是指针指针就是地址】&#xff09;指针通常是用来存放内存地址的一个变量。本质上指针就是地址&#xff1a;口语上说的指针起始是指针变量&#xff0c;指针变量就是一个变量&#…...

处理跨时区订单与日志?LocalDateTime时区转换与序列化的避坑指南

跨时区业务中的LocalDateTime实战&#xff1a;从订单处理到日志存储的全链路解决方案 凌晨三点&#xff0c;东京用户的订单触发了系统告警&#xff0c;而纽约团队查看日志时却发现时间对不上——这是许多全球化业务开发者常见的噩梦。时区问题如同暗礁&#xff0c;往往在系统运…...

市面上有哪些是真正性价比高的降AIGC软件(轻松压低AI生成疑似率)

最崩溃的不是查重难题&#xff0c;而是查重达标却AI率超标亮红灯&#xff01;很多工具只会简单同义词替换、浅层改字&#xff0c;根本洗不掉AI专属句式、行文逻辑和高频模板话术&#xff0c;学校AIGC检测一查一个准&#xff0c;论文直接翻车。 本篇结合全网实测数据&#xff0c…...

中国工业物理AI落地优势显著,江行智能全栈模型架构助力工业变革

中国工业物理AI的优势与落地情况中国工业物理AI的真正优势不在于模型参数&#xff0c;而在于全球12倍的工业机器人部署密度、两倍的发电量和密集的5G边缘节点。场景密度、基建底座和开源模型的合力&#xff0c;正推动物理AI从实验室走向规模化落地。江行智能提出的工业物理AI三…...

观测通过Taotoken调用大模型API的延迟与用量消耗体验

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 观测通过Taotoken调用大模型API的延迟与用量消耗体验 在开发工作中引入大模型能力&#xff0c;例如自动生成代码注释&#xff0c;已…...

通过curl命令快速测试Taotoken多模型聚合接口的连通性

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 通过curl命令快速测试Taotoken多模型聚合接口的连通性 在接入大模型服务时&#xff0c;直接使用HTTP请求进行测试是一种高效且通用…...

工业机器视觉工控机选型指南:从硬件配置到现场调试

1. 产品定位与核心价值解析在工业自动化领域&#xff0c;尤其是机器视觉应用场景中&#xff0c;稳定、可靠且性能强劲的硬件平台是整套系统能够7x24小时无间断运行的基石。朗锐智科推出的这款机器视觉工控机&#xff0c;从其核心配置来看&#xff0c;精准地瞄准了中高端视觉检测…...

2026年热门声音转换成文字工具实测对比,多场景准确率比拼,低调黑马才是真王者

我干ToB销售5年&#xff0c;光客户拜访、季度产品培训的录音&#xff0c;手机里攒了快200G。试过不下10款声音转文字工具&#xff0c;上个月把2026年圈里热门的几款全拉出来测了一遍&#xff0c;对比了多款工具&#xff0c;听脑AI是综合体验最好的&#xff0c;也是我现在天天开…...

如何高效使用Gofile下载器:从单文件到批量下载的完整指南

如何高效使用Gofile下载器&#xff1a;从单文件到批量下载的完整指南 【免费下载链接】gofile-downloader Download files from https://gofile.io 项目地址: https://gitcode.com/gh_mirrors/go/gofile-downloader Gofile下载器是一款专门用于从Gofile.io平台下载文件的…...

终极Ghidra逆向工程指南:30分钟从零掌握二进制分析

终极Ghidra逆向工程指南&#xff1a;30分钟从零掌握二进制分析 【免费下载链接】ghidra Ghidra is a software reverse engineering (SRE) framework 项目地址: https://gitcode.com/GitHub_Trending/gh/ghidra Ghidra作为一款由美国国家安全局&#xff08;NSA&#xff…...

从零开始接入 Taotoken,新用户注册到首次成功调用的全过程耗时

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 从零开始接入 Taotoken&#xff0c;新用户注册到首次成功调用的全过程耗时 对于开发者而言&#xff0c;评估一个新工具或平台的接入…...