Предложение ценности 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 требуется четыре шага:
- Установите необходимые пакеты Python (ref)
- Создайте макет приложения (ref), используя базовые компоненты HTML из основных компонентов Dash (ref) или компонентов HTML Dash (DCC, ref) или с помощью более полный фреймворк HTML, такой как Bootstrap 4, заключенный в компоненты Dash Boostrap (DBC, ref)
- Создайте приложение Dash с указанным выше макетом (ref)
- Добавить обратные вызовы для обработки взаимодействия с пользователем (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>
:
- Выбранное значение передается родительскому элементу (
<App>
) <App>
обновляется,<audio>
- URL-адрес статического файла на сервере, а<Scores>
- имя файла образца для выполнения логического вывода<Scores>
обновляется и асинхронно вызывает сервер для выполнения логического вывода<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: