Я пытаюсь использовать вложенные модели в вызове 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
Я решил это. Проблема была в файле 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()