streamlit-nightly 1.35.1.dev20240610__py2.py3-none-any.whl → 1.35.1.dev20240612__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 (121) hide show
  1. streamlit/__init__.py +5 -1
  2. streamlit/case_converters.py +2 -2
  3. streamlit/cli_util.py +2 -2
  4. streamlit/color_util.py +2 -2
  5. streamlit/commands/experimental_query_params.py +6 -8
  6. streamlit/commands/logo.py +4 -9
  7. streamlit/commands/navigation.py +6 -4
  8. streamlit/components/lib/local_component_registry.py +4 -2
  9. streamlit/components/types/base_component_registry.py +3 -2
  10. streamlit/components/v1/component_arrow.py +2 -1
  11. streamlit/components/v1/component_registry.py +6 -2
  12. streamlit/components/v1/components.py +4 -2
  13. streamlit/components/v1/custom_component.py +6 -6
  14. streamlit/config.py +15 -12
  15. streamlit/connections/snowflake_connection.py +2 -1
  16. streamlit/connections/snowpark_connection.py +2 -4
  17. streamlit/connections/sql_connection.py +2 -1
  18. streamlit/delta_generator.py +3 -4
  19. streamlit/elements/arrow.py +3 -6
  20. streamlit/elements/code.py +1 -1
  21. streamlit/elements/dialog_decorator.py +10 -8
  22. streamlit/elements/doc_string.py +1 -1
  23. streamlit/elements/exception.py +1 -1
  24. streamlit/elements/form.py +1 -1
  25. streamlit/elements/heading.py +1 -1
  26. streamlit/elements/html.py +1 -1
  27. streamlit/elements/image.py +5 -3
  28. streamlit/elements/layouts.py +36 -13
  29. streamlit/elements/lib/built_in_chart_utils.py +24 -12
  30. streamlit/elements/lib/column_config_utils.py +2 -1
  31. streamlit/elements/lib/dialog.py +8 -5
  32. streamlit/elements/lib/dicttools.py +3 -3
  33. streamlit/elements/lib/mutable_status_container.py +8 -5
  34. streamlit/elements/lib/pandas_styler_utils.py +2 -1
  35. streamlit/elements/lib/subtitle_utils.py +0 -1
  36. streamlit/elements/lib/utils.py +8 -10
  37. streamlit/elements/plotly_chart.py +5 -10
  38. streamlit/elements/pyplot.py +0 -1
  39. streamlit/elements/toast.py +2 -2
  40. streamlit/elements/vega_charts.py +46 -10
  41. streamlit/elements/widgets/color_picker.py +6 -4
  42. streamlit/elements/widgets/file_uploader.py +4 -8
  43. streamlit/elements/widgets/multiselect.py +2 -4
  44. streamlit/elements/widgets/number_input.py +4 -8
  45. streamlit/elements/widgets/select_slider.py +1 -1
  46. streamlit/elements/widgets/slider.py +2 -5
  47. streamlit/elements/widgets/time_widgets.py +5 -5
  48. streamlit/errors.py +1 -6
  49. streamlit/git_util.py +2 -2
  50. streamlit/hello/Animation_Demo.py +0 -1
  51. streamlit/logger.py +1 -1
  52. streamlit/navigation/page.py +6 -1
  53. streamlit/net_util.py +2 -5
  54. streamlit/proto/AutoRerun_pb2.py +3 -2
  55. streamlit/proto/Block_pb2.py +24 -22
  56. streamlit/proto/Block_pb2.pyi +19 -1
  57. streamlit/runtime/app_session.py +7 -7
  58. streamlit/runtime/caching/__init__.py +9 -13
  59. streamlit/runtime/caching/cache_data_api.py +18 -7
  60. streamlit/runtime/caching/cache_errors.py +8 -6
  61. streamlit/runtime/caching/cache_resource_api.py +10 -9
  62. streamlit/runtime/caching/cache_utils.py +10 -7
  63. streamlit/runtime/caching/cached_message_replay.py +10 -9
  64. streamlit/runtime/caching/hashing.py +3 -3
  65. streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
  66. streamlit/runtime/connection_factory.py +4 -2
  67. streamlit/runtime/credentials.py +11 -20
  68. streamlit/runtime/forward_msg_cache.py +10 -11
  69. streamlit/runtime/forward_msg_queue.py +6 -4
  70. streamlit/runtime/fragment.py +7 -9
  71. streamlit/runtime/media_file_manager.py +4 -4
  72. streamlit/runtime/memory_media_file_storage.py +7 -8
  73. streamlit/runtime/metrics_util.py +2 -4
  74. streamlit/runtime/pages_manager.py +41 -41
  75. streamlit/runtime/runtime.py +4 -4
  76. streamlit/runtime/runtime_util.py +7 -12
  77. streamlit/runtime/scriptrunner/magic.py +1 -1
  78. streamlit/runtime/scriptrunner/script_requests.py +4 -2
  79. streamlit/runtime/scriptrunner/script_run_context.py +15 -15
  80. streamlit/runtime/scriptrunner/script_runner.py +8 -8
  81. streamlit/runtime/secrets.py +3 -5
  82. streamlit/runtime/session_manager.py +8 -7
  83. streamlit/runtime/state/common.py +1 -1
  84. streamlit/runtime/state/query_params_proxy.py +5 -10
  85. streamlit/runtime/state/safe_session_state.py +8 -7
  86. streamlit/runtime/state/widgets.py +27 -27
  87. streamlit/runtime/stats.py +1 -1
  88. streamlit/runtime/uploaded_file_manager.py +4 -2
  89. streamlit/runtime/websocket_session_manager.py +6 -4
  90. streamlit/static/asset-manifest.json +3 -3
  91. streamlit/static/index.html +1 -1
  92. streamlit/static/static/js/{8492.8ad745d1.chunk.js → 4335.b492cdb7.chunk.js} +1 -1
  93. streamlit/static/static/js/main.0ebf040e.js +2 -0
  94. streamlit/string_util.py +1 -1
  95. streamlit/testing/v1/app_test.py +4 -2
  96. streamlit/testing/v1/element_tree.py +33 -37
  97. streamlit/testing/v1/local_script_runner.py +7 -7
  98. streamlit/time_util.py +2 -4
  99. streamlit/type_util.py +16 -29
  100. streamlit/user_info.py +4 -2
  101. streamlit/util.py +1 -1
  102. streamlit/watcher/event_based_path_watcher.py +6 -3
  103. streamlit/watcher/local_sources_watcher.py +11 -7
  104. streamlit/web/bootstrap.py +1 -1
  105. streamlit/web/cache_storage_manager_config.py +5 -1
  106. streamlit/web/cli.py +9 -4
  107. streamlit/web/server/browser_websocket_handler.py +7 -8
  108. streamlit/web/server/component_request_handler.py +4 -2
  109. streamlit/web/server/routes.py +3 -3
  110. streamlit/web/server/server.py +12 -12
  111. streamlit/web/server/server_util.py +5 -6
  112. streamlit/web/server/stats_request_handler.py +1 -1
  113. streamlit/web/server/upload_file_request_handler.py +5 -3
  114. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240612.dist-info}/METADATA +1 -1
  115. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240612.dist-info}/RECORD +120 -120
  116. streamlit/static/static/js/main.dc75074b.js +0 -2
  117. /streamlit/static/static/js/{main.dc75074b.js.LICENSE.txt → main.0ebf040e.js.LICENSE.txt} +0 -0
  118. {streamlit_nightly-1.35.1.dev20240610.data → streamlit_nightly-1.35.1.dev20240612.data}/scripts/streamlit.cmd +0 -0
  119. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240612.dist-info}/WHEEL +0 -0
  120. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240612.dist-info}/entry_points.txt +0 -0
  121. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240612.dist-info}/top_level.txt +0 -0
