Каждый исследователь, студент или преподаватель рано или поздно сталкивается с необходимостью создавать интерактивные и красивые отчеты, которые позже следует приложить к статье, сдать на проверку или поделиться со студентами. Все чаще в топовых ВУЗах приевшиеся методички заменяют на Jupiter ноутбуки, а возможность сварганить красивый отчет «на коленке» прельщает огромное количество студентов.
Выделим основные недостатки отчетов в Jupiter Notebook:
-
Много кода. В большинстве отчетов важны таблицы, графики и выводы, а не куски кода, которые помогли эти данные получить и составляют, как правило, более половины отчета.
-
Сложность в интерактивной демонстрации. Для полноценной работы Jupiter Notebook необходимо иметь приложение и интерпретатор питон (или онлайн сервис).
Streamlit
Это low-code фреймворк, созданные для исследователей, которые используют python. Благодаря встроенному набору элементов можно быстро накидать свой отчет или веб приложение, а главное поделиться им с другими, развернув его в облаке всего за пять минут!
Установка
Устанавливается streamlit через pip:
pip install streamlit
После установки можно запустить пример, введя в терминале команду:
streamlit
Когда приложение запустится, в терминале будет приветственное сообщение и адрес, причем окно в браузере, скорее всего, откроется самостоятельно.
На страничке мы видим ссылку на сайт и много других полезных ссылок, которые пригодятся во время создания своего приложения.
Создаем свой отчет
Все начитается с того, что нужно установить и импортировать streamlit
import streamlit as st
Я хочу сделать так, чтобы в одном проекте можно было переключаться между разными отчетами, которые будут представлять отдельные странички. Для этого используется виджет sidebar:
page = st.sidebar.selectbox("Выбрать страницу", ["Тяжелые хвосты распределений", "Iris Dataset"])
Здесь первый параметр является заголовком виджета, а список содержит варианты выбора. Когда пользователь меняет свой выбор, пременной page присваивается соответствующее значение из списка.
Чтобы переключать страницы, нужно лишь использовать условный оператор if:
if page == "Тяжелые хвосты распределений": st.header("""Демонстрация Fisher's Iris датасета""") elif page == "Iris Dataset": st.header("""Сгенерировать N случайных событий из распределения Фреше с функцией распределения:""")
Для формирования заголовка используется виджет st.header
Так же есть возможность использовать latex:
st.latex(r''' F(x) = exp(-(\gamma x)^{-1/\gamma}1\{x>0\}) ''')

