10.FastAPI响应体

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10.FastAPI响应体相关的知识,希望对你有一定的参考价值。

参考技术A 在FastAPI 中,使用 response_model 的作用:

代码示例:

在上面的代码中,输入模型为UsrIn,输出模型为UsrOut,通过输出模型来屏蔽pwd字段的输出。执行请求:

在FastAPI中,响应模型也可以具有默认值。

代码示例:

执行请求:

从上面的代码执行结果可以看出:当在实际输出中没有定义对应的字段属性值时,使用响应模型的默认值输出。如果希望响应结果中不输出默认值,仅输出实际数据,则可以在 可以设置路由操作装饰器的 response_model_exclude_unset 参数为真,下面代码在路由中增加该参数,代码如下:

执行请求:

在以上情况下,如果实际数据值与默认值相同,那么FastAPI仍然会输出,也就是说,当设置response_model_exclude_unset=True时,其输出是按照实际值输出的。下面将代码'id': 'p2', 'name': '百合花', 'price': 12.8中的price字段值修改为10.0,然后执行请求:

从上面的执行结果可以看出:虽然实际数据值与默认值相同,但仍然会输出。如果此时,不希望输出与默认值相同的数据值,可以设置 response_model_exclude_defaults参数为True,代码片段如下:

执行请求:

在上面的执行结果中:"id":"p2","name":"百合花"没有输出price字段的实际数据值,因为与默认值相同。

另外还有一个装饰器参数: response_model_exclude_none,如果设置该参数为True,则表示在响应模型中不输出None值。代码片段如下:

执行请求:

可以使用装饰器参数response_model_include 和 response_model_exclude来显式指明包含或者排除的字段,这两个参数接受由字符串组成的set类型,也可以使用list或tuple,但使用list或tuple最终会转换为set类型。

在Python中,set类型使用一组花括号定义,如:'sex', 'name'。

代码示例:

执行请求:

在FastAPI中,响应模型可以设置为多个类型的Union,响应为多种类型中的一种;定义该类型使用标准的Python类型提示typing.Union,原则上应该是先使用详细的类型,然后使用粗略的类型。代码示例:

执行请求:

在FastAPI中,如果事先不确定返回值的键名称,但可以确定返回的数据类型,那么,可以使用只包含类型的dict作为响应模型,使用 typing.Dict。示例代码如下:

执行请求:

FastAPI Web框架 [1.4]

学习,做个记录

请求体 - 多个参数

from fastapi import FastAPI,Path,Body
from typing import Optional
from pydantic import BaseModel

app=FastAPI()

#   混合使用 Path、Query 和请求体参数声明
class Item(BaseModel):
    name:str
    description:Optional[str] = None
    price:float
    tax:Optional[float]=None

@app.put("/items/item_id")
async def update_item(
        *,
        item_id:int=Path(...,title="The ID of the item to get",ge=0,le=1000),
        q:Optional[str] = None,
        item:Optional[Item] = None,         #   将从请求体获取的 item 是可选的。因为它的默认值为 None
):
    results =  "item_id":item_id
    if q:
        results.update("q":q)
    if item:
        results.update("item":item)
    return results

#   多个请求体参数
#   声明多个请求体参数,例如 item 和 user:
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

class User(BaseModel):
    username:str
    full_name:Optional[str] = None

@app.put("/items/item_id")
async def update_item(
        item_id:int,
        item:Item,
        user:User
):
    results = 
        "item_id":item_id,
        "item":item,
        "user":user
    
    return results

# 请求体中的单一值
#  为了扩展先前的模型,你可能决定除了 item 和 user 之外,还想在同一请求体中具有另一个键 importance。
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

class User(BaseModel):
    username:str
    full_name:Optional[str] = None

@app.put("/items/item_id")
async def update_item(
        item_id:int,item:Item,user:User,importance:int = Body(...)
):
    results = 
        "item_id":item_id,
        "item":item,
        "user":user,
        "importance":importance
    
    return results
#   FastAPI 将期望像这样的请求体:
#   
#     "item": 
#         "name": "Foo",
#         "description": "The pretender",
#         "price": 42.0,
#         "tax": 3.2
#     ,
#     "user": 
#         "username": "dave",
#         "full_name": "Dave Grohl"
#     ,
#     "importance": 5
# 


#   多个请求体参数和查询参数
#   除了请求体参数外,你还可以在任何需要的时候声明额外的查询参数。
#   由于默认情况下单一值被解释为查询参数,因此你不必显式地添加 Query,你可以仅执行以下操作: q: str = None
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

class User(BaseModel):
    username:str
    full_name:Optional[str] = None

@app.put("/items/item_id")
async def update_item(
        *,
        item_id:int,
        item:Item,
        user:User,
        importance:int = Body(...,gt=0),
        q:Optional[str] = None          #可选的q
):
    results = 
        "item_id":item_id,
        "item":item,
        "user":user,
        "importance":importance
    
    if q:
        results.update("q":q)
    return results
#  Body 同样具有与 Query、Path 以及其他后面将看到的类完全相同的额外校验和元数据参数。



#   嵌入单个请求体参数
#   假设你只有一个来自 Pydantic 模型 Item 的请求体参数 item。
#   默认情况下,FastAPI 将直接期望这样的请求体。
#   但是,如果你希望它期望一个拥有 item 键并在值中包含模型内容的 JSON,就像在声明额外的请求体参数时所做的那样,则可以使用一个特殊的 Body 参数 embed:
#   item: Item = Body(..., embed=True)
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.put("/items/item_id")
async def update_item(
        item_id:int,
        item:Item = Body(...,embed=True)
):
    results = 
        "item_id":item_id,
        "item":item
    
    return results
#   在这种情况下,FastAPI 将期望像这样的请求体:
#   
#     "item": 
#         "name": "Foo",
#         "description": "The pretender",
#         "price": 42.0,
#         "tax": 3.2
#     
# 
#   ##而不是:!!!!
#   
#     "name": "Foo",
#     "description": "The pretender",
#     "price": 42.0,
#     "tax": 3.2
# 

##      总结!
#   你可以添加多个请求体参数到路径操作函数中,即使一个请求只能有一个请求体。
# 但是 FastAPI 会处理它,在函数中为你提供正确的数据,并在路径操作中校验并记录正确的模式。
# 你还可以声明将作为请求体的一部分所接收的单一值。
# 你还可以指示 FastAPI 在仅声明了一个请求体参数的情况下,将原本的请求体嵌入到一个键中。

以上是关于10.FastAPI响应体的主要内容,如果未能解决你的问题,请参考以下文章

覆盖 fastAPI 的 HTTPException 响应体

fastapi教程翻译(四):Request Body(请求体)

04 FastApi的请求体

FastAPI 中间件窥探响应

FastAPI 学习之路请求体有多个参数如何处理?

[FastAPI-14]pydantic多个请求体