Black Lives Matter. Please consider donating to Black Girls Code today.

Obtaining data from layout elements out of callbacks

Is it possible?
Thank you!

are you able to describe your problem a little better? there isn’t too much context provided to help.

Ok, sorry for that, I regarded it as a trivial matter. The thing is I want to create and download a file with data from graphs. I use two buttons for that. One of them generates the file in the local server from within a callback and the other one allows to download it from another device (phone, tablet…), but this time using a Flask server.route direction
I would like to join both actions in a single “Generate and download” button.
I’ve got stuck trying with requests library (How do you specify the download path from a external device like a mobile phone?) or trying embedding the callback into the server.route direction.
Now I’m thinking about collecting data from layout from within the server.route clause but not using a callback.
So any idea?

Here is the chunk of code:

@server.route("/download/<path:path>")
def download_report(path):
         return send_from_directory(FILE_DIRECTORY,path,as_attachment=True)


app.layout=html.Div([
           html.Div([
                 html.A(html.Button('Download file'), href="download/file.docx")
                 dcc.Graph(
                    id='crossfilter-indicator-scatter',
                    hoverData={'points': [{'customdata': 'Spain'}]}
                 ),
            ], style={'display': 'inline-block', 'width': '49%'}
           ),
           
           html.Div([
                 html.Div([
                      dcc.Graph(id='x-time-series'),
                      html.Button(id="generate-file-button", n_clicks=0, children="Generate file"),
                     
  
 
                       
                   
                      
           html.Div(id='file-content',
                    style={'display': 'none'},
                    children='{"columns":["country_name","Year","Indicator_Name","Value"],"index":[6,16,26],"data":[["Spain",1962,"Agriculture.value added (% of GDP)",null],["Spain",1967,"Agriculture.value added (% of GDP)",null],["Spain",1972,"Agriculture.value added (% of GDP)",null]]}'
           ),
           html.Div(id='garbage-generate-file-button',
                    style={'display': 'none'},
                    children=''
           )
    ])        

@app.callback(
    dash.dependencies.Output('garbage-generate-file-button','children'),
    [dash.dependencies.Input('generate-file-button','n_clicks')],
    [dash.dependencies.State('graph','figure'),
     dash.dependencies.State('file-content', 'children')])  
def imprime_x(n_clicks,figure,dff_text):
        
        ... #Various preprocessing code sentences

        document=Document()
        document.add_heading(title)
        document.add_picture('picture.png', width=Inches(7), height=Inches(8))
 
        table = document.add_table(rows=1, cols=2, style='Colorful List Accent 1')
        document.save('file.docx')
        return json.dumps(dff_dicc)

Here is a chuck of code I use to create an excel file (via openpyxl) when a user presses a button on the app. The file is created within the download_file function.

The browser handles the prompt to where to save (Firefox opens a dialog box, Chrome automatically downloads to the Downloads folder on my laptop).

Not sure if this helps but it could spawn an idea or two.

@app.server.route('/download_file/')
def download_file():
    # Process inputs
    slider_date = flask.request.args.get('slider')
    station_v = flask.request.args.get('station_v')
    ...

    # Create excel file
    wb = excel.create_workbook(...)
    
    #  ...code to create excel file using openpyxl...

    # Set filename
    desired_filename = 'yourfilename.xlsx'

    with NamedTemporaryFile() as tmp:
        wb.save(tmp.name)
        str_io = io.BytesIO(tmp.read())

    return flask.send_file(str_io,
                           attachment_filename=desired_filename,
                           as_attachment=True)