FastAPI中如何返回文件验证与其他字段的全部校验错误?
问题:如何将文件验证错误与其他字段校验错误一并返回
实际需求并非实现文件大小/扩展名验证,而是要让文件验证错误能和其他字段的校验错误一起返回,具体分为以下两个问题:
要点1:依赖注入方式下的批量错误返回问题
当前实现代码如下:
app = FastAPI() class FileExtensionValidator: message = 'Extension “{extension}” not allowed. Allowed extensions are {allowed_extensions}' def __init__(self, allowed_extensions=None, message=None): if allowed_extensions is not None: allowed_extensions = [allowed_extension.lower() for allowed_extension in allowed_extensions] self.allowed_extensions = allowed_extensions if message is not None: self.message = message def __call__(self, file: UploadFile): extension = Path(file.filename).suffix[1:].lower() if self.allowed_extensions is not None and extension not in self.allowed_extensions: detail = self.message.format(extension=extension, allowed_extensions=', '.join(self.allowed_extensions)) raise HTTPException(400, detail=detail) class MaxFileSizeMBValidator: def __init__(self, max_mb: int): self.max_mb = max_mb def __call__(self, file: UploadFile): if file.size / 1024 / 1024 > self.max_mb: message = f'Maximum file size exceeded' raise HTTPException(400, detail=message) @router.post( '/upload/', dependencies=[ Depends(MaxFileSizeMBValidator(max_mb=1)), Depends(FileExtensionValidator(allowed_extensions=['.docx'])), ] ) async def upload_file(file: UploadFile, user_id: int = Form()): return {'filename': file.filename}
上述代码无法返回全部校验错误:比如上传.csv文件且未传入必填字段user_id时,FastAPI仅返回单个错误:
{ "detail": "Extension “csv” not allowed. Allowed extensions are .docx" }
但期望同时返回所有错误,格式如下:
{ "detail": [ { "loc": [ "body", "file" ], "msg": "Extension “csv” not allowed. Allowed extensions are .docx", "type": "value_error.missing" }, { "loc": [ "body", "user_id" ], "msg": "field required", "type": "value_error.missing" } ] }
需求:如何实现上述批量错误返回?若采用依赖注入方式,该如何调整校验逻辑?要求保持验证器独立,可按需调用。
要点2:自定义UploadFile类的灵活性优化问题
通过重写UploadFile类可以实现验证:
class CustomUploadFile(UploadFile): validators = [ MaxFileSizeMBValidator(max_mb=10), FileExtensionValidator(allowed_extensions=['.docx']), ] @classmethod def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]: yield cls.validate for validator in cls.validators: yield validator
但这种方式灵活性不足,每次更换验证器都需要重新子类化,寻求更优实现方案。
内容的提问来源于stack exchange,提问作者Альберт Александров
相关产品推荐
相关产品推荐

