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

В разделе Какую библиотеку я должен использовать для своей панели инструментов Python? Мы видели, что создание визуализации данных на панели инструментов Web быстро становится сложным и требует инфраструктуры, которая делает больше, чем просто сшивание некоторых графиков. Plotly Dash - один из таких фреймворков, который очень доступен для большинства специалистов по данным, поскольку приложение представляет собой чистый код Python.

В то же время Dash создает веб-приложение, основанное на React.js, ведущей платформе Javascript для веб-приложений. Рано или поздно вы почувствуете себя ограниченным Dash. Либо из-за ограничений или принципов Dash, либо из-за отсутствия контроля над созданным приложением, либо из-за интеграции панели управления с более крупным приложением. Например, вашему приложению может потребоваться аутентификация пользователя, оно может получить некоторые данные клиента и в конечном итоге привести к панели мониторинга.

Что, если я захочу переключиться с Dash на классическое приложение React.js после этапа прототипирования? Это дорого?

Что, если я хочу полностью пропустить этап Dash и напрямую создать приложение React.js? Кривая обучения слишком крутая?

Ниже показано, что означает написание приложения Dash и альтернативы React.js на основе варианта использования, который подходит для Dash: при выборе пользователя вывод выполняется для аудиофайла с использованием классификатора YAMNet. Вывод возвращает оценки, а также форму волны, эти серии отображаются на панели инструментов.

Код статьи доступен в репозитории Github tonio73 / dash-to-response. Это учебное пособие, а не шаблон для начала разработки. Вот почему шаги по воспроизведению этого кода описаны ниже.

Обе версии панели инструментов основаны на Plotly для графиков, Bootstrap 4 для дизайна HTML и CSS. Оба они доступны как плагины для Dash и как пакеты Node.js для React.js.

Приложение Plotly Dash

В папке dash_version/

В случае Plotly Dash весь пользовательский код написан на Python. Dash генерирует не только необходимый код Javascript, но и веб-API для создания и обновления содержимого веб-приложения в браузере. Dash создает всю эту сантехнику и обслуживает код через HTTP с помощью Flask (который должен быть развернут на мощном веб-сервере в производственной среде: рекомендуется Gunicorn + Nginx).

Для создания приложения Dash требуется четыре шага:

  1. Установите необходимые пакеты Python (ref)
  2. Создайте макет приложения (ref), используя базовые компоненты HTML из основных компонентов Dash (ref) или компонентов HTML Dash (DCC, ref) или с помощью более полный фреймворк HTML, такой как Bootstrap 4, заключенный в компоненты Dash Boostrap (DBC, ref)
  3. Создайте приложение Dash с указанным выше макетом (ref)
  4. Добавить обратные вызовы для обработки взаимодействия с пользователем (ref)

Шаги с 1 по 3 должны быть довольно простыми, учитывая документацию Dash. Основные дизайнерские решения заключаются в том, как представить данные в визуализации, как установить параметры Plotly. Вы, вероятно, столкнетесь с выбором между API Plotly: Express или Graphical Object? Express удобен, если данные находятся во фрейме данных Pandas. Однако даже в этом случае он весьма ограничен построением однородных рядов. Для более сложных графиков необходим Графический объект.

Шаг 4, обратные вызовы, сложнее, чем предыдущие. Во-первых, необходимо определить взаимодействие с пользователем, а во-вторых, найти способ выразить его в концепциях Dash. Это часто довольно сложно, если элементы управления связаны (например, выбор, который изменяет параметры другого выбора, который определяет график). Вот несколько рекомендаций:

  • Если требуется выбор пользователя, не инициализируйте графические изображения при построении макета. Цифры устанавливаются в обратных вызовах.
  • Если данные для построения графика требуют вычислений или являются довольно тяжелыми (более 100 точек), оберните графики в компонент загрузки компонентов ядра Dash.

Ждать! Как данные для отображения загружаются? Как выполняется вывод?

Эти вопросы приводят к еще одной важной концепции Dash: сервер не должен отслеживать пользовательские значения, то есть он не должен иметь состояния (ref). Поскольку нет языковых границ или разделения пакетов между серверным и клиентским (браузером) программным обеспечением, очень легко создать какое-либо состояние на сервере. Как правило: чтобы не иметь состояния, обратные вызовы не должны использовать переменные, которые недоступны из аргументов функции обратного вызова.

Однако иногда рекомендуется сохранить какое-то состояние. Например, чтобы предварительно загрузить некоторые большие переменные, такие как модель машинного обучения, которая используется для вывода. В нашем случае загрузка Tensorflow и модели YAMNet занимает несколько секунд и не должна выполняться при каждом вызове логического вывода. Это будет не только медленно, но и потребляет ресурсы процессора и памяти.

