FastAPI - 使用嵌套模型会产生 JSON 序列化错误
FastAPI - Using nested model gives JSON serialization error
我正在尝试在 POST 调用中使用嵌套模型。目标是在我的 Keycloak 实例中使用 API 创建一个用户,因此我按照文档创建了我需要的模型。
当我尝试使用我的 API 通过 Postman 创建用户时,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
创建_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
当我尝试创建用户时在后端收到的正文:
{'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 格式出现。但是为什么我会收到这样的结果?
将 FastAPI 与 Python3.10 和 Pydantic
结合使用
我解决了。问题出在文件 create_user.py
我正在使用 vars()
转换我的用户对象,后者将我的用户转换为字典(这与 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}")
我正在尝试在 POST 调用中使用嵌套模型。目标是在我的 Keycloak 实例中使用 API 创建一个用户,因此我按照文档创建了我需要的模型。
当我尝试使用我的 API 通过 Postman 创建用户时,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
创建_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
当我尝试创建用户时在后端收到的正文:
{'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 格式出现。但是为什么我会收到这样的结果?
将 FastAPI 与 Python3.10 和 Pydantic
结合使用我解决了。问题出在文件 create_user.py
我正在使用 vars()
转换我的用户对象,后者将我的用户转换为字典(这与 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}")