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
@@ -0,0 +1,42 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ *!
5
+ Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+ """
19
+
20
+ import google.protobuf.descriptor
21
+ import google.protobuf.message
22
+ import typing
23
+
24
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
25
+
26
+ @typing.final
27
+ class Space(google.protobuf.message.Message):
28
+ """A space element for adding vertical or horizontal spacing.
29
+ The size and direction are controlled via Element.width_config and
30
+ Element.height_config. The frontend uses FlexContext to determine which
31
+ dimension to apply based on the parent container's direction.
32
+ Space element has no content - layout is controlled via
33
+ Element.width_config and Element.height_config
34
+ """
35
+
36
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
37
+
38
+ def __init__(
39
+ self,
40
+ ) -> None: ...
41
+
42
+ global___Space = Space
@@ -16,7 +16,7 @@ from streamlit.proto import Common_pb2 as streamlit_dot_proto_dot_Common__pb2
16
16
  from streamlit.proto import Components_pb2 as streamlit_dot_proto_dot_Components__pb2
17
17
 
18
18
 
19
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"streamlit/proto/WidgetStates.proto\x1a\x1cstreamlit/proto/Common.proto\x1a streamlit/proto/Components.proto\"-\n\x0cWidgetStates\x12\x1d\n\x07widgets\x18\x01 \x03(\x0b\x32\x0c.WidgetState\"\x87\x04\n\x0bWidgetState\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\rtrigger_value\x18\x02 \x01(\x08H\x00\x12\x14\n\nbool_value\x18\x03 \x01(\x08H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x13\n\tint_value\x18\x05 \x01(\x12H\x00\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x00\x12*\n\x12\x64ouble_array_value\x18\x07 \x01(\x0b\x32\x0c.DoubleArrayH\x00\x12\'\n\x0fint_array_value\x18\x08 \x01(\x0b\x32\x0c.SInt64ArrayH\x00\x12*\n\x12string_array_value\x18\t \x01(\x0b\x32\x0c.StringArrayH\x00\x12\x14\n\njson_value\x18\n \x01(\tH\x00\x12\"\n\x0b\x61rrow_value\x18\x0b \x01(\x0b\x32\x0b.ArrowTableH\x00\x12\x15\n\x0b\x62ytes_value\x18\x0c \x01(\x0cH\x00\x12\x37\n\x19\x66ile_uploader_state_value\x18\r \x01(\x0b\x32\x12.FileUploaderStateH\x00\x12\x37\n\x14string_trigger_value\x18\x0e \x01(\x0b\x32\x13.StringTriggerValueB\x02\x18\x01H\x00\x12+\n\x10\x63hat_input_value\x18\x0f \x01(\x0b\x32\x0f.ChatInputValueH\x00\x42\x07\n\x05valueB1\n\x1c\x63om.snowflake.apps.streamlitB\x11WidgetStatesProtob\x06proto3')
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"streamlit/proto/WidgetStates.proto\x1a\x1cstreamlit/proto/Common.proto\x1a streamlit/proto/Components.proto\"-\n\x0cWidgetStates\x12\x1d\n\x07widgets\x18\x01 \x03(\x0b\x32\x0c.WidgetState\"\xa5\x04\n\x0bWidgetState\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\rtrigger_value\x18\x02 \x01(\x08H\x00\x12\x14\n\nbool_value\x18\x03 \x01(\x08H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x13\n\tint_value\x18\x05 \x01(\x12H\x00\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x00\x12*\n\x12\x64ouble_array_value\x18\x07 \x01(\x0b\x32\x0c.DoubleArrayH\x00\x12\'\n\x0fint_array_value\x18\x08 \x01(\x0b\x32\x0c.SInt64ArrayH\x00\x12*\n\x12string_array_value\x18\t \x01(\x0b\x32\x0c.StringArrayH\x00\x12\x14\n\njson_value\x18\n \x01(\tH\x00\x12\"\n\x0b\x61rrow_value\x18\x0b \x01(\x0b\x32\x0b.ArrowTableH\x00\x12\x15\n\x0b\x62ytes_value\x18\x0c \x01(\x0cH\x00\x12\x37\n\x19\x66ile_uploader_state_value\x18\r \x01(\x0b\x32\x12.FileUploaderStateH\x00\x12\x37\n\x14string_trigger_value\x18\x0e \x01(\x0b\x32\x13.StringTriggerValueB\x02\x18\x01H\x00\x12+\n\x10\x63hat_input_value\x18\x0f \x01(\x0b\x32\x0f.ChatInputValueH\x00\x12\x1c\n\x12json_trigger_value\x18\x10 \x01(\tH\x00\x42\x07\n\x05valueB1\n\x1c\x63om.snowflake.apps.streamlitB\x11WidgetStatesProtob\x06proto3')
20
20
 
21
21
  _globals = globals()
22
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -29,5 +29,5 @@ if not _descriptor._USE_C_DESCRIPTORS:
29
29
  _globals['_WIDGETSTATES']._serialized_start=102
30
30
  _globals['_WIDGETSTATES']._serialized_end=147
31
31
  _globals['_WIDGETSTATE']._serialized_start=150
32
- _globals['_WIDGETSTATE']._serialized_end=669
32
+ _globals['_WIDGETSTATE']._serialized_end=699
33
33
  # @@protoc_insertion_point(module_scope)
@@ -67,6 +67,7 @@ class WidgetState(google.protobuf.message.Message):
67
67
  FILE_UPLOADER_STATE_VALUE_FIELD_NUMBER: builtins.int
68
68
  STRING_TRIGGER_VALUE_FIELD_NUMBER: builtins.int
69
69
  CHAT_INPUT_VALUE_FIELD_NUMBER: builtins.int
70
+ JSON_TRIGGER_VALUE_FIELD_NUMBER: builtins.int
70
71
  id: builtins.str
71
72
  trigger_value: builtins.bool
72
73
  """trigger_value is for buttons. A button's value needs to