@@ -18,15 +18,15 @@ import contextlib
18
18
  import os
19
19
  import threading
20
20
  from pathlib import Path
21
- from typing import TYPE_CHECKING, Any, Callable, Final, Type
21
+ from typing import TYPE_CHECKING, Any, Callable, Final
22
22
 
23
23
  from streamlit import source_util
24
24
  from streamlit.logger import get_logger
25
- from streamlit.runtime.scriptrunner.script_cache import ScriptCache
26
25
  from streamlit.util import calc_md5
27
26
  from streamlit.watcher import watch_dir
28
27
 
29
28
  if TYPE_CHECKING:
29
+ from streamlit.runtime.scriptrunner.script_cache import ScriptCache
30
30
  from streamlit.source_util import PageHash, PageInfo, PageName, ScriptPath
31
31
 
32
32
  _LOGGER: Final = get_logger(__name__)
@@ -76,17 +76,17 @@ class PagesStrategyV1:
76
76
 
77
77
  # In MPA v1, there's no difference between the active hash
78
78
  # and the page script hash.
79
- def get_active_script_hash(self) -> "PageHash":
79
+ def get_active_script_hash(self) -> PageHash:
80
80
  return self.pages_manager.current_page_hash
81
81
 
82
- def set_active_script_hash(self, _page_hash: "PageHash"):
82
+ def set_active_script_hash(self, _page_hash: PageHash):
83
83
  # Intentionally do nothing as MPA v1 active_script_hash does not
84
84
  # differentiate the active_script_hash and the page_script_hash
85
85
  pass
86
86
 
