Generate PDF using reportlab and write to s3 bucket without saving locally

956 views
Skip to first unread message

Danny Blaker

unread,
Apr 22, 2019, 11:18:14 AM4/22/19
to Django users
I'm trying to generate a PDF using reportlab and write to s3 bucket without saving locally

I know I'm missing something simple:

# create a stream
stream = io.BytesIO()

# generate PDF
doc = SimpleDocTemplate(stream, pagesize=letter,
                        rightMargin=72, leftMargin=72,
                        topMargin=72, bottomMargin=18)
Story = []

styles = getSampleStyleSheet()

Story.append(Paragraph('<font size=11>This is a PDF</font>', styles["Normal"]))

doc.build(Story)

# get buffer
pdf_buffer = stream.getbuffer()

filename = "new.pdf"
bucket_name = 'insert_bucket_name'
object_name = bucket_name

# here is where I get stuck - how should be passing the pdf_buffer to s3?

# how you typically write to s3 :
# Method 1

s3 = boto3.client('s3')
with open(filename, "rb") as f:
    s3.upload_fileobj(f, bucket_name, object_name)

# Method 2
s3.Bucket(bucket_name).put_object(Key=filename, Body=file)

Any ideas most appreciated!

Thanks!

here are some related resources:


dzu...@gmail.com

unread,
Apr 29, 2019, 12:19:13 AM4/29/19
to Django users
Figured it out: streams have this builtin position attr which bytesIO uses to keep track of to know where to insert data. Reportlab simpledoctemplate writes to the stream object, but when it completes pdf generation at doc.build(story), it doesn't reset the stream position back to the beginning of the file. as a result the s3 put_object method writes only the portion of the file from where the position is at currently, through to the end, resulting in corrupt file. all that was neeeded was to reset the stream position just before writing to s3 using stream.seek(0)
Reply all
Reply to author
Forward
0 new messages