Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

159
Visualizações
Boto3 download gzip and upload as stream

Using the python module boto3, let me say that again, using boto3, not boto. How can I download a file from S3, gzip and re-upload to S3 without the file ever being written to disk?

I am trying to write an AWS lambda function that Gzips all content uploaded to S3. The problem is a lambda function is limited to 512MB of disk space and my uploads could far exceed this.

My assumption is it may be possible to do this using streams, any help would be much appreciated! Thanks.

[UPDATE]

The below code works, kind of. It will upload the chunks to S3, and I can see the resulting *.gz file. However the gzip headers aren't getting added correctly. Opening the file results in on mac Error 32 - Broken Pipe.

Interesting fact, if the file size is less then the CHUNK_SIZE, i.e. only one iteration, the file is uploaded, and is not corrupt.

Any see something I am doing wrong?

CHUNK_SIZE = 10000000
gz_buffer = io.BytesIO()
gz_stream = gzip.GzipFile(fileobj=gz_buffer, mode='wb', compresslevel=9)
obj = resource.Object(bucket, key)
body = obj.get()['Body']
try:
    while True:
        data = body.read(CHUNK_SIZE)
        if data:
            compressed_bytes = gz_stream.write(data)
            if compressed_bytes < CHUNK_SIZE:
                gz_stream.close()
            cdata = gz_buffer.getvalue()[0:compressed_bytes]
            # Upload cdata as multipart upload
            # This is a little helper function that 
            # uses boto3 create_multipart_upload
            multipart.upload(cdata)
        else:
            # Signal to S3 complete multipart upload
            multipart.complete()
            break
except Exception as e:
    pass
over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

I would do this:

import gzip,io

out_buffer = io.BytesIO()
f = gzip.open(out_buffer,"wb")

obj = resource.Object(bucket, key)
body = obj.get()['Body']
while True:
    read = body.read(500000)
    print('reading...')
    if read:
        # 1.) Stream chunks to gzip
        f.seek(0)
        nb_bytes = f.write(read)
        # 2.) Stream compressed chunks back to S3
        cdata = out_buffer.getvalue()[0:nb_bytes]
        # cdata now holds the compressed chunk of data
    else:
        break
  • use io.BytesIO to create a "fake" file in memory
  • map a gzip handle on it
  • loop to read (your code)
  • seek to start of the fake file handle before writing so it doesn't use too much memory (current write overwrites previous iteration write)
  • write the data read to the gzip handle, note down the number of bytes written (they vary depending on the data, and if it's shorter than the previous iteration, the out_buffer does not shrink so we must know the length
  • slice the contents of the buffer using this length to create your compressed chunk.

note that in python 2.x, you cannot pass a fileobject to gzip.open, you have to create a Gzip object instead, like this:

f = gzip.GzipFile("foo.gz","wb",fileobj=out_buffer)
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda