✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚾️ It's finally Baseball season! Root for the home team... & Register for our Sports Analytics Webinar!

How to create and download pdf file

hi all,

I want to create a pdf and download this pdf when a button is pressed. I started from this tutorial and modify
a code but the downloaded file cannot be opened.
Upload and Download Files with Plotly Dash

Below is my code:

import base64
import os

from flask import Flask, send_from_directory

# imports for the dashboard creation
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
from dash_extensions.snippets import send_file
from dash_extensions import Download

import numpy as np

from io import BytesIO


# imports for the pdf creation
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import ParagraphStyle



UPLOAD_DIRECTORY = "/files/pdf"

# create folder if not yet created
if not os.path.exists(UPLOAD_DIRECTORY):
    os.makedirs(UPLOAD_DIRECTORY)



# Normally, Dash creates its own Flask server internally. By creating our own,
# we can create a route for downloading files directly:
server = Flask(__name__)
app = dash.Dash(server=server)


# Dash Layout
app.layout = html.Div(
    [
        html.Div([html.Button("Download File", id="button_download_file", n_clicks=0), Download(id="download")]),
    ],
)


@server.route("/download/<path:path>")
def download(path):
    """Serve a file from the upload directory."""
    
    
    # Create PDF
    #-----------
    pdf_buffer = BytesIO()
    elements = []
    # create style
    doc = SimpleDocTemplate(pdf_buffer)
    style_title_header = ParagraphStyle(name = 'Title')       
    # Create Paragraph.
    elements.append(Paragraph('hello world !!!', style_title_header))
    # create pdf
    doc.multiBuild(elements)
        
    # store pdf file
    with open(path, "wb") as fp:
#        fp.write(base64.decodebytes(pdf_buffer.getvalue()))
        fp.write(base64.decodebytes(pdf_buffer.read()))

    
    
@app.callback(Output("download", "data"),
                [Input("button_download_file", "n_clicks")])
def download_file(n_clicks):
    if n_clicks>0:
        
        # pdf file name
        pdf_name = 'test.pdf'  
        
        # init path of the pdf file 
        path = os.path.join(UPLOAD_DIRECTORY, pdf_name)
        
        
        # create pdf and store it
        download(path)
        
        
        return send_file(path, mime_type='application/pdf')

    else:
        return None


if __name__ == "__main__":
    app.run_server(debug=True)