1414
1515from dataclasses import dataclass , field
1616from typing import Dict , Iterable , Iterator , List , MutableMapping , Union
17+ from urllib import parse
1718
19+ from streamlit .constants import EMBED_QUERY_PARAMS_KEYS
1820from streamlit .errors import StreamlitAPIException
1921from streamlit .proto .ForwardMsg_pb2 import ForwardMsg
2022
@@ -29,7 +31,12 @@ class QueryParams(MutableMapping[str, str]):
2931
3032 def __iter__ (self ) -> Iterator [str ]:
3133 self ._ensure_single_query_api_used ()
32- return iter (self ._query_params .keys ())
34+
35+ return iter (
36+ key
37+ for key in self ._query_params .keys ()
38+ if key not in EMBED_QUERY_PARAMS_KEYS
39+ )
3340
3441 def __getitem__ (self , key : str ) -> str :
3542 """Retrieves a value for a given key in query parameters.
@@ -38,6 +45,8 @@ def __getitem__(self, key: str) -> str:
3845 """
3946 self ._ensure_single_query_api_used ()
4047 try :
48+ if key in EMBED_QUERY_PARAMS_KEYS :
49+ raise KeyError (missing_key_error_message (key ))
4150 value = self ._query_params [key ]
4251 if isinstance (value , list ):
4352 if len (value ) == 0 :
@@ -56,6 +65,10 @@ def __setitem__(self, key: str, value: Union[str, Iterable[str]]) -> None:
5665 f"You cannot set a query params key `{ key } ` to a dictionary."
5766 )
5867
68+ if key in EMBED_QUERY_PARAMS_KEYS :
69+ raise StreamlitAPIException (
70+ "Query param embed and embed_options (case-insensitive) cannot be set programmatically."
71+ )
5972 # Type checking users should handle the string serialization themselves
6073 # We will accept any type for the list and serialize to str just in case
6174 if isinstance (value , Iterable ) and not isinstance (value , str ):
@@ -66,25 +79,28 @@ def __setitem__(self, key: str, value: Union[str, Iterable[str]]) -> None:
6679
6780 def __delitem__ (self , key : str ) -> None :
6881 try :
82+ if key in EMBED_QUERY_PARAMS_KEYS :
83+ raise KeyError (missing_key_error_message (key ))
6984 del self ._query_params [key ]
7085 self ._send_query_param_msg ()
7186 except KeyError :
7287 raise KeyError (missing_key_error_message (key ))
7388
7489 def get_all (self , key : str ) -> List [str ]:
7590 self ._ensure_single_query_api_used ()
76- if key not in self ._query_params :
91+ if key not in self ._query_params or key in EMBED_QUERY_PARAMS_KEYS :
7792 return []
7893 value = self ._query_params [key ]
7994 return value if isinstance (value , list ) else [value ]
8095
8196 def __len__ (self ) -> int :
8297 self ._ensure_single_query_api_used ()
83- return len (self ._query_params )
98+ return len (
99+ {key for key in self ._query_params if key not in EMBED_QUERY_PARAMS_KEYS }
100+ )
84101
85102 def _send_query_param_msg (self ) -> None :
86103 # Avoid circular imports
87- from streamlit .commands .experimental_query_params import _ensure_no_embed_params
88104 from streamlit .runtime .scriptrunner import get_script_run_ctx
89105
90106 ctx = get_script_run_ctx ()
@@ -93,27 +109,31 @@ def _send_query_param_msg(self) -> None:
93109 self ._ensure_single_query_api_used ()
94110
95111 msg = ForwardMsg ()
96- msg .page_info_changed .query_string = _ensure_no_embed_params (
97- self ._query_params , ctx . query_string
112+ msg .page_info_changed .query_string = parse . urlencode (
113+ self ._query_params , doseq = True
98114 )
99115 ctx .query_string = msg .page_info_changed .query_string
100116 ctx .enqueue (msg )
101117
102118 def clear (self ) -> None :
103- self ._query_params .clear ()
119+ new_query_params = {}
120+ for key , value in self ._query_params .items ():
121+ if key in EMBED_QUERY_PARAMS_KEYS :
122+ new_query_params [key ] = value
123+ self ._query_params = new_query_params
124+
104125 self ._send_query_param_msg ()
105126
106127 def to_dict (self ) -> Dict [str , str ]:
107128 self ._ensure_single_query_api_used ()
108- # return the last query param if multiple keys are set
109- return {key : self [key ] for key in self ._query_params }
129+ # return the last query param if multiple values are set
130+ return {
131+ key : self [key ]
132+ for key in self ._query_params
133+ if key not in EMBED_QUERY_PARAMS_KEYS
134+ }
110135
111136 def set_with_no_forward_msg (self , key : str , val : Union [List [str ], str ]) -> None :
112- # Avoid circular imports
113- from streamlit .commands .experimental_query_params import EMBED_QUERY_PARAMS_KEYS
114-
115- if key .lower () in EMBED_QUERY_PARAMS_KEYS :
116- return
117137 self ._query_params [key ] = val
118138
119139 def clear_with_no_forward_msg (self ) -> None :
0 commit comments