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
@@ -12,10 +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 re
18
+ from typing import Any, Callable
16
19
 
17
20
 
18
- def to_upper_camel_case(snake_case_str):
21
+ def to_upper_camel_case(snake_case_str: str) -> str:
19
22
  """Converts snake_case to UpperCamelCase.
20
23
 
21
24
  Example
@@ -26,7 +29,7 @@ def to_upper_camel_case(snake_case_str):
26
29
  return "".join(map(str.title, snake_case_str.split("_")))
27
30
 
28
31
 
29
- def to_lower_camel_case(snake_case_str):
32
+ def to_lower_camel_case(snake_case_str: str) -> str:
30
33
  """Converts snake_case to lowerCamelCase.
31
34
 
32
35
  Example
@@ -44,7 +47,7 @@ def to_lower_camel_case(snake_case_str):
44
47
  return snake_case_str
45
48
 
46
49
 
47
- def to_snake_case(camel_case_str):
50
+ def to_snake_case(camel_case_str: str) -> str:
48
51
  """Converts UpperCamelCase and lowerCamelCase to snake_case.
49
52
 
50
53
  Examples
@@ -57,7 +60,9 @@ def to_snake_case(camel_case_str):
57
60
  return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()
58
61
 
59
62
 
60
- def convert_dict_keys(func, in_dict):
63
+ def convert_dict_keys(
64
+ func: Callable[[str], str], in_dict: dict[Any, Any]
65
+ ) -> dict[Any, Any]:
61
66
  """Apply a conversion function to all keys in a dict.
62
67
 
63
68
  Parameters
streamlit/cli_util.py CHANGED
@@ -14,6 +14,8 @@
14
14
 
15
15
  """ Utilities related to the CLI."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
 
18
20
  def print_to_cli(message: str, **kwargs) -> None:
19
21
  """Print a message to the terminal using click if available, else print
streamlit/code_util.py CHANGED
@@ -14,10 +14,13 @@
14
14
 
15
15
  """A bunch of useful code utilities."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  import re
20
+ from typing import Any
18
21
 
19
22
 
20
- def extract_args(line):
23
+ def extract_args(line: str) -> list[str]:
21
24
  """Parse argument strings from all outer parentheses in a line of code.
22
25
 
23
26
  Parameters
@@ -53,7 +56,7 @@ def extract_args(line):
53
56
  return results
54
57
 
55
58
 
56
- def get_method_args_from_code(args, line):
59
+ def get_method_args_from_code(args: list[Any], line: str) -> list[str]:
57
60
  """Parse arguments from a stringified arguments list inside parentheses
58
61
 
59
62
  Parameters
streamlit/color_util.py CHANGED
@@ -12,6 +12,8 @@
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 typing import Any, Callable, Collection, Tuple, Union, cast
16
18
 
17
19
  from typing_extensions import TypeAlias
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Column types that can be configured via the ``column_config`` parameter of ``st.dataframe`` and ``st.data_editor``."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  __all__ = [
18
20
  "Column",
19
21
  "TextColumn",
@@ -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
  import os
16
- from typing import NoReturn
18
+ from typing import Final, NoReturn
17
19
 
18
20
  import streamlit as st
19
21
  from streamlit import source_util
@@ -24,7 +26,7 @@ from streamlit.logger import get_logger
24
26
  from streamlit.runtime.metrics_util import gather_metrics
25
27
  from streamlit.runtime.scriptrunner import RerunData, get_script_run_ctx
26
28
 
27
- _LOGGER = get_logger(__name__)
29
+ _LOGGER: Final = get_logger(__name__)
28
30
 
29
31
 
30
32
  @gather_metrics("stop")
@@ -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
  import urllib.parse as parse
16
- from typing import Any, Dict, List, Union
18
+ from typing import Any
17
19
 
18
20
  from streamlit import util
19
21
  from streamlit.constants import (
@@ -28,7 +30,7 @@ from streamlit.runtime.scriptrunner import get_script_run_ctx
28
30
 
29
31
 
30
32
  @gather_metrics("experimental_get_query_params")
31
- def get_query_params() -> Dict[str, List[str]]:
33
+ def get_query_params() -> dict[str, list[str]]:
32
34
  """Return the query parameters that is currently showing in the browser's URL bar.
33
35
 
34
36
  Returns
