While True loop in Streamlit for text_input

I’m developing a streamlit front end for my script that lets me use a UPC scanner to add things to my cart using the Kroger API. This is the original but translate the input and print to text_input and toast. The whole True loop works when running the script from terminal no problem. When I use it in streamlit it throws key errors. When I take the while loop out, it runs through the entire script again. I’m having trouble understanding session states. Can anyone help?


while True:
    # Waits for user input from the UPC scanner
    print("Waiting for UPC")
    upc = input()
    items = {
        "upc": upc,
        "quantity": 1          
    }
    while True:
        status = add_items_to_cart(token, items)
        # Submits the PUT request to add the UPC to the cart
        if status == 401:
            """
            If the access token is expired for 30 minutes, it will throw a 401 error.
            This will use the refresh_auth_token function to request a new access token.
            Once it obtains a new token, it will attempt to add the item to the cart

            Backlog Item - Need to throw the authorization function in this loop so the user
            will not even notice it's renewing.
            """
            token, refresh_token = refresh_auth_token(refresh_token, encoded_client_token)
            # This prints the time the token was renewed just for developer awareness, not needed
            print(f"Refresh token renewed at {current_time}")
            # Adds the item to the cart
            status = add_items_to_cart(token, items)
            # Returns the product JSON
            product = get_product(upc, token)
            # Obtains the description, size, and image URL of the product
            description, size, imgurl = get_product_info(product)
            # Standard message for adding something to the cart
            message = f"{description} - {size} has been added to your cart"
            print(message)
           
            break
           
        elif status == 400:
            # User probably left it blank or UPC was not found
            print("Shit's fucked, maybe you left it blank")
           
            break
           
        elif status == 204:
            # Success
            product = get_product(upc, token)
            description, size, imgurl = get_product_info(product)
            message = f"{description} - {size} has been added to your cart"
            print(f'{message}')
            break

For most cases, you won’t want to use while True to handle user input in a Streamlit app. Wherever you need user input, you can use an input widget, but Streamlit doesn’t “wait” at widgets like terminal input.

Instead, the widget returns the default value when it’s called on the first script run and your following code should just check the value of the widget. If it’s the default value, it can stop there. When the user does enter something, the whole script reruns to to bottom but this time the widget returns their provided value. So the code that follows the widget can see it’s not the default value this time and proceed.

For example, your code snippet could start with:

import streamlit as st

UPC = st.number_input("UPC", value=None)

if UPC is not None:
    do_something()

The point is that Streamlit blows straight through any widget, returning the default value the first time. It gets to the end of the script and stops. Your code that follows checks that value to know if it proceeds or stops. User interaction drives the running of the script over and over again rather than a while loop.

Now, because of the rerurn structure of Streamlit, be careful how you handle one-time or accumulative processes. That’s where Session State and callback functions become helpful.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.