Примеры состояния сеанса Streamlit и обратных вызовов в созданном мною инструменте маркировки данных.

В настоящее время создать веб-приложение с помощью Streamlit очень просто, но есть ограничения при создании чего-то сложного. Одна из них - отсутствие состояния, поскольку переменные в коде будут повторно инициализироваться каждый раз, когда мы взаимодействуем с виджетом. Хорошая новость заключается в том, что Streamlit теперь имеет встроенную поддержку состояния сеанса и функцию обратного вызова в версии 0.84. Теперь мы можем сохранять переменные во время повторных запусков и определять собственный обработчик событий при взаимодействии с виджетом.

Состояние сеанса

Взломы состояния сеанса существуют с октября 2019 года, но новый st.session_state предоставляет нам элегантное решение для доступа к переменным с отслеживанием состояния. Один из вариантов использования состояния сеанса в моем инструменте маркировки данных - сохранить выбранный проект. Приложению необходимо знать, какие проекты доступны и над чем работает проект. Это можно просто сделать:

import streamlit as st
# set variables in session state
st.session_state.projects = [
    'Boring Project', 'Interesting Project'
]
st.session_state.current_project = st.radio(
    'Select a project to work with:',
    st.session_state.projects,
)

Следующим шагом будет получение данных выбранного проекта. Помимо выбранного проекта, приложению также требуется индекс строки данных для выборки. Для простоты мы предполагаем, что существует функция, которая извлекает данные из базы данных следующим образом:

def fetch_data(project_name: str, row_index: int):
    """ A simple example function to fetch data. """
    dbs = {
        'Boring Project': [...],
        'Interesting Project': [...],
    }
    return dbs[project_name][row_index]  # output can be any form
if 'current_project' in st.session_state:
    row_index = st.session_state.get('row_index', 0)
    data = fetch_data(st.session_state.current_project, row_index)

Когда пользователь щелкает следующие или предыдущие данные, переменная row_index в состоянии сеанса может быть установлена ​​на другой номер, и новые данные будут загружены автоматически.

# examples to update row index
if st.button('Next', key='next_data'):
    st.session_state.row_index += 1
if st.button('Previous', key='previous_data'):
    st.session_state.row_index -= 1

Обратные вызовы

Обратный вызов - это функция, которая вызывается при срабатывании виджета ввода. Виджеты Streamlit, которые поддерживают обратный вызов: st.button(), st.radio(), st.text_input() и т. Д. Давайте рассмотрим пример обратного вызова в кнопке отправки для добавления нового проекта.

def submit_add_project(project_name: str):
    """ Callback function during adding a new project. """
    # display a warning if the user entered an existing name
    if project_name in st.session_state.projects:
        st.warning(f'The name "{project_name}" is already exists.')
    else:
        st.session_state.projects.append(project_name)
new_project = st.text_input('New project name:',
                            key='input_new_project_name')
st.button('Add project', key='button_add_project',
          on_click=submit_add_project, args=(new_project, ))

Обратите внимание, что для функции обратного вызова требуется аргумент project_name, поэтому нам нужно передать аргумент с помощью args. Помимо добавления нового проекта, мы также должны разрешить пользователю удалить проект, выполнив следующие действия:

def submit_delete_project(project_name: str):
    """ Callback function during deleting an existing project. """
    st.session_state.projects.remove(project_name)
to_delete = st.selectbox('Project to be deleted:',
                         st.session_state.projects)
st.button('Delete project', key='button_delete_project',
          on_click=submit_delete_project, args=(to_delete, ))

Заключение

В этой статье показаны некоторые примеры состояния сеанса и обратных вызовов, которые позволяют приложению сохранять переменные при повторном запуске и взаимодействии с виджетами. Я рекомендую вам попробовать их для более глубокого понимания и ознакомиться с модернизированным сообщением в блоге. Наконец, вы можете найти репозиторий для инструмента маркировки данных в Github.

Это мой первый средний пост, и я очень благодарен за то, что вы стали моими читателями. Надеюсь, вам понравилась эта статья и вы узнали что-то новое. Спасибо за уделенное время. Оставайся в безопасности.