streamlit 1.49.1__py3-none-any.whl → 1.51.0__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 (259) hide show
  1. streamlit/__init__.py +4 -1
  2. streamlit/column_config.py +2 -0
  3. streamlit/commands/navigation.py +7 -7
  4. streamlit/commands/page_config.py +4 -6
  5. streamlit/components/v1/custom_component.py +17 -42
  6. streamlit/components/v2/__init__.py +458 -0
  7. streamlit/components/v2/bidi_component/__init__.py +20 -0
  8. streamlit/components/v2/bidi_component/constants.py +29 -0
  9. streamlit/components/v2/bidi_component/main.py +386 -0
  10. streamlit/components/v2/bidi_component/serialization.py +265 -0
  11. streamlit/components/v2/bidi_component/state.py +92 -0
  12. streamlit/components/v2/component_definition_resolver.py +143 -0
  13. streamlit/components/v2/component_file_watcher.py +403 -0
  14. streamlit/components/v2/component_manager.py +431 -0
  15. streamlit/components/v2/component_manifest_handler.py +122 -0
  16. streamlit/components/v2/component_path_utils.py +245 -0
  17. streamlit/components/v2/component_registry.py +409 -0
  18. streamlit/components/v2/get_bidi_component_manager.py +51 -0
  19. streamlit/components/v2/manifest_scanner.py +615 -0
  20. streamlit/components/v2/presentation.py +198 -0
  21. streamlit/components/v2/types.py +324 -0
  22. streamlit/config.py +741 -32
  23. streamlit/config_option.py +4 -1
  24. streamlit/config_util.py +650 -1
  25. streamlit/connections/base_connection.py +4 -2
  26. streamlit/dataframe_util.py +18 -10
  27. streamlit/delta_generator.py +8 -7
  28. streamlit/delta_generator_singletons.py +3 -1
  29. streamlit/deprecation_util.py +17 -6
  30. streamlit/elements/arrow.py +90 -42
  31. streamlit/elements/deck_gl_json_chart.py +98 -39
  32. streamlit/elements/dialog_decorator.py +2 -1
  33. streamlit/elements/exception.py +3 -1
  34. streamlit/elements/form.py +6 -6
  35. streamlit/elements/graphviz_chart.py +24 -9
  36. streamlit/elements/heading.py +3 -5
  37. streamlit/elements/iframe.py +0 -2
  38. streamlit/elements/image.py +12 -13
  39. streamlit/elements/layouts.py +89 -22
  40. streamlit/elements/lib/built_in_chart_utils.py +95 -31
  41. streamlit/elements/lib/color_util.py +8 -18
  42. streamlit/elements/lib/column_config_utils.py +9 -8
  43. streamlit/elements/lib/column_types.py +595 -148
  44. streamlit/elements/lib/dialog.py +3 -2
  45. streamlit/elements/lib/image_utils.py +3 -5
  46. streamlit/elements/lib/layout_utils.py +50 -13
  47. streamlit/elements/lib/mutable_status_container.py +2 -2
  48. streamlit/elements/lib/options_selector_utils.py +2 -2
  49. streamlit/elements/lib/pandas_styler_utils.py +30 -14
  50. streamlit/elements/lib/utils.py +21 -9
  51. streamlit/elements/map.py +81 -40
  52. streamlit/elements/media.py +7 -7
  53. streamlit/elements/metric.py +11 -35
  54. streamlit/elements/pdf.py +2 -4
  55. streamlit/elements/plotly_chart.py +142 -26
  56. streamlit/elements/progress.py +2 -4
  57. streamlit/elements/pyplot.py +6 -6
  58. streamlit/elements/space.py +113 -0
  59. streamlit/elements/vega_charts.py +400 -143
  60. streamlit/elements/widgets/audio_input.py +52 -4
  61. streamlit/elements/widgets/button.py +29 -29
  62. streamlit/elements/widgets/button_group.py +33 -6
  63. streamlit/elements/widgets/camera_input.py +3 -4
  64. streamlit/elements/widgets/chat.py +7 -0
  65. streamlit/elements/widgets/checkbox.py +1 -0
  66. streamlit/elements/widgets/color_picker.py +1 -0
  67. streamlit/elements/widgets/data_editor.py +34 -29
  68. streamlit/elements/widgets/file_uploader.py +6 -10
  69. streamlit/elements/widgets/multiselect.py +14 -3
  70. streamlit/elements/widgets/number_input.py +5 -4
  71. streamlit/elements/widgets/radio.py +10 -2
  72. streamlit/elements/widgets/select_slider.py +8 -4
  73. streamlit/elements/widgets/selectbox.py +9 -2
  74. streamlit/elements/widgets/slider.py +38 -41
  75. streamlit/elements/widgets/text_widgets.py +6 -0
  76. streamlit/elements/widgets/time_widgets.py +15 -12
  77. streamlit/elements/write.py +28 -23
  78. streamlit/emojis.py +1 -1
  79. streamlit/errors.py +115 -0
  80. streamlit/git_util.py +65 -43
  81. streamlit/hello/hello.py +8 -0
  82. streamlit/hello/utils.py +2 -1
  83. streamlit/material_icon_names.py +1 -1
  84. streamlit/navigation/page.py +4 -1
  85. streamlit/proto/ArrowData_pb2.py +27 -0
  86. streamlit/proto/ArrowData_pb2.pyi +46 -0
  87. streamlit/proto/Arrow_pb2.py +10 -8
  88. streamlit/proto/Arrow_pb2.pyi +31 -2
  89. streamlit/proto/AudioInput_pb2.py +2 -2
  90. streamlit/proto/AudioInput_pb2.pyi +6 -2
  91. streamlit/proto/BidiComponent_pb2.py +34 -0
  92. streamlit/proto/BidiComponent_pb2.pyi +153 -0
  93. streamlit/proto/Block_pb2.py +11 -11
  94. streamlit/proto/Block_pb2.pyi +9 -1
  95. streamlit/proto/DeckGlJsonChart_pb2.py +10 -4
  96. streamlit/proto/DeckGlJsonChart_pb2.pyi +9 -3
  97. streamlit/proto/Element_pb2.py +5 -3
  98. streamlit/proto/Element_pb2.pyi +14 -4
  99. streamlit/proto/HeightConfig_pb2.py +2 -2
  100. streamlit/proto/HeightConfig_pb2.pyi +6 -3
  101. streamlit/proto/NewSession_pb2.py +18 -16
  102. streamlit/proto/NewSession_pb2.pyi +158 -6
  103. streamlit/proto/PlotlyChart_pb2.py +8 -6
  104. streamlit/proto/PlotlyChart_pb2.pyi +3 -1
  105. streamlit/proto/Space_pb2.py +27 -0
  106. streamlit/proto/Space_pb2.pyi +42 -0
  107. streamlit/proto/WidgetStates_pb2.py +2 -2
  108. streamlit/proto/WidgetStates_pb2.pyi +13 -3
  109. streamlit/proto/WidthConfig_pb2.py +2 -2
  110. streamlit/proto/WidthConfig_pb2.pyi +6 -3
  111. streamlit/runtime/app_session.py +45 -6
  112. streamlit/runtime/caching/cache_data_api.py +4 -4
  113. streamlit/runtime/caching/cache_errors.py +4 -1
  114. streamlit/runtime/caching/cache_resource_api.py +3 -2
  115. streamlit/runtime/caching/cache_utils.py +2 -1
  116. streamlit/runtime/caching/cached_message_replay.py +3 -3
  117. streamlit/runtime/caching/hashing.py +3 -4
  118. streamlit/runtime/caching/legacy_cache_api.py +2 -1
  119. streamlit/runtime/connection_factory.py +1 -3
  120. streamlit/runtime/forward_msg_queue.py +4 -1
  121. streamlit/runtime/fragment.py +2 -1
  122. streamlit/runtime/memory_media_file_storage.py +1 -1
  123. streamlit/runtime/metrics_util.py +6 -2
  124. streamlit/runtime/runtime.py +14 -0
  125. streamlit/runtime/scriptrunner/exec_code.py +2 -1
  126. streamlit/runtime/scriptrunner/script_runner.py +2 -2
  127. streamlit/runtime/scriptrunner_utils/script_run_context.py +3 -6
  128. streamlit/runtime/secrets.py +2 -4
  129. streamlit/runtime/session_manager.py +3 -1
  130. streamlit/runtime/state/common.py +30 -5
  131. streamlit/runtime/state/presentation.py +85 -0
  132. streamlit/runtime/state/safe_session_state.py +2 -2
  133. streamlit/runtime/state/session_state.py +220 -16
  134. streamlit/runtime/state/widgets.py +19 -3
  135. streamlit/runtime/theme_util.py +148 -0
  136. streamlit/runtime/websocket_session_manager.py +3 -1
  137. streamlit/source_util.py +2 -2
  138. streamlit/static/index.html +2 -2
  139. streamlit/static/manifest.json +244 -227
  140. streamlit/static/static/css/{index.C8X8rNzw.css → index.BpABIXK9.css} +1 -1
  141. streamlit/static/static/css/index.DgR7E2CV.css +1 -0
  142. streamlit/static/static/js/{ErrorOutline.esm.DcGrhbBP.js → ErrorOutline.esm.YoJdlW1p.js} +1 -1
  143. streamlit/static/static/js/{FileDownload.esm.DgBvV6Pq.js → FileDownload.esm.Ddx8VEYy.js} +1 -1
  144. streamlit/static/static/js/{FileHelper.M6AAaeuA.js → FileHelper.90EtOmj9.js} +1 -1
  145. streamlit/static/static/js/{FormClearHelper.DHh1GFzm.js → FormClearHelper.BB1Km6eP.js} +1 -1
  146. streamlit/static/static/js/InputInstructions.jhH15PqV.js +1 -0
  147. streamlit/static/static/js/{Particles.DDVT-6Qc.js → Particles.DUsputn1.js} +1 -1
  148. streamlit/static/static/js/{ProgressBar.BEY0cXXV.js → ProgressBar.DLY8H6nE.js} +2 -2
  149. streamlit/static/static/js/Toolbar.D8nHCkuz.js +1 -0
  150. streamlit/static/static/js/{base-input.CK3UVGp1.js → base-input.CJGiNqed.js} +3 -3
  151. streamlit/static/static/js/{checkbox.D8W881TL.js → checkbox.Cpdd482O.js} +1 -1
  152. streamlit/static/static/js/{createSuper.B6W-Dh9S.js → createSuper.CuQIogbW.js} +1 -1
  153. streamlit/static/static/js/data-grid-overlay-editor.2Ufgxc6y.js +1 -0
  154. streamlit/static/static/js/{downloader.DiKpuU_S.js → downloader.CN0K7xlu.js} +1 -1
  155. streamlit/static/static/js/{es6.B8zRNPZ-.js → es6.BJcsVXQ0.js} +2 -2
  156. streamlit/static/static/js/{iframeResizer.contentWindow.DIewJmmh.js → iframeResizer.contentWindow.XzUvQqcZ.js} +1 -1
  157. streamlit/static/static/js/index.B1ZQh4P1.js +1 -0
  158. streamlit/static/static/js/index.BKstZk0M.js +27 -0
  159. streamlit/static/static/js/{index.Bte_9Lyq.js → index.BMcFsUee.js} +1 -1
  160. streamlit/static/static/js/{index.qhs54UAB.js → index.BR-IdcTb.js} +1 -1
  161. streamlit/static/static/js/{index.CejBxbg1.js → index.B_dWA3vd.js} +1 -1
  162. streamlit/static/static/js/{index.D5naqx-J.js → index.BgnZEMVh.js} +1 -1
  163. streamlit/static/static/js/{index.C7fRKRs4.js → index.BohqXifI.js} +1 -1
  164. streamlit/static/static/js/{index.cnnXF7xQ.js → index.Br5nxKNj.js} +1 -1
  165. streamlit/static/static/js/index.BrIKVbNc.js +3 -0
  166. streamlit/static/static/js/index.BtWUPzle.js +1 -0
  167. streamlit/static/static/js/index.C0RLraek.js +1 -0
  168. streamlit/static/static/js/{index.CP5TD2z1.js → index.CAIjskgG.js} +1 -1
  169. streamlit/static/static/js/{index.CD8HuT3N.js → index.CAj-7vWz.js} +135 -162
  170. streamlit/static/static/js/{index.DtYN2x4k.js → index.CMtEit2O.js} +1 -1
  171. streamlit/static/static/js/index.CkRlykEE.js +12 -0
  172. streamlit/static/static/js/{index.Ts_0SdB9.js → index.CmN3FXfI.js} +2 -2
  173. streamlit/static/static/js/{index.BnEpvLEz.js → index.CwbFI1_-.js} +1 -1
  174. streamlit/static/static/js/{index.CcJf6BCU.js → index.CxIUUfab.js} +27 -27
  175. streamlit/static/static/js/index.D2KPNy7e.js +1 -0
  176. streamlit/static/static/js/{index.Ch7MBCx0.js → index.D3GPA5k4.js} +47 -47
  177. streamlit/static/static/js/{index.ho6NIXGl.js → index.DGAh7DMq.js} +1 -1
  178. streamlit/static/static/js/index.DKb_NvmG.js +197 -0
  179. streamlit/static/static/js/{index.CvYYtxD_.js → index.DMqgUYKq.js} +1 -1
  180. streamlit/static/static/js/{index.zecpGxtj.js → index.DOFlg3dS.js} +1 -1
  181. streamlit/static/static/js/{index.B9mjBcgE.js → index.DPUXkcQL.js} +1 -1
  182. streamlit/static/static/js/index.DX1xY89g.js +1 -0
  183. streamlit/static/static/js/index.DYATBCsq.js +2 -0
  184. streamlit/static/static/js/{index.D2-atlaQ.js → index.DaSmGJ76.js} +3 -3
  185. streamlit/static/static/js/index.Dd7bMeLP.js +1 -0
  186. streamlit/static/static/js/{index.4eF4NxG2.js → index.DjmmgI5U.js} +1 -1
  187. streamlit/static/static/js/index.Dq56CyM2.js +1 -0
  188. streamlit/static/static/js/index.DuiXaS5_.js +7 -0
  189. streamlit/static/static/js/index.DvFidMLe.js +2 -0
  190. streamlit/static/static/js/{index.452cqrrL.js → index.DwkhC5Pc.js} +1 -1
  191. streamlit/static/static/js/{index.Dk4C7X3i.js → index.Q-3sFn1v.js} +1 -1
  192. streamlit/static/static/js/{index.CjXWwH-y.js → index.QJ5QO9sJ.js} +1 -1
  193. streamlit/static/static/js/{index.B6U8LQo3.js → index.VwTaeety.js} +1 -1
  194. streamlit/static/static/js/index.YOqQbeX8.js +1 -0
  195. streamlit/static/static/js/{input.nzVJphXi.js → input.D4MN_FzN.js} +1 -1
  196. streamlit/static/static/js/{memory.CjCgTQz3.js → memory.DrZjtdGT.js} +1 -1
  197. streamlit/static/static/js/{number-overlay-editor.DaRFzZEO.js → number-overlay-editor.DRwAw1In.js} +1 -1
  198. streamlit/static/static/js/{possibleConstructorReturn.DgiPnZ9N.js → possibleConstructorReturn.exeeJQEP.js} +1 -1
  199. streamlit/static/static/js/record.B-tDciZb.js +1 -0
  200. streamlit/static/static/js/{sandbox.mithfq7Z.js → sandbox.ClO3IuUr.js} +1 -1
  201. streamlit/static/static/js/{timepicker.Dbl5KFh6.js → timepicker.DAhu-vcF.js} +4 -4
  202. streamlit/static/static/js/{toConsumableArray.D-Dx88BQ.js → toConsumableArray.DNbljYEC.js} +1 -1
  203. streamlit/static/static/js/{uniqueId.Bh26R_3S.js → uniqueId.oG4Gvj1v.js} +1 -1
  204. streamlit/static/static/js/{useBasicWidgetState.DeK-QJpD.js → useBasicWidgetState.D6sOH6oI.js} +1 -1
  205. streamlit/static/static/js/{useTextInputAutoExpand.4iAdLWD-.js → useTextInputAutoExpand.4u3_GcuN.js} +2 -2
  206. streamlit/static/static/js/{useUpdateUiValue.CmT7_nJN.js → useUpdateUiValue.F2R3eTeR.js} +1 -1
  207. streamlit/static/static/js/wavesurfer.esm.vI8Eid4k.js +73 -0
  208. streamlit/static/static/js/withFullScreenWrapper.zothJIsI.js +1 -0
  209. streamlit/static/static/media/MaterialSymbols-Rounded.C7IFxh57.woff2 +0 -0
  210. streamlit/string_util.py +56 -1
  211. streamlit/testing/v1/app_test.py +2 -2
  212. streamlit/testing/v1/element_tree.py +23 -9
  213. streamlit/testing/v1/util.py +2 -2
  214. streamlit/type_util.py +3 -4
  215. streamlit/url_util.py +1 -3
  216. streamlit/user_info.py +1 -2
  217. streamlit/util.py +3 -1
  218. streamlit/watcher/event_based_path_watcher.py +23 -12
  219. streamlit/watcher/local_sources_watcher.py +11 -1
  220. streamlit/watcher/path_watcher.py +9 -6
  221. streamlit/watcher/polling_path_watcher.py +4 -1
  222. streamlit/watcher/util.py +2 -2
  223. streamlit/web/bootstrap.py +0 -31
  224. streamlit/web/cli.py +51 -22
  225. streamlit/web/server/bidi_component_request_handler.py +193 -0
  226. streamlit/web/server/component_file_utils.py +97 -0
  227. streamlit/web/server/component_request_handler.py +8 -21
  228. streamlit/web/server/oidc_mixin.py +3 -1
  229. streamlit/web/server/routes.py +18 -5
  230. streamlit/web/server/server.py +10 -0
  231. streamlit/web/server/server_util.py +3 -1
  232. streamlit/web/server/upload_file_request_handler.py +3 -1
  233. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/METADATA +4 -5
  234. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/RECORD +238 -209
  235. streamlit/static/static/css/index.COe1010n.css +0 -1
  236. streamlit/static/static/js/Hooks.DGu1od_L.js +0 -1
  237. streamlit/static/static/js/InputInstructions.z6sVgyYt.js +0 -1
  238. streamlit/static/static/js/Toolbar.DSnK1fUh.js +0 -1
  239. streamlit/static/static/js/data-grid-overlay-editor.DRTHOydk.js +0 -1
  240. streamlit/static/static/js/index.BXYmrqnf.js +0 -1
  241. streamlit/static/static/js/index.B_8AnktO.js +0 -1
  242. streamlit/static/static/js/index.Bl7zGQSh.js +0 -7
  243. streamlit/static/static/js/index.BnJIOYn9.js +0 -73
  244. streamlit/static/static/js/index.C1HcTl5K.js +0 -1
  245. streamlit/static/static/js/index.C7lSmSOP.js +0 -1
  246. streamlit/static/static/js/index.C_tmcx4B.js +0 -1
  247. streamlit/static/static/js/index.D3K5nOu9.js +0 -197
  248. streamlit/static/static/js/index.DkKT3LUI.js +0 -1
  249. streamlit/static/static/js/index.MTPPBDHk.js +0 -2
  250. streamlit/static/static/js/index.pqW9AMJD.js +0 -3
  251. streamlit/static/static/js/index.urHgTgMQ.js +0 -12
  252. streamlit/static/static/js/index.wzkv_11M.js +0 -1
  253. streamlit/static/static/js/index.yF5AncHY.js +0 -1
  254. streamlit/static/static/js/withFullScreenWrapper.DLp1ENGm.js +0 -1
  255. streamlit/static/static/media/MaterialSymbols-Rounded.CBxVaFdk.woff2 +0 -0
  256. {streamlit-1.49.1.data → streamlit-1.51.0.data}/scripts/streamlit.cmd +0 -0
  257. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/WHEEL +0 -0
  258. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/entry_points.txt +0 -0
  259. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/top_level.txt +0 -0
