Drawable canvas

Hello @andfanilo and all;
I am building a multipage app that does some stuff. In one page, the user selects image(s) and then I use canvas as an annotation tool for the image. I use canvas 0.9.0 for local work, and it works perfectly. But when I deploy the app to streamlit cloud (using latest canvas “0.9.2” to resolve the background image being opened on cloud), I face a very strange error. The error is variables (not related to canvas) stored in st.session_state do not exist!

Here is a code snippet:

df_columns = ['class_name','truncation','occlusion','alpha','bbox_tl_x','bbox_tl_y','bbox_br_x','bbox_br_y','height','width','length','loc_x','loc_y','loc_z','rot_y']
entry = {'img':'', 'labels': pd.DataFrame(columns=df_columns)}

#defining st.session_state variables
if 'df_anns' not in st.session_state.keys():
    st.session_state.df_anns = []
if 'df_ix' not in st.session_state.keys():
    st.session_state.df_ix = -1
if 'tmp_ds_file_set' not in st.session_state.keys():
    st.session_state.tmp_ds_file_set =set()
if 'tmp_cam_dev_img_id' not in st.session_state.keys():
    st.session_state.tmp_cam_dev_img_id =''

#Input method for user to either use camera or upload files
ip_method = st.radio('Input Method',('Camera','Files'))
if ip_method == 'Camera':
    img_stream = st.camera_input('Capture an image')
    if img_stream is not None:
        if img_stream.id != st.session_state.tmp_cam_dev_img_id:
            img_bytes = img_stream.getvalue()
            cv_img = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR)
            new_entry = entry.copy()
            new_entry['img']=cv_img
            st.session_state.df_anns.append(new_entry)
            st.session_state.df_ix += 1
            st.session_state.tmp_cam_dev_img_id = img_stream.id
elif ip_method == 'Files':
    img_streams = st.file_uploader('Select Image', type=['png','jpeg','jpg'], key='dset_fu', accept_multiple_files=True)
    new_file_names = [i.name for i in img_streams]
    new_file_set = set(new_file_names)
    diff_file_set = new_file_set.difference(st.session_state.tmp_ds_file_set)
    for img_stream in img_streams:
        if img_stream.name in diff_file_set:
            img_bytes = img_stream.getvalue()
            cv_img = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR)
            new_entry = entry.copy()
            new_entry['img']=cv_img
            st.session_state.df_anns.append(new_entry)
            st.session_state.df_ix += 1
            st.session_state.tmp_ds_file_set.add(img_stream.name)

#Adjust image dimensions to show in canvas
img_org_w = st.session_state.df_anns[st.session_state.df_ix]['img'].shape[1] if st.session_state.df_ix >= 0 else 0
img_org_h = st.session_state.df_anns[st.session_state.df_ix]['img'].shape[0] if st.session_state.df_ix >= 0 else 0
cvs_w = 700
cvs_h = int(img_org_h * (cvs_w/img_org_w)) if st.session_state.df_ix >= 0 else 400
scale_w = img_org_w / cvs_w if st.session_state.df_ix >= 0 else 1
scale_h = img_org_h / cvs_h if st.session_state.df_ix >= 0 else 1
scale_img = cv2.resize(st.session_state.df_anns[st.session_state.df_ix]['img'][:,:,::-1], (cvs_w,cvs_h)) if st.session_state.df_ix >= 0 else None

#convert image to buffer to allow using PIL.Image.open
if st.session_state.df_ix >= 0:
    x = Image.fromarray(scale_img)
    img_obj = BytesIO()
    x.save(img_obj,format='png')
    img_obj.seek(0)
else:
    img_obj=None

canvas_result = st_canvas(fill_color='rgba(0,165,255,0.3)', stroke_width=3, stroke_color='#000000', background_color='#eee',
                            background_image=Image.open(img_obj) if img_obj else None, update_streamlit=True, height=cvs_h, width=cvs_w,
                            drawing_mode='rect', point_display_radius=0, key='canvas'+(str(st.session_state.df_ix) if st.session_state.df_ix>=0 else ''))

This is the error I get from streamlit cloud:

Traceback (most recent call last):

  File "/home/appuser/venv/lib/python3.9/site-packages/streamlit/runtime/state/session_state_proxy.py", line 118, in __getattr__

    return self[key]

  File "/home/appuser/venv/lib/python3.9/site-packages/streamlit/runtime/state/session_state_proxy.py", line 89, in __getitem__

    return get_session_state()[key]

  File "/home/appuser/venv/lib/python3.9/site-packages/streamlit/runtime/state/safe_session_state.py", line 108, in __getitem__

    raise KeyError(key)

KeyError: 'df_ix'


During handling of the above exception, another exception occurred:


Traceback (most recent call last):

  File "/home/appuser/venv/lib/python3.9/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 563, in _run_script

    exec(code, module.__dict__)

  File "/app/monocular_measurement_3d/pages/02_Label_Dataset.py", line 90, in <module>

    if st.session_state.df_ix >= 0:

  File "/home/appuser/venv/lib/python3.9/site-packages/streamlit/runtime/state/session_state_proxy.py", line 120, in __getattr__

    raise AttributeError(_missing_attr_error_message(key))

To make it even more challenging, if I st.write(st.session_state) All the variables, including the df_ix are printed as expected!

Any clues??
Thanks