Полностью используйте FastApi — изящно возвращайте ошибки исключения

Python

Нажмите «Программирование Python и реальный бой», выберите «Официальная учетная запись Zhiding»\

Получите техническую галантерею Python впервые!

При разработке интерфейса или сервиса часто встречается необходимость возврата клиенту ошибки исключения, например: \

  • Разрешения пользователя недостаточно
  • Ошибка параметра
  • Запрошенный ресурс не существует.

Как мы все знаем, если ошибка вызвана клиентом или вызывающей стороной, возвращаемый код состояния начинается с 4 (400~499).

такие как общие404 Not Found, ресурса нет...

Для интуитивного и удобного возврата ошибок клиенту обычно используется в FastApi.HTTPException

from fastapi import FastAPI, HTTPException

app = FastAPI()

items = {"foo": "The Foo Wrestlers"}


@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]}

При обнаружении ненормального запроса пользователя вы можете использоватьraiseгенерировать исключение

Если возникает исключение, запрос будет немедленно завершен, аHTTPошибка отHTTPExceptionОтправить клиенту или браузеру

Например: введите в браузереhttp://127.0.0.1:8000/items/jerry

потому чтоjerryне тамitems, браузер получит 404 иjsonформатированныйresponse

Примечание. Этот файл json автоматически обрабатывается и преобразуется FastAPI.

пользовательский класс исключений

Подобно обработке исключений в исходном коде starlette, вы также можете настроить класс обработки исключений, определенный классом обработки исключений, используя@app.exception_handler()Поддержка глобального использования этого класса исключений в FastAPI.

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse


class UnicornException(Exception):
    def __init__(self, name: str):
        self.name = name

app = FastAPI()

@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
    return JSONResponse(
        status_code=418,
        content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
    )

В функции маршрутизации используйте класс

@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
    if name == "yolo":
        raise UnicornException(name=name)
    return {"unicorn_name": name}

После запуска службы запросите путь службы/unicorns/yolo

На стороне клиента вы можете получить дружественную подсказку и заранее определить код состояния418быстрая ошибка

Переопределить класс исключений по умолчанию

FastAPI имеет множество классов обработки исключений по умолчанию.

Эти обработчики отвечают за поднятиеHTTPExceptionи вернуть значение по умолчанию, когда запрос содержит неверные данныеJSONотклик

Например, следующие маршруты поддерживаются толькоitem_idзаintтип функции пути

@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}

при отправке с клиентаitem_idибо неintтип, он возвращает значение по умолчаниюJSONотклик

Вы можете переопределить эти классы обработки исключений по умолчанию и сделать их настраиваемыми. Например

Переопределить класс исключения проверки запроса

Когда запрос содержит неверные данные запроса, FastAPI сработает.RequestValidationError

Чтобы переопределить класс обработки исключений, вам нужно импортироватьRequestValidationErrorи использовать@app.exception_handler(RequestValidationError)Украсьте обработчики исключений

from fastapi.exceptions import RequestValidationError

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
    return PlainTextResponse(str(exc), status_code=400)

Объедините эту часть кода с приведенным выше кодом и запустите его. Если вы запросите еще раз, вы увидите другое приглашение~~~

Переопределить HTTPException

Точно так же вы также можете переопределитьHTTPExceptionобработчик

Например, вы хотите вернуть текстовое сообщение об ошибке вместо сообщения по умолчанию.JSONсообщение об ошибке форматирования

Как указано выше, используйте@app.exception_handler(HTTPException)Просто украсьте обработчик исключений

from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPException

app = FastAPI()

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

@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}

вернуть тело запроса исключения

При получении незаконного запросаRequestValidationErrorсодержит тело запроса исключения, но не возвращает нам

Но при разработке приложения или отладке с интерфейсом вы можете добавить тело запроса к возвращаемомуresponseсередина

Таким образом, когда возникает проблема, вы можете быстро найти проблему с помощью журналов или ответов!

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 BaseModel

app = FastAPI()

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: 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: str
    size: int

@app.post("/items/")
async def create_item(item: Item):
    return item

Давайте вызовем исключение, такое как тело запроса:

{
  "title": "towel",
  "size": "XL"
}

Для ненормального запроса полученный ответ будет содержать запрос ненормального запроса.body

{
  "detail": [
    {
      "loc": [
        "body",
        "size"
      ],
      "msg": "value is not a valid integer",
      "type": "type_error.integer"
    }
  ],
  "body": {
    "title": "towel",
    "size": "XL"
  }
}

При совместной отладке или разработке вы можете сэкономить лишнее время и повысить эффективность!

Рекомендуемое чтение

Полностью используйте FastApi — три параметра и проверка

Полное использование FastApi — планирование структуры проекта с несколькими приложениями

\