streamlit-nightly 1.35.1.dev20240610__py2.py3-none-any.whl → 1.35.1.dev20240611__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 (113) 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 +7 -7
  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/runtime/app_session.py +7 -7
  56. streamlit/runtime/caching/__init__.py +9 -13
  57. streamlit/runtime/caching/cache_data_api.py +18 -7
  58. streamlit/runtime/caching/cache_errors.py +8 -6
  59. streamlit/runtime/caching/cache_resource_api.py +10 -9
  60. streamlit/runtime/caching/cache_utils.py +10 -7
  61. streamlit/runtime/caching/cached_message_replay.py +10 -9
  62. streamlit/runtime/caching/hashing.py +3 -3
  63. streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
  64. streamlit/runtime/connection_factory.py +4 -2
  65. streamlit/runtime/credentials.py +11 -20
  66. streamlit/runtime/forward_msg_cache.py +10 -11
  67. streamlit/runtime/forward_msg_queue.py +6 -4
  68. streamlit/runtime/fragment.py +7 -9
  69. streamlit/runtime/media_file_manager.py +4 -4
  70. streamlit/runtime/memory_media_file_storage.py +7 -8
  71. streamlit/runtime/metrics_util.py +2 -4
  72. streamlit/runtime/pages_manager.py +41 -41
  73. streamlit/runtime/runtime.py +4 -4
  74. streamlit/runtime/runtime_util.py +7 -12
  75. streamlit/runtime/scriptrunner/magic.py +1 -1
  76. streamlit/runtime/scriptrunner/script_requests.py +4 -2
  77. streamlit/runtime/scriptrunner/script_run_context.py +15 -15
  78. streamlit/runtime/scriptrunner/script_runner.py +8 -8
  79. streamlit/runtime/secrets.py +3 -5
  80. streamlit/runtime/session_manager.py +8 -7
  81. streamlit/runtime/state/common.py +1 -1
  82. streamlit/runtime/state/query_params_proxy.py +5 -10
  83. streamlit/runtime/state/safe_session_state.py +8 -7
  84. streamlit/runtime/state/widgets.py +27 -27
  85. streamlit/runtime/stats.py +1 -1
  86. streamlit/runtime/uploaded_file_manager.py +4 -2
  87. streamlit/runtime/websocket_session_manager.py +6 -4
  88. streamlit/string_util.py +1 -1
  89. streamlit/testing/v1/app_test.py +4 -2
  90. streamlit/testing/v1/element_tree.py +33 -37
  91. streamlit/testing/v1/local_script_runner.py +7 -7
  92. streamlit/time_util.py +2 -4
  93. streamlit/type_util.py +16 -29
  94. streamlit/user_info.py +4 -2
  95. streamlit/util.py +1 -1
  96. streamlit/watcher/event_based_path_watcher.py +6 -3
  97. streamlit/watcher/local_sources_watcher.py +11 -7
  98. streamlit/web/bootstrap.py +1 -1
  99. streamlit/web/cache_storage_manager_config.py +5 -1
  100. streamlit/web/cli.py +9 -4
  101. streamlit/web/server/browser_websocket_handler.py +7 -8
  102. streamlit/web/server/component_request_handler.py +4 -2
  103. streamlit/web/server/routes.py +3 -3
  104. streamlit/web/server/server.py +12 -12
  105. streamlit/web/server/server_util.py +5 -6
  106. streamlit/web/server/stats_request_handler.py +1 -1
  107. streamlit/web/server/upload_file_request_handler.py +5 -3
  108. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240611.dist-info}/METADATA +1 -1
  109. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240611.dist-info}/RECORD +113 -113
  110. {streamlit_nightly-1.35.1.dev20240610.data → streamlit_nightly-1.35.1.dev20240611.data}/scripts/streamlit.cmd +0 -0
  111. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240611.dist-info}/WHEEL +0 -0
  112. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240611.dist-info}/entry_points.txt +0 -0
  113. {streamlit_nightly-1.35.1.dev20240610.dist-info → streamlit_nightly-1.35.1.dev20240611.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """ Declares the CacheStorageContext dataclass, which contains parameter information for
15
+ """Declares the CacheStorageContext dataclass, which contains parameter information for
16
16
  each function decorated by `@st.cache_data` (for example: ttl, max_entries etc.)
17
17
 
18
18
  Declares the CacheStorageManager protocol, which implementations are used
@@ -16,8 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import os
18
18
  import re
19
- from datetime import timedelta
20
- from typing import Any, Final, Literal, TypeVar, overload
19
+ from typing import TYPE_CHECKING, Any, Final, Literal, TypeVar, overload
21
20
 
22
21
  from streamlit.connections import (
23
22
  BaseConnection,
@@ -31,6 +30,9 @@ from streamlit.runtime.caching import cache_resource
31
30
  from streamlit.runtime.metrics_util import gather_metrics
32
31
  from streamlit.runtime.secrets import secrets_singleton
33
32
 
33
+ if TYPE_CHECKING:
34
+ from datetime import timedelta
35
+
34
36
  # NOTE: Adding support for a new first party connection requires:
35
37
  # 1. Adding the new connection name and class to this dict.
36
38
  # 2. Writing two new @overloads for connection_factory (one for the case where the
@@ -20,9 +20,8 @@ import json
20
20
  import os
21
21
  import sys
22
22
  import textwrap
23
- from collections import namedtuple
24
23
  from datetime import datetime
25
- from typing import Final, NoReturn
24
+ from typing import Final, NamedTuple, NoReturn
26
25
  from uuid import uuid4
27
26
 
28
27
  from streamlit import cli_util, env_util, file_util, util
@@ -36,13 +35,10 @@ if env_util.IS_WINDOWS:
36
35
  else:
37
36
  _CONFIG_FILE_PATH = "~/.streamlit/config.toml"
38
37
 
39
- _Activation = namedtuple(
40
- "_Activation",
41
- [
42
- "email", # str : the user's email.
43
- "is_valid", # boolean : whether the email is valid.
44
- ],
45
- )
38
+
39
+ class _Activation(NamedTuple):
40
+ email: str | None # the user's email.
41
+ is_valid: bool # whether the email is valid.
46
42
 
47
43
 
48
44
  def email_prompt() -> str:
@@ -55,19 +51,14 @@ def email_prompt() -> str:
55
51
  )
56
52
 
57
53
  # IMPORTANT: Break the text below at 80 chars.
58
- return """
59
- {0}%(welcome)s
54
+ return f"""
55
+ {"👋 " if show_emoji else ""}{cli_util.style_for_cli("Welcome to Streamlit!", bold=True)}
60
56
 
61
57
  If you’d like to receive helpful onboarding emails, news, offers, promotions,
62
58
  and the occasional swag, please enter your email address below. Otherwise,
63
59
  leave this field blank.
64
60
 
65
- %(email)s""".format(
66
- "👋 " if show_emoji else ""
67
- ) % {
68
- "welcome": cli_util.style_for_cli("Welcome to Streamlit!", bold=True),
69
- "email": cli_util.style_for_cli("Email: ", fg="blue"),
70
- }
61
+ {cli_util.style_for_cli("Email: ", fg="blue")}"""
71
62
 
72
63
 
73
64
  _TELEMETRY_HEADLESS_TEXT = """
@@ -119,10 +110,10 @@ def _send_email(email: str) -> None:
119
110
  response.raise_for_status()
120
111
 
121
112
 
122
- class Credentials(object):
113
+ class Credentials:
123
114
  """Credentials class."""
124
115
 
125
- _singleton: "Credentials" | None = None
116
+ _singleton: Credentials | None = None
126
117
 
127
118
  @classmethod
128
119
  def get_current(cls):
@@ -156,7 +147,7 @@ class Credentials(object):
156
147
  import toml
157
148
 
158
149
  try:
159
- with open(self._conf_file, "r") as f:
150
+ with open(self._conf_file) as f:
160
151
  data = toml.load(f).get("general")
161
152
  if data is None:
162
153
  raise Exception
@@ -111,9 +111,9 @@ class ForwardMsgCache(CacheStatsProvider):
111
111
 
112
112
  def __init__(self, msg: ForwardMsg | None):
113
113
  self.msg = msg
114
- self._session_script_run_counts: MutableMapping[
115
- AppSession, int
116
- ] = WeakKeyDictionary()
114
+ self._session_script_run_counts: MutableMapping[AppSession, int] = (
115
+ WeakKeyDictionary()
116
+ )
117
117
 
118
118
  def __repr__(self) -> str:
119
119
  return util.repr_(self)
@@ -285,13 +285,12 @@ class ForwardMsgCache(CacheStatsProvider):
285
285
  self._entries.clear()
286
286
 
287
287
  def get_stats(self) -> list[CacheStat]:
288
- stats: list[CacheStat] = []
289
- for entry_hash, entry in self._entries.items():
290
- stats.append(
291
- CacheStat(
292
- category_name="ForwardMessageCache",
293
- cache_name="",
294
- byte_length=entry.msg.ByteSize() if entry.msg is not None else 0,
295
- )
288
+ stats: list[CacheStat] = [
289
+ CacheStat(
290
+ category_name="ForwardMessageCache",
291
+ cache_name="",
292
+ byte_length=entry.msg.ByteSize() if entry.msg is not None else 0,
296
293
  )
294
+ for _, entry in self._entries.items()
295
+ ]
297
296
  return group_stats(stats)
@@ -14,11 +14,13 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any
17
+ from typing import TYPE_CHECKING, Any
18
18
 
19
- from streamlit.proto.Delta_pb2 import Delta
20
19
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
21
20
 
21
+ if TYPE_CHECKING:
22
+ from streamlit.proto.Delta_pb2 import Delta
23
+
22
24
 
23
25
  class ForwardMsgQueue:
24
26
  """Accumulates a session's outgoing ForwardMsgs.
@@ -38,7 +40,7 @@ class ForwardMsgQueue:
38
40
  # redundant outgoing Deltas (where a newer Delta supersedes
39
41
  # an older Delta, with the same delta_path, that's still in the
40
42
  # queue).
41
- self._delta_index_map: dict[tuple[int, ...], int] = dict()
43
+ self._delta_index_map: dict[tuple[int, ...], int] = {}
42
44
 
43
45
  def get_debug(self) -> dict[str, Any]:
44
46
  from google.protobuf.json_format import MessageToDict
@@ -102,7 +104,7 @@ class ForwardMsgQueue:
102
104
  }
