Mohamed-512 / Extra-Streamlit-Components

An all in one place, to find complex or just not available components by default on streamlit.
Apache License 2.0
468 stars 59 forks source link

Can't access a cookie twice #10

Closed LeoGrin closed 2 years ago

LeoGrin commented 2 years ago

Minimal code:

import streamlit as st
import extra_streamlit_components as stx

cookie_manager = stx.CookieManager()

print(cookie_manager.get("cookie"))
print(cookie_manager.get("cookie"))

Error:

None
2021-10-20 10:46:56.280 Traceback (most recent call last):
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/script_runner.py", line 354, in _run_script
    exec(code, module.__dict__)
  File "/Users/leo/JupyterProjects/nootropics_survey/test.py", line 13, in <module>
    print(cookie_manager.get("cookie"))
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/extra_streamlit_components/CookieManager/__init__.py", line 20, in get
    return self.cookie_manager(method="get", cookie=cookie, key=key)
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/components/v1/components.py", line 80, in __call__
    return self.create_instance(*args, default=default, key=key, **kwargs)
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/components/v1/components.py", line 218, in create_instance
    return_value = marshall_component(dg, element)
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/components/v1/components.py", line 191, in marshall_component
    widget_value, _ = register_widget(
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/state/widgets.py", line 148, in register_widget
    raise DuplicateWidgetID(
streamlit.errors.DuplicateWidgetID: There are multiple identical `st.extra_streamlit_components.CookieManager.cookie_manager` widgets with
`key='get'`.

To fix this, please make sure that the `key` argument is unique for
each `st.extra_streamlit_components.CookieManager.cookie_manager` you create.

None
2021-10-20 10:46:56.855 Traceback (most recent call last):
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/script_runner.py", line 354, in _run_script
    exec(code, module.__dict__)
  File "/Users/leo/JupyterProjects/nootropics_survey/test.py", line 13, in <module>
    print(cookie_manager.get("cookie"))
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/extra_streamlit_components/CookieManager/__init__.py", line 20, in get
    return self.cookie_manager(method="get", cookie=cookie, key=key)
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/components/v1/components.py", line 80, in __call__
    return self.create_instance(*args, default=default, key=key, **kwargs)
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/components/v1/components.py", line 218, in create_instance
    return_value = marshall_component(dg, element)
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/components/v1/components.py", line 191, in marshall_component
    widget_value, _ = register_widget(
  File "/Users/leo/opt/anaconda3/envs/nootropics/lib/python3.8/site-packages/streamlit/state/widgets.py", line 148, in register_widget
    raise DuplicateWidgetID(
streamlit.errors.DuplicateWidgetID: There are multiple identical `st.extra_streamlit_components.CookieManager.cookie_manager` widgets with
`key='get'`.

To fix this, please make sure that the `key` argument is unique for
each `st.extra_streamlit_components.CookieManager.cookie_manager` you create.
Mohamed-512 commented 2 years ago

This is not a bug, you are required to supply a unique key for the each of the cookie_manager.get calls, as both have the same defualt key and content. This is a regulation by Streamlit to not have two componets that are identical in everything. The following snippet will spit out the same error:

import streamlit as st

st.number_input("n1")
st.number_input("n1")

A fix to this problem is to add a key to the second call of cookie manager as follows:

import streamlit as st
import extra_streamlit_components as stx

cookie_manager = stx.CookieManager()

print(cookie_manager.get("cookie"))
print(cookie_manager.get("cookie", key="second"))
LeoGrin commented 2 years ago

Ok thank you!

I see what you mean, but as "get" doesn't really create a widget, I think it's a weird behavior and could maybe be dealt with internally in Extra-Streamlit-Component.

Anyway, thank you for your time and your library !

Mohamed-512 commented 2 years ago

You're welcome! You might be right, getting a cookie can be abstracted a bit more. But setting a cookie requires a communication between the Streamlit server and the browser, which needs a component initialized to do specifically this. But this will give an inconsistent developer experience as a trade off.