【Python】FastAPI学习记录(二)

模型,请求数据

  • 使用记录
    • 模型
      • 响应模型
      • 减少代码量
      • 任意 `dict` 构成的响应
    • 请求附加信息
      • Header信息
    • 其他的请求信息
      • 表单数据
      • 文件数据
        • 基本使用
        • 多文件
      • 表单+文件

使用记录

模型

响应模型

有的时候一个post接口,请求模型和响应模型我们需要的字段是不一样的,比如用户登录的接口:

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@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn) -> Any:return user

上述代码中添加了两个模型,UserIn用来做请求体的映射,而UserOut则是返回值的映射,通过response_model即可指定返回值模型;

除此之外,还可以选择在返回的时候忽略空的值,否则可能出现一个接口的返回值很冗长,携带大量空的json键值对,这个操作借由response_model_exclude_unset=True来实现。

减少代码量

对于用户模型来说,可以声明一个 UserBase 模型作为其他模型的基类。然后可以创建继承该模型属性(类型声明,校验等)的子类。这样,可以仅声明模型之间的差异部分(具有明文的 password、具有 hashed_password 以及不包括密码)。

from fastapi import FastAPI
from pydantic import BaseModel, EmailStrapp = FastAPI()class UserBase(BaseModel):username: stremail: EmailStrfull_name: str | None = Noneclass UserIn(UserBase):password: strclass UserOut(UserBase):passclass 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_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

任意 dict 构成的响应

可以使用一个任意的普通 dict 声明响应,仅声明键和值的类型,而不使用 Pydantic 模型。如果事先不知道有效的字段/属性名称(对于 Pydantic 模型是必需的),这将很有用。在这种情况下,可以使用 typing.Dict

from fastapi import FastAPIapp = FastAPI()@app.get("/keyword-weights/", response_model=dict[str, float])
async def read_keyword_weights():return {"foo": 2.3, "bar": 3.4}

请求附加信息

定义Header参数和Cookies参数的方式与定义Query等参数的方式是一样的。

这是因为他们都是Path, Query等类的兄弟类型。它也继承自通用的Param 类.

Header信息

需要注意的其实只有一个点,那就是Header提供了自动转换的能力。

首先要知道大多数标准的headers用-分割,然而这种名字的变量在Python中无效,比如user-agent,因此,默认情况下,Header 将把参数名称的字符从_ 转换为-)来提取并记录 headers.

from typing import Annotatedfrom fastapi import FastAPI, Headerapp = FastAPI()@app.get("/items/")
async def read_items(user_agent: Annotated[str | None, Header()] = None):return {"User-Agent": user_agent}

其他的请求信息

上面说的大部分都是json数据格式的交互,有的时候会提交表单数据,或者用户上传文件,这里有别的处理方式。

表单数据

使用表单首先要安装额外的包

pip install python-multipart

fastapi 导入 Form

from fastapi import FastAPI, Formapp = FastAPI()@app.post("/login/")
async def login(username: str = Form(), password: str = Form()):return {"username": username}

Tips:例如,OAuth2 规范的 “密码流” 模式规定要通过表单字段发送 usernamepassword

该规范要求字段必须命名为 usernamepassword,并通过表单字段发送,不能用 JSON。

使用 Form 可以声明与 Body (及 QueryPathCookie)相同的元数据和验证。

声明表单体要显式使用Form,否则,FastAPI 会把该参数当作查询参数或请求体(JSON)参数

文件数据

基本使用

文件数据使用File,从 fastapi 导入 File 并使用:

from fastapi import FastAPI, File, UploadFileapp = FastAPI()@app.post("/files/")
async def create_file(file: bytes = File()):return {"file_size": len(file)}

上面的例子中如果把路径操作函数参数的类型声明为 bytesFastAPI 将以 bytes 形式读取和接收文件内容。这种方式把文件的所有内容都存储在内存里,适用于小型文件,实际上在多数情况下UploadFile 更好用。

from fastapi import FastAPI, UploadFileapp = FastAPI()@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):return {"filename": file.filename}

UploadFile的优势:

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

UploadFile 的属性如下:

  • filename:上传文件名字符串(str),例如, myimage.jpg
  • content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),例如,image/jpeg
  • fileSpooledTemporaryFile( file-like 对象)。其实就是 Python文件,可直接传递给其他预期 file-like 对象的函数或支持库。

UploadFile 支持以下 async 方法,(使用内部 SpooledTemporaryFile)可调用相应的文件方法。

  • write(data):把 datastrbytes)写入文件;
  • read(size):按指定数量的字节或字符(size (int))读取文件内容;
  • seek(offset):移动至文件offset(int)字节处的位置;
    • 例如,await myfile.seek(0) 移动到文件开头;
    • 执行 await myfile.read() 后,需再次读取已读取内容时,这种方法特别好用;
  • close():关闭文件。

