Исключение «Объект типа EXAMPLE_TYPE не является сериализуемым в формате JSON», возникающее при возврате ответа FastAPI Python

Программы на Python
Ответить
Anonymous
 Исключение «Объект типа EXAMPLE_TYPE не является сериализуемым в формате JSON», возникающее при возврате ответа FastAPI

Сообщение Anonymous »

Структура моей системы состоит из двух частей:
  • Имеется интерфейс веб-сервера FastAPI, который содержит некоторую базовую логику
  • Существует класс, который содержит всю основную логику, назовем его KeyValueStore для этого примера.
Основная логика может поднимать исключения. Я не уверен, как мне следует обрабатывать их на уровне FastAPI.
Скажем, основная логика так же проста, как структура данных, в которой хранятся пары ключ-значение:

Код: Выделить всё

class KeyValueStore():
def __init__(self):
self.data = {}
def put(self, key, value):
if key in self.data:
raise RuntimeError(f'duplicate key {key}')
self.data[key] = value
def get(self, key):
# doesn't really matter what the implementation is
Как видите, если KeyValueStore.put() вызывается с ключом, который ранее использовался, это приводит к ошибке времени RuntimeError поднято.
Это фиксируется на уровне FastAPI. Код выглядит примерно так:

Код: Выделить всё

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi import status
from pydantic import BaseModel

class FastAPI_KeyValuePair(BaseModel):
key: str
value: str

class FastAPI_ReturnStatus(BaseModel):
status: str
message: str|None = None

@app.post('/put_key_value')
def put_key_value(key_value_pair: FastAPI_KeyValuePair):
try:
key_value_store.put(
key_value_pair.key,
key_value_pair.value,
)
return FastAPI_ReturnStatus(status='success', message=None)
except RuntimeError as error:
return JSONResponse(
status_code=status.HTTP_409_CONFLICT,
content=FastAPI_ReturnStatus(
status='error',
message=str(error),
)
)
В данном конкретном случае я хочу вернуть код состояния 409 Conflict, но я не был уверен, как это сделать, одновременно возвращая некоторое тело JSON.
Обычный оператор возврата выглядит примерно так:

Код: Выделить всё

return FastAPI_ReturnStatus(status='success', message=None)
Если я правильно понимаю, FastAPI сериализует этот тип в JSON с помощью json.dumps. Этот сериализованный контент будет возвращен в качестве тела ответа. Кроме того, код состояния автоматически устанавливается на 200.
Я хотел установить для этого кода состояния что-нибудь другое, например 409. Я не смог найти способа сделать это, кроме как с помощью JSONResponse:

Код: Выделить всё

return JSONResponse(
status_code=status.HTTP_409_CONFLICT,
content=FastAPI_ReturnStatus(
status='error',
message=str(error),
)
)
Я не знаю, действительно ли это правильный подход. Я просто решил использовать JSONResponse, поскольку другого способа вернуть тело JSON и установить код состояния ошибки (в данном случае 409) не было.
Что на самом деле происходит с этим кодом, так это то, что я получаю исключение:

Код: Выделить всё

TypeError: Object of type FastAPI_ReturnStatus is not JSON serializable
Это меня смущает, поскольку этот тип является сериализуемым в формате JSON. Должно быть, потому что строка:

Код: Выделить всё

return FastAPI_ReturnStatus(status='success', message=None)
работает.
Почему FastAPI_ReturnStatus не сериализуется в этом контексте, но сериализуется, если тип возвращаемого значения — FastAPI_ReturnStatus (не вложен в какой-либо другой объект)?

Подробнее здесь: https://stackoverflow.com/questions/787 ... n-when-ret
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»