@@ -82,6 +83,14 @@ class WidgetState(google.protobuf.message.Message):
82
83
  string_value: builtins.str
83
84
  json_value: builtins.str
84
85
  bytes_value: builtins.bytes
86
+ json_trigger_value: builtins.str
87
+ """Transient trigger payload transport (JSON-stringified).
88
+ - Purpose: carry per-run, non-persistent trigger data across the wire.
89
+ - Shape: JSON object or JSON array (batched within a single update).
90
+ - Lifecycle: treated as a trigger; cleared after each script run.
91
+ Use json_value for persistent state; use json_trigger_value for
92
+ auto-resetting payloads.
93
+ """
85
94
  @property
86
95
  def double_array_value(self) -> streamlit.proto.Common_pb2.DoubleArray: ...
87
96
  @property
@@ -122,9 +131,10 @@ class WidgetState(google.protobuf.message.Message):
122
131
  file_uploader_state_value: streamlit.proto.Common_pb2.FileUploaderState | None = ...,
123
132
  string_trigger_value: streamlit.proto.Common_pb2.StringTriggerValue | None = ...,
124
133
  chat_input_value: streamlit.proto.Common_pb2.ChatInputValue | None = ...,
134
+ json_trigger_value: builtins.str = ...,
125
135
  ) -> None: ...
