- Are you running your app locally or is it deployed? - locally running
- If your app is deployed: no
a. Is it deployed on Community Cloud or another hosting platform?
b. Share the link to the public deployed app. - Share the link to your app’s public GitHub repository (including a requirements file).
- Share the full text of the error message (not a screenshot).
- Share the Streamlit and Python versions.
streamlit 1.30.0
streamlit-pagination 0.0.3
python 3.9.6
Hi, I am really new in streamlit. Currently I am trying to apply pagination to st.columns list. but in my current code the list of n-page is being updated when the page button is clicked twice. If I call recursive function it just adds columns below the first collections of columns. is there any way to refresh the list of columns only? not restarting the hole process due to background processes to be done.
Please anyone give me some insight and help to cope this issue.
import streamlit as st
import pandas as pd
import os
import hashlib
from concurrent.futures import ThreadPoolExecutor
import time
import json
import math
import requests
from streamlit_pagination import pagination_component
st.markdown('<style>' + """iframe{
height:100px;
width:500px;
}""" + '</style>', unsafe_allow_html=True)
slack_webhook_url = ""
headers = {
"Content-type": "application/json"
}
table_header = ["title", "upload status", "analysis_status", "re-analysis", "download"]
PAGE_SIZE = 3
os.makedirs('uploaded_files', exist_ok=True)
os.makedirs('results', exist_ok=True)
executor = ThreadPoolExecutor(max_workers=5)
@st.cache_resource
def load_shared_state():
if os.path.exists('shared_state.json'):
with open('shared_state.json', 'r') as f:
return json.load(f)
else:
return {}
shared_state = load_shared_state()
if 'uploaded_files' not in st.session_state:
st.session_state['uploaded_files'] = shared_state.get('uploaded_files', {})
if 'upload_status' not in st.session_state:
st.session_state['upload_status'] = shared_state.get('upload_status', {})
if 'analysis_status' not in st.session_state:
st.session_state['analysis_status'] = shared_state.get('analysis_status', {})
if 'analysis_futures' not in st.session_state:
st.session_state['analysis_futures'] = shared_state.get('analysis_futures', {})
if 'analysis_results' not in st.session_state:
st.session_state['analysis_results'] = shared_state.get('analysis_results', {})
def update_shared_state(updated_state):
filtered_state = {key: updated_state[key] for key in ["uploaded_files", "analysis_status", "analysis_futures", "analysis_results"] if key in updated_state}
with open('shared_state.json', 'w') as f:
json.dump(filtered_state, f)
def get_file_hash(uploaded_file):
content = uploaded_file.getvalue()
return hashlib.md5(content).hexdigest()
def perform_analysis(file_path):
result_path = f"results/{os.path.basename(file_path).split('.')[0]}_result.csv"
pd.DataFrame().to_csv(result_path)
return result_path
def handle_file(uploaded_file):
global shared_state
file_hash = get_file_hash(uploaded_file)
file_path = f"uploaded_files/{file_hash}.mp4"
with open(file_path, "wb") as f:
f.write(uploaded_file.getbuffer())
st.session_state['uploaded_files'][uploaded_file.name] = file_path
st.session_state['upload_status'][uploaded_file.name] = 'Uploaded'
future = executor.submit(perform_analysis, file_path)
st.session_state['analysis_status'][uploaded_file.name] = 'Analyzing'
st.session_state['analysis_futures'][uploaded_file.name] = future
shared_state.update(st.session_state)
future.add_done_callback(lambda x: analysis_done_callback(uploaded_file.name, x.result()))
def download_results(filename):
with open(st.session_state['analysis_results'][filename], "rb") as f:
st.download_button(label='Download Results', data=f, file_name=f'{filename}_results.csv')
def reanalyze_file(filename):
st.session_state.page = 'Collections'
file_path = st.session_state['uploaded_files'][filename]
future = executor.submit(perform_analysis, file_path)
st.session_state['analysis_status'][filename] = 'Analyzing'
st.session_state['analysis_futures'][filename] = future
future.add_done_callback(lambda x: analysis_done_callback(filename.name, x.result()))
def analysis_done_callback(filename, result_path):
shared_state['analysis_status'][filename] = 'Analysis Complete'
shared_state['analysis_results'][filename] = result_path
if st.session_state:
st.session_state.update(shared_state)
else:
for k, v in shared_state.items():
st.session_state[k] = v
data = {
"text": f"{filename}."
}
# res = requests.post(slack_webhook_url, headers=headers, data=json.dumps(data))
update_shared_state(st.session_state)
print(data["text"])
if 'page' not in st.session_state:
st.session_state.page = 'Upload page'
if st.sidebar.button('Upload page'):
st.session_state.page = 'Upload page'
if st.sidebar.button('Collections'):
st.session_state.page = 'Collections'
if 'current_page' not in st.session_state:
st.session_state['current_page'] = 1
def display_page_buttons(total_pages, current_page):
num_buttons = min(5, total_pages)
button_cols = st.columns([1 for _ in range(num_buttons + 2)])
# 'Previous' 버튼
if current_page > 1 and button_cols[0].button("Previous", key="prev"):
st.session_state['current_page'] = current_page - 1
start_page = max(1, current_page - (num_buttons // 2))
end_page = min(total_pages, start_page + num_buttons - 1)
start_page = max(1, end_page - num_buttons + 1) # Adjust start_page if end_page is at the limit
for i, page_num in enumerate(range(start_page, end_page + 1), start=1):
if button_cols[i].button(str(page_num), key=f"page-{page_num}"):
st.session_state['current_page'] = page_num
if current_page < total_pages and button_cols[-1].button("Next", key="next"):
st.session_state['current_page'] = current_page + 1
st.write(f"Page {st.session_state['current_page']} of {total_pages}")
def main():
if st.session_state.page == 'Upload page':
st.title("Upload your video")
uploaded_file = st.file_uploader("Choose a file", type=["mp4"])
if uploaded_file is not None:
handle_file(uploaded_file)
elif st.session_state.page == 'Collections':
st.title("list of analysis")
sorted_files = sorted(st.session_state['uploaded_files'].items(), key=lambda item: os.path.getmtime(item[1]), reverse=True)
total_files = len(sorted_files)
current_page = st.session_state['current_page']
start_index = (current_page - 1) * PAGE_SIZE
end_index = start_index + PAGE_SIZE
global shared_state
cols = st.columns([2, 1, 1, 1, 1])
for col, field in zip(cols, table_header):
col.write("**" + field + "**")
total_pages = (len(sorted_files) - 1) // PAGE_SIZE + 1
current_page = st.session_state['current_page']
for filename, file_path in sorted_files[start_index:end_index]:
if filename in st.session_state['analysis_futures']:
future = st.session_state['analysis_futures'][filename]
if future.done():
st.session_state['analysis_status'][filename] = 'Analysis Complete'
st.session_state['analysis_results'][filename] = future.result()
shared_state = st.session_state
cols = st.columns([2, 1, 1, 1, 1])
cols[0].write(filename)
cols[1].write(st.session_state['upload_status'][filename])
cols[2].write(st.session_state['analysis_status'][filename])
with cols[3]:
reanalyze_button = st.button(label='Reanalyze', key=f'reanalyze-{filename}')
if reanalyze_button:
reanalyze_file(filename)
cols[4].empty()
with cols[4]:
if st.session_state['analysis_status'][filename] == 'Analysis Complete':
download_results(filename)
display_page_buttons(total_pages, current_page)
# layout = {'color': "primary", 'style': {'margin-top': '10px', 'display': 'flex','justify-content': 'center'}}
# selected_page = pagination_component(math.ceil(total_files / PAGE_SIZE) + 1, layout=layout) + 1
# st.session_state['current_page'] = selected_page
if __name__ == "__main__":
main()