Я пытаюсь стандартизировать свои ответы в своих маршрутах.
Например:
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. Есть ли способ сделать так, чтобы оба статуса были одинаковыми?
Желаемое поведение @drum — это когда в теле ответа код status_code равен X, реальный статус также имеет X
Пожалуйста, обновите свой вопрос, чтобы было яснее. Также укажите фактические и ожидаемые ответы. Учитывая всю вашу информацию, я смогу воспроизвести вашу проблему локально.
Единственный способ сделать это — вызвать HTTPException.
Самый гибкий способ, вероятно, — использовать пользовательский 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, если вы хотите использовать его для определенной части вашего приложения.
Кажется, я не понимаю вашего вопроса. Вы хотите, чтобы всех ответов было 200?