Приложение React.js с сервером Flask API

В папке react_version/

В этой настройке веб-сервер Python действует только как сервер API, открывая некоторые конечные точки REST. Приложение изначально разработано на React.js с использованием пакетов Plotly.js и React-plotly.js (ref1, ref2). Bootstrap также добавлен как зависимость от приложения React.js. Асинхронные вызовы API-сервера выполняет Axios (ref).

Во время разработки используются два сервера (могут быть собраны в один сервер для производства):

  • Flask запускает сервер разработки для разработки и отладки API.
  • Скомпилированное приложение React.js, а также другие зависимости HTML (CSS, изображения…) предоставляются сервером на основе Node.js

Точно так же есть два списка зависимостей:

  • Зависимости Python, управляемые Conda или Pip
  • Зависимости Javascript, управляемые диспетчером пакетов узлов (NPM)

Последнее серьезное изменение - это необходимость скомпилировать и связать приложение React.js. Этим занимается Yarn с помощью скриптов Webpack и React.

Сообщение в блоге Как создать проект React + Flask предоставляет простой способ настроить и запустить такую ​​настройку и избежать проблем с безопасностью, таких как совместное использование ресурсов между источниками (ref): сервер Node.js настроен на выступать в качестве прокси для сервера API: любой неизвестный запрос перенаправляется на сервер API.

Следующие шаги - это разработка API и приложение React.js.

Сервер API

В приложении учебника сервер API имеет две конечные точки (файл api / app.py):

  • /api/samples, чтобы получить список доступных метаданных аудиосэмплов (URL, заголовок, имя файла)
  • /api/infer для выполнения вывода по выбранному пользователем образцу

Приложение React.js

В React с JSX (ref) компоненты создаются иерархически как пользовательские HTML-подобные теги. На верхнем уровне используются три компонента:

  • <audio> - стандартный аудиоплеер HTML 5.
  • <SampleList>, который извлекает с сервера API список образцов и предоставляет раскрывающийся список, чтобы получить выбор пользователя.
  • <Scores> вызывается логический вывод на сервере API и отображается форма звуковой волны и оценки логического вывода.

Это простое приложение требует хорошего понимания концепций компонентов React.js (ref):

  • Состояние и свойства компонентов
  • Циклы создания и обновления компонента
  • Обновление состояния родителя с помощью обратных вызовов

Когда пользователь выбирает образец из раскрывающегося списка <SampleList>:

  1. Выбранное значение передается родительскому элементу (<App>)
  2. <App> обновляется, <audio> - URL-адрес статического файла на сервере, а <Scores> - имя файла образца для выполнения логического вывода
  3. <Scores> обновляется и асинхронно вызывает сервер для выполнения логического вывода
  4. <Scores> отображается после завершения вывода и получения формы волны и результатов

Plotly.js

Plotly.js - это основа Plotly для версий Python и React.

Это, вероятно, должно означать, что операторы Python массируются для создания кода React ... Однако по какой-то неясной причине Plotly-react.js не тематизирует графики, необходимо определить свойство template графика. С помощью инспектора Chrome это свойство копируется из версии Dash. В настоящее время замечено, что Plotly Python довольно ленив: полный шаблон, содержащий тематику для всех типов графиков, всегда передается клиенту и для каждого графа. Это похоже на некоторые накладные расходы, которые можно было бы уменьшить, если бы в компоненте Javascript был шаблон по умолчанию.

Кроме того, инструменты сборки React жалуются, что пакет приложения слишком велик и его следует разделить (ref). Используя Source-map-explorer (ref), я обнаружил, что это невозможно, поскольку почти весь вес пакета приходится на пакет Plotly.

Заворачивать

Реализация Dash довольно аккуратная, 1 файл, всего 47 операторов, один язык. В то же время уже существует кривая обучения, чтобы обойти формализм обратных вызовов Dash. Это становится намного сложнее, когда приложение более сложное, с большим количеством компонентов, многостраничным. Интеграция в более сложное приложение Flask может потребоваться, если приложение обрабатывает аутентификацию или редактирует некоторые данные в формах.

Однако написать приложение React тоже не так сложно:

  • 1 файл Python с 24 операторами
  • 6 файлов Javascript, все с несколькими операторами

Кривая обучения будет круче, даже больше, если сначала нужно изучить Javascript или React. Есть больше инструментов, больше концепций. Но в конечном итоге фреймворк (React.js) стал более последовательным, более мощным и поддерживался широким сообществом.

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

В то же время Plotly, имеющий версии Python и Javascript, обеспечивает плавный переход между двумя реализациями.

Теперь ваша очередь попробовать, код доступен на Github:

Https://github.com/tonio73/dash-to-react