[PYTHON] Carry over data to another page (tab) with streamlit

1. First

Data analysis results can be quickly visualized as a web app streamlit. It's fun because there are various samples on the official website. I recently saw what huggingface used to view published datasets.

I use streamlit very conveniently, but when I move to another page (tab) with a radio button like the page below, all variables and dataframes disappear. When I upload data on the "Input data" page and go to the "Data processing" page, I cannot see the data I uploaded and put in the dataframe.

image.png

Data upload page → data processing page → data visualization page, etc. I was in trouble when I wanted to process data across multiple pages. If you try to complete it in one page, it will be very long vertically due to the current specifications of streamlit.

2. Summary

It was good to wander around the internet and relay using session at the end, so I will write it down. Liver part ↓

session part
class _SessionState:

    def __init__(self, session, hash_funcs):
        """Initialize SessionState instance."""
        self.__dict__["_state"] = {
            "data": {},
            "hash": None,
            "hasher": _CodeHasher(hash_funcs),
            "is_rerun": False,
            "session": session,
        }

    def __call__(self, **kwargs):
        """Initialize state data once."""
        for item, value in kwargs.items():
            if item not in self._state["data"]:
                self._state["data"][item] = value

    def __getitem__(self, item):
        """Return a saved state value, None if item is undefined."""
        return self._state["data"].get(item, None)
        
    def __getattr__(self, item):
        """Return a saved state value, None if item is undefined."""
        return self._state["data"].get(item, None)

    def __setitem__(self, item, value):
        """Set state value."""
        self._state["data"][item] = value

    def __setattr__(self, item, value):
        """Set state value."""
        self._state["data"][item] = value
    
    def clear(self):
        """Clear session state and request a rerun."""
        self._state["data"].clear()
        self._state["session"].request_rerun()
    
    def sync(self):
        """Rerun the app with all state values up to date from the beginning to fix rollbacks."""

        # Ensure to rerun only once to avoid infinite loops
        # caused by a constantly changing state value at each run.
        #
        # Example: state.value += 1
        if self._state["is_rerun"]:
            self._state["is_rerun"] = False
        
        elif self._state["hash"] is not None:
            if self._state["hash"] != self._state["hasher"].to_bytes(self._state["data"], None):
                self._state["is_rerun"] = True
                self._state["session"].request_rerun()

        self._state["hash"] = self._state["hasher"].to_bytes(self._state["data"], None)


def _get_session():
    session_id = get_report_ctx().session_id
    session_info = Server.get_current()._get_session_info(session_id)

    if session_info is None:
        raise RuntimeError("Couldn't get your Streamlit Session object.")
    
    return session_info.session


def _get_state(hash_funcs=None):
    session = _get_session()

    if not hasattr(session, "_custom_session_state"):
        session._custom_session_state = _SessionState(session, hash_funcs)

    return session._custom_session_state


3. 3. Specific example

If you put the above in the code,

def main():
    state = _get_state()
    pages = {
        "Input data":in_page,
        "Data processing":tran_page,
        "Data visualization":out_page
    }

    #st.sidebar.title(":floppy_disk: Page states")
    page = st.sidebar.radio("Page selection", tuple(pages.keys()))

    # Display the selected page with the session state
    pages[page](state)

    # Mandatory to avoid rollbacks with widgets, must be called at the end of your app
    state.sync()

Make a main page with You can connect the page you want to deliver and the page you want to accept with state. ~~. Of course, I was able to pass the dataframe as well.

def in_page(state):
    ~~~
    
    #State the variable you want to pass.~~Put it in
    state.dataframe1 = dataframe1
    state.var1 = var1

def tran_page(state):
    #Variables you want to accept~~=state.~~Accept at.
    dataframe1 = state.dataframe1
    var1 = state.var1
    ~~~

def out_page(state):
    ~~~

#Finally main()And execute.
main()

4. Reference

  • https://discuss.streamlit.io/t/multi-page-app-with-session-state/3074/24
  • https://huggingface.co/nlp/viewer/?dataset=aeslc

Recommended Posts

Carry over data to another page (tab) with streamlit
Visualize data with Streamlit
Get another tab with pyppeteer
How to deal with imbalanced data
How to Data Augmentation with PyTorch
Convert Excel data to JSON with python
Send data to DRF API with Vue.js
Convert FX 1-minute data to 5-minute data with Python
Try converting to tidy data with pandas
copy consumer offset to another with kafka-python
How to read problem data with paiza
How to create sample CSV data with hypothesis
Try to aggregate doujin music data with pandas
Convert data with shape (number of data, 1) to (number of data,) with numpy.
I tried to save the data with discord
Save data to flash with STM32 Nucleo Board
I tried to get CloudWatch data with Python
How to scrape horse racing data with BeautifulSoup
Write CSV data to AWS-S3 with AWS-Lambda + Python
I want to start over with Django's Migrate
Extract data from a web page with Python
Quickly create a Python data analysis dashboard with Streamlit and deploy it to AWS