126
- def HasField(self, field_name: typing.Literal["arrow_value", b"arrow_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "chat_input_value", b"chat_input_value", "double_array_value", b"double_array_value", "double_value", b"double_value", "file_uploader_state_value", b"file_uploader_state_value", "int_array_value", b"int_array_value", "int_value", b"int_value", "json_value", b"json_value", "string_array_value", b"string_array_value", "string_trigger_value", b"string_trigger_value", "string_value", b"string_value", "trigger_value", b"trigger_value", "value", b"value"]) -> builtins.bool: ...
127
- def ClearField(self, field_name: typing.Literal["arrow_value", b"arrow_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "chat_input_value", b"chat_input_value", "double_array_value", b"double_array_value", "double_value", b"double_value", "file_uploader_state_value", b"file_uploader_state_value", "id", b"id", "int_array_value", b"int_array_value", "int_value", b"int_value", "json_value", b"json_value", "string_array_value", b"string_array_value", "string_trigger_value", b"string_trigger_value", "string_value", b"string_value", "trigger_value", b"trigger_value", "value", b"value"]) -> None: ...
128
- def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["trigger_value", "bool_value", "double_value", "int_value", "string_value", "double_array_value", "int_array_value", "string_array_value", "json_value", "arrow_value", "bytes_value", "file_uploader_state_value", "string_trigger_value", "chat_input_value"] | None: ...
136
+ def HasField(self, field_name: typing.Literal["arrow_value", b"arrow_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "chat_input_value", b"chat_input_value", "double_array_value", b"double_array_value", "double_value", b"double_value", "file_uploader_state_value", b"file_uploader_state_value", "int_array_value", b"int_array_value", "int_value", b"int_value", "json_trigger_value", b"json_trigger_value", "json_value", b"json_value", "string_array_value", b"string_array_value", "string_trigger_value", b"string_trigger_value", "string_value", b"string_value", "trigger_value", b"trigger_value", "value", b"value"]) -> builtins.bool: ...
137
+ def ClearField(self, field_name: typing.Literal["arrow_value", b"arrow_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "chat_input_value", b"chat_input_value", "double_array_value", b"double_array_value", "double_value", b"double_value", "file_uploader_state_value", b"file_uploader_state_value", "id", b"id", "int_array_value", b"int_array_value", "int_value", b"int_value", "json_trigger_value", b"json_trigger_value", "json_value", b"json_value", "string_array_value", b"string_array_value", "string_trigger_value", b"string_trigger_value", "string_value", b"string_value", "trigger_value", b"trigger_value", "value", b"value"]) -> None: ...
138
+ def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["trigger_value", "bool_value", "double_value", "int_value", "string_value", "double_array_value", "int_array_value", "string_array_value", "json_value", "arrow_value", "bytes_value", "file_uploader_state_value", "string_trigger_value", "chat_input_value", "json_trigger_value"] | None: ...
129
139
 
130
140
  global___WidgetState = WidgetState
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
14
14
 
15
15
 
16
16
 
17
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!streamlit/proto/WidthConfig.proto\x12\tstreamlit\"`\n\x0bWidthConfig\x12\x15\n\x0buse_stretch\x18\x01 \x01(\x08H\x00\x12\x15\n\x0buse_content\x18\x02 \x01(\x08H\x00\x12\x15\n\x0bpixel_width\x18\x03 \x01(\rH\x00\x42\x0c\n\nwidth_specB0\n\x1c\x63om.snowflake.apps.streamlitB\x10WidthConfigProtob\x06proto3')
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!streamlit/proto/WidthConfig.proto\x12\tstreamlit\"u\n\x0bWidthConfig\x12\x15\n\x0buse_stretch\x18\x01 \x01(\x08H\x00\x12\x15\n\x0buse_content\x18\x02 \x01(\x08H\x00\x12\x15\n\x0bpixel_width\x18\x03 \x01(\rH\x00\x12\x13\n\trem_width\x18\x04 \x01(\x02H\x00\x42\x0c\n\nwidth_specB0\n\x1c\x63om.snowflake.apps.streamlitB\x10WidthConfigProtob\x06proto3')
18
18
 
19
19
  _globals = globals()
20
20
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -23,5 +23,5 @@ if not _descriptor._USE_C_DESCRIPTORS:
23
23
  _globals['DESCRIPTOR']._loaded_options = None
24
24
  _globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\020WidthConfigProto'
25
25
  _globals['_WIDTHCONFIG']._serialized_start=48
26
- _globals['_WIDTHCONFIG']._serialized_end=144
26
+ _globals['_WIDTHCONFIG']._serialized_end=165
27
27
  # @@protoc_insertion_point(module_scope)
@@ -31,18 +31,21 @@ class WidthConfig(google.protobuf.message.Message):
31
31
  USE_STRETCH_FIELD_NUMBER: builtins.int
32
32
  USE_CONTENT_FIELD_NUMBER: builtins.int
33
33
  PIXEL_WIDTH_FIELD_NUMBER: builtins.int
34
+ REM_WIDTH_FIELD_NUMBER: builtins.int
34
35
  use_stretch: builtins.bool
35
36
  use_content: builtins.bool
36
37
  pixel_width: builtins.int
38
+ rem_width: builtins.float
37
39
  def __init__(
38
40
  self,
39
41
  *,
40
42
  use_stretch: builtins.bool = ...,
41
43
  use_content: builtins.bool = ...,
42
44
  pixel_width: builtins.int = ...,
45
+ rem_width: builtins.float = ...,
43
46
  ) -> None: ...
44
- def HasField(self, field_name: typing.Literal["pixel_width", b"pixel_width", "use_content", b"use_content", "use_stretch", b"use_stretch", "width_spec", b"width_spec"]) -> builtins.bool: ...
45
- def ClearField(self, field_name: typing.Literal["pixel_width", b"pixel_width", "use_content", b"use_content", "use_stretch", b"use_stretch", "width_spec", b"width_spec"]) -> None: ...
46
- def WhichOneof(self, oneof_group: typing.Literal["width_spec", b"width_spec"]) -> typing.Literal["use_stretch", "use_content", "pixel_width"] | None: ...
47
+ def HasField(self, field_name: typing.Literal["pixel_width", b"pixel_width", "rem_width", b"rem_width", "use_content", b"use_content", "use_stretch", b"use_stretch", "width_spec", b"width_spec"]) -> builtins.bool: ...
48
+ def ClearField(self, field_name: typing.Literal["pixel_width", b"pixel_width", "rem_width", b"rem_width", "use_content", b"use_content", "use_stretch", b"use_stretch", "width_spec", b"width_spec"]) -> None: ...
49
+ def WhichOneof(self, oneof_group: typing.Literal["width_spec", b"width_spec"]) -> typing.Literal["use_stretch", "use_content", "pixel_width", "rem_width"] | None: ...
47
50
 
48
51
  global___WidthConfig = WidthConfig
@@ -20,7 +20,7 @@ import os
20
20
  import sys
21
21
  import uuid
22
22
  from enum import Enum
23
- from typing import TYPE_CHECKING, Any, Callable, Final
23
+ from typing import TYPE_CHECKING, Any, Final
24
24
 
25
25
  from google.protobuf.json_format import ParseDict
26
26
 
@@ -45,11 +45,14 @@ from streamlit.runtime.metrics_util import Installation
45
45
  from streamlit.runtime.pages_manager import PagesManager
46
46
  from streamlit.runtime.scriptrunner import RerunData, ScriptRunner, ScriptRunnerEvent
47
47
  from streamlit.runtime.secrets import secrets_singleton
48
+ from streamlit.runtime.theme_util import parse_fonts_with_source
48
49
  from streamlit.string_util import to_snake_case
49
50
  from streamlit.version import STREAMLIT_VERSION_STRING
50
51
  from streamlit.watcher import LocalSourcesWatcher
51
52
 
52
53
  if TYPE_CHECKING:
54
+ from collections.abc import Callable
55
+
53
56
  from streamlit.proto.BackMsg_pb2 import BackMsg
54
57
  from streamlit.runtime.script_data import ScriptData
55
58
  from streamlit.runtime.scriptrunner.script_cache import ScriptCache
@@ -735,11 +738,35 @@ class AppSession:
735
738
  msg.new_session, pages or self._pages_manager.get_pages()
736
739
  )
737
740
  _populate_config_msg(msg.new_session.config)
741
+
742
+ # Handles theme sections
743
+ # [theme] configs
738
744
  _populate_theme_msg(msg.new_session.custom_theme)
745
+ # [theme.light] configs
746
+ _populate_theme_msg(
747
+ msg.new_session.custom_theme.light,
748
+ f"theme.{config.CustomThemeCategories.LIGHT.value}",
749
+ )
750
+ # [theme.dark] configs
751
+ _populate_theme_msg(
752
+ msg.new_session.custom_theme.dark,
753
+ f"theme.{config.CustomThemeCategories.DARK.value}",
754
+ )
755
+ # [theme.sidebar] configs
739
756
  _populate_theme_msg(
740
757
  msg.new_session.custom_theme.sidebar,
741
758
  f"theme.{config.CustomThemeCategories.SIDEBAR.value}",
742
759
  )
760
+ # [theme.light.sidebar] configs
761
+ _populate_theme_msg(
762
+ msg.new_session.custom_theme.light.sidebar,
763
+ f"theme.{config.CustomThemeCategories.LIGHT_SIDEBAR.value}",
764
+ )
765
+ # [theme.dark.sidebar] configs
766
+ _populate_theme_msg(
767
+ msg.new_session.custom_theme.dark.sidebar,
768
+ f"theme.{config.CustomThemeCategories.DARK_SIDEBAR.value}",
769
+ )
743
770
 
744
771
  # Immutable session data. We send this every time a new session is
745
772
  # started, to avoid having to track whether the client has already
@@ -810,6 +837,12 @@ class AppSession:
810
837
  else:
811
838
  msg.git_info_changed.state = GitInfo.GitStates.DEFAULT
812
839
 
840
+ _LOGGER.debug(
841
+ "Git information found. Name: %s, Branch: %s, Module: %s",
842
+ repository_name,
843
+ branch,
844
+ module,
845
+ )
813
846
  self._enqueue_forward_msg(msg)
814
847
  except Exception as ex:
815
848
  # Users may never even install Git in the first place, so this
@@ -946,6 +979,8 @@ def _populate_theme_msg(msg: CustomThemeConfig, section: str = "theme") -> None:
946
979
  "base",
947
980
  "font",
948
981
  "fontFaces",
982
+ "codeFont",
983
+ "headingFont",
949
984
  "headingFontSizes",
950
985
  "headingFontWeights",
951
986
  "chartCategoricalColors",
@@ -975,11 +1010,15 @@ def _populate_theme_msg(msg: CustomThemeConfig, section: str = "theme") -> None:
975
1010
  else:
976
1011
  msg.base = base_map[base]
977
1012
 
978
- # Since the font field uses the deprecated enum, we need to put the font
979
- # config into the body_font field instead:
980
- body_font = theme_opts.get("font", None)
981
- if body_font:
982
- msg.body_font = body_font
1013
+ # Handle font, codeFont, and headingFont config options and if they are
1014
+ # specified with a source URL
1015
+ msg = parse_fonts_with_source(
1016
+ msg,
1017
+ theme_opts.get("font", None),
1018
+ theme_opts.get("codeFont", None),
1019
+ theme_opts.get("headingFont", None),
1020
+ section,
1021
+ )
983
1022
 
984
1023
  font_faces = theme_opts.get("fontFaces", None)
985
1024
  # If fontFaces was configured via config.toml, it's already a parsed list of
@@ -21,15 +21,14 @@ import threading
21
21
  from typing import (
22
22
  TYPE_CHECKING,
23
23
  Any,
24
- Callable,
25
24
  Final,
26
25
  Literal,
26
+ TypeAlias,
27
27
  TypeVar,
28
- Union,
29
28
  overload,
30
29
  )
31
30
 
32
- from typing_extensions import ParamSpec, TypeAlias
31
+ from typing_extensions import ParamSpec
33
32
 
34
33
  import streamlit as st
35
34
  from streamlit import runtime
@@ -66,6 +65,7 @@ from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
66
65
  from streamlit.time_util import time_to_seconds
67
66
 
68
67
  if TYPE_CHECKING:
68
+ from collections.abc import Callable
69
69
  from datetime import timedelta
70
70
 
71
71
  from streamlit.runtime.caching.hashing import HashFuncsDict
@@ -75,7 +75,7 @@ _LOGGER: Final = get_logger(__name__)
75
75
  CACHE_DATA_MESSAGE_REPLAY_CTX = CachedMessageReplayContext(CacheType.DATA)
76
76
 
77
77
  # The cache persistence options we support: "disk" or None
78
- CachePersistType: TypeAlias = Union[Literal["disk"], None]
78
+ CachePersistType: TypeAlias = Literal["disk"] | None
79
79
 
80
80
 
81
81
  P = ParamSpec("P")
@@ -14,12 +14,15 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Callable, Generic, TypeVar
17
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar
18
18
 
19
19
  from streamlit import type_util
20
20
  from streamlit.errors import MarkdownFormattedException, StreamlitAPIException
21
21
  from streamlit.runtime.caching.cache_type import CacheType, get_decorator_api_name
22
22
 
23
+ if TYPE_CHECKING:
24
+ from collections.abc import Callable
25
+
23
26
  CACHE_DOCS_URL = "https://docs.streamlit.io/develop/concepts/architecture/caching"
24
27
 
25
28
 
@@ -19,17 +19,18 @@ from __future__ import annotations
19
19
 
20
20
  import math
21
21
  import threading
22
+ from collections.abc import Callable
22
23
  from typing import (
23
24
  TYPE_CHECKING,
24
25
  Any,
25
- Callable,
26
26
  Final,
27
+ TypeAlias,
27
28
  TypeVar,
28
29
  overload,
29
30
  )
30
31
 
31
32
  from cachetools import TTLCache
32
- from typing_extensions import ParamSpec, TypeAlias
33
+ from typing_extensions import ParamSpec
33
34
 
34
35
  import streamlit as st
35
36
  from streamlit.logger import get_logger
@@ -24,7 +24,7 @@ import threading
24
24
  import time
25
25
  from abc import abstractmethod
26
26
  from collections import defaultdict
27
- from typing import TYPE_CHECKING, Any, Callable, Final, Generic, TypeVar, cast, overload
27
+ from typing import TYPE_CHECKING, Any, Final, Generic, TypeVar, cast, overload
28
28
 
29
29
  from typing_extensions import ParamSpec
30
30
 
@@ -54,6 +54,7 @@ from streamlit.runtime.scriptrunner_utils.script_run_context import (
54
54
 
55
55
  if TYPE_CHECKING:
56
56
  import types
57
+ from collections.abc import Callable
57
58
 
58
59
  from streamlit.runtime.caching.cache_type import CacheType
59
60
 
@@ -17,7 +17,7 @@ from __future__ import annotations
17
17
  import contextlib
18
18
  import threading
19
19
  from dataclasses import dataclass
20
- from typing import TYPE_CHECKING, Any, Callable, Generic, TypeVar, Union
20
+ from typing import TYPE_CHECKING, Any, Generic, TypeAlias, TypeVar
21
21
 
22
22
  from typing_extensions import ParamSpec
23
23
 
@@ -29,7 +29,7 @@ from streamlit.runtime.scriptrunner_utils.script_run_context import (
29
29
  )
30
30
 
31
31
  if TYPE_CHECKING:
32
- from collections.abc import Iterator
32
+ from collections.abc import Callable, Iterator
33
33
 
34
34
  from google.protobuf.message import Message
35
35
 
@@ -69,7 +69,7 @@ class BlockMsgData:
69
69
  returned_dgs_id: str
70
70
 
71
71
 
72
- MsgData = Union[ElementMsgData, BlockMsgData]
72
+ MsgData: TypeAlias = ElementMsgData | BlockMsgData
73
73
 
74
74
 
75
75
  R = TypeVar("R")
@@ -31,12 +31,11 @@ import tempfile
31
31
  import threading
32
32
  import uuid
33
33
  import weakref
34
+ from collections.abc import Callable
34
35
  from enum import Enum
35
36
  from re import Pattern
36
37
  from types import MappingProxyType
37
- from typing import TYPE_CHECKING, Any, Callable, Final, Union, cast
38
-
39
- from typing_extensions import TypeAlias
38
+ from typing import TYPE_CHECKING, Any, Final, TypeAlias, cast
40
39
 
41
40
  from streamlit import logger, type_util, util
42
41
  from streamlit.errors import StreamlitAPIException
@@ -59,7 +58,7 @@ _PANDAS_SAMPLE_SIZE: Final = 10_000
59
58
  _NP_SIZE_LARGE: Final = 500_000
60
59
  _NP_SAMPLE_SIZE: Final = 100_000
61
60
 
62
- HashFuncsDict: TypeAlias = dict[Union[str, type[Any]], Callable[[Any], Any]]
61
+ HashFuncsDict: TypeAlias = dict[str | type[Any], Callable[[Any], Any]]
63
62
 
64
63
  # Arbitrary item to denote where we found a cycle in a hashed object.
65
64
  # This allows us to hash self-referencing lists, dictionaries, etc.
@@ -16,7 +16,8 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import TYPE_CHECKING, Any, Callable, TypeVar
19
+ from collections.abc import Callable
20
+ from typing import TYPE_CHECKING, Any, TypeVar
20
21
 
21
22
  from streamlit import deprecation_util
22
23
  from streamlit.runtime.caching import CACHE_DOCS_URL
@@ -369,9 +369,7 @@ def connection_factory( # type: ignore
369
369
  """
370
370
 
371
371
  if name.startswith(_USE_ENV_PREFIX):
372
- # It'd be nice to use str.removeprefix() here, but we won't be able to do that
373
- # until the minimum Python version we support is 3.9.
374
- envvar_name = name[len(_USE_ENV_PREFIX) :]
372
+ envvar_name = name.removeprefix(_USE_ENV_PREFIX)
375
373
  name = os.environ[envvar_name]
376
374
 
377
375
  # type is a nice kwarg name for the st.connection user but is annoying to work with
@@ -14,10 +14,13 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Callable
17
+ from typing import TYPE_CHECKING, Any
18
18
 
19
19
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
20
20
 
21
+ if TYPE_CHECKING:
22
+ from collections.abc import Callable
23
+
21
24
 
22
25
  class ForwardMsgQueue:
23
26
  """Accumulates a session's outgoing ForwardMsgs.
@@ -17,9 +17,10 @@ from __future__ import annotations
17
17
  import contextlib
18
18
  import inspect
19
19
  from abc import abstractmethod
20
+ from collections.abc import Callable
20
21
  from copy import deepcopy
21
22
  from functools import wraps
22
- from typing import TYPE_CHECKING, Any, Callable, Protocol, TypeVar, overload
23
+ from typing import TYPE_CHECKING, Any, Protocol, TypeVar, overload
23
24
 
24
25
  from streamlit.error_util import handle_uncaught_app_exception
25
26
  from streamlit.errors import FragmentHandledException, FragmentStorageKeyError
@@ -34,7 +34,7 @@ _LOGGER: Final = get_logger(__name__)
34
34
 
35
35
  # Mimetype -> filename extension map for the `get_extension_for_mimetype`
36
36
  # function. We use Python's `mimetypes.guess_extension` for most mimetypes,
37
- # but (as of Python 3.9) `mimetypes.guess_extension("audio/wav")` returns None,
37
+ # but (as of Python 3.12) `mimetypes.guess_extension("audio/wav")` returns None,
38
38
  # so we handle it ourselves.
39
39
  PREFERRED_MIMETYPE_EXTENSION_MAP: Final = {
40
40
  "audio/wav": ".wav",
@@ -21,9 +21,9 @@ import sys
21
21
  import threading
22
22
  import time
23
23
  import uuid
24
- from collections.abc import Sized
24
+ from collections.abc import Callable, Sized
25
25
  from functools import wraps
26
- from typing import Any, Callable, Final, TypeVar, cast, overload
26
+ from typing import Any, Final, TypeVar, cast, overload
27
27
 
28
28
  from streamlit import config, file_util, util
29
29
  from streamlit.logger import get_logger
@@ -331,6 +331,10 @@ def _get_command_telemetry(
331
331
  ):
332
332
  name = f"component:{self_arg.name}"
333
333
 
334
+ if name == "_bidi_component" and len(args) > 0 and isinstance(args[0], str):
335
+ component_name = args[0]
336
+ name = f"component_v2:{component_name}"
337
+
334
338
  return Command(name=name, args=arguments)
335
339
 
336
340
 
@@ -23,6 +23,7 @@ from enum import Enum
23
23
  from typing import TYPE_CHECKING, Final, NamedTuple
24
24
 
25
25
  from streamlit.components.lib.local_component_registry import LocalComponentRegistry
26
+ from streamlit.components.v2.component_manager import BidiComponentManager
26
27
  from streamlit.logger import get_logger
27
28
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
28
29
  from streamlit.runtime.app_session import AppSession
@@ -101,6 +102,11 @@ class RuntimeConfig:
101
102
  default_factory=LocalComponentRegistry
102
103
  )
103
104
 
105
+ # The BidiComponentManager instance to use for v2 components.
106
+ bidi_component_registry: BidiComponentManager = field(
107
+ default_factory=BidiComponentManager
108
+ )
109
+
104
110
  # The SessionManager class to be used.
105
111
  session_manager_class: type[SessionManager] = WebsocketSessionManager
106
112
 
@@ -201,11 +207,15 @@ class Runtime:
201
207
 
202
208
  # Initialize managers
203
209
  self._component_registry = config.component_registry
210
+ self._bidi_component_registry = config.bidi_component_registry
204
211
  self._uploaded_file_mgr = config.uploaded_file_manager
205
212
  self._media_file_mgr = MediaFileManager(storage=config.media_file_storage)
206
213
  self._cache_storage_manager = config.cache_storage_manager
207
214
  self._script_cache = ScriptCache()
208
215
 
216
+ # Discover and register components for CCv2 from installed packages
217
+ self._bidi_component_registry.discover_and_register_components()
218
+
209
219
  self._session_mgr = config.session_manager_class(
210
220
  session_storage=config.session_storage,
211
221
  uploaded_file_manager=self._uploaded_file_mgr,
@@ -227,6 +237,10 @@ class Runtime:
227
237
  def component_registry(self) -> BaseComponentRegistry:
228
238
  return self._component_registry
229
239
 
240
+ @property
241
+ def bidi_component_registry(self) -> BidiComponentManager:
242
+ return self._bidi_component_registry
243
+
230
244
  @property
231
245
  def uploaded_file_mgr(self) -> UploadedFileManager:
232
246
  return self._uploaded_file_mgr
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import sys
18
- from typing import TYPE_CHECKING, Any, Callable, Literal
18
+ from typing import TYPE_CHECKING, Any, Literal
19
19
 
20
20
  from streamlit import util
21
21
  from streamlit.delta_generator_singletons import (
@@ -30,6 +30,7 @@ from streamlit.runtime.scriptrunner_utils.exceptions import (
30
30
  )
31
31
 
32
32
  if TYPE_CHECKING:
33
+ from collections.abc import Callable
33
34
  from types import TracebackType
34
35
 
35
36
  from streamlit.runtime.scriptrunner_utils.script_requests import RerunData
@@ -21,7 +21,7 @@ import types
21
21
  from contextlib import contextmanager
22
22
  from enum import Enum
23
23
  from timeit import default_timer as timer
24
- from typing import TYPE_CHECKING, Any, Callable, Final, Literal, cast
24
+ from typing import TYPE_CHECKING, Any, Final, Literal, cast
25
25
 
26
26
  from blinker import Signal
27
27
 
@@ -62,7 +62,7 @@ from streamlit.runtime.state import (
62
62
  from streamlit.source_util import page_sort_key
63
63
 
64
64
  if TYPE_CHECKING:
65
- from collections.abc import Generator
65
+ from collections.abc import Callable, Generator
66
66
 
67
67
  from streamlit.runtime.fragment import FragmentStorage
68
68
  from streamlit.runtime.scriptrunner.script_cache import ScriptCache
@@ -22,14 +22,11 @@ from collections import Counter
22
22
  from dataclasses import dataclass, field
23
23
  from typing import (
24
24
  TYPE_CHECKING,
25
- Callable,
26
25
  Final,
27
- Union,
26
+ TypeAlias,
28
27
  )
29
28
  from urllib import parse
30
29
 
31
- from typing_extensions import TypeAlias
32
-
33
30
  from streamlit.errors import (
34
31
  NoSessionContext,
35
32
  StreamlitAPIException,
@@ -41,7 +38,7 @@ from streamlit.runtime.forward_msg_cache import (
41
38
  )
42
39
 
43
40
  if TYPE_CHECKING:
44
- from collections.abc import Generator
41
+ from collections.abc import Callable, Generator
45
42
  from pathlib import Path
46
43
 
47
44
  from streamlit.cursor import RunningCursor
@@ -55,7 +52,7 @@ if TYPE_CHECKING:
55
52
  from streamlit.runtime.uploaded_file_manager import UploadedFileManager
56
53
  _LOGGER: Final = get_logger(__name__)
57
54
 
58
- UserInfo: TypeAlias = dict[str, Union[str, bool, None]]
55
+ UserInfo: TypeAlias = dict[str, str | bool | None]
59
56
 
60
57
 
61
58
  # If true, it indicates that we are in a cached function that disallows the usage of
@@ -16,11 +16,10 @@ from __future__ import annotations
16
16
 
17
17
  import os
18
18
  import threading
19
- from collections.abc import ItemsView, Iterator, KeysView, Mapping, ValuesView
19
+ from collections.abc import Callable, ItemsView, Iterator, KeysView, Mapping, ValuesView
20
20
  from copy import deepcopy
21
21
  from typing import (
22
22
  Any,
23
- Callable,
24
23
  Final,
25
24
  NoReturn,
26
25
  )
@@ -461,8 +460,7 @@ class Secrets(Mapping[str, Any]):
461
460
  return value
462
461
  return AttrDict(value)
463
462
  # We add FileNotFoundError since __getattr__ is expected to only raise
464
- # AttributeError. Without handling FileNotFoundError, unittests.mocks
465
- # fails during mock creation on Python3.9
463
+ # AttributeError and mocking utilities expect that contract.
466
464
  except (KeyError, FileNotFoundError):
467
465
  raise AttributeError(_missing_attr_error_message(key))
468
466
 
@@ -16,9 +16,11 @@ from __future__ import annotations
16
16
 
17
17
  from abc import abstractmethod
18
18
  from dataclasses import dataclass
19
- from typing import TYPE_CHECKING, Callable, Protocol, cast
19
+ from typing import TYPE_CHECKING, Protocol, cast
20
20
 
21
21
  if TYPE_CHECKING:
22
+ from collections.abc import Callable
23
+
22
24
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
23
25
  from streamlit.runtime.app_session import AppSession
24
26
  from streamlit.runtime.script_data import ScriptData