Рубрики
Без рубрики

Интеграция сюжета в приложении в вашем приложении

Ааа, сюжета. Набрав это имя в заголовке пост, вызывает эмоциональный коктейль как гордости, так и … помечен с заговоркой, колбой, Python, наукой данных.

Ааа, Сюжер Отказ Набрав это имя в заголовок пост, вызывает эмоциональный коктейль как гордости, так и смущения. Чутливо было в ядре некоторых из самых влиятельных продуктов, которые я лично работал на протяжении многих лет: спутник Fintech и гуманитарных клиентов, все они все еще гордо размахивают своими диаграммами и панелями по всему миру. Тем не менее, мой разум очаровывается простым вопросом: Что за ад Взяв нас так долго, чтобы написать наш первый пост о застройке? Мы работали хакерами и бездельниками в течение всего года сейчас … Я серьезно написал пост о jquery В то время до достижения этого момента?

Многое изменилось в прошлом году или около того для наших друзей в Монреале. Номер 1 в моей книге – снижение цен на свой основной продукт: от _ 300 долларов _ к _ Ноль _. Я заплатил 300 долларов. Нам очень нужно получить здесь «пожертвовать».

Близкая секунда, несомненно, введение Сюжет . Dash получится настроение, которое танцевало через многие молодые и беспомощно наивные умы Pythonistas: Что если мы могли бы написать Только в питоне, как, навсегда ? Будь ужасным идеей, чтобы начать Googling Code Python To-Frontend Code Interneteters (они существуют; я проверил), DART HURTLY делает шокирующе хорошую работу по дыханию в этой романтической фантазии при совершении питона навсегда.

Но мы здесь не для доставки переработанного «Что такое заговор?» Синопсис. Мы даже не заинтересованы в обязательном « Как начать использовать это уже хорошо документированные технологии ‘ post _._ заговорно заслуживает лучшего, чем это. Вместо этого мы приходим горячим из раскатывающих ворот: мы собираемся показать вам, как побить сюжета, сломайте его и заставьте его согнуть на свою волю. Добро пожаловать в волшебное издание взлома заговор. Это должно быть Рождество, люди.

Давайте сделаем сюжета + колбы Lovechild из ада

Как и большинство доспехов в архитектуре, связанной с Python в этом году, имеет небольшой секрет: он получил здесь с небольшой помощью с колба. На самом деле, тире на самом деле расширяется Флэк: каждый раз, когда мы делаем приложение Dash, мы на самом деле создаем приложение для колбы с дополнительными колоколами и свистами. Это звучит разумно, и, возможно, даже захватывающе: если вы любите колбу, как я делаю, твой рот может быть прямо сейчас. Перспектива расчесывания силы сюда с колбой является эквивалентным каждому влюбленному, вы когда-либо решили, что лучше, чтобы просто поместить свои различия, чтобы начать групповое общение с вами в интересах сделать ваше сексуальное благополучие равным Усиление команды из чистой любви. Как вы уже догадались, жизнь не работает так.

Момент тире инициализируется Имя приложения__ ) , он вращает приложение для колбы к автоблоникам. При ретроспективе это не должно быть удивительным, потому что синтаксис для запуска приложения Dash точно такой же, как запуск приложения Flask. Проверьте рекомендуемую бойную табличку запуска:

from dash import Dash
import dash_core_components as dcc
import dash_html_components as html


app = Dash(__name__,
          external_stylesheets=['/static/dist/css/style.css'],
          external_scripts=external_scripts,
          routes_pathname_prefix='/dash/')

app.layout = html.Div(id='example-div-element')

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

Если вы должны были попытаться взять эту бойную плату и попытаться добавить основную логику колба, например, аутентификацию с Flask-login Создание активов с Флэк-активы или просто создавая глобальную базу данных, где бы вы начали? Чутливо умно говорит о резервировании приложение Пространство имен для вашего приложения – то же самое, что мы сделаем с колбой. Тем не менее, если мы попытаемся изменить приложение Объект так же, как мы бы с колбой, ничто не будет работать. Чутлино (возможно, намеренно) создал для вас песочницу с конкретными ограничениями. Это понятно: perressly – это коммерческая компания, и это некоммерческий продукт. Если бы было слишком легко наклониться заговор, компании все еще нуждаются в лицензии предприятия?