Итак, код для отображения страницы «Тяжелые хвосты распределений»:
def main(): page = st.sidebar.selectbox("Выбрать страницу", ["Тяжелые хвосты распределений", "Iris Dataset"]) if page == "Тяжелые хвосты распределений": st.header("""Сгенерировать N случайных событий из распределения Фреше с функцией распределения:""") st.latex(r''' F(x) = exp(-(\gamma x)^{-1/\gamma}1\{x>0\}) ''') st.text("Для получения результата:") st.markdown("* Сгенерируем N нормально распределенных случайных величин $U_i$ [0,1] (нулевое среднее и единичная диспресия).") st.markdown("* Вычислим N cлучайных величин с распределением Фреше по формуле:") st.latex(r''' X_i=\dfrac{1}{\gamma}\left(-lnU_i)^{-\gamma}\right) ''') mu, sigma = 0, 1 # mean and standard deviation gamma = st.slider('Желаемая гамма', 0.25, 2.25, 0.5, 0.25) N = st.number_input("Желаемое N", 100, 10000, 10000) U = np.abs(np.random.normal(mu, sigma, N)) X = 1 / gamma * (-np.log(U)) ** (-gamma) X2 = X[X < 20] fig, ax = plt.subplots() count, bins, ignored = plt.hist(X2, 100, density=True) plt.plot(bins, np.exp(- (gamma * bins) ** (-1 / gamma)) * (1 / gamma) * (gamma * bins) ** (-1 / gamma - 1) * gamma, linewidth=2, color='r') st.pyplot(fig)
Кэширование данных
Каждый раз, когда пользователь нажимает что-то в интерфейсе весь скрипт выполняется заново. Это не очень хорошо, если мы скачиваем какие-то датасеты и работаем с ML моделями. Специально для этого есть две аннотации:
-
st.cache_data— используется для кеширования загружаемых датасетов. -
st.cache_resource— используется для ML моделей.
Так, чтобы загрузить известный датасет ирисов, напишем функцию с аннотацией st.cache_data:
@st.cache_data def load_data(): if not os.path.isfile("data/iris.csv"): # Download the Iris Fisher dataset url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data" response = requests.get(url) data = response.text # Save the dataset to a local file with open("data/iris.csv", "w") as file: file.write(data) # Load the dataset into a pandas DataFrame df = pd.read_csv("data/iris.csv", header=None, names=["sepal_length", "sepal_width", "petal_length", "petal_width", "class"]) return df
Я поместил датсет в папку data не спроста, она нам потом понадобиться.
Отобразим его на соответствующей странице, используя st.pyplot:
elif page == "Iris Dataset": st.header("""Демонстрация Fisher's Iris датасета""") df = load_data() # Plotting the dataset fig, ax = plt.subplots() plt.scatter(df['sepal_length'], df['sepal_width'], c='blue', label='Iris-setosa') plt.scatter(df['sepal_length'], df['petal_width'], c='red', label='Iris-versicolor') plt.scatter(df['sepal_length'], df['petal_length'], c='green', label='Iris-virginica') plt.xlabel('sepal_length') plt.ylabel('sepal_width') plt.title('Iris Fisher Dataset') plt.legend() st.pyplot(fig)
Запуск приложения
Для запуска проекта можно рассмотреть два варианта:
-
Запустить командой
streamlit run app.py,через параметр--server.port=8057можно указать, какой порт будет слушать приложение.Не забываем в нашем файле указать точку входа:
if __name__ == "__main__": main() -
Для любителей запускать всего через
python main.py:Создадим отдельный файл main.py и обозначим точку входа, где пропишем, что нужно запустить и с каким портом:
from streamlit.web.cli import main import sys if __name__ == "__main__": # Set prog_name so that the Streamlit server sees the same command line # string whether streamlit is called directly or via `python -m streamlit`. sys.argv = ["streamlit", "run", "app.py", ""] sys.exit(main(prog_name="streamlit"))
В итоге получаем красивый отчет:
Разворачиваем в облаке
Нам осталось самое интересное. То, ради чего мы вообще все это затеяли: сделать наш отчет общедоступным. Есть несколько вариантов, как это сделать:
-
Воспользоваться Streamlit Community Cloud — облако от создателей данного фреймворка.
-
Через хостинг у облачных провайдеров. Это довольно затратный и сложный метод для такой задачи, поэтому его опустим.
-
Разворачивание в облаке через пуш в GIT. Это такие сервисы, как Heroku и Amvera.
Amvera Cloud
-
Переходим на страничку входа и создаем аккаунт, если его ещё нет.
-
Нажимаем на кнопку «Создать» и вводим название проекта и тариф. Для большинтства проектов подойдет «Начальный»
Создание проекта -
На ПК переходим в папку с нашим проектом. Создаем там GIT репозиторий командой
git init -
На странице проекта находим инструкцию, как подключиться к удаленному репозиторию. Для этого нужно выполнить
git remote add amvera <адрес удаленного репозитория> -
Генерируем инструкцию для облака, как развернуть наше приложение:
-
Переходим на страницу генератора инструкций, которая, кстати, тоже написана с помощью streamlit.
-
Указываем, что мы используем python, обязательно иметь файл requirements.txt, где указаны все используемые библиотеки (в том числе и streamlit).
-
Если локально запускали все через команду
streamlit run app.py, то ставим галку на «укажу свою» и прописываем эту команду. -
Тут ещё есть поле «Введите mountpoint», где указывается, где будут храниться данные, которые не стираются после перезапуска или остановки проекта. Так, если вы собираете какую-то статистику или собираетесь хранить данные, то их слудует класть в отдельную папку, путь до которой указывается в этом поле. Я не хочу аждый раз при перезапуске проекта скачивать заново весь датесет, поэтому положил его в папку
dataи указал этот путь в конфигурации. -
Нажимаем на кнопку Generate YAML. Добавляем полученный файл amvera.yml в корень нашего проекта.
-

-
-
Моя папка с проектом выглядит следующим образом (venv у вас может отсутствовать)
Папка с проектом -
Заносим наши изменения в репозиторий, выполнив:
git add . git commit -m "Initial commit" git push amvera master
-
Ждем статуса «Успешно развернуто на странице проекта
Успешно развернутый проект -
Переходи по ссылке, указанной на этой же странице, у меня это https://streamlit-amvera-services.amvera.io и наслаждаемся нашим отчетом.
-
(Опционально) В разделе «Настройки» можно привязать свое доменное имя.
Вот такими простыми действиями мы развернули наш отчет и сделали его публичным. При этом, чтобы сэкономить, можно включать и выключать проект, нажимая на символ паузы. Деньги со счета будут списываться только в то время, когда проект включен.
ссылка на оригинал статьи https://habr.com/ru/companies/amvera/articles/744952/

Добавить комментарий