与 JSON 不同,HTML 表单(<form></form>)向服务器发送数据通常使用「特殊」的编码,在不包含文件时,表单数据一般采用 application/x-www-form-urlencoded「媒体类型」编码,包含文件时则使用multipart/form-data编码;

如果想要文件上传选项是可选的,只需要以None作为注解即可:

from fastapi import FastAPI, File, UploadFileapp = FastAPI()@app.post("/files/")
async def create_file(file: bytes | None = File(default=None)): # 这里多了None = File(default=None)if not file:return {"message": "No file sent"}else:return {"file_size": len(file)}@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile | None = None):if not file:return {"message": "No upload file sent"}else:return {"filename": file.filename}
多文件

同一个表单字段可以包含多个文件,可以想到这种情况下使用含 bytesUploadFileList

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponseapp = FastAPI()@app.post("/files/")
async def create_files(files: list[bytes] = File()):return {"file_sizes": [len(file) for file in files]}@app.post("/uploadfiles/")
async def create_upload_files(files: list[UploadFile]):return {"filenames": [file.filename for file in files]}@app.get("/")
async def main():content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>"""return HTMLResponse(content=content)

表单+文件

直接设置多个内容即可:

from fastapi import FastAPI, File, Form, UploadFileapp = FastAPI()@app.post("/files/")
async def create_file(file: bytes = File(), fileb: UploadFile = File(), token: str = Form()
):return {"file_size": len(file),"token": token,"fileb_content_type": fileb.content_type,}

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

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

相关文章

鹅目标检测数据集VOC格式350张

鹅是一种大型的水禽&#xff0c;常见于湖泊、河流和农田周围。它们的体形庞大&#xff0c;长有长颈和宽阔的翅膀&#xff0c;通常呈灰白色或棕褐色。鹅的头部呈黑色&#xff0c;嘴呈橙色&#xff0c;眼睛则是明亮的蓝色。 鹅是非常社交的动物&#xff0c;常以大群的形式生活在…

Jtti 香港服务器使用RAID技术的优势

RAID(冗余磁盘阵列)技术在服务器中的应用为数据存储提供了冗余、性能优化和容错能力。在香港服务器中使用RAID技术可以带来一些优势&#xff1a; 数据冗余&#xff1a; RAID 提供了数据冗余功能&#xff0c;通过在多个磁盘上存储相同的数据&#xff0c;使得即使其中一个磁盘发生…

DevC++ easyx实现视口编辑,在超过屏幕大小的地图上画点,与解决刮刮乐bug效果中理解C语言指针的意义

继上篇文案&#xff0c; DevC easyx实现地图拖动&#xff0c;超过屏幕大小的巨大地图的局部显示在屏幕的方法——用悬浮窗的原理来的实现一个视口-CSDN博客 实现了大地图拖动&#xff0c;但是当时野心不止&#xff0c;就想着一气能搓啥就继续搓啥&#xff0c;看着地图移动都搓…

树莓派,mediapipe,Picamera2利用舵机云台追踪人手(PID控制)

一、项目目标 追踪人手大拇指指尖&#xff1a; 当人手移动时&#xff0c;摄像头通过控制两个伺服电机&#xff08;分别是偏航和俯仰&#xff09;把大拇指指尖放到视界的中心位置&#xff0c;本文采用了PID控制伺服电机 Mediapipe Hand简介 MediaPipe 手部标志任务可检测图像…

windows搭建MySQL主从补充说明

这3种情况是在HA切换时&#xff0c;由于是异步复制&#xff0c;且sync_binlog0&#xff0c;会造成一小部分binlog没接收完导致同步报错。 第一种&#xff1a;在master上删除一条记录&#xff0c;而slave上找不到。 第二种&#xff1a;主键重复。在slave已经有该记录&#xff…

Kotlin 数据类

1、语法 data 修饰的类 data class User(val name: String, val age: Int) 编译器自动从主构造函数中声明的所有属性导出以下成员&#xff1a; .equals()/.hashCode() 对.toString() 格式是 "User(nameJohn, age42)".componentN() 按声明顺序对应于所有属性.cop…

链接世界与中国时尚文化,积萨伯爵国际时尚品牌在中国大放异彩

时尚的历史是一部文化发展的历史。从中国古代到现代西方&#xff0c;每个时代的时尚都有其独特的文化背景和历史意义。自丝绸之路开启了古代中国与罗马帝国之间的贸易&#xff0c;时尚的不断创新和变革&#xff0c;是文化变迁和时代精神的反映。时尚的变化&#xff0c;也引领着…

【Jmeter】Jmeter基础9-BeanShell介绍

3、BeanShell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法。 3.1、Jmeter中使用的BeanShell 在Jmeter中&#xff0c;除了配置元件&#xff0c;其他类型的元件中都有BeanShell。BeanShell 是一种完全符合Java语法规范的脚本语言,并且又拥…

Prompt 提示工程学习笔记

一、Prompt设计的四个关键要素&#xff1a; 任务描述、输入数据、上下文信息、提示风格 &#xff08;1&#xff09;任务描述&#xff1a;描述想要让LLM遵循的指令。描述应详细清晰&#xff0c;可进一步使用关键词突出特殊设置&#xff0c;从而更好地指导LLM工作。 &#xff0…

华为防火墙双机热备

实验需求&#xff1a; 如图所示&#xff0c;PC1为公司内部网络设备&#xff0c;AR1为出口设备&#xff0c;在FW1和FW2上配置双机热备&#xff0c;当网络正常时PC1访问AR1路径为FW1-AR1&#xff0c;当FW1出现故障后&#xff0c;切换路径为FW2-AR1。 实现目的&#xff1a; 了解…

抖店商品卡运营两个月,店铺只出了几十单,这个店还有必要做吗?

我是王路飞。 现在的抖店&#xff0c;很多商家都感觉“内卷”、“不好做”、“做不下去”、“不赚钱”...... 其实&#xff0c;当你自己做不起来的时候&#xff0c;你就只能看到跟你一样遭遇的同行不好的消息。 而那些做起来的商家&#xff0c;他们不仅不会向别人发布一些负…

RK3588平台开发系列讲解(AI 篇)RKNN rknn_query函数详细说明

文章目录 一、查询 SDK 版本二、查询输入输出 tensor 个数三、查询输入 tensor 属性(用于通用 API 接口)四、查询输出 tensor 属性(用于通用 API 接口)五、查询模型推理的逐层耗时六、查询模型推理的总耗时七、查询模型的内存占用情况八、查询模型里用户自定义字符串九、查询原…

Mysql 将数据按照年月分组 统计

要的效果: 方案&#xff1a; ① 使用 DATE_FORMAT(date, ‘%Y-%m-%d’) 函数 DATE_FORMAT 怎么去使用格式化&#xff0c;取决于后面的格式模式。 我们这里只是想区分到年 、月&#xff0c; 所以我们的sql 里面使用 %Y-%m : SELECT DATE_FORMAT(create_time, %Y-%m) AS …

Linux dirs命令

Linux dirs命令用于显示目录记录。 显示目录堆叠中的记录。 语法 dirs [/-n -l]参数&#xff1a; n 显示从左边算起第n笔的目录。-n 显示从右边算起第n笔的目录。-l 显示目录完整的记录。 实例 列出"/home/cc/Ruijie"里所有内容的详细信息。可用如下命令。 dir…

【cesium-5】鼠标交互与数据查询

scene.pick返回的是包含给定窗口位置基元的对象 scene.drillpack返回的是给定窗口位置所有对象的列表 Globe.pick返回的是给光线和地形的交点 Cesium.ScreenSpaceEventType.MIDDLE_CLICK 鼠标中间点击事件 Cesium.ScreenSpaceEventType.MOUSE_MOVE 鼠标移入事件 Cesium.ScreenS…

支持多医院使用的云HIS医院信息化管理系统源码 SaaS模式

一、什么是HIS系统 HIS系统&#xff08;Hospital InformationSystem&#xff09;是医院信息化建设的核心组成部分&#xff0c;它是为了管理和运营医院而设计和开发的一套综合性的信息系统。HIS系统通过整合医院各个部门和业务流程的数据和信息&#xff0c;实现了医院内部的信息…

Uncaught ReferenceError: VueRouter is not defined

没有引入完全&#xff0c;报缺什么就引入什么 import * as VueRouter from vue-router;

ElasticSearch 文档操作

批量操作 语法 批量操作对json有严格的要求&#xff0c;每个json串不能换行&#xff0c;只能放在同一行&#xff0c;相邻的json串之间必须要有换行。每个操作必须是一对json串&#xff08;delete语法除外&#xff09; { action: { metadata }} { request body } { ac…

[幻灯片]软件需求设计方法学全程实例剖析-01-概述

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 pdf下载&#xff1a;umlchina.com/training/umlchina_01_overview.pdf UMLChina公众号精选&#xff08;20231222更新&#xff09;按ABCD工作流分类

格密码基础:垂直子空间与子格,q-ary垂直格

目录 一.写在前面 二.子空间垂直 2.1 理论解释 2.2 举例分析 三. 零空间 3.1 零空间与q-ary垂直格 3.2 零空间与行/列空间 四. 格密码相关 一.写在前面 格密码中的很多基础原语都来自于线性代数的基本概念&#xff0c;比如举几个例子&#xff1a; 格密码中的非满秩格…