重用验证文件大小的函数[fastapi]



我是FastAPI的新手。我想验证上传文件的文件类型和文件大小,如果超过大小并且与类型不匹配,则引发Exception。此文件将上载到S3这就是我的代码看起来像

@router.post("/upload/", status_code=200, description="***** Upload customer document asset to S3 *****")
async def upload(
document_type: DocumentEnum,
customer_id: UUID,
current_user=Depends(get_current_user),
fileobject: UploadFile = File(...)
):
# delete the file from memory and rollover to disk to save unnecessary memory space
fileobject.file.rollover()
fileobject.file.flush()
valid_types = [
'image/png',
'image/jpeg',
'image/bmp',
'application/pdf'
]
await validate_file(fileobject, 5000000, valid_types)
# .... Proceed to upload file 

我的validate_file函数看起来像这个

async def validate_file(file: UploadFile, max_size: int = None, mime_types: list = None):
"""
Validate a file by checking the size and mime types a.k.a file types
"""
if mime_types and file.content_type not in mime_types:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="You can only upload pdf and image for document"
)
if max_size:
size = await file.read()
if len(size) > max_size:
raise HTTPException(
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
detail="File size is too big. Limit is 5mb"
)
return file

现在,当文件上传到S3时,它的大小总是0 bytes。但是,如果我从validate_file函数中排除了文件大小检查,那么原始文件就会被上传,没有问题。如果validate_file函数是这样的,那么它会上传精细的

async def validate_file(file: UploadFile, max_size: int = None, mime_types: list = None):
"""
Validate a file by checking the size and mime types a.k.a file types
"""
if mime_types and file.content_type not in mime_types:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="You can only upload pdf and image for document"
)
)
return file

我不知道为什么会发生这种事。提前感谢您的帮助。

在文件上调用read时,当前文件指针将位于读取内容的末尾。当您(或库(第二次调用read时,内部文件指针将已经位于文件的末尾。

您可以使用await file.seek(0)将文件指针放在文件的开头,这样下一次读取将再次读取相同的内容:

if max_size:
size = await file.read()
if len(size) > max_size:
raise HTTPException(
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
detail="File size is too big. Limit is 5mb"
)
await file.seek(0)
return file

您可能还想显式解析文件的mime类型,而不是相信用户所说的文件是什么——您可以使用mimetypes.guess_type或类似的方法来实现这一点。

最新更新