01.12.2018       Выпуск 258 (26.11.2018 - 02.12.2018)       Статьи

Краткое руководство по Dash — Python веб-фреймворк для создания дэшбордов. Installation + Dash Layout

Сегодня предлагаю погрузиться в один из удобнейших веб-фреймворков в связке c Python под названием Dash. Появился он не так давно, пару лет назад благодаря разработчикам фреймворка plotly. Сам Dash является связкой Flask, React.Js, HTML и CSS.

Читать>>




Экспериментальная функция:

Ниже вы видите текст статьи по ссылке. По нему можно быстро понять ссылка достойна прочтения или нет

Просим обратить внимание, что текст по ссылке и здесь может не совпадать.

Всем привет!

Сегодня предлагаю погрузиться в один из удобнейших веб-фреймворков в связке c Python под названием

Dash

. Появился он не так давно, пару лет назад благодаря разработчикам фреймворка plotly. Сам Dash является связкой Flask, React.Js, HTML и CSS.

Выступление Криса Пармера на PLOTCON 2016

Давайте сразу установим фреймворк. Обновленные версии уточняйте

тут

.

pip install dash==0.31.1  # The core dash backend
pip install dash-html-components==0.13.2  # HTML components
pip install dash-core-components==0.38.1  # Supercharged components
pip install dash-table==3.1.7  # Interactive DataTable component (new!)

Друзья, если вы действительно хотите разобраться в данном фреймворке, читайте публикации до конца, так как зачастую сначала следуют примеры, а уже после детальный обзор кода. Если вам все равно непонятно — советую читать документацию по Dash на английском языке в оригинале. Также в рунете есть несколько статей, которые объясняют концепции, которые я решил пропустить в данном туториале.

Начнем.

Приложения Dash состоят из двух частей. Первая часть — «layout» описывает то, как выглядит наше приложение. Вторая часть описывает интерактивность приложения, о ней мы поговорим в следующей статье.

Dash предоставляет Python классы для всех визуальных компонентов приложения. Разработчики предоставляют набор компонентов в так называемых

dash_core_components

и

dash_html_components

. Но также вы можете

построить свой компонент

используя JavaScript и React.js.

Важно

В

dash_core_components

содержатся различные динамические формы такие как, например, выпадающие списки, графики и чек-боксы.

В

dash_html_components

содержатся html конструкции, которыми можно завернуть наши формы. Например Div блоки или теги заголовков H1, H2, и так далее. Разработчики предоставляют нам некую абстракцию от html с помощью словарей Python.

Чтобы начать разбираться, создадим файл

app.py

, в котором будет содержаться следующее:

# -*- coding: utf-8 -*-

# Загрузим необходимые пакеты
import dash
import dash_core_components as dcc
import dash_html_components as html

#  Объяснение данных строк пока опускается, будет объяснено далее
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(children='''
        Dash: A web application framework for Python.
    '''),

    dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
            ],
            'layout': {
                'title': 'Dash Data Visualization'
            }
        }
    )
])

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

И запустим его из текущей директории командой:

$ python app.py ...Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)

Видим, что сервер запустился и готов принимать запросы на порт 8050 (у вас может быть другой порт).

Переходим по адресу

http://127.0.0.1:8050/

и видим:

Примечание

  1. Компонент layout состоит из дерева «компонентов», которые содержаться в dash_html_components. Например блоков Div.

  2. dash_html_components имеет компонент для каждого html тэга. html.H1(children='Hello Dash') компонент генерирует HTML элемент
    <h1>Hello Dash</h1>
    в вашем приложении.

  3. Не все компоненты фреймворка являются HTML компонентами. dash_core_components генерирует более высокоуровневые элементы и интерактивные элементы, используя связку JS, HTML, CSS и React.Js.

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

  5. Атрибут children немного особенный. По соглашению, он всегда идет первым, что означает, что вы можете заменить html.H1(children='Hello Dash') на html.H1('Hello Dash').

На заметку

Dash содержит привычную веб разработчика фичу:

hot-reloading

. Она активируется в тот момент, когда запускается функция

app.run_server(debug=True)

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

Как мы помним, Dash содержит компонент для каждого тега HTML. Но также он может принимать все аргументы ключевых слов, как и элементы HTML.

Давайте немного изменим наш код:

# -*- coding: utf-8 -*-
import dash
import dash_core_components as dcc
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}

