streamlit-nightly 1.31.2.dev20240213__py2.py3-none-any.whl → 1.31.2.dev20240214__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. streamlit/case_converters.py +9 -4
  2. streamlit/cli_util.py +2 -0
  3. streamlit/code_util.py +5 -2
  4. streamlit/color_util.py +2 -0
  5. streamlit/column_config.py +2 -0
  6. streamlit/commands/execution_control.py +4 -2
  7. streamlit/commands/experimental_query_params.py +7 -4
  8. streamlit/commands/page_config.py +11 -9
  9. streamlit/components/v1/components.py +23 -16
  10. streamlit/config.py +3 -5
  11. streamlit/config_option.py +12 -11
  12. streamlit/connections/base_connection.py +4 -2
  13. streamlit/connections/snowflake_connection.py +4 -4
  14. streamlit/connections/snowpark_connection.py +3 -3
  15. streamlit/connections/sql_connection.py +6 -6
  16. streamlit/connections/util.py +8 -5
  17. streamlit/constants.py +2 -0
  18. streamlit/cursor.py +16 -14
  19. streamlit/delta_generator.py +10 -13
  20. streamlit/deprecation_util.py +4 -3
  21. streamlit/echo.py +5 -3
  22. streamlit/elements/alert.py +16 -14
  23. streamlit/elements/altair_utils.py +8 -6
  24. streamlit/elements/arrow.py +4 -4
  25. streamlit/elements/arrow_altair.py +24 -34
  26. streamlit/elements/arrow_vega_lite.py +9 -14
  27. streamlit/elements/balloons.py +4 -2
  28. streamlit/elements/bokeh_chart.py +7 -7
  29. streamlit/elements/code.py +6 -4
  30. streamlit/elements/deck_gl_json_chart.py +8 -8
  31. streamlit/elements/doc_string.py +5 -9
  32. streamlit/elements/empty.py +4 -2
  33. streamlit/elements/exception.py +10 -10
  34. streamlit/elements/form.py +1 -3
  35. streamlit/elements/graphviz_chart.py +5 -6
  36. streamlit/elements/heading.py +16 -14
  37. streamlit/elements/iframe.py +14 -12
  38. streamlit/elements/image.py +8 -8
  39. streamlit/elements/json.py +6 -4
  40. streamlit/elements/layouts.py +12 -10
  41. streamlit/elements/lib/column_config_utils.py +2 -2
  42. streamlit/elements/lib/column_types.py +23 -23
  43. streamlit/elements/lib/dicttools.py +10 -6
  44. streamlit/elements/lib/mutable_status_container.py +7 -7
  45. streamlit/elements/lib/pandas_styler_utils.py +6 -6
  46. streamlit/elements/lib/streamlit_plotly_theme.py +2 -0
  47. streamlit/elements/map.py +11 -22
  48. streamlit/elements/markdown.py +16 -14
  49. streamlit/elements/media.py +16 -16
  50. streamlit/elements/metric.py +9 -7
  51. streamlit/elements/plotly_chart.py +5 -5
  52. streamlit/elements/progress.py +6 -6
  53. streamlit/elements/pyplot.py +10 -13
  54. streamlit/elements/snow.py +4 -2
  55. streamlit/elements/spinner.py +2 -0
  56. streamlit/elements/text.py +7 -5
  57. streamlit/elements/toast.py +6 -4
  58. streamlit/elements/utils.py +15 -28
  59. streamlit/elements/widgets/button.py +39 -39
  60. streamlit/elements/widgets/camera_input.py +21 -17
  61. streamlit/elements/widgets/chat.py +6 -7
  62. streamlit/elements/widgets/checkbox.py +21 -19
  63. streamlit/elements/widgets/color_picker.py +18 -16
  64. streamlit/elements/widgets/data_editor.py +7 -7
  65. streamlit/elements/widgets/file_uploader.py +59 -55
  66. streamlit/elements/widgets/multiselect.py +33 -42
  67. streamlit/elements/widgets/number_input.py +10 -5
  68. streamlit/elements/widgets/radio.py +1 -1
  69. streamlit/elements/widgets/select_slider.py +25 -34
  70. streamlit/elements/widgets/selectbox.py +1 -1
  71. streamlit/elements/widgets/slider.py +28 -36
  72. streamlit/elements/widgets/text_widgets.py +6 -6
  73. streamlit/elements/widgets/time_widgets.py +13 -13
  74. streamlit/elements/write.py +8 -19
  75. streamlit/env_util.py +5 -3
  76. streamlit/error_util.py +7 -3
  77. streamlit/errors.py +3 -1
  78. streamlit/external/langchain/streamlit_callback_handler.py +26 -24
  79. streamlit/file_util.py +18 -14
  80. streamlit/folder_black_list.py +3 -1
  81. streamlit/git_util.py +5 -3
  82. streamlit/js_number.py +10 -13
  83. streamlit/logger.py +5 -5
  84. streamlit/net_util.py +14 -11
  85. streamlit/platform.py +2 -0
  86. streamlit/runtime/__init__.py +2 -0
  87. streamlit/runtime/app_session.py +42 -42
  88. streamlit/runtime/caching/__init__.py +4 -4
  89. streamlit/runtime/caching/cache_data_api.py +3 -3
  90. streamlit/runtime/caching/cache_errors.py +5 -3
  91. streamlit/runtime/caching/cache_type.py +2 -0
  92. streamlit/runtime/caching/cache_utils.py +2 -4
  93. streamlit/runtime/caching/cached_message_replay.py +12 -5
  94. streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -2
  95. streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -5
  96. streamlit/runtime/connection_factory.py +8 -8
  97. streamlit/runtime/forward_msg_cache.py +20 -18
  98. streamlit/runtime/forward_msg_queue.py +8 -9
  99. streamlit/runtime/legacy_caching/caching.py +32 -42
  100. streamlit/runtime/media_file_manager.py +16 -14
  101. streamlit/runtime/media_file_storage.py +8 -8
  102. streamlit/runtime/memory_media_file_storage.py +12 -14
  103. streamlit/runtime/memory_session_storage.py +4 -3
  104. streamlit/runtime/memory_uploaded_file_manager.py +9 -10
  105. streamlit/runtime/metrics_util.py +20 -20
  106. streamlit/runtime/runtime.py +25 -27
  107. streamlit/runtime/runtime_util.py +5 -3
  108. streamlit/runtime/script_data.py +2 -0
  109. streamlit/runtime/scriptrunner/magic.py +17 -11
  110. streamlit/runtime/scriptrunner/magic_funcs.py +2 -0
  111. streamlit/runtime/scriptrunner/script_requests.py +6 -4
  112. streamlit/runtime/scriptrunner/script_run_context.py +17 -17
  113. streamlit/runtime/scriptrunner/script_runner.py +7 -5
  114. streamlit/runtime/secrets.py +4 -6
  115. streamlit/runtime/session_manager.py +14 -14
  116. streamlit/runtime/state/common.py +5 -4
  117. streamlit/runtime/state/query_params.py +8 -6
  118. streamlit/runtime/state/query_params_proxy.py +7 -5
  119. streamlit/runtime/state/safe_session_state.py +7 -5
  120. streamlit/runtime/state/session_state.py +3 -4
  121. streamlit/runtime/state/session_state_proxy.py +5 -5
  122. streamlit/runtime/state/widgets.py +20 -18
  123. streamlit/runtime/uploaded_file_manager.py +6 -5
  124. streamlit/runtime/websocket_session_manager.py +14 -14
  125. streamlit/source_util.py +13 -11
  126. streamlit/string_util.py +13 -9
  127. streamlit/temporary_directory.py +3 -1
  128. streamlit/testing/v1/element_tree.py +1 -2
  129. streamlit/type_util.py +21 -25
  130. streamlit/url_util.py +6 -4
  131. streamlit/user_info.py +8 -6
  132. streamlit/util.py +23 -37
  133. streamlit/watcher/event_based_path_watcher.py +10 -10
  134. streamlit/watcher/local_sources_watcher.py +15 -13
  135. streamlit/watcher/path_watcher.py +0 -3
  136. streamlit/watcher/polling_path_watcher.py +9 -8
  137. streamlit/watcher/util.py +3 -2
  138. streamlit/web/cache_storage_manager_config.py +2 -0
  139. streamlit/web/server/app_static_file_handler.py +6 -5
  140. streamlit/web/server/browser_websocket_handler.py +10 -8
  141. streamlit/web/server/component_request_handler.py +7 -4
  142. streamlit/web/server/media_file_handler.py +5 -4
  143. streamlit/web/server/routes.py +6 -3
  144. streamlit/web/server/server.py +31 -31
  145. streamlit/web/server/server_util.py +4 -2
  146. streamlit/web/server/upload_file_request_handler.py +7 -8
  147. streamlit/web/server/websocket_headers.py +2 -2
  148. {streamlit_nightly-1.31.2.dev20240213.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/METADATA +1 -1
  149. {streamlit_nightly-1.31.2.dev20240213.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/RECORD +153 -153
  150. {streamlit_nightly-1.31.2.dev20240213.data → streamlit_nightly-1.31.2.dev20240214.data}/scripts/streamlit.cmd +0 -0
  151. {streamlit_nightly-1.31.2.dev20240213.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/WHEEL +0 -0
  152. {streamlit_nightly-1.31.2.dev20240213.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/entry_points.txt +0 -0
  153. {streamlit_nightly-1.31.2.dev20240213.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/top_level.txt +0 -0
@@ -19,12 +19,10 @@ import threading
19
19
  from copy import deepcopy
20
20
  from typing import (
21
21
  Any,
22
- Dict,
23
22
  Final,
24
23
  ItemsView,
25
24
  Iterator,
26
25
  KeysView,
27
- List,
28
26
  Mapping,
29
27
  NoReturn,
30
28
  ValuesView,
@@ -37,8 +35,8 @@ import streamlit.watcher.path_watcher
37
35
  from streamlit import file_util, runtime
38
36
  from streamlit.logger import get_logger
39
37
 
40
- _LOGGER = get_logger(__name__)
41
- SECRETS_FILE_LOCS: Final[List[str]] = [
38
+ _LOGGER: Final = get_logger(__name__)
39
+ SECRETS_FILE_LOCS: Final[list[str]] = [
42
40
  file_util.get_streamlit_file_path("secrets.toml"),
43
41
  # NOTE: The order here is important! Project-level secrets should overwrite global
44
42
  # secrets.
@@ -107,7 +105,7 @@ class AttrDict(Mapping[str, Any]):
107
105
  def __setattr__(self, key, value) -> NoReturn:
108
106
  raise TypeError("Secrets does not support attribute assignment.")
109
107
 
110
- def to_dict(self) -> Dict[str, Any]:
108
+ def to_dict(self) -> dict[str, Any]:
111
109
  return deepcopy(self.__nested_secrets__)
112
110
 
113
111
 
@@ -118,7 +116,7 @@ class Secrets(Mapping[str, Any]):
118
116
  Safe to use from multiple threads.
119
117
  """
120
118
 
121
- def __init__(self, file_paths: List[str]):
119
+ def __init__(self, file_paths: list[str]):
122
120
  # Our secrets dict.
123
121
  self._secrets: Mapping[str, Any] | None = None
124
122
  self._lock = threading.RLock()
@@ -12,11 +12,11 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from abc import abstractmethod
16
18
  from dataclasses import dataclass
17
- from typing import Callable, Dict, List, Optional, cast
18
-
19
- from typing_extensions import Protocol
19
+ from typing import Callable, Protocol, cast
20
20
 
21
21
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
22
22
  from streamlit.runtime.app_session import AppSession
@@ -64,7 +64,7 @@ class SessionInfo:
64
64
  the ForwardMsgCache.
65
65
  """
66
66
 
67
- client: Optional[SessionClient]
67
+ client: SessionClient | None
68
68
  session: AppSession
69
69
  script_run_count: int = 0
70
70
 
@@ -90,7 +90,7 @@ class SessionStorageError(Exception):
90
90
 
91
91
  class SessionStorage(Protocol):
92
92
  @abstractmethod
93
- def get(self, session_id: str) -> Optional[SessionInfo]:
93
+ def get(self, session_id: str) -> SessionInfo | None:
94
94
  """Return the SessionInfo corresponding to session_id, or None if one does not
95
95
  exist.
96
96
 
@@ -152,7 +152,7 @@ class SessionStorage(Protocol):
152
152
  raise NotImplementedError
153
153
 
154
154
  @abstractmethod
155
- def list(self) -> List[SessionInfo]:
155
+ def list(self) -> list[SessionInfo]:
156
156
  """List all sessions tracked by this SessionStorage.
157
157
 
158
158
  Returns
@@ -210,7 +210,7 @@ class SessionManager(Protocol):
210
210
  session_storage: SessionStorage,
211
211
  uploaded_file_manager: UploadedFileManager,
212
212
  script_cache: ScriptCache,
213
- message_enqueued_callback: Optional[Callable[[], None]],
213
+ message_enqueued_callback: Callable[[], None] | None,
214
214
  ) -> None:
215
215
  """Initialize a SessionManager with the given SessionStorage.
216
216
 
@@ -235,9 +235,9 @@ class SessionManager(Protocol):
235
235
  self,
236
236
  client: SessionClient,
237
237
  script_data: ScriptData,
238
- user_info: Dict[str, Optional[str]],
239
- existing_session_id: Optional[str] = None,
240
- session_id_override: Optional[str] = None,
238
+ user_info: dict[str, str | None],
239
+ existing_session_id: str | None = None,
240
+ session_id_override: str | None = None,
241
241
  ) -> str:
242
242
  """Create a new session or connect to an existing one.
243
243
 
@@ -290,7 +290,7 @@ class SessionManager(Protocol):
290
290
  raise NotImplementedError
291
291
 
292
292
  @abstractmethod
293
- def get_session_info(self, session_id: str) -> Optional[SessionInfo]:
293
+ def get_session_info(self, session_id: str) -> SessionInfo | None:
294
294
  """Return the SessionInfo for the given id, or None if no such session
295
295
  exists.
296
296
 
@@ -306,7 +306,7 @@ class SessionManager(Protocol):
306
306
  raise NotImplementedError
307
307
 
308
308
  @abstractmethod
309
- def list_sessions(self) -> List[SessionInfo]:
309
+ def list_sessions(self) -> list[SessionInfo]:
310
310
  """Return the SessionInfo for all sessions managed by this SessionManager.
311
311
 
312
312
  Returns
@@ -344,7 +344,7 @@ class SessionManager(Protocol):
344
344
  """
345
345
  self.close_session(session_id)
346
346
 
347
- def get_active_session_info(self, session_id: str) -> Optional[ActiveSessionInfo]:
347
+ def get_active_session_info(self, session_id: str) -> ActiveSessionInfo | None:
348
348
  """Return the ActiveSessionInfo for the given id, or None if either no such
349
349
  session exists or the session is not active.
350
350
 
@@ -371,7 +371,7 @@ class SessionManager(Protocol):
371
371
  """
372
372
  return self.get_active_session_info(session_id) is not None
373
373
 
374
- def list_active_sessions(self) -> List[ActiveSessionInfo]:
374
+ def list_active_sessions(self) -> list[ActiveSessionInfo]:
375
375
  """Return the session info for all active sessions tracked by this SessionManager.
376
376
 
377
377
  Returns
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Functions and data structures shared by session_state.py and widgets.py"""
16
+
16
17
  from __future__ import annotations
17
18
 
18
19
  import hashlib
@@ -23,8 +24,8 @@ from typing import (
23
24
  Any,
24
25
  Callable,
25
26
  Dict,
27
+ Final,
26
28
  Generic,
27
- Optional,
28
29
  Sequence,
29
30
  Tuple,
30
31
  TypeVar,
@@ -32,7 +33,7 @@ from typing import (
32
33
  )
33
34
 
34
35
  from google.protobuf.message import Message
35
- from typing_extensions import Final, TypeAlias
36
+ from typing_extensions import TypeAlias
36
37
 
37
38
  from streamlit import util
38
39
  from streamlit.errors import StreamlitAPIException
@@ -151,7 +152,7 @@ class RegisterWidgetResult(Generic[T_co]):
151
152
  @classmethod
152
153
  def failure(
153
154
  cls, deserializer: WidgetDeserializer[T_co]
154
- ) -> "RegisterWidgetResult[T_co]":
155
+ ) -> RegisterWidgetResult[T_co]:
155
156
  """The canonical way to construct a RegisterWidgetResult in cases
156
157
  where the true widget value could not be determined.
157
158
  """
@@ -200,7 +201,7 @@ def compute_widget_id(
200
201
  return f"{GENERATED_WIDGET_ID_PREFIX}-{h.hexdigest()}-{user_key}"
201
202
 
202
203
 
203
- def user_key_from_widget_id(widget_id: str) -> Optional[str]:
204
+ def user_key_from_widget_id(widget_id: str) -> str | None:
204
205
  """Return the user key portion of a widget id, or None if the id does not
205
206
  have a user key.
206
207
 
@@ -12,8 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from dataclasses import dataclass, field
16
- from typing import Dict, Iterable, Iterator, List, MutableMapping, Union
18
+ from typing import Iterable, Iterator, MutableMapping
17
19
  from urllib import parse
18
20
 
19
21
  from streamlit.constants import EMBED_QUERY_PARAMS_KEYS
@@ -27,7 +29,7 @@ class QueryParams(MutableMapping[str, str]):
27
29
  It stores str keys with str and List[str] values.
28
30
  """
29
31
 
30
- _query_params: Dict[str, Union[List[str], str]] = field(default_factory=dict)
32
+ _query_params: dict[str, list[str] | str] = field(default_factory=dict)
31
33
 
32
34
  def __iter__(self) -> Iterator[str]:
33
35
  self._ensure_single_query_api_used()
@@ -59,7 +61,7 @@ class QueryParams(MutableMapping[str, str]):
59
61
  except KeyError:
60
62
  raise KeyError(missing_key_error_message(key))
61
63
 
62
- def __setitem__(self, key: str, value: Union[str, Iterable[str]]) -> None:
64
+ def __setitem__(self, key: str, value: str | Iterable[str]) -> None:
63
65
  if isinstance(value, dict):
64
66
  raise StreamlitAPIException(
65
67
  f"You cannot set a query params key `{key}` to a dictionary."
@@ -86,7 +88,7 @@ class QueryParams(MutableMapping[str, str]):
86
88
  except KeyError:
87
89
  raise KeyError(missing_key_error_message(key))
88
90
 
89
- def get_all(self, key: str) -> List[str]:
91
+ def get_all(self, key: str) -> list[str]:
90
92
  self._ensure_single_query_api_used()
91
93
  if key not in self._query_params or key in EMBED_QUERY_PARAMS_KEYS:
92
94
  return []
@@ -128,7 +130,7 @@ class QueryParams(MutableMapping[str, str]):
128
130
 
129
131
  self._send_query_param_msg()
130
132
 
131
- def to_dict(self) -> Dict[str, str]:
133
+ def to_dict(self) -> dict[str, str]:
132
134
  self._ensure_single_query_api_used()
133
135
  # return the last query param if multiple values are set
134
136
  return {
@@ -137,7 +139,7 @@ class QueryParams(MutableMapping[str, str]):
137
139
  if key not in EMBED_QUERY_PARAMS_KEYS
138
140
  }
139
141
 
140
- def set_with_no_forward_msg(self, key: str, val: Union[List[str], str]) -> None:
142
+ def set_with_no_forward_msg(self, key: str, val: list[str] | str) -> None:
141
143
  self._query_params[key] = val
142
144
 
143
145
  def clear_with_no_forward_msg(self) -> None:
@@ -12,7 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Dict, Iterable, Iterator, List, MutableMapping, Union
15
+ from __future__ import annotations
16
+
17
+ from typing import Iterable, Iterator, MutableMapping
16
18
 
17
19
  from streamlit.runtime.metrics_util import gather_metrics
18
20
  from streamlit.runtime.state.query_params import missing_key_error_message
@@ -47,7 +49,7 @@ class QueryParamsProxy(MutableMapping[str, str]):
47
49
  del qp[key]
48
50
 
49
51
  @gather_metrics("query_params.set_item")
50
- def __setitem__(self, key: str, value: Union[str, Iterable[str]]) -> None:
52
+ def __setitem__(self, key: str, value: str | Iterable[str]) -> None:
51
53
  with get_session_state().query_params() as qp:
52
54
  qp[key] = value
53
55
 
@@ -67,12 +69,12 @@ class QueryParamsProxy(MutableMapping[str, str]):
67
69
  raise AttributeError(missing_key_error_message(key))
68
70
 
69
71
  @gather_metrics("query_params.set_attr")
70
- def __setattr__(self, key: str, value: Union[str, Iterable[str]]) -> None:
72
+ def __setattr__(self, key: str, value: str | Iterable[str]) -> None:
71
73
  with get_session_state().query_params() as qp:
72
74
  qp[key] = value
73
75
 
74
76
  @gather_metrics("query_params.get_all")
75
- def get_all(self, key: str) -> List[str]:
77
+ def get_all(self, key: str) -> list[str]:
76
78
  """
77
79
  Get a list of all query parameter values associated to a given key.
78
80
 
@@ -107,7 +109,7 @@ class QueryParamsProxy(MutableMapping[str, str]):
107
109
  qp.clear()
108
110
 
109
111
  @gather_metrics("query_params.to_dict")
110
- def to_dict(self) -> Dict[str, str]:
112
+ def to_dict(self) -> dict[str, str]:
111
113
  """
112
114
  Get all query parameters as a dictionary.
113
115
 
@@ -12,9 +12,11 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import threading
16
18
  from contextlib import contextmanager
17
- from typing import Any, Callable, Dict, Iterator, List, Optional, Set
19
+ from typing import Any, Callable, Iterator
18
20
 
19
21
  from streamlit.proto.WidgetStates_pb2 import WidgetState as WidgetStateProto
20
22
  from streamlit.proto.WidgetStates_pb2 import WidgetStates as WidgetStatesProto
@@ -47,7 +49,7 @@ class SafeSessionState:
47
49
  object.__setattr__(self, "_yield_callback", yield_callback)
48
50
 
49
51
  def register_widget(
50
- self, metadata: WidgetMetadata[T], user_key: Optional[str]
52
+ self, metadata: WidgetMetadata[T], user_key: str | None
51
53
  ) -> RegisterWidgetResult[T]:
52
54
  self._yield_callback()
53
55
  with self._lock:
@@ -62,7 +64,7 @@ class SafeSessionState:
62
64
  # to a Lock.)
63
65
  self._state.on_script_will_rerun(latest_widget_states)
64
66
 
65
- def on_script_finished(self, widget_ids_this_run: Set[str]) -> None:
67
+ def on_script_finished(self, widget_ids_this_run: set[str]) -> None:
66
68
  with self._lock:
67
69
  self._state.on_script_finished(widget_ids_this_run)
68
70
 
@@ -70,7 +72,7 @@ class SafeSessionState:
70
72
  with self._lock:
71
73
  self._state.maybe_check_serializable()
72
74
 
73
- def get_widget_states(self) -> List[WidgetStateProto]:
75
+ def get_widget_states(self) -> list[WidgetStateProto]:
74
76
  """Return a list of serialized widget values for each widget with a value."""
75
77
  with self._lock:
76
78
  return self._state.get_widget_states()
@@ -80,7 +82,7 @@ class SafeSessionState:
80
82
  return self._state.is_new_state_value(user_key)
81
83
 
82
84
  @property
83
- def filtered_state(self) -> Dict[str, Any]:
85
+ def filtered_state(self) -> dict[str, Any]:
84
86
  """The combined session and widget state, excluding keyless widgets."""
85
87
  with self._lock:
86
88
  return self._state.filtered_state
@@ -152,8 +152,7 @@ class WStates(MutableMapping[str, Any]):
152
152
  # For this and many other methods, we can't simply delegate to the
153
153
  # states field, because we need to invoke `__getitem__` for any
154
154
  # values, to handle deserialization and unwrapping of values.
155
- for key in self.states:
156
- yield key
155
+ yield from self.states
157
156
 
158
157
  def keys(self) -> KeysView[str]:
159
158
  return KeysView(self.states)
@@ -164,7 +163,7 @@ class WStates(MutableMapping[str, Any]):
164
163
  def values(self) -> set[Any]: # type: ignore[override]
165
164
  return {self[wid] for wid in self}
166
165
 
167
- def update(self, other: "WStates") -> None: # type: ignore[override]
166
+ def update(self, other: WStates) -> None: # type: ignore[override]
168
167
  """Copy all widget values and metadata from 'other' into this mapping,
169
168
  overwriting any data in this mapping that's also present in 'other'.
170
169
  """
@@ -674,7 +673,7 @@ def _is_internal_key(key: str) -> bool:
674
673
 
675
674
  @dataclass
676
675
  class SessionStateStatProvider(CacheStatsProvider):
677
- _session_mgr: "SessionManager"
676
+ _session_mgr: SessionManager
678
677
 
679
678
  def get_stats(self) -> list[CacheStat]:
680
679
  stats: list[CacheStat] = []
@@ -12,9 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Any, Dict, Iterator, MutableMapping
15
+ from __future__ import annotations
16
16
 
17
- from typing_extensions import Final
17
+ from typing import Any, Final, Iterator, MutableMapping
18
18
 
19
19
  from streamlit import logger as _logger
20
20
  from streamlit import runtime
@@ -24,7 +24,7 @@ from streamlit.runtime.state.safe_session_state import SafeSessionState
24
24
  from streamlit.runtime.state.session_state import SessionState
25
25
  from streamlit.type_util import Key
26
26
 
27
- LOGGER: Final = _logger.get_logger(__name__)
27
+ _LOGGER: Final = _logger.get_logger(__name__)
28
28
 
29
29
 
30
30
  _state_use_warning_already_displayed: bool = False
@@ -48,7 +48,7 @@ def get_session_state() -> SafeSessionState:
48
48
  if not _state_use_warning_already_displayed:
49
49
  _state_use_warning_already_displayed = True
50
50
  if not runtime.exists():
51
- LOGGER.warning(
51
+ _LOGGER.warning(
52
52
  "Session state does not function when running a script without `streamlit run`"
53
53
  )
54
54
  return SafeSessionState(SessionState(), lambda: None)
@@ -130,7 +130,7 @@ class SessionStateProxy(MutableMapping[Key, Any]):
130
130
  except KeyError:
131
131
  raise AttributeError(_missing_attr_error_message(key))
132
132
 
133
- def to_dict(self) -> Dict[str, Any]:
133
+ def to_dict(self) -> dict[str, Any]:
134
134
  """Return a dict containing all session_state and keyed widget values."""
135
135
  return get_session_state().filtered_state
136
136
 
@@ -12,11 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import textwrap
16
18
  from types import MappingProxyType
17
- from typing import TYPE_CHECKING, Dict, Mapping, Optional
19
+ from typing import TYPE_CHECKING, Final, Mapping
18
20
 
19
- from typing_extensions import Final, TypeAlias
21
+ from typing_extensions import TypeAlias
20
22
 
21
23
  from streamlit.errors import DuplicateWidgetID
22
24
  from streamlit.proto.WidgetStates_pb2 import WidgetState, WidgetStates
@@ -86,12 +88,12 @@ def register_widget(
86
88
  element_proto: WidgetProto,
87
89
  deserializer: WidgetDeserializer[T],
88
90
  serializer: WidgetSerializer[T],
89
- ctx: Optional["ScriptRunContext"],
90
- user_key: Optional[str] = None,
91
- widget_func_name: Optional[str] = None,
92
- on_change_handler: Optional[WidgetCallback] = None,
93
- args: Optional[WidgetArgs] = None,
94
- kwargs: Optional[WidgetKwargs] = None,
91
+ ctx: ScriptRunContext | None,
92
+ user_key: str | None = None,
93
+ widget_func_name: str | None = None,
94
+ on_change_handler: WidgetCallback | None = None,
95
+ args: WidgetArgs | None = None,
96
+ kwargs: WidgetKwargs | None = None,
95
97
  ) -> RegisterWidgetResult[T]:
96
98
  """Register a widget with Streamlit, and return its current value.
97
99
  NOTE: This function should be called after the proto has been filled.
@@ -107,21 +109,21 @@ def register_widget(
107
109
  its st.<widget_name> function.
108
110
  serializer : WidgetSerializer[T]
109
111
  Called to convert a widget's value to its protobuf representation.
110
- ctx : Optional[ScriptRunContext]
112
+ ctx : ScriptRunContext or None
111
113
  Used to ensure uniqueness of widget IDs, and to look up widget values.
112
- user_key : Optional[str]
114
+ user_key : str or None
113
115
  Optional user-specified string to use as the widget ID.
114
116
  If this is None, we'll generate an ID by hashing the element.
115
- widget_func_name : Optional[str]
117
+ widget_func_name : str or None
116
118
  The widget's DeltaGenerator function name, if it's different from
117
119
  its element_type. Custom components are a special case: they all have
118
120
  the element_type "component_instance", but are instantiated with
119
121
  dynamically-named functions.
120
- on_change_handler : Optional[WidgetCallback]
122
+ on_change_handler : WidgetCallback or None
121
123
  An optional callback invoked when the widget's value changes.
122
- args : Optional[WidgetArgs]
124
+ args : WidgetArgs or None
123
125
  args to pass to on_change_handler when invoked
124
- kwargs : Optional[WidgetKwargs]
126
+ kwargs : WidgetKwargs or None
125
127
  kwargs to pass to on_change_handler when invoked
126
128
 
127
129
  Returns
@@ -163,8 +165,8 @@ def register_widget(
163
165
 
164
166
  def register_widget_from_metadata(
165
167
  metadata: WidgetMetadata[T],
166
- ctx: Optional["ScriptRunContext"],
167
- widget_func_name: Optional[str],
168
+ ctx: ScriptRunContext | None,
169
+ widget_func_name: str | None,
168
170
  element_type: ElementType,
169
171
  ) -> RegisterWidgetResult[T]:
170
172
  """Register a widget and return its value, using an already constructed
@@ -226,7 +228,7 @@ def coalesce_widget_states(
226
228
  `old_states` will be set to True in the coalesced result, so that button
227
229
  presses don't go missing.
228
230
  """
229
- states_by_id: Dict[str, WidgetState] = {
231
+ states_by_id: dict[str, WidgetState] = {
230
232
  wstate.id: wstate for wstate in new_states.widgets
231
233
  }
232
234
 
@@ -254,7 +256,7 @@ def coalesce_widget_states(
254
256
 
255
257
 
256
258
  def _build_duplicate_widget_message(
257
- widget_func_name: str, user_key: Optional[str] = None
259
+ widget_func_name: str, user_key: str | None = None
258
260
  ) -> str:
259
261
  if user_key is not None:
260
262
  message = textwrap.dedent(
@@ -11,11 +11,12 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
14
17
  import io
15
18
  from abc import abstractmethod
16
- from typing import List, NamedTuple, Sequence
17
-
18
- from typing_extensions import Protocol
19
+ from typing import NamedTuple, Protocol, Sequence
19
20
 
20
21
  from streamlit import util
21
22
  from streamlit.proto.Common_pb2 import FileURLs as FileURLsProto
@@ -98,7 +99,7 @@ class UploadedFileManager(CacheStatsProvider, Protocol):
98
99
  @abstractmethod
99
100
  def get_files(
100
101
  self, session_id: str, file_ids: Sequence[str]
101
- ) -> List[UploadedFileRec]:
102
+ ) -> list[UploadedFileRec]:
102
103
  """Return a list of UploadedFileRec for a given sequence of file_ids.
103
104
 
104
105
  Parameters
@@ -123,7 +124,7 @@ class UploadedFileManager(CacheStatsProvider, Protocol):
123
124
 
124
125
  def get_upload_urls(
125
126
  self, session_id: str, file_names: Sequence[str]
126
- ) -> List[UploadFileUrlInfo]:
127
+ ) -> list[UploadFileUrlInfo]:
127
128
  """Return a list of UploadFileUrlInfo for a given sequence of file_names.
128
129
  Optional to implement, issuing of URLs could be done by other service.
129
130
 
@@ -12,9 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Callable, Dict, List, Optional, cast
15
+ from __future__ import annotations
16
16
 
17
- from typing_extensions import Final
17
+ from typing import Callable, Final, List, cast
18
18
 
19
19
  from streamlit.logger import get_logger
20
20
  from streamlit.runtime.app_session import AppSession
@@ -30,7 +30,7 @@ from streamlit.runtime.session_manager import (
30
30
  from streamlit.runtime.uploaded_file_manager import UploadedFileManager
31
31
  from streamlit.watcher import LocalSourcesWatcher
32
32
 
33
- LOGGER: Final = get_logger(__name__)
33
+ _LOGGER: Final = get_logger(__name__)
34
34
 
35
35
 
36
36
  class WebsocketSessionManager(SessionManager):
@@ -48,7 +48,7 @@ class WebsocketSessionManager(SessionManager):
48
48
  session_storage: SessionStorage,
49
49
  uploaded_file_manager: UploadedFileManager,
50
50
  script_cache: ScriptCache,
51
- message_enqueued_callback: Optional[Callable[[], None]],
51
+ message_enqueued_callback: Callable[[], None] | None,
52
52
  ) -> None:
53
53
  self._session_storage = session_storage
54
54
  self._uploaded_file_mgr = uploaded_file_manager
@@ -56,22 +56,22 @@ class WebsocketSessionManager(SessionManager):
56
56
  self._message_enqueued_callback = message_enqueued_callback
57
57
 
58
58
  # Mapping of AppSession.id -> ActiveSessionInfo.
59
- self._active_session_info_by_id: Dict[str, ActiveSessionInfo] = {}
59
+ self._active_session_info_by_id: dict[str, ActiveSessionInfo] = {}
60
60
 
61
61
  def connect_session(
62
62
  self,
63
63
  client: SessionClient,
64
64
  script_data: ScriptData,
65
- user_info: Dict[str, Optional[str]],
66
- existing_session_id: Optional[str] = None,
67
- session_id_override: Optional[str] = None,
65
+ user_info: dict[str, str | None],
66
+ existing_session_id: str | None = None,
67
+ session_id_override: str | None = None,
68
68
  ) -> str:
69
69
  assert not (
70
70
  existing_session_id and session_id_override
71
71
  ), "Only one of existing_session_id and session_id_override should be truthy"
72
72
 
73
73
  if existing_session_id in self._active_session_info_by_id:
74
- LOGGER.warning(
74
+ _LOGGER.warning(
75
75
  "Session with id %s is already connected! Connecting to a new session.",
76
76
  existing_session_id,
77
77
  )
@@ -105,7 +105,7 @@ class WebsocketSessionManager(SessionManager):
105
105
  session_id_override=session_id_override,
106
106
  )
107
107
 
108
- LOGGER.debug(
108
+ _LOGGER.debug(
109
109
  "Created new session for client %s. Session ID: %s", id(client), session.id
110
110
  )
111
111
 
@@ -133,13 +133,13 @@ class WebsocketSessionManager(SessionManager):
133
133
  )
134
134
  del self._active_session_info_by_id[session_id]
135
135
 
136
- def get_active_session_info(self, session_id: str) -> Optional[ActiveSessionInfo]:
136
+ def get_active_session_info(self, session_id: str) -> ActiveSessionInfo | None:
137
137
  return self._active_session_info_by_id.get(session_id)
138
138
 
139
139
  def is_active_session(self, session_id: str) -> bool:
140
140
  return session_id in self._active_session_info_by_id
141
141
 
142
- def list_active_sessions(self) -> List[ActiveSessionInfo]:
142
+ def list_active_sessions(self) -> list[ActiveSessionInfo]:
143
143
  return list(self._active_session_info_by_id.values())
144
144
 
145
145
  def close_session(self, session_id: str) -> None:
@@ -154,13 +154,13 @@ class WebsocketSessionManager(SessionManager):
154
154
  self._session_storage.delete(session_id)
155
155
  session_info.session.shutdown()
156
156
 
157
- def get_session_info(self, session_id: str) -> Optional[SessionInfo]:
157
+ def get_session_info(self, session_id: str) -> SessionInfo | None:
158
158
  session_info = self.get_active_session_info(session_id)
159
159
  if session_info:
160
160
  return cast(SessionInfo, session_info)
161
161
  return self._session_storage.get(session_id)
162
162
 
163
- def list_sessions(self) -> List[SessionInfo]:
163
+ def list_sessions(self) -> list[SessionInfo]:
164
164
  return (
165
165
  cast(List[SessionInfo], self.list_active_sessions())
166
166
  + self._session_storage.list()