Объект типа EXAMPLE_TYPE не подлежит сериализации JSON.Python

Программы на Python
Anonymous
Объект типа EXAMPLE_TYPE не подлежит сериализации JSON.

Сообщение 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, но не знаю, как это сделать, одновременно возвращая тело 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),
)
)
Что на самом деле происходит с этим кодом, так это то, что я получаю исключение:

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

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 ... rializable

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