我试图在POST调用中使用嵌套模型。目标是在我的Keycloak实例中使用API创建一个用户,所以我已经按照文档创建了我需要的模型。
当我尝试使用我的API用Postman创建用户时,fastAPI给了我以下错误:
属性类型的对象不是JSON序列化的
代码如下:
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
当我尝试创建user:
时,我在后端收到的正文{'email': 'jhondoe@mail.it', '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格式中不允许这样的事情。但我为什么会收到这样的结果呢?
使用Python3.10和Pydantic的FastAPI
我解决了。问题在create_user.py
文件中我正在转换我的用户对象与vars()
谁把我的用户变成一个字典(这是不一样的JSON),但相反,我需要使用由FastAPI框架提供适当的JSON编码器。
旧代码:
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}")