streamlit 1.50.0__py3-none-any.whl → 1.52.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 (406) hide show
  1. streamlit/__init__.py +5 -1
  2. streamlit/commands/execution_control.py +89 -14
  3. streamlit/commands/navigation.py +4 -6
  4. streamlit/commands/page_config.py +4 -6
  5. streamlit/components/v1/component_arrow.py +7 -7
  6. streamlit/components/v2/__init__.py +514 -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 +534 -0
  10. streamlit/components/v2/bidi_component/serialization.py +272 -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 +439 -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 +426 -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 +456 -53
  23. streamlit/config_option.py +4 -1
  24. streamlit/config_util.py +650 -1
  25. streamlit/connections/snowflake_connection.py +1 -1
  26. streamlit/connections/snowpark_connection.py +1 -1
  27. streamlit/dataframe_util.py +33 -26
  28. streamlit/delta_generator.py +13 -4
  29. streamlit/delta_generator_singletons.py +11 -15
  30. streamlit/deprecation_util.py +17 -6
  31. streamlit/elements/alert.py +16 -0
  32. streamlit/elements/arrow.py +68 -10
  33. streamlit/elements/bokeh_chart.py +10 -78
  34. streamlit/elements/code.py +2 -2
  35. streamlit/elements/deck_gl_json_chart.py +98 -40
  36. streamlit/elements/dialog_decorator.py +2 -1
  37. streamlit/elements/exception.py +4 -2
  38. streamlit/elements/form.py +27 -0
  39. streamlit/elements/graphviz_chart.py +1 -3
  40. streamlit/elements/heading.py +63 -10
  41. streamlit/elements/html.py +13 -2
  42. streamlit/elements/image.py +3 -5
  43. streamlit/elements/layouts.py +59 -33
  44. streamlit/elements/lib/built_in_chart_utils.py +50 -19
  45. streamlit/elements/lib/color_util.py +9 -19
  46. streamlit/elements/lib/column_config_utils.py +9 -12
  47. streamlit/elements/lib/column_types.py +40 -12
  48. streamlit/elements/lib/dialog.py +2 -2
  49. streamlit/elements/lib/image_utils.py +3 -5
  50. streamlit/elements/lib/layout_utils.py +100 -13
  51. streamlit/elements/lib/mutable_status_container.py +2 -2
  52. streamlit/elements/lib/options_selector_utils.py +2 -2
  53. streamlit/elements/lib/pandas_styler_utils.py +17 -9
  54. streamlit/elements/lib/shortcut_utils.py +152 -0
  55. streamlit/elements/lib/utils.py +4 -4
  56. streamlit/elements/map.py +80 -37
  57. streamlit/elements/markdown.py +50 -3
  58. streamlit/elements/media.py +5 -7
  59. streamlit/elements/metric.py +34 -6
  60. streamlit/elements/pdf.py +2 -4
  61. streamlit/elements/plotly_chart.py +197 -20
  62. streamlit/elements/progress.py +2 -4
  63. streamlit/elements/space.py +113 -0
  64. streamlit/elements/spinner.py +1 -1
  65. streamlit/elements/text.py +20 -3
  66. streamlit/elements/toast.py +2 -0
  67. streamlit/elements/vega_charts.py +356 -149
  68. streamlit/elements/widgets/audio_input.py +12 -11
  69. streamlit/elements/widgets/button.py +280 -43
  70. streamlit/elements/widgets/button_group.py +60 -9
  71. streamlit/elements/widgets/camera_input.py +3 -5
  72. streamlit/elements/widgets/chat.py +307 -43
  73. streamlit/elements/widgets/color_picker.py +8 -1
  74. streamlit/elements/widgets/data_editor.py +88 -44
  75. streamlit/elements/widgets/file_uploader.py +9 -11
  76. streamlit/elements/widgets/multiselect.py +4 -3
  77. streamlit/elements/widgets/number_input.py +4 -4
  78. streamlit/elements/widgets/radio.py +10 -3
  79. streamlit/elements/widgets/select_slider.py +8 -5
  80. streamlit/elements/widgets/selectbox.py +6 -3
  81. streamlit/elements/widgets/slider.py +38 -42
  82. streamlit/elements/widgets/text_widgets.py +2 -0
  83. streamlit/elements/widgets/time_widgets.py +587 -21
  84. streamlit/elements/write.py +27 -6
  85. streamlit/emojis.py +1 -1
  86. streamlit/errors.py +137 -0
  87. streamlit/git_util.py +1 -1
  88. streamlit/hello/hello.py +8 -0
  89. streamlit/hello/utils.py +2 -1
  90. streamlit/material_icon_names.py +1 -1
  91. streamlit/navigation/page.py +11 -1
  92. streamlit/net_util.py +2 -2
  93. streamlit/proto/Alert_pb2.pyi +3 -3
  94. streamlit/proto/AppPage_pb2.pyi +7 -1
  95. streamlit/proto/ArrowData_pb2.py +27 -0
  96. streamlit/proto/ArrowData_pb2.pyi +52 -0
  97. streamlit/proto/ArrowNamedDataSet_pb2.pyi +7 -1
  98. streamlit/proto/ArrowVegaLiteChart_pb2.pyi +7 -1
  99. streamlit/proto/Arrow_pb2.py +10 -10
  100. streamlit/proto/Arrow_pb2.pyi +19 -12
  101. streamlit/proto/AudioInput_pb2.pyi +7 -1
  102. streamlit/proto/Audio_pb2.pyi +7 -1
  103. streamlit/proto/AuthRedirect_pb2.pyi +7 -1
  104. streamlit/proto/AutoRerun_pb2.pyi +7 -1
  105. streamlit/proto/BackMsg_pb2.py +4 -2
  106. streamlit/proto/BackMsg_pb2.pyi +34 -4
  107. streamlit/proto/Balloons_pb2.pyi +7 -1
  108. streamlit/proto/BidiComponent_pb2.py +34 -0
  109. streamlit/proto/BidiComponent_pb2.pyi +159 -0
  110. streamlit/proto/Block_pb2.py +7 -7
  111. streamlit/proto/Block_pb2.pyi +39 -36
  112. streamlit/proto/BokehChart_pb2.pyi +7 -1
  113. streamlit/proto/ButtonGroup_pb2.pyi +9 -9
  114. streamlit/proto/Button_pb2.py +2 -2
  115. streamlit/proto/Button_pb2.pyi +11 -2
  116. streamlit/proto/CameraInput_pb2.pyi +7 -1
  117. streamlit/proto/ChatInput_pb2.py +6 -6
  118. streamlit/proto/ChatInput_pb2.pyi +18 -6
  119. streamlit/proto/Checkbox_pb2.pyi +3 -3
  120. streamlit/proto/ClientState_pb2.pyi +10 -4
  121. streamlit/proto/Code_pb2.pyi +7 -1
  122. streamlit/proto/ColorPicker_pb2.pyi +7 -1
  123. streamlit/proto/Common_pb2.py +3 -3
  124. streamlit/proto/Common_pb2.pyi +35 -23
  125. streamlit/proto/Components_pb2.pyi +19 -13
  126. streamlit/proto/DataFrame_pb2.pyi +55 -49
  127. streamlit/proto/DateInput_pb2.pyi +7 -1
  128. streamlit/proto/DateTimeInput_pb2.py +28 -0
  129. streamlit/proto/DateTimeInput_pb2.pyi +92 -0
  130. streamlit/proto/DeckGlJsonChart_pb2.py +10 -4
  131. streamlit/proto/DeckGlJsonChart_pb2.pyi +12 -6
  132. streamlit/proto/Delta_pb2.pyi +7 -1
  133. streamlit/proto/DocString_pb2.pyi +10 -4
  134. streamlit/proto/DownloadButton_pb2.py +2 -2
  135. streamlit/proto/DownloadButton_pb2.pyi +16 -2
  136. streamlit/proto/Element_pb2.py +7 -3
  137. streamlit/proto/Element_pb2.pyi +33 -5
  138. streamlit/proto/Empty_pb2.pyi +7 -1
  139. streamlit/proto/Exception_pb2.pyi +7 -1
  140. streamlit/proto/Favicon_pb2.pyi +7 -1
  141. streamlit/proto/FileUploader_pb2.pyi +7 -1
  142. streamlit/proto/ForwardMsg_pb2.py +12 -10
  143. streamlit/proto/ForwardMsg_pb2.pyi +42 -15
  144. streamlit/proto/GapSize_pb2.pyi +4 -4
  145. streamlit/proto/GitInfo_pb2.pyi +3 -3
  146. streamlit/proto/GraphVizChart_pb2.pyi +7 -1
  147. streamlit/proto/Heading_pb2.pyi +7 -1
  148. streamlit/proto/HeightConfig_pb2.py +2 -2
  149. streamlit/proto/HeightConfig_pb2.pyi +13 -4
  150. streamlit/proto/Html_pb2.py +2 -2
  151. streamlit/proto/Html_pb2.pyi +11 -2
  152. streamlit/proto/IFrame_pb2.pyi +7 -1
  153. streamlit/proto/Image_pb2.pyi +10 -4
  154. streamlit/proto/Json_pb2.pyi +7 -1
  155. streamlit/proto/LabelVisibilityMessage_pb2.pyi +3 -3
  156. streamlit/proto/LinkButton_pb2.py +2 -2
  157. streamlit/proto/LinkButton_pb2.pyi +15 -2
  158. streamlit/proto/Logo_pb2.pyi +7 -1
  159. streamlit/proto/Markdown_pb2.pyi +3 -3
  160. streamlit/proto/Metric_pb2.pyi +7 -7
  161. streamlit/proto/MetricsEvent_pb2.pyi +10 -4
  162. streamlit/proto/MultiSelect_pb2.pyi +7 -1
  163. streamlit/proto/NamedDataSet_pb2.pyi +7 -1
  164. streamlit/proto/Navigation_pb2.pyi +3 -3
  165. streamlit/proto/NewSession_pb2.py +18 -18
  166. streamlit/proto/NewSession_pb2.pyi +59 -40
  167. streamlit/proto/NumberInput_pb2.pyi +3 -3
  168. streamlit/proto/PageConfig_pb2.pyi +7 -7
  169. streamlit/proto/PageInfo_pb2.pyi +7 -1
  170. streamlit/proto/PageLink_pb2.py +2 -2
  171. streamlit/proto/PageLink_pb2.pyi +11 -2
  172. streamlit/proto/PageNotFound_pb2.pyi +7 -1
  173. streamlit/proto/PageProfile_pb2.pyi +13 -7
  174. streamlit/proto/PagesChanged_pb2.pyi +7 -1
  175. streamlit/proto/ParentMessage_pb2.pyi +7 -1
  176. streamlit/proto/PlotlyChart_pb2.py +8 -6
  177. streamlit/proto/PlotlyChart_pb2.pyi +9 -7
  178. streamlit/proto/Progress_pb2.pyi +7 -1
  179. streamlit/proto/Radio_pb2.pyi +7 -1
  180. streamlit/proto/RootContainer_pb2.pyi +1 -1
  181. streamlit/proto/Selectbox_pb2.pyi +7 -1
  182. streamlit/proto/SessionEvent_pb2.pyi +7 -1
  183. streamlit/proto/SessionStatus_pb2.pyi +7 -1
  184. streamlit/proto/Skeleton_pb2.pyi +3 -3
  185. streamlit/proto/Slider_pb2.pyi +5 -5
  186. streamlit/proto/Snow_pb2.pyi +7 -1
  187. streamlit/proto/Space_pb2.py +27 -0
  188. streamlit/proto/Space_pb2.pyi +48 -0
  189. streamlit/proto/Spinner_pb2.pyi +7 -1
  190. streamlit/proto/TextAlignmentConfig_pb2.py +29 -0
  191. streamlit/proto/TextAlignmentConfig_pb2.pyi +68 -0
  192. streamlit/proto/TextArea_pb2.pyi +7 -1
  193. streamlit/proto/TextInput_pb2.pyi +3 -3
  194. streamlit/proto/Text_pb2.pyi +7 -1
  195. streamlit/proto/TimeInput_pb2.pyi +7 -1
  196. streamlit/proto/Toast_pb2.pyi +7 -1
  197. streamlit/proto/VegaLiteChart_pb2.pyi +7 -1
  198. streamlit/proto/Video_pb2.pyi +6 -6
  199. streamlit/proto/WidgetStates_pb2.py +2 -2
  200. streamlit/proto/WidgetStates_pb2.pyi +23 -7
  201. streamlit/proto/WidthConfig_pb2.py +2 -2
  202. streamlit/proto/WidthConfig_pb2.pyi +13 -4
  203. streamlit/proto/openmetrics_data_model_pb2.pyi +52 -52
  204. streamlit/runtime/app_session.py +65 -2
  205. streamlit/runtime/caching/cache_data_api.py +5 -5
  206. streamlit/runtime/caching/cache_errors.py +4 -1
  207. streamlit/runtime/caching/cache_resource_api.py +5 -4
  208. streamlit/runtime/caching/cache_utils.py +3 -2
  209. streamlit/runtime/caching/cached_message_replay.py +3 -3
  210. streamlit/runtime/caching/hashing.py +4 -5
  211. streamlit/runtime/caching/legacy_cache_api.py +2 -1
  212. streamlit/runtime/connection_factory.py +1 -3
  213. streamlit/runtime/download_data_util.py +53 -0
  214. streamlit/runtime/forward_msg_queue.py +5 -1
  215. streamlit/runtime/fragment.py +2 -1
  216. streamlit/runtime/media_file_manager.py +178 -2
  217. streamlit/runtime/memory_media_file_storage.py +1 -1
  218. streamlit/runtime/metrics_util.py +91 -3
  219. streamlit/runtime/runtime.py +14 -0
  220. streamlit/runtime/scriptrunner/exec_code.py +2 -1
  221. streamlit/runtime/scriptrunner/script_runner.py +5 -3
  222. streamlit/runtime/scriptrunner_utils/script_run_context.py +3 -6
  223. streamlit/runtime/secrets.py +2 -4
  224. streamlit/runtime/session_manager.py +3 -1
  225. streamlit/runtime/state/common.py +30 -5
  226. streamlit/runtime/state/presentation.py +85 -0
  227. streamlit/runtime/state/query_params.py +80 -29
  228. streamlit/runtime/state/safe_session_state.py +2 -2
  229. streamlit/runtime/state/session_state.py +221 -17
  230. streamlit/runtime/state/widgets.py +19 -3
  231. streamlit/runtime/websocket_session_manager.py +3 -1
  232. streamlit/source_util.py +2 -2
  233. streamlit/static/index.html +2 -2
  234. streamlit/static/manifest.json +557 -239
  235. streamlit/static/static/css/{index.CIiu7Ygf.css → index.BpABIXK9.css} +1 -1
  236. streamlit/static/static/css/index.DgR7E2CV.css +1 -0
  237. streamlit/static/static/js/{ErrorOutline.esm.DUpR0_Ka.js → ErrorOutline.esm.ZJDbmVTx.js} +1 -1
  238. streamlit/static/static/js/{FileDownload.esm.CN4j9-1w.js → FileDownload.esm.Dx0vI3vH.js} +1 -1
  239. streamlit/static/static/js/{FileHelper.CaIUKG91.js → FileHelper.B7Ero7qQ.js} +3 -3
  240. streamlit/static/static/js/{FormClearHelper.DTcdrasw.js → FormClearHelper.CG2XN1_g.js} +1 -1
  241. streamlit/static/static/js/IFrameUtil.DefezniK.js +1 -0
  242. streamlit/static/static/js/InputInstructions.Cj5-1zf6.js +1 -0
  243. streamlit/static/static/js/Particles.BfWfv0Aw.js +1 -0
  244. streamlit/static/static/js/{ProgressBar.DetlP5aY.js → ProgressBar.CGQ8OgfO.js} +2 -2
  245. streamlit/static/static/js/StreamlitSyntaxHighlighter.DTKLpwhl.js +20 -0
  246. streamlit/static/static/js/{Toolbar.C77ar7rq.js → Toolbar.B2qFUmd9.js} +1 -1
  247. streamlit/static/static/js/_arrayIncludes.B19Iyn2B.js +1 -0
  248. streamlit/static/static/js/_baseIndexOf.BTknn6Gb.js +1 -0
  249. streamlit/static/static/js/{base-input.BQft14La.js → base-input.o9tL8MDP.js} +4 -4
  250. streamlit/static/static/js/{checkbox.yZOfXCeX.js → checkbox.0BeV1IBL.js} +1 -1
  251. streamlit/static/static/js/{createSuper.Dh9w1cs8.js → createSuper.RBO59fEm.js} +1 -1
  252. streamlit/static/static/js/data-grid-overlay-editor.CiTkUy0t.js +1 -0
  253. streamlit/static/static/js/{downloader.MeHtkq8r.js → downloader.DwNZg3Mw.js} +1 -1
  254. streamlit/static/static/js/embed.XT9xNd3F.js +195 -0
  255. streamlit/static/static/js/{es6.VpBPGCnM.js → es6.x9KsYQg-.js} +2 -2
  256. streamlit/static/static/js/{iframeResizer.contentWindow.yMw_ARIL.js → iframeResizer.contentWindow.ZVXpMPi0.js} +1 -1
  257. streamlit/static/static/js/index.5VPOamri.js +1 -0
  258. streamlit/static/static/js/index.8HslT92O.js +14 -0
  259. streamlit/static/static/js/index.AnXMIBz3.js +7 -0
  260. streamlit/static/static/js/index.B0yp3bM1.js +6 -0
  261. streamlit/static/static/js/index.B1fRb5wF.js +1 -0
  262. streamlit/static/static/js/index.B527JZdO.js +3 -0
  263. streamlit/static/static/js/index.BHgV-yW4.js +1 -0
  264. streamlit/static/static/js/index.BQr-XwGV.js +1 -0
  265. streamlit/static/static/js/index.BTtmaLDB.js +1 -0
  266. streamlit/static/static/js/index.BWB_91TA.js +1 -0
  267. streamlit/static/static/js/index.BfEKaEmw.js +1 -0
  268. streamlit/static/static/js/index.BfXjTO8b.js +1 -0
  269. streamlit/static/static/js/index.Bjy4NRu9.js +3 -0
  270. streamlit/static/static/js/index.Bu5JWpT_.js +1 -0
  271. streamlit/static/static/js/index.BuCx76ZV.js +1 -0
  272. streamlit/static/static/js/index.BxjzhVUb.js +2 -0
  273. streamlit/static/static/js/index.By55VdPY.js +1 -0
  274. streamlit/static/static/js/index.CF5MxTbK.js +1 -0
  275. streamlit/static/static/js/index.CLmq_z9K.js +1 -0
  276. streamlit/static/static/js/index.CNH4rdSz.js +1 -0
  277. streamlit/static/static/js/{index.B0H9IXUJ.js → index.CTgm_-jO.js} +10 -41
  278. streamlit/static/static/js/index.C_rK-Swb.js +188 -0
  279. streamlit/static/static/js/index.CjozwSzS.js +1 -0
  280. streamlit/static/static/js/{index.CH1tqnSs.js → index.CkGVt6-G.js} +1 -1
  281. streamlit/static/static/js/index.CuvXOyER.js +2 -0
  282. streamlit/static/static/js/{index.FFOzOWzC.js → index.CyUHWoCC.js} +2 -2
  283. streamlit/static/static/js/index.CyroQtI4.js +2 -0
  284. streamlit/static/static/js/index.D6HmkoDm.js +263 -0
  285. streamlit/static/static/js/index.DAqCNvsO.js +1 -0
  286. streamlit/static/static/js/index.DB_w_CZQ.js +1 -0
  287. streamlit/static/static/js/index.DBalctjj.js +2 -0
  288. streamlit/static/static/js/index.DK0RFJUG.js +11 -0
  289. streamlit/static/static/js/index.DMxc2XFp.js +151 -0
  290. streamlit/static/static/js/index.DO5utP74.js +2 -0
  291. streamlit/static/static/js/index.DS7lf09n.js +1 -0
  292. streamlit/static/static/js/index.DWexTVLY.js +1 -0
  293. streamlit/static/static/js/index.DXxnU5ej.js +1 -0
  294. streamlit/static/static/js/index.DcU3uDvB.js +2 -0
  295. streamlit/static/static/js/index.DlltaH7J.js +1 -0
  296. streamlit/static/static/js/index.DpNTZz82.js +27 -0
  297. streamlit/static/static/js/index.Dr9HIhQw.js +1 -0
  298. streamlit/static/static/js/index.DsgAU5lc.js +1 -0
  299. streamlit/static/static/js/{index.64ejlaaT.js → index.KfXqjDYy.js} +1 -1
  300. streamlit/static/static/js/index.PaidgjCs.js +1 -0
  301. streamlit/static/static/js/index.RJZuWCGA.js +1 -0
  302. streamlit/static/static/js/{index.Ctn27_AE.js → index.hbeqcRTn.js} +53 -122
  303. streamlit/static/static/js/index.q5hIQwAY.js +1 -0
  304. streamlit/static/static/js/index.rORSX6IW.js +1 -0
  305. streamlit/static/static/js/index.uSX757_v.js +1 -0
  306. streamlit/static/static/js/index.x_QRaLMd.js +1 -0
  307. streamlit/static/static/js/{input.s6pjQ49A.js → input.D5oh9-aB.js} +2 -2
  308. streamlit/static/static/js/main.q9oGOg0H.js +13 -0
  309. streamlit/static/static/js/{memory.Cuvsdfrl.js → memory.5kCSFUJS.js} +1 -1
  310. streamlit/static/static/js/moment.C3j7ZXd7.js +4 -0
  311. streamlit/static/static/js/number-overlay-editor.Cn_LsK8N.js +9 -0
  312. streamlit/static/static/js/pandasStylerUtils.BqhXt51_.js +1 -0
  313. streamlit/static/static/js/{possibleConstructorReturn.CqidKeei.js → possibleConstructorReturn.DD9NK1Z8.js} +1 -1
  314. streamlit/static/static/js/record.B-tDciZb.js +1 -0
  315. streamlit/static/static/js/{sandbox.CCQREcJx.js → sandbox.DACSyz29.js} +1 -1
  316. streamlit/static/static/js/styled-components.C3R090At.js +1 -0
  317. streamlit/static/static/js/threshold.Q1mXg5rX.js +1 -0
  318. streamlit/static/static/js/throttle.B0GR3Iyz.js +1 -0
  319. streamlit/static/static/js/{timepicker.mkJF97Bb.js → timepicker.BdhzPxrv.js} +1 -1
  320. streamlit/static/static/js/timer.C2hYhUse.js +1 -0
  321. streamlit/static/static/js/{toConsumableArray.De7I7KVR.js → toConsumableArray.Db2pdqM2.js} +1 -1
  322. streamlit/static/static/js/uniqueId.CtqIr-Yh.js +1 -0
  323. streamlit/static/static/js/urls.BwSlolu9.js +1 -0
  324. streamlit/static/static/js/{useBasicWidgetState.CedkNjUW.js → useBasicWidgetState.Bfp6TnSw.js} +1 -1
  325. streamlit/static/static/js/useIntlLocale.hRV75Xgj.js +12 -0
  326. streamlit/static/static/js/{useTextInputAutoExpand.Ca7w8dVs.js → useTextInputAutoExpand.QepX7n8Y.js} +1 -1
  327. streamlit/static/static/js/useUpdateUiValue.DHx8TzX6.js +1 -0
  328. streamlit/static/static/js/useWaveformController.WxVzpzEX.js +1 -0
  329. streamlit/static/static/js/value.B4vHRSi7.js +1 -0
  330. streamlit/static/static/js/wavesurfer.esm.vI8Eid4k.js +73 -0
  331. streamlit/static/static/js/withCalculatedWidth.DcKeRSWJ.js +1 -0
  332. streamlit/static/static/js/withFullScreenWrapper.CrHddARq.js +1 -0
  333. streamlit/static/static/media/MaterialSymbols-Rounded.C7IFxh57.woff2 +0 -0
  334. streamlit/string_util.py +9 -4
  335. streamlit/testing/v1/app_test.py +17 -2
  336. streamlit/testing/v1/element_tree.py +85 -9
  337. streamlit/testing/v1/util.py +2 -2
  338. streamlit/type_util.py +3 -4
  339. streamlit/url_util.py +1 -3
  340. streamlit/user_info.py +1 -2
  341. streamlit/util.py +3 -1
  342. streamlit/watcher/event_based_path_watcher.py +23 -12
  343. streamlit/watcher/local_sources_watcher.py +11 -1
  344. streamlit/watcher/path_watcher.py +9 -6
  345. streamlit/watcher/polling_path_watcher.py +4 -1
  346. streamlit/watcher/util.py +2 -2
  347. streamlit/web/bootstrap.py +24 -0
  348. streamlit/web/cli.py +51 -22
  349. streamlit/web/server/bidi_component_request_handler.py +193 -0
  350. streamlit/web/server/component_file_utils.py +97 -0
  351. streamlit/web/server/component_request_handler.py +8 -21
  352. streamlit/web/server/oauth_authlib_routes.py +5 -2
  353. streamlit/web/server/oidc_mixin.py +3 -1
  354. streamlit/web/server/routes.py +2 -2
  355. streamlit/web/server/server.py +9 -0
  356. streamlit/web/server/server_util.py +3 -1
  357. streamlit/web/server/upload_file_request_handler.py +19 -1
  358. {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/METADATA +10 -7
  359. streamlit-1.52.0.dist-info/RECORD +620 -0
  360. streamlit/static/static/css/index.CHEnSPGk.css +0 -1
  361. streamlit/static/static/js/Hooks.BRba_Own.js +0 -1
  362. streamlit/static/static/js/InputInstructions.xnSDuYeQ.js +0 -1
  363. streamlit/static/static/js/Particles.CElH0XX2.js +0 -1
  364. streamlit/static/static/js/data-grid-overlay-editor.DcuHuCyW.js +0 -1
  365. streamlit/static/static/js/index.6xX1278W.js +0 -975
  366. streamlit/static/static/js/index.B-hiXRzw.js +0 -1
  367. streamlit/static/static/js/index.B4cAbHP6.js +0 -1
  368. streamlit/static/static/js/index.B4dUQfni.js +0 -1
  369. streamlit/static/static/js/index.BPQo7BKk.js +0 -1
  370. streamlit/static/static/js/index.Baqa90pe.js +0 -2
  371. streamlit/static/static/js/index.Bj9JgOEC.js +0 -1
  372. streamlit/static/static/js/index.BjCwMzj4.js +0 -3
  373. streamlit/static/static/js/index.Bm3VbPB5.js +0 -1
  374. streamlit/static/static/js/index.Bxz2yX3P.js +0 -1
  375. streamlit/static/static/js/index.BycLveZ4.js +0 -1
  376. streamlit/static/static/js/index.C9BdUqTi.js +0 -1
  377. streamlit/static/static/js/index.CFMf5_ez.js +0 -197
  378. streamlit/static/static/js/index.CGYqqs6j.js +0 -1
  379. streamlit/static/static/js/index.CMItVsFA.js +0 -1
  380. streamlit/static/static/js/index.CTBk8Vk2.js +0 -1
  381. streamlit/static/static/js/index.CiAQIz1H.js +0 -7
  382. streamlit/static/static/js/index.Cj7DSzVR.js +0 -73
  383. streamlit/static/static/js/index.Ck8rQ9OL.js +0 -1
  384. streamlit/static/static/js/index.ClELlchS.js +0 -1617
  385. streamlit/static/static/js/index.Cnpi3o3E.js +0 -1
  386. streamlit/static/static/js/index.D2QEXQq_.js +0 -1
  387. streamlit/static/static/js/index.DH71Ezyj.js +0 -1
  388. streamlit/static/static/js/index.DHh-U0dK.js +0 -3
  389. streamlit/static/static/js/index.DK7hD7_w.js +0 -1
  390. streamlit/static/static/js/index.DKv_lNO7.js +0 -2
  391. streamlit/static/static/js/index.DNLrMXgm.js +0 -12
  392. streamlit/static/static/js/index.DW0Grddz.js +0 -1
  393. streamlit/static/static/js/index.Dbe-Q3C-.js +0 -2
  394. streamlit/static/static/js/index.DcPNYEUo.js +0 -1
  395. streamlit/static/static/js/index.DuxqVQpd.js +0 -1
  396. streamlit/static/static/js/index.GRUzrudl.js +0 -1
  397. streamlit/static/static/js/number-overlay-editor.DdgVR5m3.js +0 -9
  398. streamlit/static/static/js/uniqueId.RI1LJdtz.js +0 -1
  399. streamlit/static/static/js/useUpdateUiValue.DeXelfRH.js +0 -1
  400. streamlit/static/static/js/withFullScreenWrapper.C3561XxJ.js +0 -1
  401. streamlit/static/static/media/MaterialSymbols-Rounded.DeCZgS-4.woff2 +0 -0
  402. streamlit-1.50.0.dist-info/RECORD +0 -557
  403. {streamlit-1.50.0.data → streamlit-1.52.0.data}/scripts/streamlit.cmd +0 -0
  404. {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/WHEEL +0 -0
  405. {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/entry_points.txt +0 -0
  406. {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/top_level.txt +0 -0
@@ -16,48 +16,33 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- import json
20
- from typing import TYPE_CHECKING, Final, cast
19
+ from typing import TYPE_CHECKING, cast
21
20
 
22
21
  from streamlit.deprecation_util import (
23
22
  show_deprecation_warning,
24
23
  )
25
- from streamlit.errors import StreamlitAPIException
26
- from streamlit.proto.BokehChart_pb2 import BokehChart as BokehChartProto
27
24
  from streamlit.runtime.metrics_util import gather_metrics
28
- from streamlit.util import calc_md5
29
25
 
30
26
  if TYPE_CHECKING:
31
- from bokeh.plotting.figure import Figure
32
-
33
27
  from streamlit.delta_generator import DeltaGenerator
34
28
 
35
- ST_BOKEH_VERSION: Final = "2.4.3"
36
-
37
29
 
38
30
  class BokehMixin:
39
31
  @gather_metrics("bokeh_chart")
40
32
  def bokeh_chart(
41
33
  self,
42
- figure: Figure,
43
- use_container_width: bool = True,
34
+ figure: object, # noqa: ARG002
35
+ use_container_width: bool = True, # noqa: ARG002
44
36
  ) -> DeltaGenerator:
45
37
  """Display an interactive Bokeh chart.
46
38
 
47
- Bokeh is a charting library for Python. The arguments to this function
48
- closely follow the ones for Bokeh's ``show`` function. You can find
39
+ Bokeh is a charting library for Python. You can find
49
40
  more about Bokeh at https://bokeh.pydata.org.
50
41
 
51
- To show Bokeh charts in Streamlit, call ``st.bokeh_chart``
52
- wherever you would call Bokeh's ``show``.
53
-
54
42
  .. Important::
55
- You must install ``bokeh==2.4.3`` and ``numpy<2`` to use this
56
- command, which is deprecated and will be removed in a future
57
- version.
58
-
59
- For more current updates, use the |streamlit-bokeh|_ custom
60
- component instead.
43
+ This command has been deprecated and removed. Please use our custom
44
+ component, |streamlit-bokeh|_, instead. Calling st.bokeh_chart will
45
+ do nothing.
61
46
 
62
47
  .. |streamlit-bokeh| replace:: ``streamlit-bokeh``
63
48
  .. _streamlit-bokeh: https://github.com/streamlit/streamlit-bokeh
@@ -74,70 +59,17 @@ class BokehMixin:
74
59
  container. If ``use_container_width`` is ``False``, Streamlit sets the
75
60
  width of the chart to fit its contents according to the plotting library,
76
61
  up to the width of the parent container.
77
-
78
- Example
79
- -------
80
- >>> import streamlit as st
81
- >>> from bokeh.plotting import figure
82
- >>>
83
- >>> x = [1, 2, 3, 4, 5]
84
- >>> y = [6, 7, 2, 4, 5]
85
- >>>
86
- >>> p = figure(title="simple line example", x_axis_label="x", y_axis_label="y")
87
- >>> p.line(x, y, legend_label="Trend", line_width=2)
88
- >>>
89
- >>> st.bokeh_chart(p)
90
-
91
- .. output::
92
- https://doc-bokeh-chart.streamlit.app/
93
- height: 700px
94
-
95
62
  """
96
- import bokeh
97
-
98
- if bokeh.__version__ != ST_BOKEH_VERSION:
99
- raise StreamlitAPIException(
100
- f"Streamlit only supports Bokeh version {ST_BOKEH_VERSION}, "
101
- f"but you have version {bokeh.__version__} installed. Please "
102
- f"run `pip install --force-reinstall --no-deps bokeh=="
103
- f"{ST_BOKEH_VERSION}` to install the correct version.\n\n\n"
104
- f"To use the latest version of Bokeh, install our custom component, "
105
- f"[streamlit-bokeh](https://github.com/streamlit/streamlit-bokeh)."
106
- )
107
63
 
108
64
  show_deprecation_warning(
109
- "st.bokeh_chart is deprecated and will be removed in a future version. "
65
+ "st.bokeh_chart has been deprecated and removed. "
110
66
  "Please use our custom component, "
111
67
  "[streamlit-bokeh](https://github.com/streamlit/streamlit-bokeh), "
112
- "instead."
68
+ "instead. Calling st.bokeh_chart will do nothing."
113
69
  )
114
- # Generate element ID from delta path
115
- delta_path = self.dg._get_delta_path_str()
116
-
117
- element_id = calc_md5(delta_path.encode())
118
- bokeh_chart_proto = BokehChartProto()
119
- marshall(bokeh_chart_proto, figure, use_container_width, element_id)
120
- return self.dg._enqueue("bokeh_chart", bokeh_chart_proto)
70
+ return self.dg
121
71
 
122
72
  @property
123
73
  def dg(self) -> DeltaGenerator:
124
74
  """Get our DeltaGenerator."""
125
75
  return cast("DeltaGenerator", self)
126
-
127
-
128
- def marshall(
129
- proto: BokehChartProto,
130
- figure: Figure,
131
- use_container_width: bool,
132
- element_id: str,
133
- ) -> None:
134
- """Construct a Bokeh chart object.
135
-
136
- See DeltaGenerator.bokeh_chart for docs.
137
- """
138
- from bokeh.embed import json_item
139
-
140
- data = json_item(figure)
141
- proto.figure = json.dumps(data)
142
- proto.use_container_width = use_container_width
143
- proto.element_id = element_id
@@ -109,7 +109,7 @@ class CodeMixin:
109
109
  ... print("Hello, Streamlit!")'''
110
110
  >>> st.code(code, language="python")
111
111
 
112
- .. output ::
112
+ .. output::
113
113
  https://doc-code.streamlit.app/
114
114
  height: 220px
115
115
 
@@ -129,7 +129,7 @@ class CodeMixin:
129
129
  ... '''
130
130
  >>> st.code(code, language=None)
131
131
 
132
- .. output ::
132
+ .. output::
133
133
  https://doc-code-ascii.streamlit.app/
134
134
  height: 380px
135
135
  """
@@ -21,15 +21,25 @@ from typing import (
21
21
  Any,
22
22
  Final,
23
23
  Literal,
24
+ TypeAlias,
24
25
  TypedDict,
25
26
  cast,
26
27
  overload,
27
28
  )
28
29
 
29
- from typing_extensions import TypeAlias
30
-
31
30
  from streamlit import config
31
+ from streamlit.deprecation_util import (
32
+ make_deprecated_name_warning,
33
+ show_deprecation_warning,
34
+ )
32
35
  from streamlit.elements.lib.form_utils import current_form_id
36
+ from streamlit.elements.lib.layout_utils import (
37
+ HeightWithoutContent,
38
+ LayoutConfig,
39
+ WidthWithoutContent,
40
+ validate_height,
41
+ validate_width,
42
+ )
33
43
  from streamlit.elements.lib.policies import check_widget_policies
34
44
  from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
35
45
  from streamlit.errors import StreamlitAPIException
@@ -172,7 +182,7 @@ class PydeckSelectionState(TypedDict, total=False):
172
182
  >>>
173
183
  >>> event.selection
174
184
 
175
- .. output ::
185
+ .. output::
176
186
  https://doc-pydeck-event-state-selections.streamlit.app/
177
187
  height: 700px
178
188
 
@@ -263,9 +273,9 @@ class PydeckMixin:
263
273
  self,
264
274
  pydeck_obj: Deck | None = None,
265
275
  *,
266
- use_container_width: bool = True,
267
- width: int | None = None,
268
- height: int | None = None,
276
+ width: WidthWithoutContent = "stretch",
277
+ use_container_width: bool | None = None,
278
+ height: HeightWithoutContent = 500,
269
279
  selection_mode: Literal[
270
280
  "single-object"
271
281
  ], # Selection mode will only be activated by on_select param; default value here to make it work with mypy
@@ -279,9 +289,9 @@ class PydeckMixin:
279
289
  self,
280
290
  pydeck_obj: Deck | None = None,
281
291
  *,
282
- use_container_width: bool = True,
283
- width: int | None = None,
284
- height: int | None = None,
292
+ width: WidthWithoutContent = "stretch",
293
+ use_container_width: bool | None = None,
294
+ height: HeightWithoutContent = 500,
285
295
  selection_mode: SelectionMode = "single-object",
286
296
  on_select: Literal["rerun"] | WidgetCallback = "rerun",
287
297
  key: Key | None = None,
@@ -292,9 +302,9 @@ class PydeckMixin:
292
302
  self,
293
303
  pydeck_obj: Deck | None = None,
294
304
  *,
295
- use_container_width: bool = True,
296
- width: int | None = None,
297
- height: int | None = None,
305
+ width: WidthWithoutContent = "stretch",
306
+ use_container_width: bool | None = None,
307
+ height: HeightWithoutContent = 500,
298
308
  selection_mode: SelectionMode = "single-object",
299
309
  on_select: Literal["rerun", "ignore"] | WidgetCallback = "ignore",
300
310
  key: Key | None = None,
@@ -342,26 +352,43 @@ class PydeckMixin:
342
352
  ----------
343
353
  pydeck_obj : pydeck.Deck or None
344
354
  Object specifying the PyDeck chart to draw.
345
- use_container_width : bool
346
- Whether to override the figure's native width with the width of
347
- the parent container. If ``use_container_width`` is ``True`` (default),
348
- Streamlit sets the width of the figure to match the width of the parent
349
- container. If ``use_container_width`` is ``False``, Streamlit sets the
350
- width of the chart to fit its contents according to the plotting library,
351
- up to the width of the parent container.
352
- width : int or None
353
- Desired width of the chart expressed in pixels. If ``width`` is
354
- ``None`` (default), Streamlit sets the width of the chart to fit
355
- its contents according to the plotting library, up to the width of
356
- the parent container. If ``width`` is greater than the width of the
357
- parent container, Streamlit sets the chart width to match the width
358
- of the parent container.
359
-
360
- To use ``width``, you must set ``use_container_width=False``.
361
- height : int or None
362
- Desired height of the chart expressed in pixels. If ``height`` is
363
- ``None`` (default), Streamlit sets the height of the chart to fit
364
- its contents according to the plotting library.
355
+ width : "stretch" or int
356
+ The width of the chart element. This can be one of the following:
357
+
358
+ - ``"stretch"`` (default): The width of the element matches the
359
+ width of the parent container.
360
+ - An integer specifying the width in pixels: The element has a
361
+ fixed width. If the specified width is greater than the width of
362
+ the parent container, the width of the element matches the width
363
+ of the parent container.
364
+
365
+ use_container_width : bool or None
366
+ Whether to override the chart's native width with the width of
367
+ the parent container. This can be one of the following:
368
+
369
+ - ``None`` (default): Streamlit will use the chart's default behavior.
370
+ - ``True``: Streamlit sets the width of the chart to match the
371
+ width of the parent container.
372
+ - ``False``: Streamlit sets the width of the chart to fit its
373
+ contents according to the plotting library, up to the width of
374
+ the parent container.
375
+
376
+ .. deprecated::
377
+ ``use_container_width`` is deprecated and will be removed in a
378
+ future release. For ``use_container_width=True``, use
379
+ ``width="stretch"``.
380
+
381
+ height : "stretch" or int
382
+ The height of the chart element. This can be one of the following:
383
+
384
+ - An integer specifying the height in pixels: The element has a
385
+ fixed height. If the content is larger than the specified
386
+ height, scrolling is enabled. This is ``500`` by default.
387
+ - ``"stretch"``: The height of the element matches the height of
388
+ its content or the height of the parent container, whichever is
389
+ larger. If the element is not in a parent container, the height
390
+ of the element matches the height of its content.
391
+
365
392
  on_select : "ignore" or "rerun" or callable
366
393
  How the figure should respond to user selection events. This controls
367
394
  whether or not the chart behaves like an input widget.
@@ -460,6 +487,25 @@ class PydeckMixin:
460
487
  you can set ``map_style=None`` in the ``pydeck.Deck`` object.
461
488
 
462
489
  """
490
+ if use_container_width is not None:
491
+ show_deprecation_warning(
492
+ make_deprecated_name_warning(
493
+ "use_container_width",
494
+ "width",
495
+ "2025-12-31",
496
+ "For `use_container_width=True`, use `width='stretch'`. "
497
+ "For `use_container_width=False`, specify an integer width.",
498
+ include_st_prefix=False,
499
+ ),
500
+ show_in_browser=False,
501
+ )
502
+ if use_container_width:
503
+ width = "stretch"
504
+ # Otherwise keep the provided width.
505
+
506
+ validate_width(width, allow_content=False)
507
+ validate_height(height, allow_content=False)
508
+
463
509
  pydeck_proto = PydeckProto()
464
510
 
465
511
  ctx = get_script_run_ctx()
@@ -467,12 +513,6 @@ class PydeckMixin:
467
513
  spec = json.dumps(EMPTY_MAP) if pydeck_obj is None else pydeck_obj.to_json()
468
514
 
469
515
  pydeck_proto.json = spec
470
- pydeck_proto.use_container_width = use_container_width
471
-
472
- if width:
473
- pydeck_proto.width = width
474
- if height:
475
- pydeck_proto.height = height
476
516
 
477
517
  tooltip = _get_pydeck_tooltip(pydeck_obj)
478
518
  if tooltip:
@@ -535,11 +575,17 @@ class PydeckMixin:
535
575
  value_type="string_value",
536
576
  )
537
577
 
538
- self.dg._enqueue("deck_gl_json_chart", pydeck_proto)
578
+ layout_config = LayoutConfig(width=width, height=height)
579
+ self.dg._enqueue(
580
+ "deck_gl_json_chart", pydeck_proto, layout_config=layout_config
581
+ )
539
582
 
540
583
  return widget_state.value
541
584
 
542
- return self.dg._enqueue("deck_gl_json_chart", pydeck_proto)
585
+ layout_config = LayoutConfig(width=width, height=height)
586
+ return self.dg._enqueue(
587
+ "deck_gl_json_chart", pydeck_proto, layout_config=layout_config
588
+ )
543
589
 
544
590
  @property
545
591
  def dg(self) -> DeltaGenerator:
@@ -547,6 +593,18 @@ class PydeckMixin:
547
593
  return cast("DeltaGenerator", self)
548
594
 
549
595
 
596
+ def _get_pydeck_width(pydeck_obj: Deck | None) -> int | None:
597
+ """Extract the width from a pydeck Deck object, if specified."""
598
+ if pydeck_obj is None:
599
+ return None
600
+
601
+ width = getattr(pydeck_obj, "width", None)
602
+ if width is not None and isinstance(width, (int, float)):
603
+ return int(width)
604
+
605
+ return None
606
+
607
+
550
608
  def _get_pydeck_tooltip(pydeck_obj: Deck | None) -> dict[str, str] | None:
551
609
  if pydeck_obj is None:
552
610
  return None
@@ -14,8 +14,9 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ from collections.abc import Callable
17
18
  from functools import wraps
18
- from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar, cast, overload
19
+ from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast, overload
19
20
 
20
21
  from streamlit.delta_generator_singletons import (
21
22
  get_dg_singleton_instance,
@@ -16,7 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import os
18
18
  import traceback
19
- from typing import TYPE_CHECKING, Callable, Final, TypeVar, cast
19
+ from typing import TYPE_CHECKING, Final, TypeVar, cast
20
20
 
21
21
  from streamlit import config
22
22
  from streamlit.elements.lib.layout_utils import validate_width
@@ -31,6 +31,8 @@ from streamlit.runtime.metrics_util import gather_metrics
31
31
  from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
32
32
 
33
33
  if TYPE_CHECKING:
34
+ from collections.abc import Callable
35
+
34
36
  from streamlit.delta_generator import DeltaGenerator
35
37
  from streamlit.elements.lib.layout_utils import WidthWithoutContent
36
38
 
@@ -77,7 +79,7 @@ class ExceptionMixin:
77
79
  >>> e = RuntimeError("This is an exception of type RuntimeError")
78
80
  >>> st.exception(e)
79
81
 
80
- .. output ::
82
+ .. output::
81
83
  https://doc-status-exception.streamlit.app/
82
84
  height: 220px
83
85
 
@@ -250,6 +250,7 @@ class FormMixin:
250
250
  disabled: bool = False,
251
251
  use_container_width: bool | None = None,
252
252
  width: Width = "content",
253
+ shortcut: str | None = None,
253
254
  ) -> bool:
254
255
  r"""Display a form submit button.
255
256
 
@@ -332,6 +333,8 @@ class FormMixin:
332
333
  <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
333
334
  font library.
334
335
 
336
+ - ``"spinner"``: Displays a spinner as an icon.
337
+
335
338
  disabled : bool
336
339
  Whether to disable the button. If this is ``False`` (default), the
337
340
  user can interact with the button. If this is ``True``, the button
@@ -369,6 +372,27 @@ class FormMixin:
369
372
  the parent container, the width of the button matches the width
370
373
  of the parent container.
371
374
 
375
+ shortcut : str or None
376
+ An optional keyboard shortcut that triggers the button. This can be
377
+ one of the following strings:
378
+
379
+ - A single alphanumeric key like ``"K"`` or ``"4"``.
380
+ - A function key like ``"F11"``.
381
+ - A special key like ``"Enter"``, ``"Esc"``, or ``"Tab"``.
382
+ - Any of the above combined with modifiers. For example, you can use
383
+ ``"Ctrl+K"`` or ``"Cmd+Shift+O"``.
384
+
385
+ .. important::
386
+ The keys ``"C"`` and ``"R"`` are reserved and can't be used,
387
+ even with modifiers. Punctuation keys like ``"."`` and ``","``
388
+ aren't currently supported.
389
+
390
+ For a list of supported keys and modifiers, see the documentation
391
+ for |st.button|_.
392
+
393
+ .. |st.button| replace:: ``st.button``
394
+ .. _st.button: https://docs.streamlit.io/develop/api-reference/widgets/st.button
395
+
372
396
  Returns
373
397
  -------
374
398
  bool
@@ -398,6 +422,7 @@ class FormMixin:
398
422
  ctx=ctx,
399
423
  width=width,
400
424
  key=key,
425
+ shortcut=shortcut,
401
426
  )
402
427
 
403
428
  def _form_submit_button(
@@ -414,6 +439,7 @@ class FormMixin:
414
439
  disabled: bool = False,
415
440
  ctx: ScriptRunContext | None = None,
416
441
  width: Width = "content",
442
+ shortcut: str | None = None,
417
443
  ) -> bool:
418
444
  form_id = current_form_id(self.dg)
419
445
  submit_button_key = to_key(key) or f"FormSubmitter:{form_id}-{label}"
@@ -430,6 +456,7 @@ class FormMixin:
430
456
  disabled=disabled,
431
457
  ctx=ctx,
432
458
  width=width,
459
+ shortcut=shortcut,
433
460
  )
434
461
 
435
462
  @property
@@ -16,9 +16,7 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- from typing import TYPE_CHECKING, Union, cast
20
-
21
- from typing_extensions import TypeAlias
19
+ from typing import TYPE_CHECKING, TypeAlias, Union, cast
22
20
 
23
21
  from streamlit import type_util
24
22
  from streamlit.deprecation_util import (
@@ -15,9 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from enum import Enum
18
- from typing import TYPE_CHECKING, Literal, Union, cast
19
-
20
- from typing_extensions import TypeAlias
18
+ from typing import TYPE_CHECKING, Literal, TypeAlias, cast
21
19
 
22
20
  from streamlit.elements.lib.layout_utils import LayoutConfig, validate_width
23
21
  from streamlit.errors import StreamlitAPIException
@@ -27,7 +25,7 @@ from streamlit.string_util import clean_text
27
25
 
28
26
  if TYPE_CHECKING:
29
27
  from streamlit.delta_generator import DeltaGenerator
30
- from streamlit.elements.lib.layout_utils import Width
28
+ from streamlit.elements.lib.layout_utils import TextAlignment, Width
31
29
  from streamlit.type_util import SupportsStr
32
30
 
33
31
 
@@ -37,8 +35,8 @@ class HeadingProtoTag(Enum):
37
35
  SUBHEADER_TAG = "h3"
38
36
 
39
37
 
40
- Anchor: TypeAlias = Union[str, Literal[False], None]
41
- Divider: TypeAlias = Union[bool, str, None]
38
+ Anchor: TypeAlias = str | Literal[False] | None
39
+ Divider: TypeAlias = bool | str | None
42
40
 
43
41
 
44
42
  class HeadingMixin:
@@ -51,6 +49,7 @@ class HeadingMixin:
51
49
  help: str | None = None,
52
50
  divider: Divider = False,
53
51
  width: Width = "stretch",
52
+ text_alignment: TextAlignment = "left",
54
53
  ) -> DeltaGenerator:
55
54
  """Display text in header formatting.
56
55
 
@@ -99,6 +98,22 @@ class HeadingMixin:
99
98
  the parent container, the width of the element matches the width
100
99
  of the parent container.
101
100
 
101
+ text_alignment : "left", "center", "right", or "justify"
102
+ The horizontal alignment of the text within the element. This can
103
+ be one of the following:
104
+
105
+ - ``"left"`` (default): Text is aligned to the left edge.
106
+ - ``"center"``: Text is centered.
107
+ - ``"right"``: Text is aligned to the right edge.
108
+ - ``"justify"``: Text is justified (stretched to fill the available
109
+ width with the last line left-aligned).
110
+
111
+ .. note::
112
+ For text alignment to have a visible effect, the element's
113
+ width must be wider than its content. If you use
114
+ ``width="content"`` with short text, the alignment may not be
115
+ noticeable.
116
+
102
117
  Examples
103
118
  --------
104
119
  >>> import streamlit as st
@@ -117,7 +132,7 @@ class HeadingMixin:
117
132
 
118
133
  """
119
134
  validate_width(width, allow_content=True)
120
- layout_config = LayoutConfig(width=width)
135
+ layout_config = LayoutConfig(width=width, text_alignment=text_alignment)
121
136
 
122
137
  return self.dg._enqueue(
123
138
  "heading",
@@ -140,6 +155,7 @@ class HeadingMixin:
140
155
  help: str | None = None,
141
156
  divider: Divider = False,
142
157
  width: Width = "stretch",
158
+ text_alignment: TextAlignment = "left",
143
159
  ) -> DeltaGenerator:
144
160
  """Display text in subheader formatting.
145
161
 
@@ -188,6 +204,22 @@ class HeadingMixin:
188
204
  the parent container, the width of the element matches the width
189
205
  of the parent container.
190
206
 
207
+ text_alignment : "left", "center", "right", or "justify"
208
+ The horizontal alignment of the text within the element. This can
209
+ be one of the following:
210
+
211
+ - ``"left"`` (default): Text is aligned to the left edge.
212
+ - ``"center"``: Text is centered.
213
+ - ``"right"``: Text is aligned to the right edge.
214
+ - ``"justify"``: Text is justified (stretched to fill the available
215
+ width with the last line left-aligned).
216
+
217
+ .. note::
218
+ For text alignment to have a visible effect, the element's
219
+ width must be wider than its content. If you use
220
+ ``width="content"`` with short text, the alignment may not be
221
+ noticeable.
222
+
191
223
  Examples
192
224
  --------
193
225
  >>> import streamlit as st
@@ -206,7 +238,7 @@ class HeadingMixin:
206
238
 
207
239
  """
208
240
  validate_width(width, allow_content=True)
209
- layout_config = LayoutConfig(width=width)
241
+ layout_config = LayoutConfig(width=width, text_alignment=text_alignment)
210
242
 
211
243
  return self.dg._enqueue(
212
244
  "heading",
@@ -228,6 +260,7 @@ class HeadingMixin:
228
260
  *, # keyword-only arguments:
229
261
  help: str | None = None,
230
262
  width: Width = "stretch",
263
+ text_alignment: TextAlignment = "left",
231
264
  ) -> DeltaGenerator:
232
265
  """Display text in title formatting.
233
266
 
@@ -271,6 +304,22 @@ class HeadingMixin:
271
304
  the parent container, the width of the element matches the width
272
305
  of the parent container.
273
306
 
307
+ text_alignment : "left", "center", "right", or "justify"
308
+ The horizontal alignment of the text within the element. This can
309
+ be one of the following:
310
+
311
+ - ``"left"`` (default): Text is aligned to the left edge.
312
+ - ``"center"``: Text is centered.
313
+ - ``"right"``: Text is aligned to the right edge.
314
+ - ``"justify"``: Text is justified (stretched to fill the available
315
+ width with the last line left-aligned).
316
+
317
+ .. note::
318
+ For text alignment to have a visible effect, the element's
319
+ width must be wider than its content. If you use
320
+ ``width="content"`` with short text, the alignment may not be
321
+ noticeable.
322
+
274
323
  Examples
275
324
  --------
276
325
  >>> import streamlit as st
@@ -284,12 +333,15 @@ class HeadingMixin:
284
333
 
285
334
  """
286
335
  validate_width(width, allow_content=True)
287
- layout_config = LayoutConfig(width=width)
336
+ layout_config = LayoutConfig(width=width, text_alignment=text_alignment)
288
337
 
289
338
  return self.dg._enqueue(
290
339
  "heading",
291
340
  HeadingMixin._create_heading_proto(
292
- tag=HeadingProtoTag.TITLE_TAG, body=body, anchor=anchor, help=help
341
+ tag=HeadingProtoTag.TITLE_TAG,
342
+ body=body,
343
+ anchor=anchor,
344
+ help=help,
293
345
  ),
294
346
  layout_config=layout_config,
295
347
  )
@@ -351,4 +403,5 @@ class HeadingMixin:
351
403
 
352
404
  if help:
353
405
  proto.help = help
406
+
354
407
  return proto