@@ -106,10 +108,11 @@ def set_query_params(**query_params: Any) -> None:
106
108
 
107
109
 
108
110
  def _ensure_no_embed_params(
109
- query_params: Dict[str, Union[List[str], str]], query_string: str
111
+ query_params: dict[str, list[str] | str], query_string: str
110
112
  ) -> str:
111
113
  """Ensures there are no embed params set (raises StreamlitAPIException) if there is a try,
112
- also makes sure old param values in query_string are preserved. Returns query_string : str."""
114
+ also makes sure old param values in query_string are preserved. Returns query_string : str.
115
+ """
113
116
  # Get query params dict without embed, embed_options params
114
117
  query_params_without_embed = util.exclude_keys_in_dict(
115
118
  query_params, keys_to_exclude=EMBED_QUERY_PARAMS_KEYS
@@ -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 random
16
18
  from textwrap import dedent
17
- from typing import TYPE_CHECKING, Mapping, Optional, Union, cast
19
+ from typing import TYPE_CHECKING, Final, Literal, Mapping, Union, cast
18
20
 
19
- from typing_extensions import Final, Literal, TypeAlias
21
+ from typing_extensions import TypeAlias
20
22
 
21
23
  from streamlit.elements import image
22
24
  from streamlit.errors import StreamlitAPIException
@@ -42,7 +44,7 @@ _GetHelp: TypeAlias = Literal["Get help", "Get Help", "get help"]
42
44
  _ReportABug: TypeAlias = Literal["Report a bug", "report a bug"]
43
45
  _About: TypeAlias = Literal["About", "about"]
44
46
  MenuKey: TypeAlias = Literal[_GetHelp, _ReportABug, _About]
45
- MenuItems: TypeAlias = Mapping[MenuKey, Optional[str]]
47
+ MenuItems: TypeAlias = Mapping[MenuKey, Union[str, None]]
46
48
 
47
49
  # Emojis recommended by https://share.streamlit.io/rensdimmendaal/emoji-recommender/main/app/streamlit.py
48
50
  # for the term "streamlit". Watch out for zero-width joiners,
@@ -113,11 +115,11 @@ def _get_favicon_string(page_icon: PageIcon) -> str:
113
115
 
114
116
  @gather_metrics("set_page_config")
115
117
  def set_page_config(
116
- page_title: Optional[str] = None,
117
- page_icon: Optional[PageIcon] = None,
118
+ page_title: str | None = None,
119
+ page_icon: PageIcon | None = None,
118
120
  layout: Layout = "centered",
119
121
  initial_sidebar_state: InitialSideBarState = "auto",
120
- menu_items: Optional[MenuItems] = None,
122
+ menu_items: MenuItems | None = None,
121
123
  ) -> None:
122
124
  """
123
125
  Configures the default settings of the page.
