Теперь, когда мы увидели, как использовать Path и Query параметры, давайте рассмотрим более продвинутые примеры обьявления тела запроса.
Обьединение Path, Query и параметров тела запроса¶
Во-первых, конечно, вы можете объединять параметры Path, Query и объявления тела запроса в своих функциях обработки, FastAPI автоматически определит, что с ними нужно делать.
Вы также можете объявить параметры тела запроса как необязательные, установив значение по умолчанию, равное None:
fromtypingimportAnnotatedfromfastapiimportFastAPI,PathfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:Annotated[int,Path(title="The ID of the item to get",ge=0,le=1000)],q:str|None=None,item:Item|None=None,):results={"item_id":item_id}ifq:results.update({"q":q})ifitem:results.update({"item":item})returnresults
fromtypingimportAnnotated,UnionfromfastapiimportFastAPI,PathfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:Annotated[int,Path(title="The ID of the item to get",ge=0,le=1000)],q:Union[str,None]=None,item:Union[Item,None]=None,):results={"item_id":item_id}ifq:results.update({"q":q})ifitem:results.update({"item":item})returnresults
fromtypingimportUnionfromfastapiimportFastAPI,PathfrompydanticimportBaseModelfromtyping_extensionsimportAnnotatedapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(item_id:Annotated[int,Path(title="The ID of the item to get",ge=0,le=1000)],q:Union[str,None]=None,item:Union[Item,None]=None,):results={"item_id":item_id}ifq:results.update({"q":q})ifitem:results.update({"item":item})returnresults
Заметка
Рекомендуется использовать Annotated версию, если это возможно.
fromfastapiimportFastAPI,PathfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:str|None=Noneprice:floattax:float|None=None@app.put("/items/{item_id}")asyncdefupdate_item(*,item_id:int=Path(title="The ID of the item to get",ge=0,le=1000),q:str|None=None,item:Item|None=None,):results={"item_id":item_id}ifq:results.update({"q":q})ifitem:results.update({"item":item})returnresults
Заметка
Рекомендуется использовать версию с Annotated, если это возможно.
fromtypingimportUnionfromfastapiimportFastAPI,PathfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:strdescription:Union[str,None]=Noneprice:floattax:Union[float,None]=None@app.put("/items/{item_id}")asyncdefupdate_item(*,item_id:int=Path(title="The ID of the item to get",ge=0,le=1000),q:Union[str,None]=None,item:Union[Item,None]=None,):results={"item_id":item_id}ifq:results.update({"q":q})ifitem:results.update({"item":item})returnresults
Заметка
Заметьте, что в данном случае параметр item, который будет взят из тела запроса, необязателен. Так как было установлено значение None по умолчанию.
Обратите внимание, что хотя параметр item был объявлен таким же способом, как и раньше, теперь предпологается, что он находится внутри тела с ключом item.
FastAPI сделает автоматические преобразование из запроса, так что параметр item получит своё конкретное содержимое, и то же самое происходит с пользователем user.
Произойдёт проверка составных данных, и создание документации в схеме OpenAPI и автоматических документах.
Точно так же, как Query и Path используются для определения дополнительных данных для query и path параметров, FastAPI предоставляет аналогичный инструмент - Body.
Например, расширяя предыдущую модель, вы можете решить, что вам нужен еще один ключ importance в том же теле запроса, помимо параметров item и user.
Если вы объявите его без указания, какой именно объект (Path, Query, Body и .т.п.) ожидаете, то, поскольку это является простым типом данных, FastAPI будет считать, что это query-параметр.
Но вы можете указать FastAPI обрабатывать его, как ещё один ключ тела запроса, используя Body:
Предположим, у вас есть только один body-параметр item из Pydantic модели Item.
По умолчанию, FastAPI ожидает получить тело запроса напрямую.
Но если вы хотите чтобы он ожидал JSON с ключом item с содержимым модели внутри, также как это происходит при объявлении дополнительных body-параметров, вы можете использовать специальный параметр embed у типа Body: