英文:
FastAPI not recognising field in Request body
问题
我在创建的FastAPI应用中遇到了一个问题。我有一个用于创建新用户日历的路由,我目前正在尝试进行测试。
路由
# 添加用户日历
@router.post("", response_model=schemas.UserCalendar)
async def add_user_calendar(
user_calendar: schemas.UserCalendarBase,
current_user: schemas.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
parent_slot: schemas.ParentSlot = None
):
return usercalendar.add_user_calendar(user_calendar,
current_user,
db,
parent_slot)
辅助函数
# 生成用户日历
def generate_user_calendar(
account_id,
calendar_name = "offline_test",
calendar_id = "test_calendar_id",
timezone = "Europe/London"
):
return {
"account_id": account_id,
"calendar_name": calendar_name,
"calendar_id": calendar_id,
"timezone": timezone
}
# 创建用户日历
def create_user_calendar(user_calendar, headers):
return requests.post(API_ENDPOINT + "/calendar",
headers=headers,
json=user_calendar)
模式
class UserCalendarBase(BaseModel):
account_id: int
calendar_name: str
calendar_id: Union[str, None]
timezone: str
class Config:
orm_mode = True
当我生成日历并调用create_user_calendar进行创建时,服务器端出现错误:
请求主体的验证错误1 - > user_calendar字段是必需的(type=value_error.missing)
如果我修改辅助函数以在顶层包含"user_calendar",则可以运行,例如:
# 生成用户日历
def generate_user_calendar(
account_id,
calendar_name = "offline_test",
calendar_id = "test_calendar_id",
timezone = "Europe/London"
):
return {
"user_calendar" : {
"account_id": account_id,
"calendar_name": calendar_name,
"calendar_id": calendar_id,
"timezone": timezone
}
}
然而,在其他路由中,我无需添加此顶层字段。
例如:
# 生成用户账户辅助函数
def generate_user_account(
user_id,
account_type = "online",
account_email = str(get_datetime_now_iso()) + "@email.com",
account_provider = "google",
used_for="PERSONAL"
):
return {
"user_id": user_id,
"account_type": account_type,
"account_email": account_email,
"account_provider": account_provider,
"used_for": used_for
}
# 创建用户账户辅助函数
def create_user_account(payload, headers):
return requests.post(API_ENDPOINT + "/account",
headers=headers,
json=payload)
# 用户创建/注册路由
@router.post("/", response_model=schemas.User)
def create_user(
user_to_create: schemas.UserCreate,
db: Session = Depends(deps.get_db)
):
return user.create_user(db=db, user=user_to_create)
# 模式
class UserBase(BaseModel):
username: str
email: str
timezone: str
class UserCreate(UserBase):
password: str
这是我做错了的吗?这似乎是我创建的唯一一个遇到此问题的路由。我显然已经找到了解决办法,但这意味着我需要以与其他路由不一致的方式处理此路由,即在请求中添加字段名,而其他路由似乎只是识别模式并完成工作。谢谢
英文:
I'm having an issue with a FastAPI app I'm creating. I have a route to create a new user calendar which I'm currently trying to test.
Route
# Add User Calendar
@router.post("", response_model=schemas.UserCalendar)
async def add_user_calendar(
user_calendar: schemas.UserCalendarBase,
current_user: schemas.User = Depends(deps.get_current_active_user),
db: Session = Depends(deps.get_db),
parent_slot: schemas.ParentSlot = None
):
return usercalendar.add_user_calendar(user_calendar,
current_user,
db,
parent_slot)
Helper Function
# generate a user calendar
def generate_user_calendar(
account_id,
calendar_name = "offline_test",
calendar_id = "test_calendar_id",
timezone = "Europe/London"
):
return {
"account_id": account_id,
"calendar_name": calendar_name,
"calendar_id": calendar_id,
"timezone": timezone
}
# create a user calendar
def create_user_calendar(user_calendar, headers):
return requests.post(API_ENDPOINT + "/calendar",
headers=headers,
json=user_calendar)
Schema
class UserCalendarBase(BaseModel):
account_id: int
calendar_name: str
calendar_id: Union[str, None]
timezone: str
class Config:
orm_mode = True
When I generate a calendar and then call create_user_calendar to create it I get an error on the server side:
1 validation error for Request body -> user_calendar field required (type=value_error.missing)
If I amend the helper function to include "user_calendar" at the top level then it works, e.g.
# generate a user calendar
def generate_user_calendar(
account_id,
calendar_name = "offline_test",
calendar_id = "test_calendar_id",
timezone = "Europe/London"
):
return {
"user_calendar" : {
"account_id": account_id,
"calendar_name": calendar_name,
"calendar_id": calendar_id,
"timezone": timezone
}
}
In other routes though I have not had to add this top level field.
For example:
# generate a user account helper function
def generate_user_account(
user_id,
account_type = "online",
account_email = str(get_datetime_now_iso()) + "@email.com",
account_provider = "google",
used_for="PERSONAL"
):
return {
"user_id": user_id,
"account_type": account_type,
"account_email": account_email,
"account_provider": account_provider,
"used_for": used_for
}
# create a user account helper function
def create_user_account(payload, headers):
return requests.post(API_ENDPOINT + "/account",
headers=headers,
json=payload)
# User creation / registration route
@router.post("/", response_model=schemas.User)
def create_user(
user_to_create: schemas.UserCreate,
db: Session = Depends(deps.get_db)
):
return user.create_user(db=db, user=user_to_create)
# schemas
class UserBase(BaseModel):
username: str
email: str
timezone: str
class UserCreate(UserBase):
password: str
Is this something that I've done wrong somewhere? It seems to be the only route I've created that I've encountered this issue. I've obviously got the fix but it means that I need to work with this route in an inconsistent manner to the others, i.e. adding the field name to the request where the others just seem to recognise the schema and do the work.
Thanks
答案1
得分: 1
在add_user_calendar
端点中,您期望有几个Pydantic对象(即user_calendar
、current_user
和parent_slot
)。这意味着这三个对象将被解释为请求主体,这显然没有意义。
解决方法是创建一个单一的Pydantic模型,该模型接受端点所需的所有字段(例如,您可以称其为AddUserRequest
)。
请注意,在您的另一个示例create_user
中,只接收一个Pydantic模型,因此不存在混淆。
英文:
In the endpoint add_user_calendar
you are expecting several Pydantic objects (i.e., user_calendar
, current_user
and parent_slot
). This means that the three of them will be interpreted as requests bodies, which makes little sense.
The solution would be to create a single Pydantic model that takes all the fields needed by the endpoint (you could call it, e.g., AddUserRequest
).
Notice that in your other example, create_user
, only one Pydantic model is received, and therefore the confusion doesn't exist.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论