【Python开发】FastAPI 04:响应模型

news2024/11/25 11:33:12

响应模型是指在接口调用之后,服务器返回给客户端的数据模型。这个数据模型可以是一个简单的字符串,也可以是一个复杂的数据结构,如 JSON XML 格式的数据。本篇文章将详细介绍 FastAPI 中的响应模型。

目录

1 响应模型

1.1 response_model

1.2 response_model_exclude_unset

1.3 response_model_include 和 response_model_exclude

2 额外的模型

2.1 **user_in.dict()

① Pydantic 的 .dict()

② 解包

③ 额外关键字

2.2 减少重复代码

2.3 响应状态码

① demo

② HTTP 状态码

③ 名称捷径


1 响应模型

1.1 response_model

你可以在任意的路径操作中使用 response_model 参数来声明用于响应的模型:

  • @app.get()
  • @app.post()
  • @app.put()
  • @app.delete()
  • 等等。
from typing import Any, List, Union
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Union[str, None] = None #默认值
    price: float
    tax: Union[float, None] = None #默认值
    tags: List[str] = [] #默认值

@app.post("/items/", response_model=Item)
async def create_item(item: Item):
    return item

@app.get("/items/", response_model=List[Item])
async def read_items():
    return [
        {"name": "Portal Gun", "price": 42.0},
        {"name": "Plumbus", "price": 32.0},
    ]

注意:response_model 是「装饰器」方法(getpost 等)的一个参数。不像之前的所有参数和请求体,它不属于路径操作函数。

它接收的类型与你将为 Pydantic 模型属性所声明的类型相同,因此它可以是一个 Pydantic 模型,但也可以是一个由 Pydantic 模型组成的 list,例如 List[Item]

FastAPI 将使用此 response_model 来做以下事:

  • 将输出数据转换为其声明的类型;
  • 校验数据;
  • 在自动生成文档系统中使用;
  • 会将输出数据限制在该模型定义内!

📌 文档

1.2 response_model_exclude_unset

可以设置路径操作装饰器中的 response_model_exclude_unset=True 参数,然后响应中将不会包含那些默认值,而是仅有实际设置的值:

