DASH: After importing a BLOB from a MySQL db, I would like to allow users to donwload it as a pdf

I have been trying to figure out a way of allowing users of my dash webapp to download pdf files that are stored as BLOBs in a MySQL db. I have tried this:

and then used the file that it returns (named photo in this case) as part of the output in for a dash_extensions.Download component in the following way:

return dict(filename=pdf_file, content=photo, type="text/pdf")

The tutorial above seems agnostic to filetype, so the name photo could be misleading. This could also be where I am going wrong.

Anything that you return in a Dash callback must be json serializeable, i.e. you cannot return bytes, which is what i guess you are trying to do (maybe you could share some code/pseudo code to illustrate what you are trying to do?). Hence, if you want to send data, you must first convert it to a string. For the case of the Download component, you can use base64 encoding. The code would be something like,

content =  base64.b64encode(photo).decode()
return dict(content=content, filename=filename, base64=True)
1 Like

You sir, are a flapping angel. Thank you. Here is a min working version of the app for anyone else that wants to let users download a pdf that was stored in a MySQL db as a BLOB.

One would have to add ones own db settings in the ‘db settings’ part

`
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
from dash_extensions import Download
import pandas as pd
import mysql.connector # pip install mysql-connector-python
import base64

=========== DB SETTINGS ===========

myconn = mysql.connector.connect(host=‘123.123123’, user=‘some_username’, passwd=‘some_password’,
database=‘some_db’)

===============================

req = ‘Research’
queries = “”“SELECT * FROM email_display where gc_SenderName = %s;”""
df_research = pd.read_sql(queries, myconn, params=(req,))

the_blob = df_research[‘GC_ATTACH_BINARY’][0] # a pdf stored as a blob in a db

app = dash.Dash(name, prevent_initial_callbacks=True)
app.layout = html.Div(children=[

html.Br(),
html.Div([html.Button("Download pdf", id="btn"), Download(id="download")]),
html.Br(),

])

@app.callback(Output(“download”, “data”), [Input(“btn”, “n_clicks”)])
def generate_csv(n_nlicks):

pdf_file = "Email_attachment.pdf"
content = base64.b64encode(the_blob).decode()

return dict(filename=pdf_file, content=content,  base64=True)

if name == ‘main’:
app.run_server()

`

Thank you @Emil

2 Likes