LivingstoneM
LivingstoneM

Reputation: 1088

Run python script on Dash-plotly button

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

Upvotes: 1

Views: 6983

Answers (3)

DaveNISC
DaveNISC

Reputation: 1

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)

Upvotes: 0

loonatic
loonatic

Reputation: 1

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)

Upvotes: 0

Jussi Nurminen
Jussi Nurminen

Reputation: 2408

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.

Upvotes: 1

Related Questions