app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
    html.H1(
        children='Hello Dash',
        style={
            'textAlign': 'center',
            'color': colors['text']
        }
    ),

    html.Div(children='Dash: A web application framework for Python.', style={
        'textAlign': 'center',
        'color': colors['text']
    }),

    dcc.Graph(
        id='example-graph-2',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font': {
                    'color': colors['text']
                }
            }
        }
    )
])

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

Обновляем страницу, и видим:

В этом примере мы изменили стили

html.Div

и

html.H1

с помощью свойства

style

.

html.H1('Hello Dash', style={'textAlign': 'center', 'color': '#7FDBFF'})

отрендерится в приложении Dash как:

<h1 style="text-align: center; color: #7FDBFF">Hello Dash</h1>

Но есть несколько важных замечаний:

  1. Свойства style в HTML это разделенная точкой с запятой строка. В Dash вы можете просто передать словарь.

  2. Ключи в style словаре немного различаются в написании относительно HTML. Вместо text-align мы пишем textAlign.

  3. Дочерние классы каждого элемента-тэга в Dash (класса) передаются в массиве через аргумент children.

Многоразовые компоненты

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

reusable components

. Рассмотрим их на примере таблицы, данные для которой будут загружаться из Pandas dataframe.

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/'
    'c78bf172206ce24f77d6363a2d754b59/raw/'
    'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'
    'usa-agricultural-exports-2011.csv')


def generate_table(dataframe, max_rows=10):
    return html.Table(
        # Header
        [html.Tr([html.Th(col) for col in dataframe.columns])] +

        # Body
        [html.Tr([
            html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
        ]) for i in range(min(len(dataframe), max_rows))]
    )


external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[
    html.H4(children='US Agriculture Exports (2011)'),
    generate_table(df)
])

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

Немного о таблицах

Давайте вспомним что из себя представляет таблица в HTML.

HTML таблица определяется тэгом

table

.

Каждая строка таблица определяется тэгом

tr

. Хедер таблица определяется тэгом

th

. A ячейки таблицы заполняются с помощью тэга

td

.

Получается такая структура:


<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th> 
    <th>Age</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td>
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
  <tr>
    <td>John</td>
    <td>Doe</td>
    <td>80</td>
  </tr>
</table>

И выглядит она так:

FirstnameLastnameAge
JillSmith50
EveJackson94
JohnDoe80

Компоненты ядра (Основные компоненты)

Как мы уже сказали ранее,

dash_core_components

включает в себя высокоуровнвые элементы. Такие, как: выпадающее меню, графики и прочее.

Вы можете ознакомиться с визуальной стороной этих элементов, каждый из которых сопровождается кодом (очень удобно, вселенский респект разрабочикам из Plot.ly)

здесь

.

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

Давайте рассмотрим следующий код:

import dash
import dash_core_components as dcc
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.Label('Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    ),

    html.Label('Multi-Select Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value=['MTL', 'SF'],
        multi=True
    ),

    html.Label('Radio Items'),
    dcc.RadioItems(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    ),

    html.Label('Checkboxes'),
    dcc.Checklist(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        values=['MTL', 'SF']
    ),

    html.Label('Text Input'),
    dcc.Input(value='MTL', type='text'),

    html.Label('Slider'),
    dcc.Slider(
        min=0,
        max=9,
        marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},
        value=5,
    ),
], style={'columnCount': 2})

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

Тут мы видим, что мы создали как обычно один общий Div блок, в котором содержатся наши различные компоненты ядра. Выглядит это как-то так:

image

Остались вопросы?

Разработчики подготовили очень подробную документацию, прочитать вы ее можете типичной Python командой для каждого класса:

>>> help(dcc.Dropdown)

Summary

Ранее нами изученый

layout

описывает то, как выглядит наше приложение. По сути он содержит древовидную иерархию HTML тэгов и высокоуровневых элементов ядра Dash, которые содержатся в

dash_core_components

.

В следующей части мы изучим то, как сделать нашу страничку интерактивной. Если вам понравился данный туториал, ставьте плюсик и подписывайтесь на меня.

* Здесь скоро будет ссылка на следующую часть *



Лучшая Python рассылка




Разместим вашу рекламу

Пиши: mail@pythondigest.ru

Нашли опечатку?

Выделите фрагмент и отправьте нажатием Ctrl+Enter.

Система Orphus