This is a transcription labelling app and I want to seamlessly navigate to the next file by adding a button and navigating to a previous file would be a HUGE plus.
Once I press the button, the updated transcript will be saved to a file - that code I haven’t added yet. I tried adding the add_selectbox in a infinite while loop - it doesn’t move forward to the next file. Without the - the code moves to the next file erratically.
I want to also SAVE my state and whenever I run the app next - It starts from my previously left file.
def RenderFile(element, TranscriptPath,WavsPath):
TranscriptFile = os.path.join(TranscriptPath,element.split("\\")[-1].replace(".wav",".txt"))
with open(TranscriptFile,'r', encoding='utf-8') as f:
data = f.read()
key = element.split("\\")[-1]
st.subheader("Name of File = " + key)
st.audio(open(element, 'rb').read(), format='audio/wav')
content = st_ace(
value = data,
theme=st.sidebar.selectbox("Theme.", options=THEMES, key=key),
font_size=st.sidebar.slider("Font size.", 5, 24, 24, key=key),
tab_size=st.sidebar.slider("Tab size.", 1, 8, 4, key=key),
show_gutter=st.sidebar.checkbox("Show gutter.", value=True, key=key),
show_print_margin=st.sidebar.checkbox("Show print margin.", value=True,key=key),
wrap=st.sidebar.checkbox("Wrap enabled.", value=True,key=key),
key=key
)
add_selectbox = st.sidebar.selectbox(
"Are you done with the file?",
("No", "Yes"), key=key)
st.title(content)
while(add_selectbox!= "Yes"):
i = 0
i = i+1
if add_selectbox == "Yes":
break
if add_selectbox == "Yes":
st.warning("Loading next file")
return
def main():
st.sidebar.title("Labeling Data")
st.title("Transcription Labeling App")
TranscriptPath = # PATH TO THE TRANSCRIPTS
WavsPath = # PATH TO THE WAVS + *
WavsList = glob.glob(WavsPath)[0:5]
session_state = SessionState.get(CurrentIndex=0, AudioList = WavsList)
if session_state.CurrentIndex == len(session_state.AudioList):
st.warning("DONE!")
st.stop()
RenderFile(session_state.AudioList[session_state.CurrentIndex], TranscriptPath, WavsPath)
`indent preformatted text by 4 spaces`
session_state.CurrentIndex = session_state.CurrentIndex + 1
Reworked your code a bit, this should work at least if you don’t exit your tab. This is Streamlit >= 0.65.
SessionState.py
# https://gist.github.com/FranzDiebold/898396a6be785d9b5ca6f3706ef9b0bc
"""Hack to add per-session state to Streamlit.
Works for Streamlit >= v0.65
Usage
-----
>>> import SessionState
>>>
>>> session_state = SessionState.get(user_name='', favorite_color='black')
>>> session_state.user_name
''
>>> session_state.user_name = 'Mary'
>>> session_state.favorite_color
'black'
Since you set user_name above, next time your script runs this will be the
result:
>>> session_state = get(user_name='', favorite_color='black')
>>> session_state.user_name
'Mary'
"""
import streamlit.report_thread as ReportThread
from streamlit.server.server import Server
class SessionState():
"""SessionState: Add per-session state to Streamlit."""
def __init__(self, **kwargs):
"""A new SessionState object.
Parameters
----------
**kwargs : any
Default values for the session state.
Example
-------
>>> session_state = SessionState(user_name='', favorite_color='black')
>>> session_state.user_name = 'Mary'
''
>>> session_state.favorite_color
'black'
"""
for key, val in kwargs.items():
setattr(self, key, val)
def get(**kwargs):
"""Gets a SessionState object for the current session.
Creates a new object if necessary.
Parameters
----------
**kwargs : any
Default values you want to add to the session state, if we're creating a
new one.
Example
-------
>>> session_state = get(user_name='', favorite_color='black')
>>> session_state.user_name
''
>>> session_state.user_name = 'Mary'
>>> session_state.favorite_color
'black'
Since you set user_name above, next time your script runs this will be the
result:
>>> session_state = get(user_name='', favorite_color='black')
>>> session_state.user_name
'Mary'
"""
# Hack to get the session object from Streamlit.
session_id = ReportThread.get_report_ctx().session_id
session_info = Server.get_current()._get_session_info(session_id)
if session_info is None:
raise RuntimeError('Could not get Streamlit session object.')
this_session = session_info.session
# Got the session object! Now let's attach some state into it.
if not hasattr(this_session, '_custom_session_state'):
this_session._custom_session_state = SessionState(**kwargs)
return this_session._custom_session_state
def sync():
session_id = ReportThread.get_report_ctx().session_id
session_info = Server.get_current()._get_session_info(session_id)
if session_info is None:
raise RuntimeError('Could not get Streamlit session object.')
this_session = session_info.session
this_session.request_rerun()
__all__ = ['get', 'sync']
app.py
import glob
import SessionState
import streamlit as st
def render_file(wav_path, transcript_path):
st.markdown(f"Currently rendering audio {wav_path}")
if st.sidebar.button("Go to next file"):
# write streamlit ace transcript to disk
SessionState.get().current_index += 1
SessionState.sync()
def main():
st.title("Transcription Labeling App")
st.sidebar.title("Labeling Data")
transcript_path = "data/transcripts"
wavs_path = "data/wav/*"
wavs_list = glob.glob(wavs_path)[0:5] # glob is ordered
session_state = SessionState.get(current_index=0)
if session_state.current_index == len(wavs_list):
st.warning("DONE!")
st.stop()
render_file(wavs_list[session_state.current_index], transcript_path)
if __name__ == "__main__":
main()
If you want to save your state for if you exit your tab and come back, the dirty fast option is you’ll need to store the current_index somewhere (like on disk) and when rerunning the app initialize current_index with value in file or disk, else 0.
Hmmm so everytime you use st.image or st.audio, the image/audio file is put in a MediaFileManager and then Streamlit asks for a reference to the image/audio through it. Whenever you session reruns (basically when you press next), the MediaFileManager considers the file is not needed anymore and kills its reference, hence the missing file.
So, thinking out loud, that may be because of my SessionState.sync() which asks for a rerun after an immediate rerun, maybe on first rerun Streamlit builds a reference to your new audio file, then I call rerun through the sync and maybe Streamlit kills the reference to the next audio, and then you get a missing file… does the bug happen if you remove the SessionState.sync() part ?
Could you write your code with the audio part here?
I will check but the issue persisted before in my previous code as well.
One dirty solution would be adding a reload button and re-rendering st.audio - is it possible I can render in place of the existing component or sth?
@Moughees_Ahmed and @andfanilo I’ve been working on the MediaFileManager missing file issues. I think I have a solution, but because this has been a tricky piece of code, I’m looking for some testers. Would you be willing to try it out with your use cases? I would greatly appreciate it.
You can download the update from my dropbox.
First you uninstall streamlit
$ pip uninstall streamlit
Then you install the package using the wheel package.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.