Complete function execution even without cache decorator

I’m trying to implement an image uploader as below in a standalone page. But on every radio selection irrespective if the image is available or not, the page/function is run fully.

def load_page():
    image = get_image()
    if image:
        st.image(image.astype(np.uint8),caption=['Resized Image'], width=150)
    st.write('Done')

def get_image():
    '''
     Displays radio options to upload images either from url or local machine
     
     Returns:
         Image numpy array
    '''
    options = ['url', 'local machine']
    upload = st.radio("Upload image from", options, index=0)
    if upload == options[0]:
        url = st.text_input('Enter url')
        if url:
            image = utils.url_to_image(url)
            return image
    elif upload == options[1]:
        file_buffer = st.file_uploader("Upload image", type=["png", "jpg", "jpeg"])
        if file_buffer:
            # to PIL image obj and to np array for easy processing
            image = np.array(PIL.Image.open(file_buffer))
            return image

My question is how do I wait till I get an image and then execute st.write(‘Done’).

Screencast :

You can see that Image being present even before image is read.!

streamlit_app_demo

May be to cache the function(?), but I’ve not used cache decorator.

Would appreciate any pointers or insights

Thanks.!

Hi @hemanth346 and welcome to the forums :slight_smile:

As you understood, the file is being rerun in its entirety every time you interact with it (change in the file or interacting with widgets).

In the load_page() function, the if image: part only runs when get_image() returns something to display, so you can put st.write('Done') inside that block to show it only when the image is being loaded for display, like in the following :

def load_page(): 
    image = get_image() 
    if image: 
        st.image(image.astype(np.uint8),caption=['Resized Image'], width=150) 
        st.write('Done') # <-- moved the "Done" write inside the image done loading block

You can also put that st.write('Done') before the return image inside get_image(). If you are not sure of the order in which you write on the webapp page, you can use st.empty to put a placeholder where you can write the Done message at the end of load_message(), you can see that in the get started page.

Thank you @andfanilo

I don’t want to use st.write('Done') that is an example I’ve taken. I want to run few functions on top of the image I’ve got. The only way is to use it inside the condition.?

How can I call a function from st.empty() place holder?

Thanks for your time :slight_smile:

Hi @hemanth346,
I believe you can just replace st.write('Done') with some processing functions. For example, to created a derived image and show it on the screen.

def load_page(): 
    image = get_image() 
    if image: 
        st.image(image.astype(np.uint8),caption=['Resized Image'], width=150) 
        derived_image = process(image)
        st.image(derived_image.astype(np.uint8),caption=['Resized Image'], width=150)

Feel free to add some more details, so I can help you more.

Matteo