在这种情况下,我希望根据FastAPI路由中的一个值(Organization
)授权活动用户。提交特定类型的对象时,其中一个键(organization_id
)应该存在,并且应该验证用户是否有权访问组织
我已将其作为API签名中的依赖项解决,以避免在需要访问此属性的所有路由中复制此代码:
def get_organization_from_body(organization_id: str = Body(None),
user: User = Depends(get_authenticated_user),
organization_service: OrganizationService = Depends(get_organization_service),
) -> Organization:
if not organization_id:
raise HTTPException(status_code=400, detail='Missing organization_id.')
organization = organization_service.get_organization_for_user(organization_id, user)
if not organization:
raise HTTPException(status_code=403, detail='Organization authorization failed.')
return organization
这很好,如果API端点希望通过请求中的organization_id
键获得一个组织,我可以通过在路由中引入get_organization_from_body
作为依赖项来直接填充该组织:
@router.post('', response_model=Bundle)
async def create_bundle([...]
organization: Organization = Depends(get_organization_from_body),
) -> Model:
。。如果用户没有访问组织的权限,则会引发403异常
但是,我还希望通过模式模型在根级别上包含我的实际对象。因此,我的第一次尝试是发出JSON请求,如下所示:
{
'name': generated_name,
'organization_id': created_organization['id_key']
}
然后添加传入的Pydantic模型:
@router.post('', response_model=Bundle)
async def create_bundle(bundle: BundleCreate,
organization: Organization = Depends(get_organization_from_body),
[...]
) -> BundleModel:
[...]
return bundle
无论pydantic模型/模式是否包含organization_id
作为字段,结果都是相同的:
class BundleBase(BaseModel):
name: str
class Config:
orm_mode = True
class BundleCreate(BundleBase):
organization_id: str
client_id: Optional[str]
。。但是当我介绍我的get_organization_from_body
依赖项时,FastAPI发现我有另一个引用主体字段的依赖项,并且bundle
对象的描述必须移动到bundle
键中(因此,不是“验证”organization_id
字段,而是需要更改JSON布局,因为我觉得organization_id
是bundle
的一部分)描述,它应该住在那里……如果可能的话)
错误消息告诉我bundle
应作为单独的字段:
{'detail': [{'loc': ['body', 'bundle'], 'msg': 'field required', 'type': 'value_error.missing'}]}
正确地说,当我在bundle
键内移动name
时:
{
'bundle': {
'name': generated_name,
},
'organization_id': created_organization['id_key']
}
。。我的测试通过,请求成功
这可能有点像自行车脱落,但如果有一个快速修复方法来解决这个限制,我会有兴趣找到一种方法来实现验证(通过Depends()
或以某种替代方式,而不是在每个需要该功能的API路由函数中显式地进行验证)还有一个与我的输出格式匹配的平面JSON布局
在FastAPI
0.53.2
之前,主体的依赖关系是按照您尝试的方式解决的。此类代码:预期该机构:
但是starting from版本
0.53.2
会自动嵌入不同的主体依赖项(embed=True
),上面的代码需要以下主体:现在,为了能够访问整个实体的模型,并且能够作为单独的依赖项访问其元素,您需要在任何地方对实体模型使用相同的依赖项:
共享依赖项的更新
您可以为多个模型共享一个主体依赖项,但在这种情况下,必须满足两个条件:依赖项的名称必须相同,并且它们的类型必须兼容(通过继承或不继承)。示例如下:
相关问题 更多 >
编程相关推荐