'FastAPI - Using nested model gives JSON serialization error
I'm trying to use nested models in a POST call. The goal is to create a user in my Keycloak instance with an API, so I have created following the documentation the model that I need.
When I try to create the user with Postman using my API, fastAPI gives me the following error:
Object of type Attributes is not JSON serializable
The code is the following:
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}")
routing.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
The body I receive in the backend when I try to create user:
{'email': '[email protected]', 'username': 'mverdi', 'enabled': True, 'firstName': 'Jhon', 'lastName': 'Doe', 'attributes': Attributes(locale='ITA', phoneNumber='+391234567891'), 'credentials': [Credentials(value='superpassword01', type='password')]}
I think it's related to this "malformed" JSON, if you notice in the previous JSON I have
'attributes': Attributes(locale='ITA', phoneNumber='+391234567891'),
which is clearly not allowed a thing like this in a properly JSON format. But why I receive as result a thing like that?
Using FastAPI with Python3.10 and Pydantic
Solution 1:[1]
I solved it. The problem was in the file create_user.py
I was converting my user object with vars() who turns my user into a dict (which is not the same thing as a JSON) but instead I needed to use a proper json encoder provided by FastAPI framework.
OLD CODE:
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}")
NEW CODE:
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}")
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Melom |