@@ -188,7 +190,7 @@ def set_page_config(
188
190
  if page_icon is not None:
189
191
  msg.page_config_changed.favicon = _get_favicon_string(page_icon)
190
192
 
191
- pb_layout: "PageConfigProto.Layout.ValueType"
193
+ pb_layout: PageConfigProto.Layout.ValueType
192
194
  if layout == "centered":
193
195
  pb_layout = PageConfigProto.CENTERED
194
196
  elif layout == "wide":
@@ -199,7 +201,7 @@ def set_page_config(
199
201
  )
200
202
  msg.page_config_changed.layout = pb_layout
201
203
 
202
- pb_sidebar_state: "PageConfigProto.SidebarState.ValueType"
204
+ pb_sidebar_state: PageConfigProto.SidebarState.ValueType
203
205
  if initial_sidebar_state == "auto":
204
206
  pb_sidebar_state = PageConfigProto.AUTO
205
207
  elif initial_sidebar_state == "expanded":
@@ -265,5 +267,5 @@ def validate_menu_items(menu_items: MenuItems) -> None:
265
267
  raise StreamlitAPIException(f'"{v}" is a not a valid URL!')
266
268
 
267
269
 
268
- def valid_menu_item_key(key: str) -> "TypeGuard[MenuKey]":
270
+ def valid_menu_item_key(key: str) -> TypeGuard[MenuKey]:
269
271
  return key in {GET_HELP_KEY, REPORT_A_BUG_KEY, ABOUT_KEY}
@@ -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 inspect
16
18
  import json
17
19
  import os
18
20
  import threading
19
- from typing import Any, Dict, Optional, Type, Union
21
+ from typing import TYPE_CHECKING, Any, Final
20
22
 
21
23
  import streamlit
22
24
  from streamlit import type_util, util
@@ -32,7 +34,10 @@ from streamlit.runtime.state import NoValue, register_widget
32
34
  from streamlit.runtime.state.common import compute_widget_id
33
35
  from streamlit.type_util import to_bytes
34
36
 
35
- LOGGER = get_logger(__name__)
37
+ if TYPE_CHECKING:
38
+ from streamlit.delta_generator import DeltaGenerator
39
+
40
+ _LOGGER: Final = get_logger(__name__)
36
41
 
37
42
 
38
43
  class MarshallComponentException(StreamlitAPIException):
@@ -47,8 +52,8 @@ class CustomComponent:
47
52
  def __init__(
48
53
  self,
49
54
  name: str,
50
- path: Optional[str] = None,
51
- url: Optional[str] = None,
55
+ path: str | None = None,
56
+ url: str | None = None,
52
57
  ):
53
58
  if (path is None and url is None) or (path is not None and url is not None):
54
59
  raise StreamlitAPIException(
@@ -63,7 +68,7 @@ class CustomComponent:
63
68
  return util.repr_(self)
64
69
 
65
70
  @property
66
- def abspath(self) -> Optional[str]:
71
+ def abspath(self) -> str | None:
67
72
  """The absolute path that the component is served from."""
68
73
  if self.path is None:
69
74
  return None
@@ -73,7 +78,7 @@ class CustomComponent:
73
78
  self,
74
79
  *args,
75
80
  default: Any = None,
76
- key: Optional[str] = None,
81
+ key: str | None = None,
77
82
  **kwargs,
78
83
  ) -> Any:
79
84
  """An alias for create_instance."""
@@ -84,7 +89,7 @@ class CustomComponent:
84
89
  self,
85
90
  *args,
86
91
  default: Any = None,
87
- key: Optional[str] = None,
92
+ key: str | None = None,
88
93
  **kwargs,
89
94
  ) -> Any:
90
95
  """Create a new instance of the component.
@@ -155,7 +160,9 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
155
160
  "Could not convert component args to JSON", ex
156
161
  )
157
162
 
158
- def marshall_component(dg, element: Element) -> Union[Any, Type[NoValue]]:
163
+ def marshall_component(
164
+ dg: DeltaGenerator, element: Element
165
+ ) -> Any | type[NoValue]:
159
166
  element.component_instance.component_name = self.name
160
167
  element.component_instance.form_id = current_form_id(dg)
161
168
  if self.url is not None:
@@ -264,8 +271,8 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
264
271
 
265
272
  def declare_component(
266
273
  name: str,
267
- path: Optional[str] = None,
268
- url: Optional[str] = None,
274
+ path: str | None = None,
275
+ url: str | None = None,
269
276
  ) -> CustomComponent:
270
277
  """Create and register a custom component.
271
278
 
