Hello,
If you try to execute the following code, interaction with the number_input will not cause any problems. However, the very first interaction with a date_input will raise a warning, “The widget with key “…” was created with a default value but also had its value set via the Session State API.”
from datetime import date
import streamlit as st
def create_date_period(min_date, max_date) -> list[date,date]:
left_box_date, right_box_date = st.sidebar.columns(2)
if "start_date" in st.session_state:
load_value("start_date")
start_chosen_date = left_box_date.date_input(
"Start period",
min_date,
min_date,
max_date,
format="DD/MM/YYYY",
key="_start_date",
on_change=store_value,
args=["start_date"]
)
if "end_date" in st.session_state:
load_value("end_date")
end_chosen_date = right_box_date.date_input(
"End period",
max_date,
start_chosen_date,
max_date,
format="DD/MM/YYYY",
key="_end_date",
on_change=store_value,
args=["end_date"]
)
if "my_key" in st.session_state:
load_value("my_key")
st.sidebar.number_input("Number of filters", key="_my_key", on_change=store_value, args=["my_key"])
return [start_chosen_date, end_chosen_date]
def store_value(key: str) -> None:
st.session_state[key] = st.session_state["_"+key]
def load_value(key : str) -> None:
st.session_state["_"+key] = st.session_state[key]
create_date_period(date(2023,2,1),date(2023,5,1))
I read here that the solution would be to do this :
from datetime import date
import streamlit as st
def create_date_period(min_date, max_date) -> list[date,date]:
left_box_date, right_box_date = st.sidebar.columns(2)
if "start_date" in st.session_state:
load_value("start_date")
start_chosen_date = left_box_date.date_input(
"Start period",
min_value=min_date,
max_value=max_date,
format="DD/MM/YYYY",
key="_start_date",
on_change=store_value,
args=["start_date"]
)
else:
start_chosen_date = left_box_date.date_input(
"Start period",
value=min_date,
min_value=min_date,
max_value=max_date,
format="DD/MM/YYYY",
key="_start_date",
on_change=store_value,
args=["start_date"]
)
if "end_date" in st.session_state:
load_value("end_date")
end_chosen_date = right_box_date.date_input(
"End period",
min_value=start_chosen_date,
max_value=max_date,
format="DD/MM/YYYY",
key="_end_date",
on_change=store_value,
args=["end_date"]
)
else:
end_chosen_date = right_box_date.date_input(
"End period",
value=max_date,
min_value=start_chosen_date,
max_value=max_date,
format="DD/MM/YYYY",
key="_end_date",
on_change=store_value,
args=["end_date"]
)
if "my_key" in st.session_state:
load_value("my_key")
st.sidebar.number_input("Number of filters", key="_my_key", on_change=store_value, args=["my_key"])
return [start_chosen_date, end_chosen_date]
def store_value(key: str) -> None:
st.session_state[key] = st.session_state["_"+key]
def load_value(key : str) -> None:
st.session_state["_"+key] = st.session_state[key]
create_date_period(date(2023,2,1),date(2023,5,1))
However, I don’t find this to be a good workaround as it requires duplication of code.
So I’d like to know if there’s a better solution or if a patch is in the works?
store_value() and load_value() functions are taken from the documentation
Thanks in advance,