――Create a web page of a reasonable size with dash ――It's not easy to write everything in app.py, so I want to divide it
As in the example, I can not find the document at all in English, so I will write it together
splitting callback and components in multiple files use the : deepl
By the way, the official sample itself is a lot, but there are always hundreds of lines of app.py.
It's been about 2 months since I touched dash, so please let me know if there is a better solution.
--I want to cut out at least components and callbacks ――It seems that you need someone to manage the components and callbacks that will increase more and more.
Early story ↓ This
.
├── app.py
├── assets
│ ├── common.css
│ └── default.css
└── src
└── some_utils.py
↓ It looks like this should be done
.
├── app.py
├── assets
│ ├── common.css
│ └── default.css
│
└── src
├── callback.py
├── callbacks
│ ├── hoge.py
│ ├── fuga.py
│ └── poyo.py
│
├── layout.py
├── components
│ ├── fizz.py
│ ├── buzz.py
│ ├── boo.py
│ └── bar.py
│
├── some_utils.py
└── utils
I borrow the source of my other article because it's a big deal
Implementation of button to select / cancel all check status of dcc.CheckList in Dash
python app.py
Start with and can be viewed at http: // localhost: 8050
↓ It becomes such a screen
app.py
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table
from dash.dependencies import Input, Output, State
from flask import Flask, request
import time
server = Flask(__name__)
app = dash.Dash(__name__, server=server)
app.title = 'checklist-test'
selected_key = None
checklists = dcc.Checklist(
id='checklist-states',
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': 'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
value=['MTL', 'SF']
)
app.layout = html.Div(id='main',children=[
html.H1(children='Checklist test'),
dcc.Location(id='location', refresh=False),
html.Div(className='main-block', children=[checklists]),
html.Div(className='second', children=[
html.Button('Select all', id='filter-check-button', className='filter_button'),
html.Button('Cancel all', id='filter-remove-button', className='filter_button')
])
])
@app.callback(
[Output('checklist-states', 'value')],
[Input('filter-check-button', 'n_clicks_timestamp'),
Input('filter-remove-button', 'n_clicks_timestamp')],
[State('checklist-states', 'value')]
)
def update_check(all_check, all_remove, checking):
if not all_check is None:
if (time.time() * 1000 - all_check) < 1000:
return [['NYC', 'MTL', 'SF']]
if not all_remove is None:
if (time.time() * 1000 - all_remove) < 1000:
return [[]]
if all_check is None and all_remove is None:
return [checking]
if __name__ == '__main__':
app.run_server(host='0.0.0.0', debug=True)
Since the layout and callback are linked to the dash object ʻapp, it seems that it will be processed by passing ʻapp
directly to another function.
That's why I'm throwing work to myself in the future and scraping app.py as much as I can
app.py
import dash
from flask import Flask
from src.layout import layout
from src.callback import callback
server = Flask(__name__)
app = dash.Dash(__name__, server=server)
app.title = 'checklist-test'
#components and callback definitions
app = layout(app)
callback(app)
if __name__ == '__main__':
app.run_server(host='0.0.0.0', debug=True)
tips: Callback registration must be absolutely after the component definition Since the callback with null input value runs at the moment of import, an error will occur if the component you are looking at in Input / Output / State does not exist.
Needless to say, please change the file name to the one you are satisfied with.
Assign html element to the attribute layout of ʻapp` received as an argument
layout.py
import dash_core_components as dcc
import dash_html_components as html
def layout(app):
checklists = dcc.Checklist(
id='checklist-states',
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': 'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
value=['MTL', 'SF']
)
# app.Assign elements to layout
app.layout = html.Div(id='main', children=[
html.H1(children='Checklist test'),
dcc.Location(id='location', refresh=False),
html.Div(className='main-block', children=[checklists]),
html.Div(className='second', children=[
html.Button('Select all', id='filter-check-button', className='filter_button'),
html.Button('Cancel all', id='filter-remove-button', className='filter_button')
])
])
return app
tips:
If you try to call ʻupdate_checkdirectly, you will not be able to interpret the decorator part well, so you need to go one step deeper and enclose each decorator in a different function. (In short,
app of
@ app.callback () `must be able to resolve the name)
callback.py
from dash.dependencies import Input, Output, State
import time
def callback(app):
@app.callback(
[
Output('checklist-states', 'value')
],
[
Input('filter-check-button', 'n_clicks_timestamp'),
Input('filter-remove-button', 'n_clicks_timestamp')
],
[
State('checklist-states', 'value')
]
)
def update_check(all_check, all_remove, checking):
if all_check is not None:
if (time.time() * 1000 - all_check) < 1000:
return [['NYC', 'MTL', 'SF']]
if all_remove is not None:
if (time.time() * 1000 - all_remove) < 1000:
return [[]]
if all_check is None and all_remove is None:
return [checking]
Manage the title, checklist, and button separately Assuming that layout manages only blocks and spacing
tips:
Attribute ʻid is not required for
html.Div () `
layout.py
from src.components import title, checklist, button
import dash_core_components as dcc
import dash_html_components as html
def layout(app):
app.layout = html.Div(id='main', children=[
html.Div(id='title-block', children=[title.layout()]),
dcc.Location(id='location', refresh=False),
html.Div(id='center-block', children=[
html.Div(children=checklist.layout()),
html.Div(children=button.layout())
])
])
return app
title.py
import dash_html_components as html
def layout():
return html.H1(id='title', children='Checklist test')
checklist.py
import dash_core_components as dcc
def layout():
return dcc.Checklist(
id='checklist-states',
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': 'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
value=['MTL', 'SF']
)
button.py
import dash_html_components as html
def layout():
return html.Button('Select all', id='filter-check-button', className='filter_button'), html.Button('Cancel all', id='filter-remove-button', className='filter_button')
Cut out for each function in the same way
callback.py
from src.callbacks import check_and_remove # hoge, fuga...
def callback(app):
check_and_remove.register(app)
# hoge.register(app)
# fuga.register(app)
check_and_remove.py
from dash.dependencies import Input, Output, State
import time
def register(app):
@app.callback(
[
Output('checklist-states', 'value')
],
[
Input('filter-check-button', 'n_clicks_timestamp'),
Input('filter-remove-button', 'n_clicks_timestamp')
],
[
State('checklist-states', 'value')
]
)
def update_check(all_check, all_remove, checking):
if all_check is not None:
if (time.time() * 1000 - all_check) < 1000:
return [['NYC', 'MTL', 'SF']]
if all_remove is not None:
if (time.time() * 1000 - all_remove) < 1000:
return [[]]
if all_check is None and all_remove is None:
return [checking]
.
├── app.py
└── src
├── callback.py
├── callbacks
│ └── check_and_remove.py
├── components
│ ├── button.py
│ ├── checklist.py
│ └── title.py
└── layout.py
Recommended Posts