1

I have a dash app with a button and I do want that button to run a different python script on click. Here is the app, How can I configure the app in that once the button is clicked, it executes another python script:

# -*- coding: utf-8 -*-
"""
Created on Mon Mar  2 10:36:21 2020

"""
import pathlib
import dash
import pandas as pd
from dash.dependencies import Input, Output, State
import dash_html_components as html
from dashlastodash import lastodash
from dash.exceptions import PreventUpdate
import dash_table
import os

app = dash.Dash(
    __name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}]
)

os.chdir("path to working dir")
    # Layout of Dash App HTML

app.layout = html.Div(
                children=[html.Div(
                            html.Button('Detect', id='button'),
                            html.Div(id='output-container-button',
                            children='Hit the button to update.')
                    ),
                ],
            )

@app.callback(
dash.dependencies.Output('output-container-button', 'children'),
[dash.dependencies.Input('button', 'n_clicks')])
def run_script_onClick(n_clicks):
    # Don't run unless the button has been pressed...
    if not n_clicks:
        raise PreventUpdate

    script_path = 'path to script\\lastodash.py'
    # The output of a script is always done through a file dump.
    # Let's just say this call dumps some data into an `output_file`
    call(["python3", script_path])

    # Load your output file with "some code"
    output_content = lastodash
    # Now return.
    return output_content
# Main
if __name__ == "__main__":
    app.run_server(debug=True, port=8585)

what I did is Imported the script from the directory then tried to run but it isnt working, can someone help.

The error I get

usage: [-h] [--debug] lasfile
: error: the following arguments are required: lasfile
An exception has occurred, use %tb to see the full traceback.

Note that from dashlastodash import lastodash if the directory to which I am importing the python script to rum. lastodash is the script I am running in the app button

6
  • do you get error message ? always put full error message (starting at word "Traceback") in question (not comment) as text (not screenshot). There are other useful information. Commented Mar 2, 2020 at 8:05
  • @furas error added on code Commented Mar 2, 2020 at 8:16
  • Your code is broken. There is no module called dashlastodash that I'm aware of and lastodash is probably misspelled. Please post a working example. Commented Mar 2, 2020 at 8:17
  • @Jussi Nurminen dasglastodash is the directory to which I am importing the python script Commented Mar 2, 2020 at 8:20
  • Ok, but then what is the lastodash object that you import? It's not referenced in the code. Commented Mar 2, 2020 at 8:22

3 Answers 3

1

For me, similar code works fine if I use following in the callback

script_fn = 'script.py'
exec(open(script_fn).read())

to run the script. This is the recommended method to execute Python scripts from within Python in Py3. I don't know where call is supposed to come from in your script.

Sign up to request clarification or add additional context in comments.

5 Comments

Wherever you want. Just define script_fn to point to where the script is.
Where exactly do you put the exec function in the callback. I am unsure where to start with callbacks. All I want to do is run a Python function whenever the button is clicked.
@Password-Classified if you want to run a Python function in the callback, just call that function in the normal way. There's no need to use exec in that situation. exec is used to run scripts (i.e. Python files) from the callback, which is somewhat unusual usage.
In Dash, what is the easiest way to run a Python function on click of a Button() element?
@Password-Classified please see e.g. Dash button examples at dash.plotly.com/dash-html-components/button. In the first example, you would simply insert your function call into the update_output callback.
0

i'am having the issue that the script executes at time of initiation of the dash app (once) and then it works when i click. The preventUpdate does not work apparently in the situation described "In other words, if the output of the callback is already present in the app layout before its input is inserted into the layout, prevent_initial_call will not prevent its execution when the input is first inserted into the layout."(https://dash.plotly.com/advanced-callbacks) Any clue how i can modify or create a new call back in order to avoid the issue, i guess you must have had the same limitation?

import pathlib
import dash
import pandas as pd
from dash.dependencies import Input, Output, State
import dash_html_components as html
from dash.exceptions import PreventUpdate
import dash_table
import os

script_fn = 'test.py'

app = dash.Dash(__name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}])

app.layout = html.Div(
                children=[html.Div((
                            html.Button('df1_Settlement 5i', id='button'),
                    html.Div(id='output-container-button',
                            children='Load new file'))
                    ),
                ],
            )

@app.callback(dash.dependencies.Output('output-container-button', 'children'),[dash.dependencies.Input('button', 'n_clicks')],prevent_initial_call=True)

def run_script_onClick(n_clicks):
    # Don't run unless the button has been pressed...
    if n_clicks is None:
        raise PreventUpdate 
    else:    
        exec(open(script_fn).read())
    
# Main
if __name__ == "__main__":
    app.run_server(debug=False)

Comments

0

I could not add a comment, but I solved this problem with the following code, the scriptpy is executed correctly when pressing the button

from dash import Dash, html
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
import os

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
scriptpy = "info.py"

app = Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.Button('Click here to see the content', id='show-secret',style={"color":"white"}),
    html.Div(id='body-div')
])

@app.callback(
    Output(component_id='body-div', component_property='children'),
    Input(component_id='show-secret', component_property='n_clicks')
)
def update_output(n_clicks):
    if n_clicks is None:
        raise PreventUpdate
    else:
        return os.system(f"python {scriptpy}")

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

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.