Dash Excels на то, что он должен был сделать: построение приложений на панели инструментов. Вопрос в том, что приложения, которые могут только отображение данных не всегда полезные конечные продукты. Что если мы хотели создать полностью оборудованное приложение, где визуализация данных была просто особенность из указанного приложения?

Создание полностью оборудованного приложения (где данные Vis – это просто особенность указанного приложения)

Обычный обходной путь, который вы найдете в сообществе, пропускает колбу, чтобы примерно в базовом «сервере», что-то вроде этого:

from flask import Flask
from dash import Dash
import dash_core_components as dcc
import dash_html_components as html

server = Flask(__name__)
app = dash.Dash(__name__,
               server=server,
               url_base_pathname='/dash')

app.layout = html.Div(id='dash-container')

@server.route("/dash")
def MyDashApp():
    return app.index()

Без ошибки: этот метод отстой. Конечно, вы восстановили возможность создавать маршруты здесь и там, но давайте не будем забывать:

  • Ваше приложение всегда начнется на странице PARM: если что-то, мы хотели бы, чтобы наша страница начала быть чем-то, что мы полностью контролируем, чтобы затем погрузиться в компоненты для приборов.
  • Доступ к глобально доступным плагинам колба все еще недоступен в этом методе. Обратите внимание, как мы никогда не устанавливаем контекст приложения?
  • Ваша способность стирать ваше приложение со статическими активами и стилями, полностью выходит из ваших рук.
  • Контейнерская архитектура, построенная на колбе, например, приложение Google App, не будет играть красиво, когда мы начнем что-то, что не колба. Таким образом, есть хороший шанс, что играя по правилам означает терять возможность развертывания.

Если мы хотим сделать это, мы не можем начать наше приложение в качестве приложения и попытаться обойти его. Вместо этого мы должны создать приложение Flask и поставьте тире на своем месте в качестве приложения, встроенного в наше приложение. Это дает нам полный контроль, когда пользователи могут ввести интерфейс Dash, и даже в этом интерфейсе мы все равно можем управлять соединениями базы данных или пользовательские сеансы, поскольку мы видим Fit. Добро пожаловать в большую лиги.

Переворачивая таблицы: Dash внутри колбы

Итак, что такое «приренение внутри колба» выглядит из перспективы структуры проекта? Если вы знакомы с Флэк приложение завод Узор, это не будет выглядеть совсем не так:

/plotlydash-flask-tutorial
├── /application
│   ├── __init__.py
│   ├── routes.py
│   ├── /static
│   ├── /templates
│   └── /plotlydash
│       └── dashboard.py
├── /data
├── README.md
├── config.py
├── requirements.txt
├── start.sh
└── wsgi.py

Это подходящие люди: я собираюсь засунуть правильную структуру приложения вниз по вашему горлу, если я получаю: даже посреди учебника по поводу взлома вещей вместе.

wsgi.py Является ли всегда точка входа нашего приложения в этом приложении. Это стандартная практика:

"""Application entry point."""
from application import create_app

app = create_app()

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

Теперь давайте посмотрим на то, как создается наше приложение для колбы в Приложение/__init__.py :

"""Initialize Flask app."""
from flask import Flask


def create_app():
    """Construct core Flask application with embedded Dash app."""
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_object('config.Config')

    with app.app_context():
        # Import Flask routes
        from application import routes

        # Import Dash application
        from application.plotlydash.dashboard import create_dashboard
        app = create_dashboard(app)

        # Compile CSS
        from application.assets import compile_assets
        compile_assets(app)

        return app

Это почти так, как будто ничего не изменилось! На самом деле, у нас есть только две линии, связанные с Dash: первый импортирует модуль Python, а второй регистрирует наше приложение на нашем изолированном приложении Dash с нашим приложением родительского колба:

...

# Import Dash app
from application.plotlydash.dashboard import create_dashboard
app = create_dashboard(app)