@@ -14,9 +14,9 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import TYPE_CHECKING, Literal, cast
17
+ from typing import TYPE_CHECKING, Literal, TypeAlias, cast
18
18
 
19
- from typing_extensions import Self, TypeAlias
19
+ from typing_extensions import Self
20
20
 
21
21
  from streamlit.delta_generator import DeltaGenerator
22
22
  from streamlit.elements.lib.utils import compute_and_register_element_id
@@ -112,6 +112,7 @@ class Dialog(DeltaGenerator):
112
112
  element_id = compute_and_register_element_id(
113
113
  "dialog",
114
114
  user_key=None,
115
+ key_as_main_identity=False,
115
116
  dg=parent,
116
117
  title=title,
117
118
  dismissible=dismissible,
@@ -20,9 +20,7 @@ import re
20
20
  from collections.abc import Sequence
21
21
  from enum import IntEnum
22
22
  from pathlib import Path
23
- from typing import TYPE_CHECKING, Final, Literal, Union, cast
24
-
25
- from typing_extensions import TypeAlias
23
+ from typing import TYPE_CHECKING, Final, Literal, TypeAlias, Union, cast
26
24
 
27
25
  from streamlit import runtime, url_util
28
26
  from streamlit.errors import StreamlitAPIException
@@ -48,7 +46,7 @@ AtomicImage: TypeAlias = Union[
48
46
  Channels: TypeAlias = Literal["RGB", "BGR"]
49
47
  ImageFormat: TypeAlias = Literal["JPEG", "PNG", "GIF"]
50
48
  ImageFormatOrAuto: TypeAlias = Literal[ImageFormat, "auto"]
51
- ImageOrImageList: TypeAlias = Union[AtomicImage, Sequence[AtomicImage]]
49
+ ImageOrImageList: TypeAlias = AtomicImage | Sequence[AtomicImage]
52
50
 
53
51
  # This constant is related to the frontend maximum content width specified
54
52
  # in App.jsx main container
@@ -434,7 +432,7 @@ def marshall_images(
434
432
 
435
433
  # Each image in an image list needs to be kept track of at its own coordinates.
436
434
  for coord_suffix, (single_image, single_caption) in enumerate(
437
- zip(images, captions)
435
+ zip(images, captions, strict=False)
438
436
  ):
439
437
  proto_img = proto_imgs.imgs.add()
440
438
  if single_caption is not None:
@@ -14,14 +14,13 @@
14
14
  from __future__ import annotations
15
15
 
16
16
  from dataclasses import dataclass
17
- from typing import Literal, Union, cast
18
-
19
- from typing_extensions import TypeAlias
17
+ from typing import Literal, TypeAlias, cast
20
18
 
21
19
  from streamlit.errors import (
22
20
  StreamlitInvalidColumnGapError,
23
21
  StreamlitInvalidHeightError,
24
22
  StreamlitInvalidHorizontalAlignmentError,
23
+ StreamlitInvalidSizeError,
25
24
  StreamlitInvalidVerticalAlignmentError,
26
25
  StreamlitInvalidWidthError,
27
26
  )
@@ -30,19 +29,29 @@ from streamlit.proto.GapSize_pb2 import GapSize
30
29
  from streamlit.proto.HeightConfig_pb2 import HeightConfig
31
30
  from streamlit.proto.WidthConfig_pb2 import WidthConfig
32
31
 
33
- WidthWithoutContent: TypeAlias = Union[int, Literal["stretch"]]
34
- Width: TypeAlias = Union[int, Literal["stretch", "content"]]
35
- HeightWithoutContent: TypeAlias = Union[int, Literal["stretch"]]
36
- Height: TypeAlias = Union[int, Literal["stretch", "content"]]
32
+ WidthWithoutContent: TypeAlias = int | Literal["stretch"]
33
+ Width: TypeAlias = int | Literal["stretch", "content"]
34
+ HeightWithoutContent: TypeAlias = int | Literal["stretch"]
35
+ Height: TypeAlias = int | Literal["stretch", "content"]
36
+ SpaceSize: TypeAlias = int | Literal["stretch", "small", "medium", "large"]
37
37
  Gap: TypeAlias = Literal["small", "medium", "large"]
38
38
  HorizontalAlignment: TypeAlias = Literal["left", "center", "right", "distribute"]
39
39
  VerticalAlignment: TypeAlias = Literal["top", "center", "bottom", "distribute"]
40
40
 
41
+ # Mapping of size literals to rem values for st.space
42
+ # If changing these, also check streamlit/frontend/lib/src/theme/primitives/sizes.ts
43
+ # to ensure sizes are kept in sync.
44
+ SIZE_TO_REM_MAPPING = {
45
+ "small": 0.75, # Height of widget label minus gap
46
+ "medium": 2.5, # Height of button/input field
47
+ "large": 4.25, # Height of large widget without label
48
+ }
49
+
41
50
 
42
51
  @dataclass
43
52
  class LayoutConfig:
44
- width: Width | None = None
45
- height: Height | None = None
53
+ width: Width | SpaceSize | None = None
54
+ height: Height | SpaceSize | None = None
46
55
 
47
56
 
48
57
  def validate_width(width: Width, allow_content: bool = False) -> None:
@@ -117,9 +126,35 @@ def validate_height(
117
126
  raise StreamlitInvalidHeightError(height, allow_content)
118
127
 
119
128
 
120
- def get_width_config(width: Width) -> WidthConfig:
129
+ def validate_space_size(size: SpaceSize) -> None:
130
+ """Validate the size parameter for st.space.
131
+
132
+ Parameters
133
+ ----------
134
+ size : Any
135
+ The size value to validate.
136
+
137
+ Raises
138
+ ------
139
+ StreamlitInvalidSizeError
140
+ If the size value is invalid.
141
+ """
142
+ if not isinstance(size, (int, str)):
143
+ raise StreamlitInvalidSizeError(size)
144
+
145
+ if isinstance(size, str):
146
+ valid_strings = ["stretch", "small", "medium", "large"]
147
+ if size not in valid_strings:
148
+ raise StreamlitInvalidSizeError(size)
149
+ elif isinstance(size, int) and size <= 0:
150
+ raise StreamlitInvalidSizeError(size)
151
+
152
+
153
+ def get_width_config(width: Width | SpaceSize) -> WidthConfig:
121
154
  width_config = WidthConfig()
122
- if isinstance(width, (int, float)):
155
+ if isinstance(width, str) and width in SIZE_TO_REM_MAPPING:
156
+ width_config.rem_width = SIZE_TO_REM_MAPPING[width]
157
+ elif isinstance(width, (int, float)):
123
158
  width_config.pixel_width = int(width)
124
159
  elif width == "content":
125
160
  width_config.use_content = True
@@ -128,9 +163,11 @@ def get_width_config(width: Width) -> WidthConfig:
128
163
  return width_config
129
164
 
130
165
 
131
- def get_height_config(height: Height) -> HeightConfig:
166
+ def get_height_config(height: Height | SpaceSize) -> HeightConfig:
132
167
  height_config = HeightConfig()
133
- if isinstance(height, (int, float)):
168
+ if isinstance(height, str) and height in SIZE_TO_REM_MAPPING:
169
+ height_config.rem_height = SIZE_TO_REM_MAPPING[height]
170
+ elif isinstance(height, (int, float)):
134
171
  height_config.pixel_height = int(height)
135
172
  elif height == "content":
136
173
  height_config.use_content = True
@@ -15,9 +15,9 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import time
18
- from typing import TYPE_CHECKING, Literal, cast
18
+ from typing import TYPE_CHECKING, Literal, TypeAlias, cast
19
19
 
20
- from typing_extensions import Self, TypeAlias
20
+ from typing_extensions import Self
21
21
 
22
22
  from streamlit.delta_generator import DeltaGenerator
23
23
  from streamlit.elements.lib.layout_utils import (
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from enum import Enum, EnumMeta
18
- from typing import TYPE_CHECKING, Any, Callable, Final, TypeVar, overload
18
+ from typing import TYPE_CHECKING, Any, Final, TypeVar, overload
19
19
 
20
20
  from streamlit import config, logger
21
21
  from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
@@ -26,7 +26,7 @@ from streamlit.type_util import (
26
26
  )
27
27
 
28
28
  if TYPE_CHECKING:
29
- from collections.abc import Iterable, Sequence
29
+ from collections.abc import Callable, Iterable, Sequence
30
30
 
31
31
  _LOGGER: Final = logger.get_logger(__name__)
32
32
 
@@ -14,6 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ from collections import defaultdict
17
18
  from collections.abc import Mapping
18
19
  from typing import TYPE_CHECKING, Any, TypeVar
19
20
 
@@ -258,21 +259,36 @@ def _use_display_values(df: DataFrame, styles: Mapping[str, Any]) -> DataFrame:
258
259
  # If values in a column are not of the same type, Arrow
259
260
  # serialization would fail. Thus, we need to cast all values
260
261
  # of the dataframe to strings before assigning them display values.
261
- new_df = df.astype(str)
262
262
 
263
+ new_df = df.astype(str)
263
264
  cell_selector_regex = re.compile(r"row(\d+)_col(\d+)")
264
- if "body" in styles:
265
- rows = styles["body"]
266
- for row in rows:
267
- for cell in row:
268
- if "id" in cell and (match := cell_selector_regex.match(cell["id"])):
269
- r, c = map(int, match.groups())
270
- # Check if the display value is an Enum type. Enum values need to be
271
- # converted to their `.value` attribute to ensure proper serialization
272
- # and display logic.
273
- if isinstance(cell["display_value"], Enum):
274
- new_df.iloc[r, c] = str(cell["display_value"].value)
275
- else:
276
- new_df.iloc[r, c] = str(cell["display_value"])
265
+ # Outer key = column index; inner key = row index -> target string value
266
+ updates_by_col: defaultdict[int, dict[int, str]] = defaultdict(dict)
267
+ for row in styles.get("body", []):
268
+ for cell in row:
269
+ cell_id = cell.get("id")
270
+ if not cell_id:
271
+ continue
272
+ match = cell_selector_regex.match(cell_id)
273
+ if not match:
274
+ continue
275
+ row_idx, col_idx = map(int, match.groups())
276
+ display_value = cell.get("display_value")
277
+
278
+ str_value = (
279
+ str(display_value.value)
280
+ # Check if the display value is an Enum type. Enum values need to be
281
+ # converted to their `.value` attribute to ensure proper serialization
282
+ # and display logic.
283
+ if isinstance(display_value, Enum)
284
+ else str(display_value)
285
+ )
286
+ updates_by_col[col_idx][row_idx] = str_value
287
+
288
+ for col_idx, values_by_row in updates_by_col.items():
289
+ row_indices = list(values_by_row.keys())
290
+ values = list(values_by_row.values())
291
+ # Batch-assign updates for this column using iloc for performance.
292
+ new_df.iloc[row_indices, col_idx] = values
277
293
 
278
294
  return new_df
@@ -20,12 +20,12 @@ from typing import (
20
20
  TYPE_CHECKING,
21
21
  Any,
22
22
  Literal,
23
+ TypeAlias,
23
24
  Union,
24
25
  overload,
25
26
  )
26
27
 
27
28
  from google.protobuf.message import Message
28
- from typing_extensions import TypeAlias
29
29
 
30
30
  from streamlit import config
31
31
  from streamlit.elements.lib.form_utils import current_form_id
@@ -49,12 +49,12 @@ if TYPE_CHECKING:
49
49
  from streamlit.delta_generator import DeltaGenerator
50
50
 
51
51
 
52
- Key: TypeAlias = Union[str, int]
52
+ Key: TypeAlias = str | int
53
53
 
54
54
  LabelVisibility: TypeAlias = Literal["visible", "hidden", "collapsed"]
55
55
 
56
- PROTO_SCALAR_VALUE = Union[float, int, bool, str, bytes]
57
- SAFE_VALUES = Union[
56
+ PROTO_SCALAR_VALUE: TypeAlias = float | int | bool | str | bytes
57
+ SAFE_VALUES: TypeAlias = Union[
58
58
  date,
59
59
  time,
60
60
  datetime,
@@ -187,7 +187,7 @@ def compute_and_register_element_id(
187
187
  *,
188
188
  user_key: str | None,
189
189
  dg: DeltaGenerator | None,
190
- key_as_main_identity: bool = False,
190
+ key_as_main_identity: bool | set[str],
191
191
  **kwargs: SAFE_VALUES | Iterable[SAFE_VALUES],
192
192
  ) -> str:
193
193
  """Compute and register the ID for the given element.
@@ -224,15 +224,27 @@ def compute_and_register_element_id(
224
224
  format_func, label_visibility, args, kwargs, on_change, and
225
225
  the active_script_hash are not supposed to be added here
226
226
 
227
- key_as_main_identity : bool
228
- If True, if a key is provided by the user, we don't include
227
+ key_as_main_identity : bool | set[str]
228
+ If True and a key is provided by the user, we don't include
229
229
  command kwargs in the element ID computation.
230
+ If a set of kwarg names is provided and a key is provided,
231
+ only the kwargs with names in this set will be included
232
+ in the element ID computation.
230
233
  """
231
234
  ctx = get_script_run_ctx()
232
235
 
233
- ignore_command_kwargs = key_as_main_identity and user_key
236
+ # When a user_key is present and key_as_main_identity is True OR a set (even empty),
237
+ # we should ignore general command kwargs and form/sidebar context. For the set case,
238
+ # only explicitly whitelisted kwargs will be included below.
239
+ ignore_command_kwargs = user_key is not None and (
240
+ (key_as_main_identity is True) or isinstance(key_as_main_identity, set)
241
+ )
234
242
 
235
- kwargs_to_use = {} if ignore_command_kwargs else {**kwargs}
243
+ if isinstance(key_as_main_identity, set) and user_key:
244
+ # Only include the explicitly whitelisted kwargs in the computation
245
+ kwargs_to_use = {k: v for k, v in kwargs.items() if k in key_as_main_identity}
246
+ else:
247
+ kwargs_to_use = {} if ignore_command_kwargs else {**kwargs}
236
248
 
237
249
  if ctx:
238
250
  # Add the active script hash to give elements on different
streamlit/elements/map.py CHANGED
@@ -21,6 +21,10 @@ import json
21
21
  from typing import TYPE_CHECKING, Any, Final, cast
22
22
 
23
23
  from streamlit import config, dataframe_util
24
+ from streamlit.deprecation_util import (
25
+ make_deprecated_name_warning,
26
+ show_deprecation_warning,
27
+ )
24
28
  from streamlit.elements import deck_gl_json_chart
25
29
  from streamlit.elements.lib.color_util import (
26
30
  Color,
@@ -28,6 +32,13 @@ from streamlit.elements.lib.color_util import (
28
32
  is_color_like,
29
33
  to_int_color_tuple,
30
34
  )
35
+ from streamlit.elements.lib.layout_utils import (
36
+ HeightWithoutContent,
37
+ LayoutConfig,
38
+ WidthWithoutContent,
39
+ validate_height,
40
+ validate_width,
41
+ )
31
42
  from streamlit.errors import StreamlitAPIException
32
43
  from streamlit.proto.DeckGlJsonChart_pb2 import DeckGlJsonChart as DeckGlJsonChartProto
33
44
  from streamlit.runtime.metrics_util import gather_metrics
@@ -85,9 +96,9 @@ class MapMixin:
85
96
  color: None | str | Color = None,
86
97
  size: None | str | float = None,
87
98
  zoom: int | None = None,
88
- use_container_width: bool = True,
89
- width: int | None = None,
90
- height: int | None = None,
99
+ width: WidthWithoutContent = "stretch",
100
+ height: HeightWithoutContent = 500,
101
+ use_container_width: bool | None = None,
91
102
  ) -> DeltaGenerator:
92
103
  """Display a map with a scatterplot overlaid onto it.
93
104
 
@@ -163,28 +174,42 @@ class MapMixin:
163
174
  Zoom level as specified in
164
175
  https://wiki.openstreetmap.org/wiki/Zoom_levels.
165
176
 
166
- use_container_width : bool
177
+ width : "stretch" or int
178
+ The width of the chart element. This can be one of the following:
179
+
180
+ - ``"stretch"`` (default): The width of the element matches the
181
+ width of the parent container.
182
+ - An integer specifying the width in pixels: The element has a
183
+ fixed width. If the specified width is greater than the width of
184
+ the parent container, the width of the element matches the width
185
+ of the parent container.
186
+
187
+ height : "stretch" or int
188
+ The height of the chart element. This can be one of the following:
189
+
190
+ - An integer specifying the height in pixels: The element has a
191
+ fixed height. If the content is larger than the specified
192
+ height, scrolling is enabled. This is ``500`` by default.
193
+ - ``"stretch"``: The height of the element matches the height of
194
+ its content or the height of the parent container, whichever is
195
+ larger. If the element is not in a parent container, the height
196
+ of the element matches the height of its content.
197
+
198
+ use_container_width : bool or None
167
199
  Whether to override the map's native width with the width of
168
- the parent container. If ``use_container_width`` is ``True``
169
- (default), Streamlit sets the width of the map to match the width
170
- of the parent container. If ``use_container_width`` is ``False``,
171
- Streamlit sets the width of the chart to fit its contents according
172
- to the plotting library, up to the width of the parent container.
173
-
174
- width : int or None
175
- Desired width of the chart expressed in pixels. If ``width`` is
176
- ``None`` (default), Streamlit sets the width of the chart to fit
177
- its contents according to the plotting library, up to the width of
178
- the parent container. If ``width`` is greater than the width of the
179
- parent container, Streamlit sets the chart width to match the width
180
- of the parent container.
181
-
182
- To use ``width``, you must set ``use_container_width=False``.
183
-
184
- height : int or None
185
- Desired height of the chart expressed in pixels. If ``height`` is
186
- ``None`` (default), Streamlit sets the height of the chart to fit
187
- its contents according to the plotting library.
200
+ the parent container. This can be one of the following:
201
+
202
+ - ``None`` (default): Streamlit will use the map's default behavior.
203
+ - ``True``: Streamlit sets the width of the map to match the
204
+ width of the parent container.
205
+ - ``False``: Streamlit sets the width of the map to fit its
206
+ contents according to the plotting library, up to the width of
207
+ the parent container.
208
+
209
+ .. deprecated::
210
+ ``use_container_width`` is deprecated and will be removed in a
211
+ future release. For ``use_container_width=True``, use
212
+ ``width="stretch"``.
188
213
 
189
214
  Examples
190
215
  --------
@@ -231,12 +256,35 @@ class MapMixin:
231
256
  height: 600px
232
257
 
233
258
  """
259
+ # Handle use_container_width deprecation (for elements that already had width parameter)
260
+ if use_container_width is not None:
261
+ show_deprecation_warning(
262
+ make_deprecated_name_warning(
263
+ "use_container_width",
264
+ "width",
265
+ "2025-12-31",
266
+ "For `use_container_width=True`, use `width='stretch'`. "
267
+ "For `use_container_width=False`, specify an integer width.",
268
+ include_st_prefix=False,
269
+ ),
270
+ show_in_browser=False,
271
+ )
272
+ if use_container_width:
273
+ width = "stretch"
274
+ # For use_container_width=False, preserve any integer width that was set.
275
+
276
+ validate_width(width, allow_content=False)
277
+ validate_height(height, allow_content=False)
278
+
234
279
  map_proto = DeckGlJsonChartProto()
235
280
  deck_gl_json = to_deckgl_json(data, latitude, longitude, size, color, zoom)
236
- marshall(
237
- map_proto, deck_gl_json, use_container_width, width=width, height=height
281
+
282
+ marshall(map_proto, deck_gl_json)
283
+
284
+ layout_config = LayoutConfig(width=width, height=height)
285
+ return self.dg._enqueue(
286
+ "deck_gl_json_chart", map_proto, layout_config=layout_config
238
287
  )
239
- return self.dg._enqueue("deck_gl_json_chart", map_proto)
240
288
 
241
289
  @property
242
290
  def dg(self) -> DeltaGenerator:
@@ -399,9 +447,7 @@ def _convert_color_arg_or_column(
399
447
 
400
448
  if color_col_name is not None:
401
449
  # Convert color column to the right format.
402
- if len(data[color_col_name]) > 0 and is_color_like(
403
- data[color_col_name].iloc[0]
404
- ):
450
+ if len(data[color_col_name]) > 0 and is_color_like(data[color_col_name].iat[0]):
405
451
  # Use .loc[] to avoid a SettingWithCopyWarning in some cases.
406
452
  data.loc[:, color_col_name] = data.loc[:, color_col_name].map(
407
453
  to_int_color_tuple
@@ -466,18 +512,13 @@ def _get_zoom_level(distance: float) -> int:
466
512
  def marshall(
467
513
  pydeck_proto: DeckGlJsonChartProto,
468
514
  pydeck_json: str,
469
- use_container_width: bool,
470
- height: int | None = None,
471
- width: int | None = None,
472
515
  ) -> None:
473
- pydeck_proto.json = pydeck_json
474
- pydeck_proto.use_container_width = use_container_width
475
-
476
- if width:
477
- pydeck_proto.width = width
478
- if height:
479
- pydeck_proto.height = height
516
+ """Marshall a map proto with the given pydeck JSON specification.
480
517
 
518
+ Layout configuration (width, height, etc.) is handled by the LayoutConfig
519
+ system and not through proto fields.
520
+ """
521
+ pydeck_proto.json = pydeck_json
481
522
  pydeck_proto.id = ""
482
523
 
483
524
  mapbox_token = config.get_option("mapbox.token")
@@ -18,9 +18,7 @@ import io
18
18
  import re
19
19
  from datetime import timedelta
20
20
  from pathlib import Path
21
- from typing import TYPE_CHECKING, Final, Union, cast
22
-
23
- from typing_extensions import TypeAlias
21
+ from typing import TYPE_CHECKING, Final, TypeAlias, Union, cast
24
22
 
25
23
  from streamlit import runtime, type_util, url_util
26
24
  from streamlit.elements.lib.layout_utils import WidthWithoutContent, validate_width
@@ -53,11 +51,11 @@ MediaData: TypeAlias = Union[
53
51
  None,
54
52
  ]
55
53
 
56
- SubtitleData: TypeAlias = Union[
57
- str, Path, bytes, io.BytesIO, dict[str, Union[str, Path, bytes, io.BytesIO]], None
58
- ]
54
+ SubtitleData: TypeAlias = (
55
+ str | Path | bytes | io.BytesIO | dict[str, str | Path | bytes | io.BytesIO] | None
56
+ )
59
57
 
60
- MediaTime: TypeAlias = Union[int, float, timedelta, str]
58
+ MediaTime: TypeAlias = int | float | timedelta | str
61
59
 
62
60
  TIMEDELTA_PARSE_ERROR_MESSAGE: Final = (
63
61
  "Failed to convert '{param_name}' to a timedelta. "
@@ -639,6 +637,7 @@ def marshall_video(
639
637
  "video",
640
638
  # video does not yet allow setting a user-defined key
641
639
  user_key=None,
640
+ key_as_main_identity=False,
642
641
  dg=dg,
643
642
  url=proto.url,
644
643
  mimetype=mimetype,
@@ -831,6 +830,7 @@ def marshall_audio(
831
830
  proto.id = compute_and_register_element_id(
832
831
  "audio",
833
832
  user_key=None,
833
+ key_as_main_identity=False,
834
834
  dg=dg,
835
835
  url=proto.url,
836
836
  mimetype=mimetype,
@@ -16,9 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  from dataclasses import dataclass
18
18
  from textwrap import dedent
19
- from typing import TYPE_CHECKING, Any, Literal, Union, cast
20
-
21
- from typing_extensions import TypeAlias
19
+ from typing import TYPE_CHECKING, Any, Literal, TypeAlias, cast
22
20
 
23
21
  from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
24
22
  from streamlit.elements.lib.layout_utils import (
@@ -36,16 +34,14 @@ from streamlit.elements.lib.utils import (
36
34
  from streamlit.errors import StreamlitAPIException
37
35
  from streamlit.proto.Metric_pb2 import Metric as MetricProto
38
36
  from streamlit.runtime.metrics_util import gather_metrics
39
- from streamlit.string_util import clean_text
37
+ from streamlit.string_util import AnyNumber, clean_text, from_number
40
38
 
41
39
  if TYPE_CHECKING:
42
- import numpy as np
43
-
44
40
  from streamlit.delta_generator import DeltaGenerator
45
41
 
46
42
 
47
- Value: TypeAlias = Union["np.integer[Any]", "np.floating[Any]", float, int, str, None]
48
- Delta: TypeAlias = Union[float, int, str, None]
43
+ Value: TypeAlias = AnyNumber | str | None
44
+ Delta: TypeAlias = AnyNumber | str | None
49
45
  DeltaColor: TypeAlias = Literal["normal", "inverse", "off"]
50
46
 
51
47
 
@@ -98,10 +94,10 @@ class MetricMixin:
98
94
  .. |st.markdown| replace:: ``st.markdown``
99
95
  .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown
100
96
 
101
- value : int, float, str, or None
102
- Value of the metric. None is rendered as a long dash.
97
+ value : int, float, decimal.Decimal, str, or None
98
+ Value of the metric. ``None`` is rendered as a long dash.
103
99
 
104
- delta : int, float, str, or None
100
+ delta : int, float, decimal.Decimal, str, or None
105
101
  Indicator of how the metric changed, rendered with an arrow below
106
102
  the metric. If delta is negative (int/float) or starts with a minus
107
103
  sign (str), the arrow points down and the text is red; else the
@@ -338,23 +334,9 @@ def _parse_label(label: str) -> str:
338
334
  def _parse_value(value: Value) -> str:
339
335
  if value is None:
340
336
  return "—"
341
- if isinstance(value, (int, float, str)):
342
- return str(value)
343
- if hasattr(value, "item"):
344
- # Add support for numpy values (e.g. int16, float64, etc.)
345
- try:
346
- # Item could also be just a variable, so we use try, except
347
- if isinstance(value.item(), (float, int)):
348
- return str(value.item())
349
- except Exception: # noqa: S110
350
- # If the numpy item is not a valid value, the TypeError below will be raised.
351
- pass
352
-
353
- raise TypeError(
354
- f"'{value}' is of type {type(value)}, which is not an accepted type."
355
- " value only accepts: int, float, str, or None."
356
- " Please convert the value to an accepted type."
357
- )
337
+ if isinstance(value, str):
338
+ return value
339
+ return from_number(value)
358
340
 
359
341
 
360
342
  def _parse_delta(delta: Delta) -> str:
@@ -362,13 +344,7 @@ def _parse_delta(delta: Delta) -> str:
362
344
  return ""
363
345
  if isinstance(delta, str):
364
346
  return dedent(delta)
365
- if isinstance(delta, (int, float)):
366
- return str(delta)
367
- raise TypeError(
368
- f"'{delta}' is of type {type(delta)}, which is not an accepted type."
369
- " delta only accepts: int, float, str, or None."
370
- " Please convert the value to an accepted type."
371
- )
347
+ return from_number(delta)
372
348
 
373
349
 
374
350
  def _determine_delta_color_and_direction(
streamlit/elements/pdf.py CHANGED
@@ -16,9 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import io
18
18
  from pathlib import Path
19
- from typing import TYPE_CHECKING, Any, Union, cast
20
-
21
- from typing_extensions import TypeAlias
19
+ from typing import TYPE_CHECKING, Any, TypeAlias, cast
22
20
 
23
21
  from streamlit import url_util
24
22
  from streamlit.elements.lib.layout_utils import validate_height
@@ -29,7 +27,7 @@ if TYPE_CHECKING:
29
27
  from streamlit.delta_generator import DeltaGenerator
30
28
  from streamlit.elements.lib.layout_utils import HeightWithoutContent
31
29
 
32
- PdfData: TypeAlias = Union[str, Path, bytes, io.BytesIO]
30
+ PdfData: TypeAlias = str | Path | bytes | io.BytesIO
33
31
 
34
32
 
35
33
  def _get_pdf_component() -> Any | None: