0

I used the reply to this question in order to read a .pptx (a template) from s3 using boto3 and io. I updated the .pptx and I now want to upload it back to s3 with a new name.

I see that boto3 has a method to upload a file-like object to s3: upload_fileobj().

So this is what I'm doing when trying to save the file:

import io
import boto3

from pptx import Presentation

s3 = boto3.client('s3')
s3_response_object = s3.get_object(Bucket='bucket', Key='file.pptx')
object_content = s3_response_object['Body'].read()

prs = Presentation(io.BytesIO(object_content))

# Do some stuff to the PowerPoint

out = io.BytesIO() # to have the presentation in binary format
with open(prs.save(out), "rb") as f:
    s3.upload_fileobj(f, 'BUCKET', 'KEY')

But I get the error

TypeError                                 Traceback (most recent call last)
<ipython-input-8-1956d13a7556> in <module>
----> 1 with open(prs.save(out), "rb") as f:
      2     s3.upload_fileobj(f, 'BUCKET', 'KEY')

TypeError: expected

 str, bytes or os.PathLike object, not NoneType

How can I upload it to s3 given that I start from a Presentation object?

blue_chip
  • 666
  • 2
  • 6
  • 22

1 Answers1

2

Try this:

import io
import boto3

from pptx import Presentation

s3 = boto3.client('s3')
s3_response_object = s3.get_object(Bucket='bucket', Key='file.pptx')
object_content = s3_response_object['Body'].read()

prs = Presentation(io.BytesIO(object_content))

# Do some stuff to the PowerPoint

with io.BytesIO() as out:
    prs.save(out)
    out.seek(0)
    s3.upload_fileobj(out, 'BUCKET', 'KEY')
jellycsc
  • 10,904
  • 2
  • 15
  • 32
  • Thanks a lot! It worked (both before and after your first edit)! Seems so simple now that you gave me the correct way to do it. – blue_chip Feb 24 '21 at 21:44
  • 1
    Np :) The latter one works better since the `with` block automatically closes the IO stream on exit. – jellycsc Feb 24 '21 at 21:45