fastapi 请求文件 / 表单 / 处理错误 / 路径操作配置 / jsonable_encoder

文章目录

    • 1. File 参数
    • 2. 多文件上传
    • 3. 请求表单与文件
    • 4. 处理错误
    • 5. 自定义响应头
    • 6. 自定义异常处理器
    • 7. 覆盖默认异常处理器
    • 8. 使用 RequestValidationError 的请求体
    • 9. 复用 FastAPI 异常处理器
    • 10. 路径操作参数配置
      • 10.1 status_code,tags
      • 10.2 summary,description
      • 10.3 response description
      • 10.4 deprecated 废除
    • 11. jsonable_encoder() 转换

learn from https://fastapi.tiangolo.com/zh/tutorial/request-files/

1. File 参数

from fastapi import FastAPI, Form, File, UploadFile
app = FastAPI()@app.post("/files/")
async def create_file(file: bytes = File(...)):return {"file_size": len(file)}@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):contents = await file.read()return {"filename": file.filename}
  • bytes 形式, 文件的所有内容都存储在内存里,适用于小型文件
  • 很多情况下,UploadFile 更好用
    1.存储在内存里的文件超出上限,FastAPI 会将其存入磁盘,大型文件不会用尽所有内存
    2.可获取上传文件的元数据
    3.自带 file-like async 接口

async 路径操作函数 内,要用以下方式读取文件内容:

contents = await myfile.read()

普通 def 路径操作函数 内,则可以直接访问 UploadFile.file

contents = myfile.file.read()

在这里插入图片描述

2. 多文件上传

  • List[bytes], List[UploadFile]
from fastapi import FastAPI, Form, File, UploadFile
from fastapi.responses import HTMLResponse
from typing import List
app = 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] = File(...)):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)

在这里插入图片描述
在这里插入图片描述

3. 请求表单与文件

  • FastAPI 支持同时使用 File 和 Form 定义文件和表单字段
@app.post("/f/")
async def create_file(file1: bytes = File(...),file2: UploadFile = UploadFile(...),token: str = Form(...)
):return {"file_size": len(file1),"token" : token,"file_content_type" : file2.content_type}

在这里插入图片描述

  • 可在一个路径操作中声明多个 FileForm 参数,但不能同时声明要接收 JSON 的 Body 字段。因为此时请求体的编码为 multipart/form-data,不是 application/json

4. 处理错误

  • raise HTTPException()
from fastapi import FastAPI, HTTPException
app = FastAPI()
items = {"foo" : "The Foo items"}@app.get("/items/{item_id}")
async def read_item(item_id: str):if item_id not in items:raise HTTPException(status_code=404, detail="item not found!")return {"item" : items[item_id]}
  • 触发 HTTPException 时,可以用参数 detail 传递任何能转换为 JSON 的值,不仅限于 str。还支持传递 dict、list 等数据结构
    在这里插入图片描述
INFO:     Started server process [12136]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     127.0.0.1:3229 - "GET /items/foo HTTP/1.1" 200 OK
INFO:     127.0.0.1:3240 - "GET /items/bar HTTP/1.1" 404 Not Found
  • 使用 dict 形式的 detail 参数也可以,只要可以被转为 JSON 即可
HTTPException(status_code=404, detail={"msg":"item not found!", "name":["michael","ming"]})

在这里插入图片描述

5. 自定义响应头

  • HTTPException(headers=xxx)
@app.get("/items-header/{item_id}")
async def read_item_header(item_id: str):if item_id not in items:raise HTTPException(status_code=404,detail="Item not found",headers={"X-Error": "There goes my error!!!"},)return {"item": items[item_id]}

在这里插入图片描述

6. 自定义异常处理器

  • 自定义异常类
  • 编写 handler @app.exception_handler(要处理的异常类)
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponseclass MichaelException(Exception):def __init__(self, name: str):self.name = nameapp = FastAPI()@app.exception_handler(MichaelException)
async def michael_exception_handler(request: Request, exec: MichaelException):return JSONResponse(status_code=408,content = {"msg": "哦,{}出错了".format(exec.name)})@app.get("/test/{name}")
async def test(name: str):if name == "yoyo":raise MichaelException(name)return {"test_name" : name}

在这里插入图片描述

7. 覆盖默认异常处理器

from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponseapp = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):if item_id == 3:raise HTTPException(status_code=418, detail="3 is not a good number")return {"item_id" : item_id}

在这里插入图片描述

  • 更改 RequestValidationError 错误的处理 handler
from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponseapp = FastAPI()@app.exception_handler(RequestValidationError)
async def valid_excep_handler(req, exec):return PlainTextResponse(str(exec), status_code=400)@app.get("/items/{item_id}")
async def read_item(item_id: int):if item_id == 3:raise HTTPException(status_code=418, detail="3 is not a good number")return {"item_id" : item_id}

在这里插入图片描述
在这里插入图片描述

  • 同样的,处理 HTTPException 的 handler,自定义处理
from starlette.exceptions import HTTPException as StarletteHTTPException
# 跟 fastapi 的 HTTPException 一样
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(req, exc):return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

or

@app.exception_handler(HTTPException)
async def http_exception_handler(req, exc):return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

在这里插入图片描述

8. 使用 RequestValidationError 的请求体

RequestValidationError 包含其接收到的 无效数据请求的 body 。可以用这个请求体生成日志、调试错误,并返回给用户

from fastapi import FastAPI, Request, status
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from pydantic import BaseModelapp = FastAPI()@app.exception_handler(RequestValidationError)
async def valid_exception_handler(req: Request, exc: RequestValidationError):return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}),)class Item(BaseModel):title: strsize: int@app.post("/items/")
async def create_item(item: Item):return item

输入 非整数的 size ,得到报错 {"detail": exc.errors(), "body": exc.body}
在这里插入图片描述

9. 复用 FastAPI 异常处理器

  • 在自定义处理完异常之后,还可以继续使用 默认的异常处理器
from fastapi import FastAPI, HTTPException
from fastapi.exception_handlers import http_exception_handler, request_validation_exception_handler
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPExceptionapp = FastAPI()@app.exception_handler(StarletteHTTPException) # 自定义处理异常
async def custom_http_exception_handler(req, exc):print(f"OMG! An HTTP error!: {repr(exc)}")return await http_exception_handler(req, exc) # 再调用自带的异常处理器@app.exception_handler(RequestValidationError)
async def validation_exception_handler(req, exc):print(f"OMG! The client sent invalid data!: {exc}")return await request_validation_exception_handler(req, exc)@app.get("/items/{item_id}")
async def read_item(item_id: int):if item_id == 3:raise HTTPException(status_code=418, detail="Nope! I don't like 3.")return {"item_id": item_id}
INFO:     127.0.0.1:9594 - "GET /items/abc HTTP/1.1" 422 Unprocessable Entity
OMG! The client sent invalid data!: 1 validation error for Request
path -> item_idvalue is not a valid integer (type=type_error.integer)
INFO:     127.0.0.1:8106 - "GET /items/abc HTTP/1.1" 422 Unprocessable Entity
INFO:     127.0.0.1:10417 - "GET /items/1 HTTP/1.1" 200 OK
OMG! An HTTP error!: HTTPException(status_code=418, detail="Nope! I don't like 3.")
INFO:     127.0.0.1:10417 - "GET /items/3 HTTP/1.1" 418

10. 路径操作参数配置

10.1 status_code,tags

  • tags = [字符串],将反映到 文档中
from typing import Optional, Setfrom fastapi import FastAPI
from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strdescription: Optional[str] = Noneprice: floattax: Optional[float] = Nonetags: Set[str] = []@app.post("/items/", response_model=Item, tags=["items, ming"], status_code=201)
async def create_item(item: Item):return item@app.get("/items/", tags=["items"])
async def read_items():return [{"name": "Foo", "price": 42}]@app.get("/users/", tags=["michael"])
async def read_users():return [{"username": "johndoe"}]

在这里插入图片描述

10.2 summary,description

@app.post("/items/", response_model=Item, tags=["items, ming"], status_code=201,summary="创建item",description="描述item的一些信息")
async def create_item(item: Item):return item

在这里插入图片描述

  • description 也可以由 多行注释直接生成,支持 MD 格式
@app.post("/items/", response_model=Item, tags=["items, ming"], status_code=201,summary="创建item",)
async def create_item(item: Item):'''多行注释 --> description- **name**: each item must have a name- **description**: a long description- **price**: required- **tax**: if the item doesn't have tax, you can omit this- **tags**: a set of unique tag strings for this item'''return item

在这里插入图片描述

10.3 response description

  • response_description 参数
@app.post("/items/", response_model=Item, tags=["items, ming"], status_code=201,summary="创建item",response_description="响应的描述")
async def create_item(item: Item):'''多行注释 --> description,支持 MD 格式## 1. 标题- **name**: each item must have a name- **description**: a long description- **price**: required- **tax**: if the item doesn't have tax, you can omit this- **tags**: a set of unique tag strings for this item'''return item

在这里插入图片描述
在这里插入图片描述

10.4 deprecated 废除

  • deprecated
@app.get("/users/", tags=["michael"], deprecated=True)
async def read_users():return [{"username": "johndoe"}]

在这里插入图片描述

11. jsonable_encoder() 转换

  • jsonable_encoder()pydantic 模型等数据结构 转换为 与 json 兼容的格式(dict, list 等)
from datetime import datetime
from typing import Optionalfrom fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModelfake_db = {}class Item(BaseModel):title: strtimestamp: datetimedescription: Optional[str] = Noneapp = FastAPI()@app.put("/items/{id}")
def update_item(id: str, item: Item):json_data = jsonable_encoder(item)fake_db[id] = json_datareturn fake_db

在这里插入图片描述
这个例子把 Pydantic model 转换为 dict, 把 datetime 转换为 str

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

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

相关文章

fastapi PUT更新数据 / PATCH部分更新

文章目录1. PUT 更新2. 用 PATCH 进行部分更新learn from https://fastapi.tiangolo.com/zh/tutorial/body-updates/1. PUT 更新 注意&#xff0c;put 没有指定的值&#xff0c;会被重置为默认值 from typing import List, Optionalfrom fastapi import FastAPI from fastap…

Chrome 扩展 最近的历史 HistoryBar v1.1

说明 以前用过一段时间傲游浏览器&#xff0c;渐渐的习惯了它的鼠标手势和一些细微的人性化的功能。比方地址栏左边的“近期訪问的页面”button。能够方便的找到近期 20 条历史记录。 但后来因为某些原因又回到了 Chrome 的怀抱&#xff0c;于是就没有了这些不起眼但非常好用的…

LeetCode 2047. 句子中的有效单词数

文章目录1. 题目2. 解题1. 题目 句子仅由小写字母&#xff08;a 到 z&#xff09;、数字&#xff08;0 到 9&#xff09;、连字符&#xff08;-&#xff09;、标点符号&#xff08;!、. 和 ,&#xff09;以及空格&#xff08; &#xff09;组成。 每个句子可以根据空格分解成 …

LeetCode 2048. 下一个更大的数值平衡数(枚举)

文章目录1. 题目2. 解题1. 题目 如果整数 x 满足&#xff1a;对于每个数位 d &#xff0c;这个数位 恰好 在 x 中出现 d 次。 那么整数 x 就是一个 数值平衡数 。 给你一个整数 n &#xff0c;请你返回 严格大于 n 的 最小数值平衡数 。 示例 1&#xff1a; 输入&#xff1a…

LeetCode 2049. 统计最高分的节点数目(DFS)

文章目录1. 题目2. 解题1. 题目 给你一棵根节点为 0 的 二叉树 &#xff0c;它总共有 n 个节点&#xff0c;节点编号为 0 到 n - 1 。 同时给你一个下标从 0 开始的整数数组 parents 表示这棵树&#xff0c;其中 parents[i] 是节点 i 的父节点。 由于节点 0 是根&#xff0c;所…

python源文件编码的含义_【原创】Python 源文件编码解读

以下内容源于对 PEP-0263 的翻译和解读&#xff0c;同时给出了一些网上网友的说法。 我是分割线 PEP 0263 -- Defining Python Source Code Encodings【摘要】给出声明 Python 源文件编码的语法。该编码信息后续会被 Python 解析器用于解析源文件。这种方式增强了对源文件中 U…

MyEclipse中SVN的常见的使用方法

本次主要内容&#xff1a; 一 、导入项目 &#xff08;Checkout&#xff09;。从svn资源库检出 二 、更新 &#xff08;Update&#xff09; 三、锁&#xff08;对要修改的文件加锁&#xff0c;防止文件冲突&#xff09; 四、提交&#xff08;项目修改后的提交&#xff09; 五、…

fastapi 路径依赖项Depends / 装饰器依赖dependencies / 全局依赖 / 带 yield 的依赖

文章目录1. 依赖项2. 类作为依赖3. 子依赖项3.1 多次使用同一个依赖项4. 路径操作装饰器依赖项5. 全局依赖项6. 带 yield 的依赖项7. 使用带 yield 上下文管理器作为依赖项learn from https://fastapi.tiangolo.com/zh/tutorial/dependencies/ 1. 依赖项 只能传给 Depends 一…

fastapi 安全性 / APIRouter / BackgroundTasks / 元数据 / 测试调试

文章目录1. 例子2. 获取当前用户3. 使用密码和 Bearer 的简单 OAuth24. 使用&#xff08;哈希&#xff09;密码和 JWT Bearer 令牌的 OAuth25. 多个应用文件5.1 APIRouter6. BackgroundTasks7. 元数据7.1 标题、描述和版本7.2 openapi_tags 标签元数据7.3 OpenAPI URL7.4 文档 …

java json path_Java使用JSONPath解析JSON完整内容详解

JsonPath是一种简单的方法来提取给定JSON文档的部分内容。 JsonPath有许多编程语言&#xff0c;如Javascript&#xff0c;Python和PHP&#xff0c;Java。JsonPath提供的json解析非常强大&#xff0c;它提供了类似正则表达式的语法&#xff0c;基本上可以满足所有你想要获得的js…

LeetCode 2050. 并行课程 III(拓扑排序)

文章目录1. 题目2. 解题1. 题目 给你一个整数 n &#xff0c;表示有 n 节课&#xff0c;课程编号从 1 到 n 。 同时给你一个二维整数数组 relations &#xff0c;其中 relations[j] [prevCoursej, nextCoursej] &#xff0c;表示课程 prevCoursej 必须在课程 nextCoursej 之前…

LeetCode 1521. 找到最接近目标值的函数值(位运算)

文章目录1. 题目2. 解题1. 题目 Winston 构造了一个如上所示的函数 func 。他有一个整数数组 arr 和一个整数 target &#xff0c;他想找到让 |func(arr, l, r) - target| 最小的 l 和 r 。 请你返回 |func(arr, l, r) - target| 的最小值。 请注意&#xff0c; func 的输入参…

LeetCode 2053. 数组中第 K 个独一无二的字符串(哈希)

文章目录1. 题目2. 解题1. 题目 独一无二的字符串 指的是在一个数组中只出现过 一次 的字符串。 给你一个字符串数组 arr 和一个整数 k &#xff0c;请你返回 arr 中第 k 个 独一无二的字符串 。 如果 少于 k 个独一无二的字符串&#xff0c;那么返回 空字符串 “” 。 注意…

LeetCode 2055. 蜡烛之间的盘子(前缀和)

文章目录1. 题目2. 解题1. 题目 给你一个长桌子&#xff0c;桌子上盘子和蜡烛排成一列。 给你一个下标从 0 开始的字符串 s &#xff0c;它只包含字符 * 和 | &#xff0c;其中 * 表示一个 盘子 &#xff0c;| 表示一支 蜡烛 。 同时给你一个下标从 0 开始的二维整数数组 que…

策略模式java 用例_java策略模式简单用例

运用java策略模式一个小程序/****/package Strategy;import java.util.Arrays;/*** author HuangRong* Funtion 定义策略*/public interface ComputablesStra {public abstract void printForm();}/****/package Strategy;/*** author HuangRong* Function 为策略模式中的上下文…

LeetCode 2057. 值相等的最小索引

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的整数数组 nums &#xff0c;返回 nums 中满足 i mod 10 nums[i] 的最小下标 i &#xff1b;如果不存在这样的下标&#xff0c;返回 -1 。 x mod y 表示 x 除以 y 的 余数 。 示例 1&#xff1a; 输入&#xff1a;num…

LeetCode 2058. 找出临界点之间的最小和最大距离(链表)

文章目录1. 题目2. 解题1. 题目 链表中的 临界点 定义为一个 局部极大值点 或 局部极小值点 。 如果当前节点的值 严格大于 前一个节点和后一个节点&#xff0c;那么这个节点就是一个 局部极大值点 。 如果当前节点的值 严格小于 前一个节点和后一个节点&#xff0c;那么这个…

LeetCode 2059. 转化数字的最小运算数(BFS)

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的整数数组 nums &#xff0c;该数组由 互不相同 的数字组成。另给你两个整数 start 和 goal 。 整数 x 的值最开始设为 start &#xff0c;你打算执行一些运算使 x 转化为 goal 。你可以对数字 x 重复执行下述运算&…

又是一年国庆假期最后一天

时间过的真的很快啊&#xff0c;美好的日子已经快过完了&#xff0c;在长假的最后一天&#xff0c;有很多的朋友可能都会抱怨&#xff0c;不想上班了&#xff0c;好想在好好的玩玩。开开心心的过完了假期的前六天&#xff0c;当突然被告知明天就是最后一天&#xff0c;你会有什…

LeetCode 2062. 统计字符串中的元音子字符串

文章目录1. 题目2. 解题1. 题目 子字符串 是字符串中的一个连续&#xff08;非空&#xff09;的字符序列。 元音子字符串 是 仅 由元音&#xff08;a、e、i、o 和 u&#xff09;组成的一个子字符串&#xff0c;且必须包含 全部五种 元音。 给你一个字符串 word &#xff0c;…