kmcgrady / streamlit-autorefresh

An autorefresh component for Streamlit apps
MIT License
176 stars 16 forks source link

Autorefreshing does not occur while tab is inactive #9

Open Sghost35T opened 1 year ago

Sghost35T commented 1 year ago

Hi @kmcgrady , i created a multipage app that displays a dataframe which gets updated in regular intervals using streamlit autorefresh component and by using st.cache to not get updated whenever there is a user_interaction , but when page is not opened the st_autorefresh is not getting triggered , so when page1 is opened it is getting refreshed but page 2 is not getting refreshed in the interval and when i open page2 since the cache got cleared it is getting refreshed.

i tried to reproduce this issue by creating a similar problem

Code snippet: “main.py” - main_page import streamlit as st import time import pandas as pd from datetime import datetime from streamlit_autorefresh import st_autorefresh

time_threshold=2

if “count1” not in st.session_state: st.session_state.count1=0 if “time” not in st.session_state: st.session_state.time = (time_threshold*60)

@st.cache_data(ttl=st.session_state.time) def hi(y): now = datetime.now() time_formatted = now.strftime(“%d/%m/%y %H:%M:%S”) st.text(time_formatted)

st.session_state.count1+=1

hi(2) st.text(st.session_state.count1)

st_autorefresh(interval=st.session_state.time*1000, key=“main_Refresh”,debounce=False)

“page2”: import streamlit as st import pandas as pd import time from datetime import datetime from streamlit_autorefresh import st_autorefresh

time_threshold1=2

if “count” not in st.session_state: st.session_state.count=0 if “time1” not in st.session_state: st.session_state.time1 = (time_threshold1*60)

@st.cache_data(ttl=st.session_state.time1) def hello(y): time2 = datetime.now() time_formatted = time2.strftime(“%d/%m/%y %H:%M:%S”) st.text(time_formatted)

st.session_state.count+=1 st.text(st.session_state.count)

hello(2)

st_autorefresh(interval=st.session_state.time1*1000, key=“main_Refresh”,debounce=False)

Appreciate any replies Thank you

Sghost35T commented 1 year ago

any update on this @kmcgrady

kmcgrady commented 1 year ago

Hey @Sghost35T I'm struggling to understand the details, but I am interpreting it as. You want to have data refresh on each page regardless of which page is open. In this case, I believe the caching needs to separate from the display.

So in one file, you would have the functions. You would want to save these directly into session state.

util.py

import streamlit as st

def get_formatted_time(name):
    st.session_state[name] = datetime.now().strftime(“%d/%m/%y %H:%M:%S”)

Then, in each page, you would want to import it in and cache it.

page_1.py

import streamlit as st
from util import get_formatted_time

@st.cache_data(ttl=...)
def hi():
    get_formatted_time("time1")

@st.cache_data(ttl=...)
def hello():
    get_formatted_time("time2")

hi()
hello()

st.text(st.session_state.time1)

st_autorefresh(interval=SOME_NUMBER, key=“main_Refresh”,debounce=False)

page_2.py

import streamlit as st
from util import get_formatted_time

@st.cache_data(ttl=...)
def hi():
    get_formatted_time("time1")

@st.cache_data(ttl=...)
def hello():
    get_formatted_time("time2")

hi()
hello()

st.text(st.session_state.time2)

st_autorefresh(interval=SOME_NUMBER, key=“main_Refresh”,debounce=False)

You can probably extract it out further (all the cache datas/hi and hello calls), but I wanted to make it clear. But we are essentially splitting the display logic from the data logic here intentionally, so that the data can update regardless of pages, but it will only display the data you want on the current page. This relies far more heavily on session state, but it seems to be the best path to deliver what I think you are looking for.

I am closing this because this does not seem inherently and issue with the autorefresh component.

Sghost35T commented 1 year ago

Hi @kmcgrady i tried the above approach but the data is not getting refreshed when the page is not opened. i think the page is only getting refreshed if the user is present in that page can u please suggest any other method please

kmcgrady commented 1 year ago

Ah. It seems like you are wanting the refresh to work when the tab is inactive. This is likely due to this the fact that the underlying interval is not working (See this StackOverflow response).

They highlight a couple solutions, but I am afraid theres's a strong complication in the implementation combined with a philosophical question of whether we want the Streamlit app to be refreshing under the hood (or if that will even work).

I can re-open this and rephrase it, but it seems not worthy to implement the solution here. Your only alternative is to do this in the server.

import time
import streamlit as st

while True:
  time.sleep(5) #5 seconds
  st.write("Here's a refresh")

That will ensure things go as expected on the server.

Sghost35T commented 1 year ago

Thanks @kmcgrady for the clarification i would also request you to find a solution for this because it is a great feature that can be useful for many applications

Thank you