[PYTHON] Schneiden Sie Komponenten und Rückrufe aus app.py mit plotly Dash aus

Was du machen willst

--Erstellen Sie eine Webseite mit angemessener Größe und einem Bindestrich ――Es ist nicht einfach, alles in app.py zu schreiben, deshalb möchte ich es teilen

Wie üblich kann ich keine Dokumente auf Englisch finden, daher schreibe ich sie zusammen.

splitting callback and components in multiple files use the : deepl

Die offizielle Stichprobe selbst ist übrigens massiv, aber es gibt immer Hunderte von Zeilen von app.py.

Es ist ungefähr 2 Monate her, seit ich Dash berührt habe. Bitte lassen Sie mich wissen, ob es eine bessere Lösung gibt.

Was ich getan habe

Denken Sie an die Struktur der Datei

Frühe Geschichte ↓

.
├── app.py
├── assets
│   ├── common.css
│   └── default.css
└── src
    └── some_utils.py

↓ Es sieht so aus, als ob dies getan werden sollte

.
├── 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

App.py organisieren

Ich leihe mir die Quelle meines anderen Artikels aus, weil es eine große Sache ist

Implementierung einer Schaltfläche zum Auswählen / Deaktivieren aller Prüfzustände von dcc.CheckList in Dash

python app.py

Beginnen Sie mit und können Sie unter http: // localhost: 8050 surfen

↓ Es wird so ein Bildschirm スクリーンショット 2020-02-19 15.43.06.png

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='Checklistentest'),
    dcc.Location(id='location', refresh=False),
    html.Div(className='main-block', children=[checklists]),
    html.Div(className='second', children=[
        html.Button('Wählen Sie Alle', id='filter-check-button', className='filter_button'),
        html.Button('Alle Absagen', 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)

Da das Layout und der Rückruf mit der "App" des Dash-Objekts verknüpft sind, wird es anscheinend verarbeitet, indem die "App" direkt an eine andere Funktion übergeben wird.

Deshalb werde ich, während ich in Zukunft Arbeit für mich selbst werfe, so viel kratzen, wie ich app.py kratzen kann

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'

#Komponenten und Rückrufdefinition
app = layout(app)
callback(app)


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

tips: Die Rückrufregistrierung muss unbedingt nach der Komponentendefinition erfolgen Ein Rückruf mit einem Null-Eingabewert wird zum Zeitpunkt des Imports ausgeführt. Daher tritt ein Fehler auf, wenn die Komponente, die Sie in Eingabe / Ausgabe / Status betrachten, nicht vorhanden ist.

Komponenten und Layout

Bitte ändern Sie den Dateinamen in den Namen, mit dem Sie zufrieden sind.

Layoutausschnitt

Ersetzen Sie das HTML-Element durch das als Argument empfangene Attributlayout "app"

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.Weisen Sie dem Layout Elemente zu
    app.layout = html.Div(id='main', children=[
        html.H1(children='Checklistentest'),
        dcc.Location(id='location', refresh=False),
        html.Div(className='main-block', children=[checklists]),
        html.Div(className='second', children=[
            html.Button('Wählen Sie Alle', id='filter-check-button', className='filter_button'),
            html.Button('Alle Absagen', id='filter-remove-button', className='filter_button')
        ])
    ])

    return app

Rückrufausschnitt

tips: Wenn Sie versuchen, "update_check" direkt aufzurufen, kann der Dekoratorteil nicht gut interpretiert werden. Sie müssen also einen Schritt tiefer gehen und jeden Dekorator in eine andere Funktion einschließen. (Kurz gesagt, app von @ app.callback () muss in der Lage sein, den Namen aufzulösen.)

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]

Was tun, wenn Sie mehr Komponenten und Rückrufe haben?

Weitere Aufteilung der Komponenten

Verwalten Sie Titel, Checkliste und Schaltfläche separat Angenommen, das Layout verwaltet nur Blöcke und Abstände

tips: Das Attribut "id" ist für "html.Div ()" nicht erforderlich

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='Checklistentest')

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('Wählen Sie Alle', id='filter-check-button', className='filter_button'), html.Button('Alle Absagen', id='filter-remove-button', className='filter_button')

Weitere Aufteilung des Rückrufs

Schneiden Sie für jede Funktion auf die gleiche Weise aus

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]

Endgültige Struktur

.
├── app.py
└── src
    ├── callback.py
    ├── callbacks
    │   └── check_and_remove.py
    ├── components
    │   ├── button.py
    │   ├── checklist.py
    │   └── title.py
    └── layout.py

Recommended Posts

Schneiden Sie Komponenten und Rückrufe aus app.py mit plotly Dash aus
Extrahieren Sie Text aus [python] pdf und lesen Sie Zeichen mit Open-Jtalk vor
Datenbanktabellen mit CSV extrahieren [ODBC-Verbindung von R und Python]
[Verarbeitung natürlicher Sprache] Extrahieren Sie Schlüsselwörter aus der Kakenhi-Datenbank mit MeCab-ipadic-neologd und termextract
Extrahieren Sie japanischen Text aus PDF mit PDFMiner
Extrahieren Sie mit Python Daten von einer Webseite
Extrahieren Sie Bilder und Tabellen mit Python aus PDF, um die Berichtslast zu verringern