Общая модель ответа fastapi

Я пытаюсь стандартизировать свои ответы в своих маршрутах.

Например:

ErrorDescription = TypeVar("ErrorDescription")

class PydanticBaseModel(BaseModel):
    """
    Base model for RequestsBody/Responses
    """

    model_config = ConfigDict(
        alias_generator=alias_generators.to_camel,
        populate_by_name=True,
        from_attributes=True,
        arbitrary_types_allowed=True,
    )

class BadResponse(
    PydanticBaseModel,
    Generic[ErrorDescription]
):
    status_code: conint(ge=400, le=499)
    error: ErrorDescription

    @classmethod
    def new(cls, *, status_code: int, error: ErrorDescription):
        return cls(status_code=status_code, error=error)

А затем используйте его так:

app = FastAPI()

@app.get("tmp")
def tmp(
):
    return BadResponse.new(status_code=status.HTTP_404_NOT_FOUND, error = "Not found")

Но, конечно, реальный статус ответа будет 200. Есть ли способ сделать так, чтобы оба статуса были одинаковыми?

Кажется, я не понимаю вашего вопроса. Вы хотите, чтобы всех ответов было 200?

drum 06.04.2024 15:57

Желаемое поведение @drum — это когда в теле ответа код status_code равен X, реальный статус также имеет X

haku 06.04.2024 16:25

Пожалуйста, обновите свой вопрос, чтобы было яснее. Также укажите фактические и ожидаемые ответы. Учитывая всю вашу информацию, я смогу воспроизвести вашу проблему локально.

drum 06.04.2024 16:33

Единственный способ сделать это — вызвать HTTPException.

drum 06.04.2024 18:57
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Самый гибкий способ, вероятно, — использовать пользовательский Response, который учитывает ваше конкретное правило изменения кода состояния:

class JSONStatusCodeAwareResponse(JSONResponse):
    def render(self, content: Any) -> bytes:
        # be aware that if you have a key named `status_code` somewhere else in your
        # application and return it as a base level key, this will override that as well.
        # - but since the Pydantic object has already been converted to a dict here,
        #   we'll work with what we have. This also works for a future GoodResponse.
        if isinstance(content, dict) and 'status_code' in content:
            self.status_code = content['status_code']
            
        return super().render(content=content)
        
 
@app.get("/foo", response_class=JSONStatusCodeAwareResponse)
def foo():
    return BadResponse.new(status_code=404, error = "Not found")

Если вы хотите использовать это значение по умолчанию на всех ваших конечных точках, вы можете настроить его в своем объекте FastAPI app, чтобы, если он не будет переопределен явно, использовался ваш класс ответа:

app = FastAPI(default_response_class=JSONStatusCodeAwareResponse)

Это также справедливо для экземпляра APIRouter, если вы хотите использовать его для определенной части вашего приложения.

Другие вопросы по теме