@@ -324,10 +331,10 @@ def declare_component(
324
331
 
325
332
  class ComponentRegistry:
326
333
  _instance_lock: threading.Lock = threading.Lock()
327
- _instance: Optional["ComponentRegistry"] = None
334
+ _instance: ComponentRegistry | None = None
328
335
 
329
336
  @classmethod
330
- def instance(cls) -> "ComponentRegistry":
337
+ def instance(cls) -> ComponentRegistry:
331
338
  """Returns the singleton ComponentRegistry"""
332
339
  # We use a double-checked locking optimization to avoid the overhead
333
340
  # of acquiring the lock in the common case:
@@ -339,7 +346,7 @@ class ComponentRegistry:
339
346
  return cls._instance
340
347
 
341
348
  def __init__(self):
342
- self._components: Dict[str, CustomComponent] = {}
349
+ self._components: dict[str, CustomComponent] = {}
343
350
  self._lock = threading.Lock()
344
351
 
345
352
  def __repr__(self) -> str:
@@ -364,15 +371,15 @@ class ComponentRegistry:
364
371
  self._components[component.name] = component
365
372
 
366
373
  if existing is not None and component != existing:
367
- LOGGER.warning(
374
+ _LOGGER.warning(
368
375
  "%s overriding previously-registered %s",
369
376
  component,
370
377
  existing,
371
378
  )
372
379
 
373
- LOGGER.debug("Registered component %s", component)
380
+ _LOGGER.debug("Registered component %s", component)
374
381
 
375
- def get_component_path(self, name: str) -> Optional[str]:
382
+ def get_component_path(self, name: str) -> str | None:
376
383
  """Return the filesystem path for the component with the given name.
377
384
 
378
385
  If no such component is registered, or if the component exists but is
streamlit/config.py CHANGED
@@ -115,9 +115,7 @@ def set_user_option(key: str, value: Any) -> None:
115
115
  try:
116
116
  opt = _config_options_template[key]
117
117
  except KeyError as ke:
118
- raise StreamlitAPIException(
119
- "Unrecognized config option: {key}".format(key=key)
120
- ) from ke
118
+ raise StreamlitAPIException(f"Unrecognized config option: {key}") from ke
121
119
  if opt.scriptable:
122
120
  set_option(key, value)
123
121
  return
@@ -245,7 +243,7 @@ def _create_option(
245
243
  )
246
244
  assert (
247
245
  option.section in _section_descriptions
248
- ), 'Section "%s" must be one of %s.' % (
246
+ ), 'Section "{}" must be one of {}.'.format(
249
247
  option.section,
250
248
  ", ".join(_section_descriptions.keys()),
251
249
  )
@@ -1310,7 +1308,7 @@ def get_config_options(
1310
1308
  if not os.path.exists(filename):
1311
1309
  continue
1312
1310
 
1313
- with open(filename, "r", encoding="utf-8") as input:
1311
+ with open(filename, encoding="utf-8") as input:
1314
1312
  file_contents = input.read()
1315
1313
 
1316
1314
  _update_config_with_toml(file_contents, filename)
@@ -14,14 +14,15 @@
14
14
 
15
15
  """Class to store a key-value pair for the config system."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  import datetime
18
20
  import re
19
21
  import textwrap
20
- from typing import Any, Callable, Optional
22
+ from typing import Any, Callable
21
23
 
22
24
  from streamlit import util
23
25
  from streamlit.case_converters import to_snake_case
24
- from streamlit.errors import DeprecationError
25
26
 
26
27
 
27
28
  class ConfigOption:
@@ -97,14 +98,14 @@ class ConfigOption:
97
98
  def __init__(
98
99
  self,
99
100
  key: str,
100
- description: Optional[str] = None,
101
- default_val: Optional[Any] = None,
101
+ description: str | None = None,
102
+ default_val: Any | None = None,
102
103
  visibility: str = "visible",
103
104
  scriptable: bool = False,
104
105
  deprecated: bool = False,
105
- deprecation_text: Optional[str] = None,
106
- expiration_date: Optional[str] = None,
107
- replaced_by: Optional[str] = None,
106
+ deprecation_text: str | None = None,
107
+ expiration_date: str | None = None,
108
+ replaced_by: str | None = None,
108
109
  type_: type = str,
109
110
  sensitive: bool = False,
110
111
  ):
@@ -174,7 +175,7 @@ class ConfigOption:
174
175
  self.deprecated = deprecated
175
176
  self.replaced_by = replaced_by
176
177
  self.is_default = True
177
- self._get_val_func: Optional[Callable[[], Any]] = None
178
+ self._get_val_func: Callable[[], Any] | None = None
178
179
  self.where_defined = ConfigOption.DEFAULT_DEFINITION
179
180
  self.type = type_
180
181
  self.sensitive = sensitive
@@ -195,7 +196,7 @@ class ConfigOption:
195
196
  def __repr__(self) -> str:
196
197
  return util.repr_(self)
197
198
 
198
- def __call__(self, get_val_func: Callable[[], Any]) -> "ConfigOption":
199
+ def __call__(self, get_val_func: Callable[[], Any]) -> ConfigOption:
199
200
  """Assign a function to compute the value for this option.
200
201
 
201
202
  This method is called when ConfigOption is used as a decorator.
@@ -226,7 +227,7 @@ class ConfigOption:
226
227
  return None
227
228
  return self._get_val_func()
228
229
 
229
- def set_value(self, value: Any, where_defined: Optional[str] = None) -> None:
230
+ def set_value(self, value: Any, where_defined: str | None = None) -> None:
230
231
  """Set the value of this option.
231
232
 
232
233
  Parameters
@@ -313,5 +314,5 @@ class ConfigOption:
313
314
 
314
315
 
315
316
  def _parse_yyyymmdd_str(date_str: str) -> datetime.datetime:
316
- year, month, day = [int(token) for token in date_str.split("-", 2)]
317
+ year, month, day = (int(token) for token in date_str.split("-", 2))
317
318
  return datetime.datetime(year, month, day)
@@ -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 json
16
18
  from abc import ABC, abstractmethod
17
- from typing import Any, Generic, Optional, TypeVar
19
+ from typing import Any, Generic, TypeVar
18
20
 
19
21
  from streamlit.runtime.secrets import AttrDict, secrets_singleton
20
22
  from streamlit.util import calc_md5
@@ -68,7 +70,7 @@ class BaseConnection(ABC, Generic[RawConnectionT]):
68
70
  self._config_section_hash = calc_md5(json.dumps(self._secrets.to_dict()))
69
71
  secrets_singleton.file_change_listener.connect(self._on_secrets_changed)
70
72
 
71
- self._raw_instance: Optional[RawConnectionT] = self._connect(**kwargs)
73
+ self._raw_instance: RawConnectionT | None = self._connect(**kwargs)
72
74
 
73
75
  def __del__(self) -> None:
74
76
  secrets_singleton.file_change_listener.disconnect(self._on_secrets_changed)
@@ -49,7 +49,7 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
49
49
  initialized directly.
50
50
  """
51
51
 
52
- def _connect(self, **kwargs) -> "InternalSnowflakeConnection":
52
+ def _connect(self, **kwargs) -> InternalSnowflakeConnection:
53
53
  import snowflake.connector # type:ignore[import]
54
54
  from snowflake.connector import Error as SnowflakeError # type:ignore[import]
55
55
 
@@ -260,7 +260,7 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
260
260
 
261
261
  return (success, nchunks, nrows)
262
262
 
263
- def cursor(self) -> "SnowflakeCursor":
263
+ def cursor(self) -> SnowflakeCursor:
264
264
  """Return a PEP 249-compliant cursor object.
265
265
 
266
266
  For more information, see the `Snowflake Python Connector documentation
@@ -269,7 +269,7 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
269
269
  return self._instance.cursor()
270
270
 
271
271
  @property
272
- def raw_connection(self) -> "InternalSnowflakeConnection":
272
+ def raw_connection(self) -> InternalSnowflakeConnection:
273
273
  """Access the underlying Snowflake Python connector object.
274
274
 
275
275
  Information on how to use the Snowflake Python Connector can be found in the
@@ -277,7 +277,7 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
277
277
  """
278
278
  return self._instance
279
279
 
280
- def session(self) -> "Session":
280
+ def session(self) -> Session:
281
281
  """Create a new Snowpark Session from this connection.
282
282
 
283
283
  Information on how to use Snowpark sessions can be found in the `Snowpark documentation
@@ -63,7 +63,7 @@ class SnowparkConnection(BaseConnection["Session"]):
63
63
  self._lock = threading.RLock()
64
64
  super().__init__(connection_name, **kwargs)
65
65
 
66
- def _connect(self, **kwargs) -> "Session":
66
+ def _connect(self, **kwargs) -> Session:
67
67
  from snowflake.snowpark.context import get_active_session # type:ignore[import]
68
68
  from snowflake.snowpark.exceptions import ( # type:ignore[import]
69
69
  SnowparkSessionException,
@@ -165,7 +165,7 @@ class SnowparkConnection(BaseConnection["Session"]):
165
165
  return _query(sql)
166
166
 
167
167
  @property
168
- def session(self) -> "Session":
168
+ def session(self) -> Session:
169
169
  """Access the underlying Snowpark session.
170
170
 
171
171
  .. note::
@@ -188,7 +188,7 @@ class SnowparkConnection(BaseConnection["Session"]):
188
188
  return self._instance
189
189
 
190
190
  @contextmanager
191
- def safe_session(self) -> Iterator["Session"]:
191
+ def safe_session(self) -> Iterator[Session]:
192
192
  """Grab the underlying Snowpark session in a thread-safe manner.
193
193
 
194
194
  As operations on a Snowpark session are not thread safe, we need to take care
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
  from collections import ChainMap
18
18
  from copy import deepcopy
19
19
  from datetime import timedelta
20
- from typing import TYPE_CHECKING, List, cast
20
+ from typing import TYPE_CHECKING, cast
21
21
 
22
22
  from streamlit.connections import BaseConnection
23
23
  from streamlit.connections.util import extract_from_dict
@@ -76,7 +76,7 @@ class SQLConnection(BaseConnection["Engine"]):
76
76
  >>> st.dataframe(df)
77
77
  """
78
78
 
79
- def _connect(self, autocommit: bool = False, **kwargs) -> "Engine":
79
+ def _connect(self, autocommit: bool = False, **kwargs) -> Engine:
80
80
  import sqlalchemy
81
81
 
82
82
  kwargs = deepcopy(kwargs)
@@ -125,7 +125,7 @@ class SQLConnection(BaseConnection["Engine"]):
125
125
  *, # keyword-only arguments:
126
126
  show_spinner: bool | str = "Running `sql.query(...)`.",
127
127
  ttl: float | int | timedelta | None = None,
128
- index_col: str | List[str] | None = None,
128
+ index_col: str | list[str] | None = None,
129
129
  chunksize: int | None = None,
130
130
  params=None,
131
131
  **kwargs,
@@ -245,7 +245,7 @@ class SQLConnection(BaseConnection["Engine"]):
245
245
  **kwargs,
246
246
  )
247
247
 
248
- def connect(self) -> "SQLAlchemyConnection":
248
+ def connect(self) -> SQLAlchemyConnection:
249
249
  """Call ``.connect()`` on the underlying SQLAlchemy Engine, returning a new\
250
250
  ``sqlalchemy.engine.Connection`` object.
251
251
 
@@ -257,7 +257,7 @@ class SQLConnection(BaseConnection["Engine"]):
257
257
  return self._instance.connect()
258
258
 
259
259
  @property
260
- def engine(self) -> "Engine":
260
+ def engine(self) -> Engine:
261
261
  """The underlying SQLAlchemy Engine.
262
262
 
263
263
  This is equivalent to accessing ``self._instance``.
@@ -273,7 +273,7 @@ class SQLConnection(BaseConnection["Engine"]):
273
273
  return self._instance.driver
274
274
 
275
275
  @property
276
- def session(self) -> "Session":
276
+ def session(self) -> Session:
277
277
  """Return a SQLAlchemy Session.
278
278
 
279
279
  Users of this connection should use the contextmanager pattern for writes,
@@ -18,17 +18,17 @@
18
18
  # way to configure this at a per-line level :(
19
19
  # mypy: no-warn-unused-ignores
20
20
 
21
+ from __future__ import annotations
21
22
 
22
- import configparser
23
23
  import os
24
- from typing import Any, Collection, Dict, cast
24
+ from typing import Any, Collection, cast
25
25
 
26
26
  SNOWSQL_CONNECTION_FILE = "~/.snowsql/config"
27
27
 
28
28
 
29
29
  def extract_from_dict(
30
- keys: Collection[str], source_dict: Dict[str, Any]
31
- ) -> Dict[str, Any]:
30
+ keys: Collection[str], source_dict: dict[str, Any]
31
+ ) -> dict[str, Any]:
32
32
  """Extract the specified keys from source_dict and return them in a new dict.
33
33
 
34
34
  Parameters
@@ -52,12 +52,15 @@ def extract_from_dict(
52
52
  return d
53
53
 
54
54
 
55
- def load_from_snowsql_config_file(connection_name: str) -> Dict[str, Any]:
55
+ def load_from_snowsql_config_file(connection_name: str) -> dict[str, Any]:
56
56
  """Loads the dictionary from snowsql config file."""
57
57
  snowsql_config_file = os.path.expanduser(SNOWSQL_CONNECTION_FILE)
58
58
  if not os.path.exists(snowsql_config_file):
59
59
  return {}
60
60
 
61
+ # Lazy-load config parser for better import / startup performance
62
+ import configparser
63
+
61
64
  config = configparser.ConfigParser(inline_comment_prefixes="#")
62
65
  config.read(snowsql_config_file)
63
66
 
streamlit/constants.py CHANGED
@@ -12,6 +12,8 @@
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
  EMBED_QUERY_PARAM = "embed"
16
18
  EMBED_OPTIONS_QUERY_PARAM = "embed_options"
17
19
  EMBED_QUERY_PARAMS_KEYS = [EMBED_QUERY_PARAM, EMBED_OPTIONS_QUERY_PARAM]