from typing import List, Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item1(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: float = 10.5
    tags: List[str] = []

items = {
    "foo": {"name": "Foo", "price": 50.2},
    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}

@app.get("/items3/{item_id}", response_model=Item1, response_model_exclude_unset=True)
async def read_item(item_id: str):
    return items[item_id]

若此时向路径操作发送 ID 为 foo 的商品的请求,则响应(不包括默认值)将为:

{
    "name": "Foo",
    "price": 50.2
}

📌 默认值字段有实际值的数据

若此时向路径操作发送 ID 为 bar 的商品的请求,则响应为:

{
    "name": "Bar",
    "description": "The bartenders",
    "price": 62,
    "tax": 20.2
}

这些值将包含在响应中。

📌 具有与默认值相同值的数据

如果数据具有与默认值相同的值,例如 ID 为 baz 的项:

{
    "name": "Baz",
    "description": None,
    "price": 50.2,
    "tax": 10.5,
    "tags": []
}

即使 descriptiontax 和 tags 具有与默认值相同的值,FastAPI 也能识别到这一点,它们的值被显式地所设定(而不是取自默认值),因此这些与默认值相同的值将包含在 JSON 响应中。

📌 你还可以使用:

  • response_model_exclude_defaults=True:等于其默认值的字段(无论是否设置)是否应从返回的字典中排除
  • response_model_exclude_none=True:是否应从返回的字典中排除等于 none 的字段

1.3 response_model_include 和 response_model_exclude

它们接收一个由属性名称 str 组成的 set 来包含(忽略其他的)或者排除(包含其他的)这些属性。

比如,如果要求返回的属性只有 name,那么可以使用 response_model_include,如果要求返回的属性排除掉 name,那么可以使用 response_model_exclude

...

@app.get(
    "/items/{item_id}/name",
    response_model=Item1,
    response_model_include={"name", "description"}
)
async def read_item_name(item_id: str):
    return items[item_id]

@app.get("/items/{item_id}/public", response_model=Item1, response_model_exclude={"tax"})
async def read_item_public_data(item_id: str):
    return items[item_id]

注意:{"name", "description"} 语法创建一个具有这两个值的 set。等同于 set(["name", "description"])

2 额外的模型

2.1 **user_in.dict()

① Pydantic 的 .dict()

Pydantic 模型具有 .dict() 方法,该方法返回一个拥有模型数据的 dict

首先我们像下面这样创建一个 Pydantic 对象 user_in

from typing import Union
from pydantic import BaseModel, EmailStr

class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    full_name: Union[str, None] = None

class UserInDB(BaseModel):
    username: str
    hashed_password: str  = None
    email: EmailStr
    full_name: Union[str, None] = None

user_in = UserIn(username="yinyu", password="secret", email="yinyu.doe@example.com")

然后调用并打印:

user_dict = user_in.dict()
print(user_dict)

我们将获得一个这样的 Python dict

{
    'username': 'yinyu',
    'password': 'secret',
    'email': 'yinyu.doe@example.com',
    'full_name': None,
}

② 解包

如果我们将 user_dict 这样的 dict 以 **user_dict 形式传递给一个函数(或类),Python将对其进行「解包」,它会将 user_dict 的键和值作为关键字参数直接传递。

从上面的 user_dict 继续编写:

user_db = UserInDB(**user_dict)

会产生类似于以下的结果:

UserInDB(
    username="yinyu",
    hashed_password=None,
    email="yinyu.doe@example.com",
    full_name=None,
)

需要注意的是,UserIn 和 UserInDB 可不是同一个模型,password 字段也不等同于 hashed_password 字段,也就是说在字段名一致的前提下,对应字段才会进行解包。

或者可以确切地进行如下表示:

UserInDB(
    username = user_dict["username"],
    hashed_password = user_dict["hashed_password"], #user_dic中没有该字段,那么会取默认值
    email = user_dict["email"],
    full_name = user_dict["full_name"]
)

③ 额外关键字

如上所述,hashed_password 字段没有取到值,这是因为字段名的不一致。

那么如何给这个 hashed_password 额外关键字设值呢,接上边代码如下:

user_dbb = UserInDB(**user_dict,hashed_password = "secret11")

最终结果如下:

UserInDB(
    username="yinyu",
    hashed_password="secret11",
    email="yinyu.doe@example.com",
    full_name=None,
)

2.2 减少重复代码

这是 FastAPI 的核心思想之一,上边的模型共享了大量数据,并拥有重复的属性名称和类型。

那么我们可以声明一个 UserBase 模型作为其他模型的基类。然后我们可以创建继承该模型属性(类型声明,校验等)的子类。

class UserBase(BaseModel):
    username: str
    email: EmailStr
    full_name: Union[str, None] = None

class UserIn1(UserBase):
    password: str

class UserInDB1(UserBase):
    hashed_password: str

2.3 响应状态码

① demo

与指定响应模型的方式相同,你也可以在以下任意的路径操作中使用 status_code 参数来声明用于响应的 HTTP 状态码:

  • @app.get()
  • @app.post()
  • @app.put()
  • @app.delete()
  • 等等。
from fastapi import FastAPI

app = FastAPI()

@app.post("/items1/", status_code=201)
async def create_item(name: str):
    return {"name": name}

status_code 参数接收一个表示 HTTP 状态码的数字。

📌 文档

② HTTP 状态码

在 HTTP 协议中,你将发送 3 位数的数字状态码作为响应的一部分。

简而言之:

  • 100 及以上状态码用于「消息」响应。很少直接使用,具有这些状态代码的响应不能带有响应体。
  • 200 及以上状态码用于「成功」响应,最常用。
  • 200 是默认状态代码,它表示一切「正常」
    • 另一个例子会是 201「已创建」。它通常在数据库中创建了一条新记录后使用。
    • 一个特殊的例子是 204「无内容」。此响应在没有内容返回给客户端时使用,因此该响应不能包含响应体。
  • 300 及以上状态码用于「重定向」。具有这些状态码的响应可能有或者可能没有响应体,但 304「未修改」是个例外,该响应不得含有响应体。
  • 400 及以上状态码用于「客户端错误」响应。这些可能是你第二常使用的类型。
    • 一个例子是 404,用于「未找到」响应。
    • 对于来自客户端的一般错误,你可以只使用 400
  • 500 及以上状态码用于服务器端错误。当你的应用程序代码或服务器中的某些部分出现问题时,它将自动返回这些状态代码之一。

③ 名称捷径

你不必去记住每个代码的含义。你可以使用来自 fastapi.status 的便捷变量。

from fastapi import FastAPI, status

app = FastAPI()

@app.post("/items2/", status_code=status.HTTP_201_CREATED)
async def create_item(name: str):
    return {"name": name}

这样使用你就可以使用编辑器的自动补全功能来查找它们:

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

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

相关文章

HTML--Java EE

目录 一、认识 HTML 标签 二、HTML 文件基本结构 三、开发者工具 四、HTML常见标签 1.注释标签 2.标题标签(h1-h6) 3.段落标签(p) 4.换行标签 5.格式化标签 6.图片标签(img) 6.1网络路径 6.2绝…

Mysql索引慢解决

索引慢解决 explain关键字 explainSQL id执行顺序,id相同从上到下;id不同,如果是子查询id序号会递增,id值越大优先级越高;id相同和不同都存在时,id相同理解为一组,从上往下顺序执行&#xff0…

最优化——几种重要的凸集

引言 这是中科大最优化理论的笔记,中科大凌青老师的凸优化课程,详尽易懂,基础扎实。不论是初学者还是从业多年的人,都值得系统地好好学一遍。 本文介绍种重要的凸集:超平面与半空间、球和椭球、多面体、单纯形。 超平面与半空间…

202314读书笔记|《孩子们的诗》——简单的语言,击中每个人心中的诗意

202314读书笔记|《孩子们的诗》——简单的语言,击中每个人心中的诗意 《孩子们的诗》作者果麦。这本书中的诗都是孩子们写的,虽然他们或许并不认为自己写的是诗。每个人都想一直做一个孩子,好奇、天真、单纯、善良、简单,多美美好…

【产品应用】一体化步进电机在全自动折页机的应用

随着科技的不断发展,机器人技术也越来越成熟,智能化和自动化已经成为了现代工业的发展趋势。在这个趋势下,全自动折页机作为一种高效、精确的印刷设备,被广泛应用于各种印刷品的生产中。而一体化步进电机作为全自动折页机的关键部…

SpringBoot+Vue 前后端分离在线学习平台-在线教育平台

SpringBootVue 前后端分离在线学习平台-在线教育平台 本项目是完整的前后端分离,在线学习系统。【有完整部署视频教程】 创新点: ①基于阿里云短信平台完成手机号变更【短信验证码】 ②基于支付宝沙箱支付完成在线购买课程【在线支付】 ③基于apach-echa…

【Python】函数 ② ( 函数参数定义和使用 | 形式参数和实际参数 )

文章目录 一、函数参数定义和使用二、形式参数和实际参数 一、函数参数定义和使用 Python 函数参数 作用 : 在 Python 函数 执行时 , 可以 接受 外部 函数调用者 提供的数据 ; 在 Python 函数中 , 可以接受零个或多个参数 , 这些参数可以传递到函数中进行操作 ; 函数参数也可…

Java并发(九)----线程join、interrupt

1、join 方法详解 1.1 为什么需要 join? 下面的代码执行,打印 r 是什么? static int r 0; public static void main(String[] args) throws InterruptedException {test1(); } private static void test1() throws InterruptedException …

用C++ 包装STM32 官方固件库 - 链式调用改写初始化结构体

拿C 在固件库上套娃一层有几点原因: 固件库都是用C 写的,而我平时都用C,虽然是兼容的,但C 的一些特性我不喜欢;我不喜欢官方库的函数命名风格;各个厂家的固件库大同小异,但是“小异”的那一部分…

路径规划算法:基于旗鱼优化的路径规划算法- 附代码

路径规划算法:基于旗鱼优化的路径规划算法- 附代码 文章目录 路径规划算法:基于旗鱼优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化算法旗鱼…

Direct3D 12——几何——基础

在几何里可分为两种几何,一种是显式几何,另外一种是隐式几何。有不同的方式表示不同的几何 隐式几何 隐式实际上是说不会告诉具体的这些点点就在哪,只告诉你这些点满足的关系。表示一定的关系但并不会给实际的点 例子: 隐式几何…

Ubuntu开机桌面黑屏只有鼠标问题解决办法(搜狗输入法导致)

参考: Ubuntu开机桌面黑屏只有鼠标问题解决办法(搜狗输入法导致) 问题描述 笔者在安装完搜狗输入法重启电脑后,电脑开机黑屏,只有鼠标的光标可以移动。笔者一开始以为是系统问题,网上查阅资料才发现有大量…

华为OD机试之全量和已占用字符集(Java源码)

全量和已占用字符集 题目描述 给定两个字符集合,一个是全量字符集,一个是已占用字符集,已占用字符集中的字符不能再使用。 输入描述 输入一个字符串 一定包含,前为全量字符集 后的为已占用字符集已占用字符集中的字符一定是全量字…

安全架构审计

安全架构审计 目录概述需求: 设计思路实现思路分析1.什么是安全架构审计2.安全架构审计工具3.现在使用的工具4.安全架构审计报告 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,ski…

最全Python+Selenium环境搭建教程-你绝对想不到有这么简单!

一,Selenium 简介 在华为工作了10年的大佬出的Web自动化测试教程,华为现用技术教程!_哔哩哔哩_bilibili在华为工作了10年的大佬出的Web自动化测试教程,华为现用技术教程!共计16条视频,包括:1. …

力扣动态规划专题(一)509 70 746 62 63 343 96 思路及C++实现

文章目录 动态规划509. 斐波那契数五步骤代码 70. 爬楼梯五步骤代码 746. 使用最小花费爬楼梯五步骤代码扩展 62. 不同路径动态规划数论 63. 不同路径 II五步骤代码 343. 整数拆分五步骤代码 96.不同的二叉搜索树五步骤代码 注意点: 动态规划 动态规划,…

Java多线程学习2

1. 多线程 线程与任务的关系 脱离了任务的线程是没有意义的 线程对象是通过Thread类来创建的 任务是通过Runnable接口来定义的 1.继承Thread类 2.实现Runnable接口 3.实现Callable接口 (与Runnable的区别,可以拿到返回值) Thread线程…

RK3588平台开发系列讲解(驱动基础篇)设备驱动 IO 控制

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们来讲的 ioctl 接口。 在内核 3.0 以前,ioctl 接口的名字叫 ioctl;内核 3.0 以后,ioctl 接口的名字叫 unlocked_ioctl。unlocked_ioctl就是 ioctl 接…

基于深度学习的高精度血小板检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度血小板检测(红细胞RBC、白细胞WBC和血小板Platelet)识别系统可用于日常生活中或野外来检测与定位血小板目标,利用深度学习算法可实现图片、视频、摄像头等方式的血小板目标检测识别,另外支持…

程序设计综合实习(C语言):用指针优化学生成绩排名

一.目的 1.熟悉变量的指针和指向变量的的指针变量的概念和使用 2.熟悉数组的指针和指向数组的的指针变量的概念和使用 3. 掌握冒泡法或选择法排序的算法 4. 掌握函数的定义、调用、声明,以及参数的两种传递方式 二、实习环境 Visual Studio 2…