重用验证文件大小的函数 [fastapi]
Reuse function that validates file size [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 类型,而不是相信用户所说的文件是什么 - 您可以 use mimetypes.guess_type
or something similar 做到这一点。
我是 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 类型,而不是相信用户所说的文件是什么 - 您可以 use mimetypes.guess_type
or something similar 做到这一点。