flask send base 64 encoded pdf string without saving

Question:

I have a flask application. I am using selenium cdp commands to generate pdfs. I get a base64 encoded string from selenium. Before sending the response as a pdf I save the file in my filesystem.

file.write(base64.b64decode(pdf_string['data'])

And the response is just send_file('path', 'name.pdf')

How do i serve the pdf without saving it to a file. I was trying to look for a BytesIO solution but I don’t fully understand it yet.
I also tried setting the mimetype / header to ‘application/pdf’ and ‘application/pdf;base64’

type of decoded string is ‘bytes’
and type of pdf_string[‘data’] is ‘str’

Is there a way I can accomplish this without saving files?

Asked By: Alan Dsilva

||

Answers:

So you are on right track to figuring out that saving a pdf and again reading it is not a great solution.

Instead, use ByteIO as follows:

pdf_bytes = base64.b64decode(pdf_string['data'])

pdf = BytesIO()
pdf.write(pdf_bytes)
pdf.seek(0)

and then use send_file

This is very similar to ByteBuffer implementation in Java. seek method as the name suggest seeks/resets the pointer to the first byte.

Let me know if this works, Thanks.

Answered By: begin

yes, you can download the PDF file without saving it as a file using BytesIO. Instead of writing decoded PDF text to an unformatted file, you can create the BytesIO object and then write the PDF decoded string to it. It is then possible to forward this BytesIO object to Flask’s send_file function in order to send the PDF file as an answer.

Here’s a code example which demonstrates how you can do this:

from io import BytesIO 
import base64 
pdf_bytes = base64.b64decode(pdf_string['data']) 
pdf_io = BytesIO(pdf_bytes) 
return send_file(pdf_io, mimetype='application/pdf', as_attachment=False, attachment_filename='name.pdf') 

The PDF will be used as a response, without saving the file to disk.

There is an alternative method of serving the PDF, without saving it to an image file making use of an alternative method called the make_response function in Flask.

Here’s an example of code which demonstrates how you can do this:

from flask import make_response 
import base64 
pdf_bytes = base64.b64decode(pdf_string['data']) 
response = make_response(pdf_bytes) 
response.headers.set('Content-Type', 'application/pdf') response.headers.set('Content-Disposition', 'inline', filename='name.pdf') return response 

In the above code we first decode the base64 encoded PDF string and then save the decoded bytes into pdf_bytes. pdf_bytes variable. Then, we use the Flask create_response method to build an object response to the request and then send pdf_bytes to it.

In the end we send our response object. It serves in response. It is not saving it as the disk.

Answered By: lastber