103
105
  ]
104
106
 
105
- self._delta_index_map = dict()
107
+ self._delta_index_map = {}
106
108
 
107
109
  def flush(self) -> list[ForwardMsg]:
108
110
  """Clear the queue and return a list of the messages it contained
@@ -19,15 +19,17 @@ import hashlib
19
19
  import inspect
20
20
  from abc import abstractmethod
21
21
  from copy import deepcopy
22
- from datetime import timedelta
23
22
  from functools import wraps
24
- from typing import Any, Callable, Protocol, TypeVar, overload
23
+ from typing import TYPE_CHECKING, Any, Callable, Protocol, TypeVar, overload
25
24
 
26
25
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
27
26
  from streamlit.runtime.metrics_util import gather_metrics
28
27
  from streamlit.runtime.scriptrunner import get_script_run_ctx
29
28
  from streamlit.time_util import time_to_seconds
30
29
 
30
+ if TYPE_CHECKING:
31
+ from datetime import timedelta
32
+
31
33
  F = TypeVar("F", bound=Callable[..., Any])
32
34
  Fragment = Callable[[], Any]
33
35
 
@@ -127,9 +129,7 @@ def _fragment(
127
129
  active_dg = dg_stack_snapshot[-1]
128
130
  h = hashlib.new("md5")
129
131
  h.update(
130
- f"{non_optional_func.__module__}.{non_optional_func.__qualname__}{active_dg._get_delta_path_str()}".encode(
131
- "utf-8"
132
- )
132
+ f"{non_optional_func.__module__}.{non_optional_func.__qualname__}{active_dg._get_delta_path_str()}".encode()
133
133
  )
134
134
  fragment_id = h.hexdigest()
135
135
 
@@ -207,8 +207,7 @@ def fragment(
207
207
  func: F,
208
208
  *,
209
209
  run_every: int | float | timedelta | str | None = None,
210
- ) -> F:
211
- ...
210
+ ) -> F: ...
212
211
 
213
212
 
214
213
  # Support being able to pass parameters to this decorator (that is, being able to write
@@ -218,8 +217,7 @@ def fragment(
218
217
  func: None = None,
219
218
  *,
220
219
  run_every: int | float | timedelta | str | None = None,
221
- ) -> Callable[[F], F]:
222
- ...
220
+ ) -> Callable[[F], F]: ...
223
221
 
224
222
 
225
223
  @gather_metrics("experimental_fragment")
@@ -82,12 +82,12 @@ class MediaFileManager:
82
82
  self._storage = storage
83
83
 
84
84
  # Dict of [file_id -> MediaFileMetadata]
85
- self._file_metadata: dict[str, MediaFileMetadata] = dict()
85
+ self._file_metadata: dict[str, MediaFileMetadata] = {}
86
86
 
87
87
  # Dict[session ID][coordinates] -> file_id.
88
- self._files_by_session_and_coord: dict[
89
- str, dict[str, str]
90
- ] = collections.defaultdict(dict)
88
+ self._files_by_session_and_coord: dict[str, dict[str, str]] = (
89
+ collections.defaultdict(dict)
90
+ )
91
91
 
92
92
  # MediaFileManager is used from multiple threads, so all operations
93
93
  # need to be protected with a Lock. (This is not an RLock, which
@@ -171,13 +171,12 @@ class MemoryMediaFileStorage(MediaFileStorage, CacheStatsProvider):
171
171
  # with other threads that may be manipulating the cache.
172
172
  files_by_id = self._files_by_id.copy()
173
173
 
174
- stats: list[CacheStat] = []
175
- for file_id, file in files_by_id.items():
176
- stats.append(
177
- CacheStat(
178
- category_name="st_memory_media_file_storage",
179
- cache_name="",
180
- byte_length=len(file.content),
181
- )
174
+ stats: list[CacheStat] = [
175
+ CacheStat(
176
+ category_name="st_memory_media_file_storage",
177
+ cache_name="",
178
+ byte_length=len(file.content),
182
179
  )
180
+ for _, file in files_by_id.items()
181
+ ]
183
182
  return group_stats(stats)
@@ -306,16 +306,14 @@ F = TypeVar("F", bound=Callable[..., Any])
306
306
  def gather_metrics(
307
307
  name: str,
308
308
  func: F,
309
- ) -> F:
310
- ...
309
+ ) -> F: ...
311
310
 
312
311
 
313
312
  @overload
314
313
  def gather_metrics(
315
314
  name: str,
316
315
  func: None = None,
317
- ) -> Callable[[F], F]:
318
- ...
316
+ ) -> Callable[[F], F]: ...
319
317
 
320
318
 
321
319
  def gather_metrics(name: str, func: F | None = None) -> Callable[[F], F] | F:
@@ -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.