Около трёх недель назад появилась одна из самых ожидаемых функций FastAPI. По крайней мере, когда мы говорим о моделях Pydantic FastAPI.
Да, я говорю о возможности использовать модели Pydantic для сопоставления параметров вашего запроса.
Итак, в этом посте я постараюсь показать вам все, что вы ? может и? не могу поделать с этой темой ?:
Первое, что вам нужно сделать, чтобы начать сопоставление параметров запроса с помощью Pydantic, — это убедиться, что вы используете FastAPI версии 0.115.0.
После этого вы всегда можете перейти к документации FastAPI, чтобы проверить, что уже доступно. Себастьян и члены команды очень, очень хорошо работают над обновлением и информативностью документации ✨.
Давайте начнем с нескольких примеров того, как мы использовали для сопоставления параметров запроса в FastAPI. ?
Самый простой способ сделать это:
from fastapi import FastAPI app = FastAPI() @app.get("/") async def search( limit: int | None = 10, skip: int | None = 1, filter: str | None = None ): return { "limit": limit, "skip": skip, "filter": filter }
А теперь вы можете просто позвонить:
GET http://localhost:8000/?limit=42&skip=12&filter=banana
Но если бы мы определили, что эти параметры запроса будут использоваться в других маршрутах, мы бы изолировали их с помощью чего-то вроде:
from typing import Any from fastapi import Depends, FastAPI, Query app = FastAPI() async def pagination_query_string( limit: int | None = Query(10, ge=5, le=100), skip: int | None = Query(1, ge=1), filter: str | None = Query(None) ) -> dict[str, Any]: return { "limit": limit, "skip": skip, "filter": filter } @app.get("/") async def search(q: dict[str, Any] = Depends(pagination_query_string)): return q
Или, поскольку мы используем Pydantic для отображения наших моделей, после небольшого рефакторинга мы получим:
from fastapi import Depends, FastAPI, Query from pydantic import BaseModel app = FastAPI() class PaginationQueryString(BaseModel): limit: int | None = 10 skip: int | None = 1 filter: str | None = None async def pagination_query_string( limit: int | None = Query(10, ge=5, le=100), skip: int | None = Query(1, ge=1), filter: str | None = Query(None) ) -> PaginationQueryString: return PaginationQueryString( limit=limit, skip=skip, filter=filter ) @app.get("/") async def search(q: PaginationQueryString = Depends(pagination_query_string)): return q
Теперь, если мы хотим получить строку запроса, нам не нужно создавать функцию, а затем добавлять ее в качестве зависимости. Мы можем просто сообщить FastAPI, что нам нужен объект типа PaginationQueryString и что это строка запроса:
from typing import Annotated from fastapi import FastAPI, Query from pydantic import BaseModel app = FastAPI() class PaginationQueryString(BaseModel): limit: int | None = 10 skip: int | None = 1 filter: str | None = None @app.get("/") async def search(q: Annotated[PaginationQueryString, Query()]): return q
Легко, правда? ?
По крайней мере, в версии 0.115.0 это не очень хорошо работает с вложенными моделями.
Давайте попробуем что-нибудь вроде:
from typing import Annotated from fastapi import FastAPI, Query from pydantic import BaseModel app = FastAPI() class Filter(BaseModel): name: str | None = None age: int | None = None nickname: str | None = None class PaginationQueryString(BaseModel): limit: int | None = 10 skip: int | None = 1 filter: Filter | None = None @app.get("/") async def search(q: Annotated[PaginationQueryString, Query()]): return q
Если мы назовем это как раньше:
GET http://localhost:8000/?limit=42&skip=12&filter=chocolate
Мы получим сообщение об ошибке, сообщающее, что фильтр является объектом:
{ "detail": [ { "type": "model_attributes_type", "loc": [ "query", "filter" ], "msg": "Input should be a valid dictionary or object to extract fields from", "input": "chocolate" } ] }
По крайней мере сейчас, это абсолютно правильно! Мы изменили наш фильтр, чтобы он стал моделью Pydantic, а не строкой. Но если мы попытаемся преобразовать его в словарь:
http://localhost:8000/?limit=42&skip=12&filter={"name": "Rafael", "age": 38, "nickname": "ceb10n"}
FastAPI сообщит нам, что фильтр должен быть действительным словарем ?:
{ "detail": [ { "type": "model_attributes_type", "loc": [ "query", "filter" ], "msg": "Input should be a valid dictionary or object to extract fields from", "input": "{\"name\": \"Rafael\", \"age\": 38, \"nickname\": \"ceb10n\"}" } ] }
Это происходит потому, что FastAPI будет полагаться на QueryParams Starlette, который передает FastAPI строку, а не словарь. И по крайней мере в версии 0.115.0 это выдаст ошибку.
Все очень просто:
✅ У вас есть простые строки запроса, для которых не нужны сложные вложенные объекты? Используйте это! ?
❌ Вы создали сложную вложенную строку запроса? Еще не пользуетесь? (И, возможно, вам стоит попытаться переосмыслить строки запроса. ? Чем проще, тем лучше?)
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3