Streamlit session state attribute is not detected on Azure deployment

Hello team,

I have developed an app that utilizes the session state functionality available for a couple of state handling requirements of different widgets in the application.

The app in-general works fine when being used locally i.e session state attributes are getting created and used for its necessary purpose.

However, the same throws this error when the app repository is being deployed on cloud using Azure DevOps:-

AttributeError: st.session_state has no attribute β€œnum”. Did you forget to initialize it? More info: Add statefulness to apps - Streamlit Docs
The command β€˜/bin/sh -c python ui_load_vinoth.py’ returned a non-zero code: 1

The code in concern looks like this :-

    def main(self):
        page_title = self.ui_config_file["page_title"]
        page_icon = ":mag:"
        layout = self.ui_config_file["page_layout"]
        st.set_page_config(page_title=page_title, page_icon=page_icon, layout=layout, initial_sidebar_state="auto")
        st.sidebar.empty()
        st.title(self.ui_config_file["title"])

        # --- HIDE STREAMLIT STYLE ---
        hide_st_style = """
                            <style>
                            MainMenu {visibility: hidden;}
                            footer {visibility: hidden;}
                            header {visibility: hidden;}
                            </style>
                            """
        st.markdown(hide_st_style, unsafe_allow_html=True)
        # --- NAVIGATION MENU ---
        selected = option_menu(menu_title=None,options=["New Project", "Existing Projects", "Start Inspection"],
                                icons=["file-plus", "gear", "play"],orientation="horizontal",default_index=0,)
        # placeholder for Forms
        # self.placeholder = st.empty()
        if selected == "New Project":
            self.new_project()
        elif selected == "Existing Projects":
            self.existing_projects()
        elif selected == "Start Inspection":
            self.start_inspection()

    def new_project(self):
        # widgets for new project
        placeholder = st.empty()
        proj_obj = CProjectData()
        if 'num' not in st.session_state:
            st.session_state.num = 0
        if "counter_non_print" not in st.session_state:
            st.session_state["counter_non_print"] = 0
        if "counter_print" not in st.session_state:
            st.session_state["counter_print"] = 0
        if "number_non_print_defects" not in st.session_state:
            st.session_state["number_non_print_defects"] = 0
        # if "number_print_defects" not in st.session_state:
        #     st.session_state["number_print_defects"] = 0
        if st.session_state.num == 0:
            with placeholder.form(key="Form_1", clear_on_submit=True):
                st.markdown("<p style='text-align: center; color: grey;'>Page 1/2</p>", unsafe_allow_html=True)
                st.text_input(self.ui_config_file["form_1"]["row_1"], "default", key='project_name')
                st.subheader(self.ui_config_file["form_1"]["sub_heading_printing_non-printing"])
                st.number_input(self.ui_config_file["form_1"]["row_2"],
                                    min_value=0, step=1, format="%i", key="number_sides")
                st.number_input(self.ui_config_file["form_1"]["row_3"],
                                min_value=0, step=1, format="%i", key="number_non_print_defects")
                st.radio(self.ui_config_file["form_1"]["row_4"], ("No", "Yes"), key="printing_defect_bool")
                st.subheader(self.ui_config_file["form_1"]["sub_heading_missing_component"])
                st.radio(self.ui_config_file["form_1"]["row_5"], ("No", "Yes"),key="template_matching_bool")

                if st.form_submit_button("Next"):
                    st.session_state.num += 1
                    condition1 = (st.session_state.num > st.session_state['number_non_print_defects'])
                    condition2 = (st.session_state['template_matching_bool'] == "No")
                    condition3 = (st.session_state['printing_defect_bool'] == "No")

                    side_condition1 = (st.session_state['number_non_print_defects'] >= st.session_state.num)
                    side_condition2 = (st.session_state['number_sides'] <= 0)
                    side_condition3 = (st.session_state['printing_defect_bool'] == "Yes")
                    if (condition1 and condition2 and condition3):
                        st.session_state.num = 0
                        st.session_state["counter_non_print"] = 0
                        placeholder.empty()
                        with placeholder:
                            st.warning("Enter at-least one Non-printing defect or select printing defect or enable missing component in assembly. Please Refresh")
                    elif (side_condition1 and side_condition2):
                        st.session_state.num = 0
                        st.session_state["counter_non_print"] = 0
                        placeholder.empty()
                        with placeholder:
                            st.warning("Enter at-least one side for Non-printing defects. Please Refresh")
                    elif (side_condition2 and side_condition3):
                        st.session_state.num = 0
                        st.session_state["counter_non_print"] = 0
                        placeholder.empty()
                        with placeholder:
                            st.warning("Enter at-least one side for printing defects. Please Refresh")
                else:
                    st.stop()

        if st.session_state.num >= 1:
            with placeholder.form(key="Form_2", clear_on_submit=True):
                st.markdown("<p style='text-align: center; color: grey;'>Page 2/2</p>", unsafe_allow_html=True)
                # widgets for view
                # if (int(st.session_state['number_sides'])>0) and ((st.session_state['number_non_print_defects']+
                #                                                 st.session_state['number_print_defects'])>0):
                for sides_index in range(int(st.session_state['number_sides'])):
                    st.subheader(f"Details of Side_{sides_index + 1}")
                    st.text_input("Enter View name", value="default", key=f"View_name_{sides_index + 1}")
                    st.number_input("Enter number of ROI for this view", min_value=0, max_value=10, value=0, step=1,
                                        format="%i", key=f"View_ROI_{sides_index + 1}")
                    st.radio("Do you want to check printing defect in this view?", ("No", "Yes"),
                             key=f"View_OCR_{sides_index+1}")

                # widgets for non-printing defect
                while st.session_state["counter_non_print"] < st.session_state['number_non_print_defects']:
                    st.session_state["counter_non_print"] += 1

                    st.subheader(self.ui_config_file["form_2"]["non_print"]["sub_heading"] +
                                     f" {st.session_state['counter_non_print']}")

                    st.text_input(self.ui_config_file["form_2"]["non_print"]["row_1"], "default",
                                      key=f"Defect_name_{st.session_state['counter_non_print']}")

                    st.number_input(self.ui_config_file["form_2"]["non_print"]["row_2"],min_value=1, step=1, format="%i",
                                        key=f"Min_size_{st.session_state['counter_non_print']}")

                    st.radio(self.ui_config_file["form_2"]["non_print"]["row_3"],("Yes","No"),
                                        key=f"Defect_freq_{st.session_state['counter_non_print']}")

                    defect_sides_list = [i for i in range(1, st.session_state['number_sides'] + 1)]
                    st.multiselect(self.ui_config_file["form_2"]["non_print"]["row_4"], defect_sides_list,
                                       key=f"Defect_sides_{st.session_state['counter_non_print']}")

                    st.radio(self.ui_config_file["form_2"]["non_print"]["row_5"],('None', 'segment', 'highlight'),
                                 key=f"Defect_seg_loc_{st.session_state['counter_non_print']}")

                # widget for template matching
                if st.session_state["template_matching_bool"] == "Yes":
                    st.subheader(self.ui_config_file["form_2"]["template_matching"]["sub_heading"])
                    st.number_input(self.ui_config_file["form_2"]["template_matching"]["row_1"],
                                min_value=1, step=1, format="%i", key="number_assembly_sides")
                    st.number_input(self.ui_config_file["form_2"]["template_matching"]["row_2"],
                                    min_value=0, step=1, format="%i", key="number_roi_assembly_sides")
                    st.write("")
                    st.write("")
                    st.write("")
                st.info("Please refresh to start again")

                # save the widgets
                if st.form_submit_button("Save"):
                    # save the project configuration
                    proj_obj.save_data_to_json()
                    proj_obj.write_data_to_json()
                    st.session_state.num += 1
                    if st.session_state.num > (st.session_state['number_non_print_defects']):
                        st.session_state.num = 0
                        st.session_state["counter_non_print"] = 0
                        st.session_state["counter_print"] = 0
                    placeholder.empty()
                    with placeholder:
                        st.success("Data Saved! Please refresh")
                else:
                    st.stop()

The issue occurs at the function new_projects() in the line :-

if st.session_state.num==0

The same session state variable is initialized a few lines before it in:-

if 'num' not in st.session_state:
            st.session_state.num = 0

The session state attribute gets created and updated when I am trying to run the application locally but the same line throws an error when I try to build the application repository using Azure DevOps.

Can someone in the team please help me out with this ?

Is there a reason why you are not using the streamlit run command?

2 Likes

Thanks for your reply. I have actually resolved the issue. I had defined the streamlit run command in the dockerfile I was using for deployment. But the issue was that I was running a redundant RUN command on my main application file before executing the streamlit run command in my Dockerfile and because of which I was not able to use session states in my application.

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