Python: как обрабатывать загрузку и архивирование больших файлов в Minio

У меня есть Django GraphQL API. Я пытаюсь реализовать конечную точку, которая бы скачивала файлы с внешних ссылок, загружала их в Minio bucket, создавала Zip-файл из этих файлов и возвращала Zip-файл пользователю для скачивания. Все это делается в бэкенде. Это работает с относительно небольшими файлами, но проблема в том, что некоторые из файлов, которые мне нужно обрабатывать, довольно большие, например ~4GB, и загрузка файлов такого размера кажется довольно часто неудачной, а добавление их в Zip-файл обычно замораживает весь сервер.

Вот как я скачиваю и загружаю файлы:

def download_and_upload_file(url: str, prefix: str, file_name: str) -> str:
        with requests.get(url, stream=True) as response:
            response.raise_for_status()
            with io.BytesIO() as file_buffer:
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        file_buffer.write(chunk)
                file_buffer.seek(0)
                upload_url = upload_object_to_minio(file_buffer, prefix, file_name)
                return upload_url

def upload_object_to_minio(stream: io.BytesIO, prefix: str, object_name: str):
    try:
        _ = MINIO_CLIENT.put_object(
            bucket_name=xxx,
            object_name=f"/{prefix}/{object_name}",
            data=stream,
            length=stream.getbuffer().nbytes,
        )
    except Exception as e:
        print(e)

    return "minio-object-url"

А вот как я застегиваю файл:

def create_zip_file(prefix: str, uploaded_urls: list[str]) -> str:
        try:
            zip_buffer = io.BytesIO()
            with zipfile.ZipFile(zip_buffer, "w") as zip_file:
                for uploaded_url in uploaded_urls:
                    file_name = uploaded_url.split("/")[-1]

                    # Retrieve the Minio object and its name
                    minio_object, object_name = get_object_from_minio(uploaded_url)

                    # Read the content of the Minio object
                    object_content = minio_object.read()

                    zip_file.writestr(file_name, object_content)

            zip_buffer.seek(0)

            zip_file_name = "name.zip"
            upload_object_to_minio(zip_buffer, prefix, zip_file_name)
            zip_url = get_minio_url(prefix, zip_file_name)
            return zip_url
        except Exception as e:
            print(e)

Буду очень благодарен за любые советы по работе с такими большими файлами. Будет ли лучше обрабатывать загрузку и застегивание во фронтенде или мой подход хорош (скачать файлы -> загрузить их в Minio -> получить файлы из Minio -> застегнуть файлы -> доставить zip пользователю)? Или весь подход к работе с большими файлами во время API-запросов неверен? Любые соображения и предложения приветствуются.

Вернуться на верх