简体   繁体   English

如何使用 FastAPI 从 Pydantic model 中排除可选的未设置值?

[英]How to exclude Optional unset values from a Pydantic model using FastAPI?

I have this model:我有这个 model:

class Text(BaseModel):
    id: str
    text: str = None


class TextsRequest(BaseModel):
    data: list[Text]
    n_processes: Union[int, None]

So I want to be able to take requests like:所以我希望能够接受如下请求:

{"data": ["id": "1", "text": "The text 1"], "n_processes": 8} 

and

{"data": ["id": "1", "text": "The text 1"]}.

Right now in the second case I get现在在第二种情况下我得到

{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}

using this code:使用此代码:

app = FastAPI()

@app.post("/make_post/", response_model_exclude_none=True)
async def create_graph(request: TextsRequest):
    input_data = jsonable_encoder(request)

So how can I exclude n_processes here?那么如何在这里排除n_processes呢?

You can use exclude_none param of dict() :您可以使用dict()exclude_none参数:

class Text(BaseModel):
    id: str
    text: str = None


class TextsRequest(BaseModel):
    data: list[Text]
    n_processes: Optional[int]



request = TextsRequest(**{"data": [{"id": "1", "text": "The text 1"}]})
print(request.dict(exclude_none=True))

Output: Output:

{'data': [{'id': '1', 'text': 'The text 1'}]}

Also, it's more idiomatic to write Optional[int] instead of Union[int, None]此外,写Optional[int]而不是Union[int, None]更惯用

Pydantic provides the following arguments for exporting models using the model.dict(...) method: Pydantic 提供以下 arguments 用于使用model.dict(...)方法导出模型:

exclude_unset : whether fields which were not explicitly set when creating the model should be excluded from the returned dictionary; exclude_unset :是否应从返回的字典中排除在创建 model 时未明确设置的字段; default False默认False

exclude_none : whether fields which are equal to None should be excluded from the returned dictionary; exclude_none :是否应该从返回的字典中排除等于 None 的字段; default False默认False

Since you are refering to excluding optional unset parameters, you can use the first method (ie, exclude_unset ).由于您指的是排除可选的未设置参数,因此您可以使用第一种方法(即exclude_unset )。 This is useful when one would like to exclude a parameter only if it has not been set to either some value or None .当一个参数没有设置为某个值或None时,这很有

The exclude_none argument, however, ignores that fact that an attribute may have been intentionally set to None , and hence, excludes it from the returned dictionary.但是, exclude_none参数忽略了一个属性可能已被有意设置为None的事实,因此将其从返回的字典中排除。

Example:例子:

from pydantic import BaseModel
from typing import List, Union

class Text(BaseModel):
    id: str
    text: str = None

class TextsRequest(BaseModel):
    data: List[Text]    # in Python 3.9+ you can use:  data: list[Text]
    n_processes: Union[int, None] = None

t = TextsRequest(**{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None})
print(t.dict(exclude_none=True))
#> {'data': [{'id': '1', 'text': 'The text 1'}]}
print(t.dict(exclude_unset=True))
#> {'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}

About Optional Parameters关于可选参数

Using Union[int, None] is the same as using Optional[int] = None or int | None使用Union[int, None]与使用Optional[int] = Noneint | None相同。 int | None (in Python 3.10+). int | None (在 Python 3.10+ 中)。 However, as per FastAPI documentation (see admonition Note and Info in the link provided):但是,根据FastAPI 文档(请参阅提供的链接中的警告说明信息):

Note笔记

FastAPI will know that the value of q is not required because of the default value = None . FastAPI 将知道q的值不是必需的,因为默认值= None

The Union in Union[str, None] will allow your editor to give you better support and detect errors. Union Union[str, None]中的 Union 将允许您的编辑器为您提供更好的支持并检测错误。

Info信息

Have in mind that the most important part to make a parameter optional is the part: = None , as it will use that None as the default value, and that way make the parameter not required .请记住,使参数成为可选的最重要部分是 part: = None ,因为它将使用None作为默认值,并且这样使参数不是 required

The Union[str, None] part allows your editor to provide better support, but it is not what tells FastAPI that this parameter is not required . Union[str, None]部分允许您的编辑器提供更好的支持,但这并不是告诉 FastAPI这个参数不是必需的。

Hence, regardless of the option (ie, Union , Optional , etc.) one may decide to use, if it is not followed by the = None part, FastAPI won't know that the value of the parameter is not required , and hence, the user will have to provide some value for it.因此,无论选项(即UnionOptional等)如何决定使用,如果它后面= None部分,FastAPI 将不知道参数的值是不需要的,因此,用户必须为其提供一些价值。 One can also check this through the auto-generated API docs at http://127.0.0.1:8000/docs , where the parameter or request body will appear as a Required field.也可以通过自动生成的 API 文档在http://127.0.0.1:8000/docs中检查这一点,其中parameterrequest body将显示为Required字段。

For example:例如:

@app.post("/upload")
def upload(t: Union[TextsRequest, None]):
def upload(t: Optional[TextsRequest]):
def upload(t: TextsRequest | None):

any of the above would require the user to pass some body for the TextsRequest model in their request.以上任何一项都需要用户在他们的请求中为TextsRequest model 传递一些正文。 If, however, the above TextsRequest definitions were succeeded by = None (eg, t: Union[TextsRequest, None] = None , or even simply t: TextsRequest = None ), the parameter or body would be optional (as = None would tell FastAPI that this parameter is not required ).但是,如果上面的TextsRequest定义由= None成功(例如, t: Union[TextsRequest, None] = None ,或者甚至只是t: TextsRequest = None ),则parameterbody将是optional的(因为= None会告诉FastAPI 表示此参数不是必需的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM