Как уже упоминалось в моем комментарии, проблема заключается в этой строке:
empty_zip_data = b'PK\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
zip = zipfile.ZipFile(empty_zip_data, 'w')
Вы пытаетесь передать объект byte
в метод ZipFile()
, но, как и open()
, он ожидает объект в виде пути.
В вашем случае вы можете использовать модуль tempfile
(в этом конкретном примере мы будем использовать SpooledTemporaryFile
из этого соответствующего вопроса :
import tempfile
import zipfile
# Create a virtual temp file
with tempfile.SpooledTemporaryFile() as tp:
# pass the temp file for zip File to open
with zipfile.ZipFile(tp, 'w') as zip:
files = [(u'file_name', b'file_data'), (u'file_name2', b'file_data2'),]
for file in files:
file_name = file[0]
file_data = file[1]
zip.writestr(file_name, file_data)
# Reset the cursor back to beginning of the temp file
tp.seek(0)
zipped_bytes = tp.read()
zipped_bytes
# b'PK\x03\x04\x14\x00\x00\x00\x00\x00\xa8U ... \x00\x00'
Обратите внимание на использование менеджеров контекста для обеспечения правильного закрытия всех файловых объектов после загрузки.
Это дает вам zipped_bytes
, то есть байты, которые вы хотите передать обратно в Odoo. Вы также можете проверить zipped_bytes
, записав его в физический файл, чтобы посмотреть, как он выглядит в первую очередь:
with open('test.zip', 'wb') as zf:
zf.write(zipped_bytes)
Если вы обрабатываете файлы достаточно большого размера, обязательно обратите внимание и используйте аргумент max_size
в документации.