FastAPI - использование вложенной модели дает ошибку сериализации JSON

Я пытаюсь использовать вложенные модели в вызове POST. Цель состоит в том, чтобы создать пользователя в моем экземпляре Keycloak с помощью API, поэтому я создал в соответствии с документацией нужную мне модель.

Когда я пытаюсь создать пользователя с Postman, используя свой API, fastAPI выдает следующую ошибку:

Object of type Attributes is not JSON serializable

Код следующий:

user.py

from pydantic import BaseModel


# TODO Error: Object of type Attributes is not JSON serializable.
class Attributes(BaseModel):
    locale: str
    phoneNumber: str

    class Config:
        orm_mode = True


class Credentials(BaseModel):
    value: str
    type: str

    class Config:
        orm_mode = True


class User(BaseModel):
    email: str
    username: str
    enabled: bool
    firstName: str
    lastName: str
    attributes: Attributes
    credentials: list[Credentials]

    class Config:
        orm_mode = True

create_user.py

def create_new_keycloak_user(user: User):
    admin = keycloak_service.connect_to_keycloak_as_admin()
    try:
        body = vars(user)
        print(body)
        new_user = admin.create_user(body)
        return new_user
    except Exception as err:
        raise HTTPException(status_code=400, detail=f"User creation failed: {err}")

маршрутизация.py

# I also have tried without response_model=User

@router.post("/create-user", response_model=User)
async def create_new_user(user: User):
    create_user.create_new_keycloak_user(user)
    return user

Тело, которое я получаю в бэкэнде, когда пытаюсь создать пользователя:

{'email': '[email protected]', 'username': 'mverdi', 'enabled': True, 'firstName': 'Jhon', 'lastName': 'Doe', 'attributes': Attributes(locale='ITA', phoneNumber='+391234567891'), 'credentials': [Credentials(value='superpassword01', type='password')]}

Я думаю, что это связано с этим «деформированным» JSON, если вы заметили в предыдущем JSON, который у меня есть

'attributes': Attributes(locale='ITA', phoneNumber='+391234567891'),

что явно не разрешено в правильном формате JSON. Но почему я получаю в результате нечто подобное?

Использование FastAPI с Python3.10 и Pydantic

Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я решил это. Проблема была в файле create_user.py

Я преобразовывал свой пользовательский объект с помощью vars(), который превращал моего пользователя в dict (что не то же самое, что JSON), но вместо этого мне нужно было использовать правильный кодировщик json, предоставляемый фреймворком FastAPI.

СТАРЫЙ КОД:

def create_new_keycloak_user(user: User):
    admin = keycloak_service.connect_to_keycloak_as_admin()
    try:
        body = vars(user)
        print(body)
        new_user = admin.create_user(body)
        return new_user
    except Exception as err:
        raise HTTPException(status_code=400, detail=f"User creation failed: {err}")

НОВЫЙ КОД:

def create_new_keycloak_user(user: User):
    admin = keycloak_service.connect_to_keycloak_as_admin()
    try:
        body = jsonable_encoder(user)
        admin.create_user(body)
    except Exception as err:
        raise HTTPException(status_code=400, detail=f"User creation failed: {err}")

Решил! Люблю видеть такие посты. Как правило, старайтесь избегать использования vars()

Yaakov Bressler 05.05.2022 13:36

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