Давайте перевернем наше внимание на Импорт create_dashboard на мгновение. Мы импортируем файл под названием Dashboard.py из каталога в нашем приложении с колбы под названием/ Плотлдаш Отказ Внутри Dashboard.py это одна функция, которая содержит в целом приложение DART HART:

from dash import Dash


def create_dashboard(server):
    """Create a Plotly Dash dashboard."""
    dash_app = dash.Dash(server=server,
                         routes_pathname_prefix='/dashapp/',
                         external_stylesheets=['/static/css/styles.css']
                         )

    # Create Dash Layout
    dash_app.layout = html.Div(id='dash-container')

    return dash_app.server

Передаем наш экземпляр колбы в create_dashboard () Как параметр под названием Сервер Отказ В отличие от предыдущих примеров, это на самом деле Сервер Продолжайте шоу на этот раз, с помощью модуля в качестве модуля. Это приводит нас к нашей самой важной линии кода:

...

dash_app = dash.Dash(server=server,
                     routes_pathname_prefix='/dashapp/',
                     external_stylesheets=['/styles.css']
                     )           
...

Вместо того, чтобы создать наши dash_app Объект как глобальная переменная (как это предлагается), мы застряли в функции под названием create_dashboard () Отказ Это позволяет нам передать наше приложение для колбы верхнего уровня в Dash, как Сервер , следовательно, dash_app (сервер = сервер) Отказ Это эффективно вращает экземпляр прибора, используя наше Приложение Flask в своем ядре, в отличие от его собственного!

Обратите внимание на то, как мы проходим значение для Marals_Pathname_prefix. при создании dash_app Отказ Это эффективно наш обходной путь для создания маршрута для тире в более широком приложении: все, что мы строим в этом приложении, будут предшествовать префиксу, который мы проходим (конечно, мы всегда можем пройти / в качестве нашего префикса). Dash имеет полный контроль над чем-нибудь, что мы строим под Иерархия нашего префикса и нашего родительской колбы может контролировать что-нибудь еще. Это означает, что мы можем построить приложение с разразависимой колбью с сотнями функций и представлений, и если мы хотим видом на тире, мы можем просто создать модуль или подкаталог для этого, чтобы охладить. Это лучший коллаб с джинсов и карманов.

Теперь вы думаете с порталами ™.

Тонкие различия

Поскольку мы создаем dash в функции, мы должны знать, как это изменит способ, которым мы взаимодействуем с объектом Core Dash. Плохой новости – это копия + вставление других людей, почти наверняка не будет работать, потому что почти каждый держит Бросаться() Объект как глобальная переменная с именем приложение Отказ Хорошая новость в том, что это не имеет значения! Нам просто нужно строить вещи немного более логически.

Например, рассмотрите обратные вызовы. Dash позволяет нам создавать функции обратного вызова с Nifty Обратный вызов декоратор. Структура документов это как таковой:

import dash
from dash.dependencies import Input, Output
import dash_table
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
    # ... Layout stuff
])


@app.callback(
    # ... Callback input/output
    )
def update_graph(rows):
    # ... Callback logic

Обратите внимание, как все глобальное; приложение Глобал, мы устанавливаем app.layout Во всем мире и обратные вызовы определяются по всему миру. Это не будет работать для нас по ряду причин. А именно, мы не создаем Dash () После нагрузки файла; Мы создаем его, когда наше приложение для родительской колбы готов. Нам нужно более логично структурировать наш файл, используя функции, чтобы убедиться, что наше приложение загружено перед определением таких вещей, как обратные вызовы:

import dash
from dash.dependencies import Input, Output
import dash_table
import dash_html_components as html

def create_dashboard(server):
    app = dash.Dash(__name__)
    app.layout = html.Div([
        # ... Layout stuff
    ])

    # Initialize callbacks after our app is loaded
    # Pass dash_app as a parameter
    init_callbacks(dash_app)

    return dash_app.server

def init_callbacks(dash_app):
    @app.callback(
        # ... Callback input/output
        )
    def update_graph():
        # ... Insert callback stuff here

Видишь, не так плохо!

Создание домашней страницы колба

Потому что точка входа в наше приложение теперь происходит через колбу, Маршруты .py имеет гибкость, чтобы служить на все, что мы хотим. Теперь у нас есть свобода создания приложения без ограничений, прыгая в или из заговорной чертежи на видах, которые мы видим в форме. Я добавил простую посадочную страницу, чтобы продемонстрировать это:

"""Core Flask app routes."""
from flask import render_template
from flask import current_app as app


@app.route('/')
def home():
    """Landing page."""
    return render_template('index.jinja2',
                           title='Plotly Dash & Flask Tutorial',
                           template='home-template',
                           body="This is a homepage served with Flask.")

dashboard.py

Dashboard.py Приложение Dash мы живем в пределах Наше приложение для колбы. Но как колбу знают, какой маршрут связан с помощью Dash? Разве это не хватало от Маршруты .py ? Действительно, это был хороший парень! Потому что мы устанавливаем Marals_Pathname_prefix. Создавая dash_app объект, мы Не нужно Чтобы создать маршрут для Dash: он всегда будет подан, когда мы перейдем к 127.0.01/dashapp Отказ Таким образом, мы можем связать на нашу приборную панель через обычный шаблон колба, как так:

Создавая что-то полезное

Я выбросил рабочую демонстрацию Dash в колбе, чтобы продемонстрировать это в действии. Пример ниже показывает путешествие пользователя, навигацию нашего приложения. Пользователь приземляется на домашнюю страницу нашего приложения для колб, которое мы определены в Маршруты .py Отказ Оттуда пользователь может щелкнуть на приборной панели на чертеже, мы определяем в Dashboard.py Безшовно:

Наше приложение в действии.

Пользователь не является мудрее, что они вскочили из приложения колба в приложение Dash, что делает эту практику, так привлекательную: объединяя простоту чертежного приборной панели с законным веб-приложением, мы уполномочены создавать опыт пользователей которые выходят далеко за рамки их частей.

Если вы голодны для исходного кода, чтобы начать создание собственных сюжетных видов приборных тире, вот источник, который я использовал для создания страницы выше:

"""Create a Dash app within a Flask app."""
import dash
import dash_table
import dash_html_components as html
import dash_core_components as dcc
import pandas as pd
import numpy as np
from .layout import html_layout


def create_dashboard(server):
    """Create a Dash app."""
    dash_app = dash.Dash(server=server,
                         routes_pathname_prefix='/dashapp/'
                         external_stylesheets=['/static/css/styles.css']
                         )

    # Prepare a DataFrame
    df = pd.read_csv('data/311-calls.csv', parse_dates=['created_date'])
    num_complaints = df['complaint_type'].value_counts()
    to_remove = num_complaints[num_complaints <= 20].index
    df.replace(to_remove, np.nan, inplace=True)

    # Custom HTML layout
    dash_app.index_string = html_layout

    # Create Layout
    dash_app.layout = html.Div(
        children=[dcc.Graph(
            id='histogram-graph',
            figure={
                'data': [
                    {
                        'x': df['complaint_type'],
                        'text': df['complaint_type'],
                        'customdata': df['unique_key'],
                        'name': '311 Calls by region.',
                        'type': 'histogram'
                    }
                ],
                'layout': {
                    'title': 'NYC 311 Calls category.',
                    'height': 600,
                    'padding': 150
                }
            }),
            create_data_table(df)
            ],
        id='dash-container'
    )
    return dash_app.server


def create_data_table(df):
    """Create Dash datatable from Pandas DataFrame."""
    table = dash_table.DataTable(
        id='database-table',
        columns=[{"name": i, "id": i} for i in df.columns],
        data=df.to_dict('records'),
        sort_action="native",
        sort_mode='native',
        page_size=300
    )
    return table

Рабочая версия этой демонстрации здесь живет:

https://plotlydashflask.hackersandslackers.app/

Я загрузил исходный код для этого рабочего прибора в Github. Возьми это, используйте это, злоупотребляйте его. Это все твое:

https://github.com/toddbirchard/plotlydash-flask-tutorial

Само собой разумеется, есть более крутое дерьмо, мы можем достичь с заговорной тире. Придерживайтесь достаточно долго, и есть хороший шанс, который мы охватим все их.

Оригинал: “https://dev.to/hackersandslackers/integrate-plotly-dash-into-your-flask-app-5gbo”