87
87
  def get_initial_active_script(
88
- self, page_script_hash: "PageHash", page_name: "PageName"
89
- ) -> "PageInfo" | None:
88
+ self, page_script_hash: PageHash, page_name: PageName
89
+ ) -> PageInfo | None:
90
90
  pages = self.get_pages()
91
91
 
92
92
  if page_script_hash:
@@ -114,7 +114,7 @@ class PagesStrategyV1:
114
114
  main_page_info = list(pages.values())[0]
115
115
  return main_page_info
116
116
 
117
- def get_pages(self) -> dict["PageHash", "PageInfo"]:
117
+ def get_pages(self) -> dict[PageHash, PageInfo]:
118
118
  return source_util.get_pages(self.pages_manager.main_script_path)
119
119
 
120
120
  def register_pages_changed_callback(
@@ -123,10 +123,10 @@ class PagesStrategyV1:
123
123
  ) -> Callable[[], None]:
124
124
  return source_util.register_pages_changed_callback(callback)
125
125
 
126
- def set_pages(self, _pages: dict["PageHash", "PageInfo"]) -> None:
126
+ def set_pages(self, _pages: dict[PageHash, PageInfo]) -> None:
127
127
  raise NotImplementedError("Unable to set pages in this V1 strategy")
128
128
 
129
- def get_page_script(self, _fallback_page_hash: "PageHash") -> "PageInfo" | None:
129
+ def get_page_script(self, _fallback_page_hash: PageHash) -> PageInfo | None:
130
130
  raise NotImplementedError("Unable to get page script in this V1 strategy")
131
131
 
132
132
 
@@ -147,18 +147,18 @@ class PagesStrategyV2:
147
147
 
148
148
  def __init__(self, pages_manager: PagesManager, **kwargs):
149
149
  self.pages_manager = pages_manager
150
- self._active_script_hash: "PageHash" = self.pages_manager.main_script_hash
151
- self._pages: dict["PageHash", "PageInfo"] | None = None
150
+ self._active_script_hash: PageHash = self.pages_manager.main_script_hash
151
+ self._pages: dict[PageHash, PageInfo] | None = None
152
152
 
153
- def get_active_script_hash(self) -> "PageHash":
153
+ def get_active_script_hash(self) -> PageHash:
154
154
  return self._active_script_hash
155
155
 
156
- def set_active_script_hash(self, page_hash: "PageHash"):
156
+ def set_active_script_hash(self, page_hash: PageHash):
157
157
  self._active_script_hash = page_hash
158
158
 
159
159
  def get_initial_active_script(
160
- self, page_script_hash: "PageHash", page_name: "PageName"
161
- ) -> "PageInfo":
160
+ self, page_script_hash: PageHash, page_name: PageName
161
+ ) -> PageInfo:
162
162
  return {
163
163
  # We always run the main script in V2 as it's the common code
164
164
  "script_path": self.pages_manager.main_script_path,
@@ -166,7 +166,7 @@ class PagesStrategyV2:
166
166
  or self.pages_manager.main_script_hash, # Default Hash
167
167
  }
168
168
 
169
- def get_page_script(self, fallback_page_hash: "PageHash") -> "PageInfo" | None:
169
+ def get_page_script(self, fallback_page_hash: PageHash) -> PageInfo | None:
170
170
  if self._pages is None:
171
171
  return None
172
172
 
@@ -196,7 +196,7 @@ class PagesStrategyV2:
196
196
 
197
197
  return self._pages.get(fallback_page_hash, None)
198
198
 
199
- def get_pages(self) -> dict["PageHash", "PageInfo"]:
199
+ def get_pages(self) -> dict[PageHash, PageInfo]:
200
200
  # If pages are not set, provide the common page info where
201
201
  # - the main script path is the executing script to start
202
202
  # - the page script hash and name reflects the intended page requested
@@ -209,7 +209,7 @@ class PagesStrategyV2:
209
209
  }
210
210
  }
211
211
 
212
- def set_pages(self, pages: dict["PageHash", "PageInfo"]) -> None:
212
+ def set_pages(self, pages: dict[PageHash, PageInfo]) -> None:
213
213
  self._pages = pages
214
214
 
