Reputation: 1088
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
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
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
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