Streamlit: Using cache not for performance but for repeatability

I came up with using random module for random selection from initial item of multi selectbox.

But my first implementation like below did not work well.

import random
import streamlit as st


def genRandIntWithoutCache():
    return random.randint(0, 3)

if __name__ == '__main__':
    
    color_list = ['yellow', 'red', 'blue', 'green']

    # Does not work well
    rand_index_01 = genRandIntWithoutCache()
    st.write(rand_index_01)
    options = st.multiselect(
        'What are your favorite colors?',
        color_list,
        color_list[rand_index_01],
        key="01"
    )
    st.write(options)

If you reloaded this page. you might see strange scene. You selected any items but every your action does not keep its state. This was caused by the feature of streamlit like being re-excecuted all of your code.

And then. our next step is to use "Cache" with decorator of it. The code below works well because of its caching. This makes its generating random number work only one time.

import random
import streamlit as st
from streamlit import caching


@st.cache
def genRandInt():
    return random.randint(0, 3)

def genRandIntWithoutCache():
    return random.randint(0, 3)

if __name__ == '__main__':
    
    color_list = ['yellow', 'red', 'blue', 'green']

    # Does not work well
    rand_index_01 = genRandIntWithoutCache()
    st.write(rand_index_01)
    options = st.multiselect(
        'What are your favorite colors?',
        color_list,
        color_list[rand_index_01],
        key="01"
    )
    st.write(options)

    # Works well
    rand_index_02 = genRandInt()
    st.write(rand_index_02)
    options = st.multiselect(
        'What are your favorite colors?',
        color_list,
        color_list[rand_index_02],
        key="02"
    )
    st.write(options)

Yes!! It works well. But is it really good?? In this time. user is only me. But in production. user will be many. If that random generator works only one time,this cause only one number generating. So next step,we add one step which make us possible to control the timing of doing cache and we do not need to use caching when generating random number.

import random
import streamlit as st
from streamlit import caching


@st.cache
def genRandInt():
    return random.randint(0, 3)

def genRandIntWithoutCache():
    return random.randint(0, 3)

if __name__ == '__main__':
    
    color_list = ['yellow', 'red', 'blue', 'green']

    # Does not work well
    rand_index_01 = genRandIntWithoutCache()
    st.write(rand_index_01)
    options = st.multiselect(
        'What are your favorite colors?',
        color_list,
        color_list[rand_index_01],
        key="01"
    )
    st.write(options)

    # Works well
    form = st.form(key="form")
    rand_index_02 = genRandIntWithoutCache()
    st.write(rand_index_02)
    options = form.multiselect(
        'What are your favorite colors?',
        color_list,
        color_list[rand_index_02],
        key="02"
    )
    st.write(options)

    # To control cache
    submitted = form.form_submit_button("Submit")
    if submitted:
        caching.clear_cache()