215
215
  def register_pages_changed_callback(
@@ -233,60 +233,60 @@ class PagesManager:
233
233
  NOTE: Each strategy handles its own thread safety when accessing the pages
234
234
  """
235
235
 
236
- DefaultStrategy: Type[PagesStrategyV1 | PagesStrategyV2] = PagesStrategyV1
236
+ DefaultStrategy: type[PagesStrategyV1 | PagesStrategyV2] = PagesStrategyV1
237
237
 
238
238
  def __init__(
239
239
  self,
240
- main_script_path: "ScriptPath",
240
+ main_script_path: ScriptPath,
241
241
  script_cache: ScriptCache | None = None,
242
242
  **kwargs,
243
243
  ):
244
244
  self._main_script_path = main_script_path
245
- self._main_script_hash: "PageHash" = calc_md5(main_script_path)
246
- self._current_page_hash: "PageHash" = self._main_script_hash
245
+ self._main_script_hash: PageHash = calc_md5(main_script_path)
246
+ self._current_page_hash: PageHash = self._main_script_hash
247
247
  self.pages_strategy = PagesManager.DefaultStrategy(self, **kwargs)
248
248
  self._script_cache = script_cache
249
- self._intended_page_script_hash: "PageHash" | None = None
250
- self._intended_page_name: "PageName" | None = None
249
+ self._intended_page_script_hash: PageHash | None = None
250
+ self._intended_page_name: PageName | None = None
251
251
 
252
252
  @property
253
- def current_page_hash(self) -> "PageHash":
253
+ def current_page_hash(self) -> PageHash:
254
254
  return self._current_page_hash
255
255
 
256
256
  @property
257
- def main_script_path(self) -> "ScriptPath":
257
+ def main_script_path(self) -> ScriptPath:
258
258
  return self._main_script_path
259
259
 
260
260
  @property
261
- def main_script_hash(self) -> "PageHash":
261
+ def main_script_hash(self) -> PageHash:
262
262
  return self._main_script_hash
263
263
 
264
264
  @property
265
- def intended_page_name(self) -> "PageName" | None:
265
+ def intended_page_name(self) -> PageName | None:
266
266
  return self._intended_page_name
267
267
 
268
268
  @property
269
- def intended_page_script_hash(self) -> "PageHash" | None:
269
+ def intended_page_script_hash(self) -> PageHash | None:
270
270
  return self._intended_page_script_hash
271
271
 
272
- def get_main_page(self) -> "PageInfo":
272
+ def get_main_page(self) -> PageInfo:
273
273
  return {
274
274
  "script_path": self._main_script_path,
275
275
  "page_script_hash": self._main_script_hash,
276
276
  }
277
277
 
278
- def get_current_page_script_hash(self) -> "PageHash":
278
+ def get_current_page_script_hash(self) -> PageHash:
279
279
  """Gets the script hash of the associated page of a script."""
280
280
  return self._current_page_hash
281
281
 
282
- def set_current_page_script_hash(self, page_hash: "PageHash") -> None:
282
+ def set_current_page_script_hash(self, page_hash: PageHash) -> None:
283
283
  self._current_page_hash = page_hash
284
284
 
285
- def get_active_script_hash(self) -> "PageHash":
285
+ def get_active_script_hash(self) -> PageHash:
286
286
  """Gets the script hash of the currently executing script."""
287
287
  return self.pages_strategy.get_active_script_hash()
288
288
 
289
- def set_active_script_hash(self, page_hash: "PageHash"):
289
+ def set_active_script_hash(self, page_hash: PageHash):
290
290
  return self.pages_strategy.set_active_script_hash(page_hash)
291
291
 
292
292
  def reset_active_script_hash(self):
@@ -294,20 +294,20 @@ class PagesManager:
294
294
  self.set_active_script_hash(self.main_script_hash)
295
295
 
296
296
  def set_script_intent(
297
- self, page_script_hash: "PageHash", page_name: "PageName"
297
+ self, page_script_hash: PageHash, page_name: PageName
298
298
  ) -> None:
299
299
  self._intended_page_script_hash = page_script_hash
300
300
  self._intended_page_name = page_name
301
301
 
302
302
  def get_initial_active_script(
303
- self, page_script_hash: "PageHash", page_name: "PageName"
304
- ) -> "PageInfo" | None:
303
+ self, page_script_hash: PageHash, page_name: PageName
304
+ ) -> PageInfo | None:
305
305
  return self.pages_strategy.get_initial_active_script(
306
306
  page_script_hash, page_name
307
307
  )
308
308
 
309
309
  @contextlib.contextmanager
310
- def run_with_active_hash(self, page_hash: "PageHash"):
310
+ def run_with_active_hash(self, page_hash: PageHash):
311
311
  original_page_hash = self.get_active_script_hash()
312
312
  self.set_active_script_hash(page_hash)
313
313
  try:
@@ -316,10 +316,10 @@ class PagesManager:
316
316
  # in the event of any exception, ensure we set the active hash back
317
317
  self.set_active_script_hash(original_page_hash)
318
318
 
319
- def get_pages(self) -> dict["PageHash", "PageInfo"]:
319
+ def get_pages(self) -> dict[PageHash, PageInfo]:
320
320
  return self.pages_strategy.get_pages()
321
321
 
322
- def set_pages(self, pages: dict["PageHash", "PageInfo"]) -> None:
322
+ def set_pages(self, pages: dict[PageHash, PageInfo]) -> None:
323
323
  # Manually setting the pages indicates we are using MPA v2.
324
324
  if isinstance(self.pages_strategy, PagesStrategyV1):
325
325
  if os.path.exists(Path(self.main_script_path).parent / "pages"):
@@ -331,7 +331,7 @@ class PagesManager:
331
331
 
332
332
  self.pages_strategy.set_pages(pages)
333
333
 
334
- def get_page_script(self, fallback_page_hash: "PageHash" = "") -> "PageInfo" | None:
334
+ def get_page_script(self, fallback_page_hash: PageHash = "") -> PageInfo | None:
335
335
  # We assume the pages strategy is V2 cause this is used
336
336
  # in the st.navigation call, but we just swallow the error
337
337
  try:
@@ -23,9 +23,7 @@ from typing import TYPE_CHECKING, Awaitable, Final, NamedTuple
23
23
 
24
24
  from streamlit import config
25
25
  from streamlit.components.lib.local_component_registry import LocalComponentRegistry
26
- from streamlit.components.types.base_component_registry import BaseComponentRegistry
27
26
  from streamlit.logger import get_logger
28
- from streamlit.proto.BackMsg_pb2 import BackMsg
29
27
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
30
28
  from streamlit.runtime.app_session import AppSession
31
29
  from streamlit.runtime.caching import (
@@ -41,7 +39,6 @@ from streamlit.runtime.forward_msg_cache import (
41
39
  populate_hash_if_needed,
42
40
  )
43
41
  from streamlit.runtime.media_file_manager import MediaFileManager
44
- from streamlit.runtime.media_file_storage import MediaFileStorage
45
42
  from streamlit.runtime.memory_session_storage import MemorySessionStorage
46
43
  from streamlit.runtime.runtime_util import is_cacheable_msg
47
44
  from streamlit.runtime.script_data import ScriptData
@@ -58,11 +55,14 @@ from streamlit.runtime.state import (
58
55
  SessionStateStatProvider,
59
56
  )
60
57
  from streamlit.runtime.stats import StatsManager
61
- from streamlit.runtime.uploaded_file_manager import UploadedFileManager
62
58
  from streamlit.runtime.websocket_session_manager import WebsocketSessionManager
63
59
 
64
60
  if TYPE_CHECKING:
61
+ from streamlit.components.types.base_component_registry import BaseComponentRegistry
62
+ from streamlit.proto.BackMsg_pb2 import BackMsg
65
63
  from streamlit.runtime.caching.storage import CacheStorageManager
64
+ from streamlit.runtime.media_file_storage import MediaFileStorage
65
+ from streamlit.runtime.uploaded_file_manager import UploadedFileManager
66
66
 
67
67
  # Wait for the script run result for 60s and if no result is available give up
68
68
  SCRIPT_RUN_CHECK_TIMEOUT: Final = 60
@@ -16,13 +16,15 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import Any
19
+ from typing import TYPE_CHECKING, Any
20
20
 
21
21
  from streamlit import config
22
22
  from streamlit.errors import MarkdownFormattedException, StreamlitAPIException
23
- from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
24
23
  from streamlit.runtime.forward_msg_cache import populate_hash_if_needed
25
24
 
25
+ if TYPE_CHECKING:
26
+ from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
27
+
26
28
 
27
29
  class MessageSizeError(MarkdownFormattedException):
28
30
  """Exception raised when a websocket message is larger than the configured limit."""
@@ -34,9 +36,8 @@ class MessageSizeError(MarkdownFormattedException):
34
36
  def _get_message(self, failed_msg_str: Any) -> str:
35
37
  # This needs to have zero indentation otherwise the markdown will render incorrectly.
36
38
  return (
37
- (
38
- """
39
- **Data of size {message_size_mb:.1f} MB exceeds the message size limit of {message_size_limit_mb} MB.**
39
+ f"""
40
+ **Data of size {len(failed_msg_str) / 1e6:.1f} MB exceeds the message size limit of {get_max_message_size_bytes() / 1e6} MB.**
40
41
 
41
42
  This is often caused by a large chart or dataframe. Please decrease the amount of data sent
42
43
  to the browser, or increase the limit by setting the config option `server.maxMessageSize`.
@@ -45,13 +46,7 @@ to the browser, or increase the limit by setting the config option `server.maxMe
45
46
  _Note that increasing the limit may lead to long loading times and large memory consumption
46
47
  of the client's browser and the Streamlit server._
47
48
  """
48
- )
49
- .format(
50
- message_size_mb=len(failed_msg_str) / 1e6,
51
- message_size_limit_mb=(get_max_message_size_bytes() / 1e6),
52
- )
53
- .strip("\n")
54
- )
49
+ ).strip("\n")
55
50
 
56
51
 
57
52
  class BadDurationStringError(StreamlitAPIException):
@@ -229,7 +229,7 @@ def _get_st_write_from_expr(
229
229
 
230
230
 
231
231
  def _is_string_constant_node(node) -> bool:
232
- return type(node) is ast.Constant and type(node.value) is str
232
+ return isinstance(node, ast.Constant) and isinstance(node.value, str)
233
233
 
234
234
 
235
235
  def _is_docstring_node(node, node_index, parent_type) -> bool:
@@ -17,12 +17,14 @@ from __future__ import annotations
17
17
  import threading
18
18
  from dataclasses import dataclass, field
19
19
  from enum import Enum
20
- from typing import cast
20
+ from typing import TYPE_CHECKING, cast
21
21
 
22
22
  from streamlit import util
23
- from streamlit.proto.WidgetStates_pb2 import WidgetStates
24
23
  from streamlit.runtime.state import coalesce_widget_states
25
24
 
25
+ if TYPE_CHECKING:
26
+ from streamlit.proto.WidgetStates_pb2 import WidgetStates
27
+
26
28
 
27
29
  class ScriptRequestType(Enum):
28
30
  # The ScriptRunner should continue running its script.
@@ -25,16 +25,16 @@ from typing_extensions import TypeAlias
25
25
  from streamlit import runtime
26
26
  from streamlit.errors import StreamlitAPIException
27
27
  from streamlit.logger import get_logger
28
- from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
29
- from streamlit.proto.PageProfile_pb2 import Command
30
- from streamlit.runtime.scriptrunner.script_requests import ScriptRequests
31
- from streamlit.runtime.state import SafeSessionState
32
- from streamlit.runtime.uploaded_file_manager import UploadedFileManager
33
28
 
34
29
  if TYPE_CHECKING:
30
+ from streamlit.cursor import RunningCursor
31
+ from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
32
+ from streamlit.proto.PageProfile_pb2 import Command
35
33
  from streamlit.runtime.fragment import FragmentStorage
36
34
  from streamlit.runtime.pages_manager import PagesManager
37
-
35
+ from streamlit.runtime.scriptrunner.script_requests import ScriptRequests
36
+ from streamlit.runtime.state import SafeSessionState
37
+ from streamlit.runtime.uploaded_file_manager import UploadedFileManager
38
38
  _LOGGER: Final = get_logger(__name__)
39
39
 
40
40
  UserInfo: TypeAlias = Dict[str, Union[str, None]]
@@ -62,8 +62,8 @@ class ScriptRunContext:
62
62
  uploaded_file_mgr: UploadedFileManager
63
63
  main_script_path: str
64
64
  user_info: UserInfo
65
- fragment_storage: "FragmentStorage"
66
- pages_manager: "PagesManager"
65
+ fragment_storage: FragmentStorage
66
+ pages_manager: PagesManager
67
67
 
68
68
  gather_usage_stats: bool = False
69
69
  command_tracking_deactivated: bool = False
@@ -74,7 +74,7 @@ class ScriptRunContext:
74
74
  widget_ids_this_run: set[str] = field(default_factory=set)
75
75
  widget_user_keys_this_run: set[str] = field(default_factory=set)
76
76
  form_ids_this_run: set[str] = field(default_factory=set)
77
- cursors: dict[int, "streamlit.cursor.RunningCursor"] = field(default_factory=dict)
77
+ cursors: dict[int, RunningCursor] = field(default_factory=dict)
78
78
  script_requests: ScriptRequests | None = None
79
79
  current_fragment_id: str | None = None
80
80
  fragment_ids_this_run: set[str] | None = None
@@ -139,9 +139,9 @@ class ScriptRunContext:
139
139
  if msg.HasField("page_config_changed") and not self._set_page_config_allowed:
140
140
  raise StreamlitAPIException(
141
141
  "`set_page_config()` can only be called once per app page, "
142
- + "and must be called as the first Streamlit command in your script.\n\n"
143
- + "For more information refer to the [docs]"
144
- + "(https://docs.streamlit.io/library/api-reference/utilities/st.set_page_config)."
142
+ "and must be called as the first Streamlit command in your script.\n\n"
143
+ "For more information refer to the [docs]"
144
+ "(https://docs.streamlit.io/library/api-reference/utilities/st.set_page_config)."
145
145
  )
146
146
 
147
147
  # We want to disallow set_page config if one of the following occurs:
@@ -161,8 +161,8 @@ class ScriptRunContext:
161
161
  if self._experimental_query_params_used and self._production_query_params_used:
162
162
  raise StreamlitAPIException(
163
163
  "Using `st.query_params` together with either `st.experimental_get_query_params` "
164
- + "or `st.experimental_set_query_params` is not supported. Please convert your app "
165
- + "to only use `st.query_params`"
164
+ "or `st.experimental_set_query_params` is not supported. Please convert your app "
165
+ "to only use `st.query_params`"
166
166
  )
167
167
 
168
168
  def mark_experimental_query_params_used(self):
@@ -233,4 +233,4 @@ def get_script_run_ctx(suppress_warning: bool = False) -> ScriptRunContext | Non
233
233
 
234
234
 
235
235
  # Needed to avoid circular dependencies while running tests.
236
- import streamlit
236
+ import streamlit # noqa: E402, F401
@@ -25,12 +25,11 @@ from typing import TYPE_CHECKING, Callable, Final
25
25
 
26
26
  from blinker import Signal
27
27
 
28
- from streamlit import config, runtime, source_util, util
28
+ from streamlit import config, runtime, util
29
29
  from streamlit.error_util import handle_uncaught_app_exception
30
30
  from streamlit.logger import get_logger
31
31
  from streamlit.proto.ClientState_pb2 import ClientState
32
32
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
33
- from streamlit.runtime.scriptrunner.script_cache import ScriptCache
34
33
  from streamlit.runtime.scriptrunner.script_requests import (
35
34
  RerunData,
36
35
  ScriptRequests,
@@ -46,18 +45,19 @@ from streamlit.runtime.state import (
46
45
  SafeSessionState,
47
46
  SessionState,
48
47
  )
49
- from streamlit.runtime.uploaded_file_manager import UploadedFileManager
50
48
  from streamlit.vendor.ipython.modified_sys_path import modified_sys_path
51
49
 
52
50
  if TYPE_CHECKING:
53
51
  from streamlit.runtime.fragment import FragmentStorage
54
52
  from streamlit.runtime.pages_manager import PagesManager
53
+ from streamlit.runtime.scriptrunner.script_cache import ScriptCache
54
+ from streamlit.runtime.uploaded_file_manager import UploadedFileManager
55
55
 
56
56
  _LOGGER: Final = get_logger(__name__)
57
57
 
58
58
 
59
59
  class ScriptRunnerEvent(Enum):
60
- ## "Control" events. These are emitted when the ScriptRunner's state changes.
60
+ # "Control" events. These are emitted when the ScriptRunner's state changes.
61
61
 
62
62
  # The script started running.
63
63
  SCRIPT_STARTED = "SCRIPT_STARTED"
@@ -80,8 +80,8 @@ class ScriptRunnerEvent(Enum):
80
80
  # is shut down.
81
81
  SHUTDOWN = "SHUTDOWN"
82
82
 
83
- ## "Data" events. These are emitted when the ScriptRunner's script has
84
- ## data to send to the frontend.
83
+ # "Data" events. These are emitted when the ScriptRunner's script has
84
+ # data to send to the frontend.
85
85
 
86
86
  # The script has a ForwardMsg to send to the frontend.
87
87
  ENQUEUE_FORWARD_MSG = "ENQUEUE_FORWARD_MSG"
@@ -114,8 +114,8 @@ class ScriptRunner:
114
114
  script_cache: ScriptCache,
115
115
  initial_rerun_data: RerunData,
116
116
  user_info: dict[str, str | None],
117
- fragment_storage: "FragmentStorage",
118
- pages_manager: "PagesManager",
117
+ fragment_storage: FragmentStorage,
118
+ pages_manager: PagesManager,
119
119
  ):
120
120
  """Initialize the ScriptRunner.
121
121
 
@@ -25,7 +25,6 @@ from typing import (
25
25
  KeysView,
26
26
  Mapping,
27
27
  NoReturn,
28
- Union,
29
28
  ValuesView,
30
29
  )
31
30
 
@@ -45,12 +44,11 @@ SECRETS_FILE_LOCS: Final[list[str]] = [
45
44
  ]
46
45
 
47
46
 
48
- def _convert_to_dict(obj: Union[Mapping[str, Any], AttrDict]) -> dict[str, Any]:
49
- """Recursively convert Mapping or AttrDict objects to dictionaries."""
47
+ def _convert_to_dict(obj: Mapping[str, Any] | AttrDict) -> dict[str, Any]:
48
+ """Convert Mapping or AttrDict objects to dictionaries."""
50
49
  if isinstance(obj, AttrDict):
51
50
  return obj.to_dict()
52
- elif isinstance(obj, Mapping):
53
- return {k: _convert_to_dict(v) for k, v in obj.items()}
51
+ return {k: v.to_dict() if isinstance(v, AttrDict) else v for k, v in obj.items()}
54
52
 
55
53
 
56
54
  def _missing_attr_error_message(attr_name: str) -> str:
@@ -16,13 +16,14 @@ from __future__ import annotations
16
16
 
17
17
  from abc import abstractmethod
18
18
  from dataclasses import dataclass
19
- from typing import Callable, Protocol, cast
20
-
21
- from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
22
- from streamlit.runtime.app_session import AppSession
23
- from streamlit.runtime.script_data import ScriptData
24
- from streamlit.runtime.scriptrunner.script_cache import ScriptCache
25
- from streamlit.runtime.uploaded_file_manager import UploadedFileManager
19
+ from typing import TYPE_CHECKING, Callable, Protocol, cast
20
+
21
+ if TYPE_CHECKING:
22
+ from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
23
+ from streamlit.runtime.app_session import AppSession
24
+ from streamlit.runtime.script_data import ScriptData
25
+ from streamlit.runtime.scriptrunner.script_cache import ScriptCache
26
+ from streamlit.runtime.uploaded_file_manager import UploadedFileManager
26
27
 
27
28
 
28
29
  class SessionClientDisconnectedError(Exception):
@@ -57,7 +57,6 @@ from streamlit.proto.Slider_pb2 import Slider
57
57
  from streamlit.proto.TextArea_pb2 import TextArea
58
58
  from streamlit.proto.TextInput_pb2 import TextInput
59
59
  from streamlit.proto.TimeInput_pb2 import TimeInput
60
- from streamlit.type_util import ValueFieldName
61
60
  from streamlit.util import HASHLIB_KWARGS
62
61
 
63
62
  if TYPE_CHECKING:
@@ -65,6 +64,7 @@ if TYPE_CHECKING:
65
64
 
66
65
  from streamlit.runtime.scriptrunner.script_run_context import ScriptRunContext
67
66
  from streamlit.runtime.state.widgets import NoValue
67
+ from streamlit.type_util import ValueFieldName
68
68
 
69
69
 
70
70
  # Protobuf types for all widgets.
@@ -74,18 +74,15 @@ class QueryParamsProxy(MutableMapping[str, str]):
74
74
  @overload
75
75
  def update(
76
76
  self, mapping: SupportsKeysAndGetItem[str, str | Iterable[str]], /, **kwds: str
77
- ) -> None:
78
- ...
77
+ ) -> None: ...
79
78
 
80
79
  @overload
81
80
  def update(
82
81
  self, keys_and_values: Iterable[tuple[str, str | Iterable[str]]], /, **kwds: str
83
- ) -> None:
84
- ...
82
+ ) -> None: ...
85
83
 
86
84
  @overload
87
- def update(self, **kwds: str | Iterable[str]) -> None:
88
- ...
85
+ def update(self, **kwds: str | Iterable[str]) -> None: ...
89
86
 
90
87
  def update(self, other=(), /, **kwds):
91
88
  """
@@ -167,14 +164,12 @@ class QueryParamsProxy(MutableMapping[str, str]):
167
164
  @overload
168
165
  def from_dict(
169
166
  self, keys_and_values: Iterable[tuple[str, str | Iterable[str]]]
170
- ) -> None:
171
- ...
167
+ ) -> None: ...
172
168
 
173
169
  @overload
174
170
  def from_dict(
175
171
  self, mapping: SupportsKeysAndGetItem[str, str | Iterable[str]]
176
- ) -> None:
177
- ...
172
+ ) -> None: ...
178
173
 
179
174
  @gather_metrics("query_params.from_dict")
180
175
  def from_dict(self, params):
@@ -16,13 +16,14 @@ from __future__ import annotations
16
16
 
17
17
  import threading
18
18
  from contextlib import contextmanager
19
- from typing import Any, Callable, Iterator
20
-
21
- from streamlit.proto.WidgetStates_pb2 import WidgetState as WidgetStateProto
22
- from streamlit.proto.WidgetStates_pb2 import WidgetStates as WidgetStatesProto
23
- from streamlit.runtime.state.common import RegisterWidgetResult, T, WidgetMetadata
24
- from streamlit.runtime.state.query_params import QueryParams
25
- from streamlit.runtime.state.session_state import SessionState
19
+ from typing import TYPE_CHECKING, Any, Callable, Iterator
20
+
21
+ if TYPE_CHECKING:
22
+ from streamlit.proto.WidgetStates_pb2 import WidgetState as WidgetStateProto
23
+ from streamlit.proto.WidgetStates_pb2 import WidgetStates as WidgetStatesProto
24
+ from streamlit.runtime.state.common import RegisterWidgetResult, T, WidgetMetadata
25
+ from streamlit.runtime.state.query_params import QueryParams
26
+ from streamlit.runtime.state.session_state import SessionState
26
27
 
27
28
 
28
29
  class SafeSessionState: