无法使用 FastAPI 打开和读取上传的 zip 文件的内容

Can't open and read content of an uploaded zip file with FastAPI

我目前正在使用 Python Framework FastAPI 为自己开发一个小的后端项目。我做了一个端点,用户应该能够上传 2 个文件,而第一个是一个 zip 文件(包含 X .xmls),而后者是一个普通的 .xml 文件。

代码如下:

@router.post("/sendxmlinzip/")
def create_upload_files_with_zip(files: List[UploadFile] = File(...)):
    if not len(files) == 2:
        raise Httpex.EXPECTEDTWOFILES
    my_file = files[0].file
    zfile = zipfile.ZipFile(my_file, 'r')
    filelist = []
    for finfo in zfile.infolist():
        print(finfo)
        ifile = zfile.open(finfo)
        line_list = ifile.readlines()
        print(line_list)

这应该打印 .zip 文件中的文件内容,但它引发了异常

AttributeError: 'SpooledTemporaryFile' object has no attribute 'seekable'

ifile = zfile.open(finfo)

经过大约 3 天的研究和大量的试验和错误,尝试使用不同的函数,如 .read() 或 .extract(),我放弃了。因为 python 文档从字面上说明,这应该可以通过这种方式实现...

对于不了解 FastAPI 的您来说,它是 Restful Web 服务的后端 fw,并且正在使用 uploadFile 的 starlette 数据结构。请原谅我,如果我看到了一些非常明显的东西,但我确实试图检查每个角落,这可能是导致错误的可能原因,例如:

这是一个known Python bug:

SpooledTemporaryFile does not fully satisfy the abstract for IOBase. Namely, seekable, readable, and writable are missing.

This was discovered when seeking a SpooledTemporaryFile-backed lzma file.

正如@larsks 在他的评论中建议的那样,我会尝试将假脱机文件的内容写入一个新的 TemporaryFile,然后对其进行操作。只要您的文件不是太大,应该也能正常工作。

这是我的解决方法

with zipfile.ZipFile(io.BytesIO(file.read()), 'r') as zip: