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
@@ -19,9 +19,9 @@ from __future__ import annotations
19
19
 
20
20
  import datetime
21
21
  import itertools
22
- from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union
22
+ from typing import TYPE_CHECKING, Literal, TypeAlias, TypedDict
23
23
 
24
- from typing_extensions import NotRequired, TypeAlias
24
+ from typing_extensions import NotRequired
25
25
 
26
26
  from streamlit.elements.lib.color_util import is_css_color_like
27
27
  from streamlit.errors import StreamlitValueError
@@ -29,7 +29,7 @@ from streamlit.runtime.metrics_util import gather_metrics
29
29
  from streamlit.string_util import validate_material_icon
30
30
 
31
31
  if TYPE_CHECKING:
32
- from collections.abc import Iterable, Iterator
32
+ from collections.abc import Callable, Iterable, Iterator
33
33
 
34
34
  NumberFormat: TypeAlias = Literal[
35
35
  "plain",
@@ -45,7 +45,7 @@ NumberFormat: TypeAlias = Literal[
45
45
  "bytes",
46
46
  ]
47
47
 
48
- ColumnWidth: TypeAlias = Union[Literal["small", "medium", "large"], int]
48
+ ColumnWidth: TypeAlias = Literal["small", "medium", "large"] | int
49
49
 
50
50
  # Type alias that represents all available column types
51
51
  # which are configurable by the user.
@@ -83,11 +83,7 @@ ThemeColor: TypeAlias = Literal[
83
83
  ]
84
84
 
85
85
  # Color options for chart columns:
86
- ChartColor: TypeAlias = Union[
87
- Literal["auto", "auto-inverse"],
88
- ThemeColor,
89
- str,
90
- ]
86
+ ChartColor: TypeAlias = Literal["auto", "auto-inverse"] | ThemeColor | str
91
87
 
92
88
 
93
89
  def _validate_chart_color(maybe_color: str) -> None:
@@ -135,7 +131,7 @@ class CheckboxColumnConfig(TypedDict):
135
131
  type: Literal["checkbox"]
136
132
 
137
133
 
138
- SelectboxOptionValue: TypeAlias = Union[str, int, float, bool]
134
+ SelectboxOptionValue: TypeAlias = str | int | float | bool
139
135
 
140
136
 
141
137
  class SelectboxOption(TypedDict):
@@ -187,7 +183,7 @@ class ListColumnConfig(TypedDict):
187
183
  class MultiselectOption(TypedDict):
188
184
  value: str
189
185
  label: NotRequired[str | None]
190
- color: NotRequired[str | ThemeColor | None]
186
+ color: NotRequired[str | Literal["auto"] | ThemeColor | None]
191
187
 
192
188
 
193
189
  class MultiselectColumnConfig(TypedDict):
@@ -229,6 +225,7 @@ class ProgressColumnConfig(TypedDict):
229
225
  min_value: NotRequired[int | float | None]
230
226
  max_value: NotRequired[int | float | None]
231
227
  step: NotRequired[int | float | None]
228
+ color: NotRequired[ChartColor | None]
232
229
 
233
230
 
234
231
  class JsonColumnConfig(TypedDict):
@@ -1732,10 +1729,15 @@ def MultiselectColumn(
1732
1729
  help: str | None = None,
1733
1730
  disabled: bool | None = None,
1734
1731
  required: bool | None = None,
1732
+ pinned: bool | None = None,
1735
1733
  default: Iterable[str] | None = None,
1736
1734
  options: Iterable[str] | None = None,
1737
1735
  accept_new_options: bool | None = None,
1738
- color: str | ThemeColor | Iterable[str | ThemeColor] | None = None,
1736
+ color: str
1737
+ | Literal["auto"]
1738
+ | ThemeColor
1739
+ | Iterable[str | ThemeColor]
1740
+ | None = None,
1739
1741
  format_func: Callable[[str], str] | None = None,
1740
1742
  ) -> ColumnConfig:
1741
1743
  """Configure a multiselect column in ``st.dataframe`` or ``st.data_editor``.
@@ -1788,6 +1790,12 @@ def MultiselectColumn(
1788
1790
  Whether edited cells in the column need to have a value. If True, an edited cell
1789
1791
  can only be submitted if it has a value other than None. Defaults to False.
1790
1792
 
1793
+ pinned : bool or None
1794
+ Whether the column is pinned. A pinned column will stay visible on the
1795
+ left side no matter where the user scrolls. If this is ``None``
1796
+ (default), Streamlit will decide: index columns are pinned, and data
1797
+ columns are not pinned.
1798
+
1791
1799
  default : Iterable of str or None
1792
1800
  Specifies the default value in this column when a new row is added by the user.
1793
1801
 
@@ -1808,6 +1816,7 @@ def MultiselectColumn(
1808
1816
  The color to use for different options. This can be:
1809
1817
 
1810
1818
  - None (default): The options are displayed without color.
1819
+ - ``"auto"``: The options are colored based on the configured categorical chart colors.
1811
1820
  - A single color value that is used for all options. This can be one of
1812
1821
  the following strings:
1813
1822
 
@@ -1943,6 +1952,7 @@ def MultiselectColumn(
1943
1952
  help=help,
1944
1953
  disabled=disabled,
1945
1954
  required=required,
1955
+ pinned=pinned,
1946
1956
  default=None if default is None else list(default),
1947
1957
  type_config=MultiselectColumnConfig(
1948
1958
  type="multiselect",
@@ -2446,6 +2456,7 @@ def ProgressColumn(
2446
2456
  min_value: int | float | None = None,
2447
2457
  max_value: int | float | None = None,
2448
2458
  step: int | float | None = None,
2459
+ color: ChartColor | None = None,
2449
2460
  ) -> ColumnConfig:
2450
2461
  """Configure a progress column in ``st.dataframe`` or ``st.data_editor``.
2451
2462
 
@@ -2528,6 +2539,19 @@ def ProgressColumn(
2528
2539
  Setting ``step`` for float columns will ensure a consistent number of
2529
2540
  digits after the decimal are displayed.
2530
2541
 
2542
+ color : "auto", "auto-inverse", str, or None
2543
+ The color to use for the chart. This can be one of the following:
2544
+
2545
+ - ``None`` (default): The primary color is used.
2546
+ - ``"auto"``: If the value is more than half, the bar is green; if the
2547
+ value is less than half, the bar is red.
2548
+ - ``"auto-inverse"``: If the value is more than half, the bar is red;
2549
+ if the value is less than half, the bar is green.
2550
+ - A single color value that is applied to all charts in the column.
2551
+ In addition to the basic color palette (red, orange, yellow, green,
2552
+ blue, violet, gray/grey, and primary), this supports hex codes like
2553
+ ``"#483d8b"``.
2554
+
2531
2555
  Examples
2532
2556
  --------
2533
2557
  >>> import pandas as pd
@@ -2558,6 +2582,9 @@ def ProgressColumn(
2558
2582
  height: 300px
2559
2583
  """ # noqa: E501
2560
2584
 
2585
+ if color is not None:
2586
+ _validate_chart_color(color)
2587
+
2561
2588
  return ColumnConfig(
2562
2589
  label=label,
2563
2590
  width=width,
@@ -2569,6 +2596,7 @@ def ProgressColumn(
2569
2596
  min_value=min_value,
2570
2597
  max_value=max_value,
2571
2598
  step=step,
2599
+ color=color,
2572
2600
  ),
2573
2601
  )
2574
2602
 
@@ -14,9 +14,9 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import TYPE_CHECKING, Literal, cast
17
+ from typing import TYPE_CHECKING, Literal, TypeAlias, cast
18
18
 
19
- from typing_extensions import Self, TypeAlias
19
+ from typing_extensions import Self
20
20
 
21
21
  from streamlit.delta_generator import DeltaGenerator
22
22
  from streamlit.elements.lib.utils import compute_and_register_element_id
@@ -20,9 +20,7 @@ import re
20
20
  from collections.abc import Sequence
21
21
  from enum import IntEnum
22
22
  from pathlib import Path
23
- from typing import TYPE_CHECKING, Final, Literal, Union, cast
24
-
25
- from typing_extensions import TypeAlias
23
+ from typing import TYPE_CHECKING, Final, Literal, TypeAlias, Union, cast
26
24
 
27
25
  from streamlit import runtime, url_util
28
26
  from streamlit.errors import StreamlitAPIException
@@ -48,7 +46,7 @@ AtomicImage: TypeAlias = Union[
48
46
  Channels: TypeAlias = Literal["RGB", "BGR"]
49
47
  ImageFormat: TypeAlias = Literal["JPEG", "PNG", "GIF"]
50
48
  ImageFormatOrAuto: TypeAlias = Literal[ImageFormat, "auto"]
51
- ImageOrImageList: TypeAlias = Union[AtomicImage, Sequence[AtomicImage]]
49
+ ImageOrImageList: TypeAlias = AtomicImage | Sequence[AtomicImage]
52
50
 
53
51
  # This constant is related to the frontend maximum content width specified
54
52
  # in App.jsx main container
@@ -434,7 +432,7 @@ def marshall_images(
434
432
 
435
433
  # Each image in an image list needs to be kept track of at its own coordinates.
436
434
  for coord_suffix, (single_image, single_caption) in enumerate(
437
- zip(images, captions)
435
+ zip(images, captions, strict=False)
438
436
  ):
439
437
  proto_img = proto_imgs.imgs.add()
440
438
  if single_caption is not None:
@@ -14,35 +14,48 @@
14
14
  from __future__ import annotations
15
15
 
16
16
  from dataclasses import dataclass
17
- from typing import Literal, Union, cast
18
-
19
- from typing_extensions import TypeAlias
17
+ from typing import Literal, TypeAlias, cast
20
18
 
21
19
  from streamlit.errors import (
22
20
  StreamlitInvalidColumnGapError,
23
21
  StreamlitInvalidHeightError,
24
22
  StreamlitInvalidHorizontalAlignmentError,
23
+ StreamlitInvalidSizeError,
24
+ StreamlitInvalidTextAlignmentError,
25
25
  StreamlitInvalidVerticalAlignmentError,
26
26
  StreamlitInvalidWidthError,
27
27
  )
28
28
  from streamlit.proto.Block_pb2 import Block
29
29
  from streamlit.proto.GapSize_pb2 import GapSize
30
30
  from streamlit.proto.HeightConfig_pb2 import HeightConfig
31
+ from streamlit.proto.TextAlignmentConfig_pb2 import TextAlignmentConfig
31
32
  from streamlit.proto.WidthConfig_pb2 import WidthConfig
32
33
 
33
- WidthWithoutContent: TypeAlias = Union[int, Literal["stretch"]]
34
- Width: TypeAlias = Union[int, Literal["stretch", "content"]]
35
- HeightWithoutContent: TypeAlias = Union[int, Literal["stretch"]]
36
- Height: TypeAlias = Union[int, Literal["stretch", "content"]]
34
+ WidthWithoutContent: TypeAlias = int | Literal["stretch"]
35
+ Width: TypeAlias = int | Literal["stretch", "content"]
36
+ HeightWithoutContent: TypeAlias = int | Literal["stretch"]
37
+ Height: TypeAlias = int | Literal["stretch", "content"]
38
+ SpaceSize: TypeAlias = int | Literal["stretch", "small", "medium", "large"]
37
39
  Gap: TypeAlias = Literal["small", "medium", "large"]
38
40
  HorizontalAlignment: TypeAlias = Literal["left", "center", "right", "distribute"]
39
41
  VerticalAlignment: TypeAlias = Literal["top", "center", "bottom", "distribute"]
42
+ TextAlignment: TypeAlias = Literal["left", "center", "right", "justify"]
43
+
44
+ # Mapping of size literals to rem values for st.space
45
+ # If changing these, also check streamlit/frontend/lib/src/theme/primitives/sizes.ts
46
+ # to ensure sizes are kept in sync.
47
+ SIZE_TO_REM_MAPPING = {
48
+ "small": 0.75, # Height of widget label minus gap
49
+ "medium": 2.5, # Height of button/input field
50
+ "large": 4.25, # Height of large widget without label
51
+ }
40
52
 
41
53
 
42
54
  @dataclass
43
55
  class LayoutConfig:
44
- width: Width | None = None
45
- height: Height | None = None
56
+ width: Width | SpaceSize | None = None
57
+ height: Height | SpaceSize | None = None
58
+ text_alignment: TextAlignment | None = None
46
59
 
47
60
 
48
61
  def validate_width(width: Width, allow_content: bool = False) -> None:
@@ -117,9 +130,35 @@ def validate_height(
117
130
  raise StreamlitInvalidHeightError(height, allow_content)
118
131
 
119
132
 
120
- def get_width_config(width: Width) -> WidthConfig:
133
+ def validate_space_size(size: SpaceSize) -> None:
134
+ """Validate the size parameter for st.space.
135
+
136
+ Parameters
137
+ ----------
138
+ size : Any
139
+ The size value to validate.
140
+
141
+ Raises
142
+ ------
143
+ StreamlitInvalidSizeError
144
+ If the size value is invalid.
145
+ """
146
+ if not isinstance(size, (int, str)):
147
+ raise StreamlitInvalidSizeError(size)
148
+
149
+ if isinstance(size, str):
150
+ valid_strings = ["stretch", "small", "medium", "large"]
151
+ if size not in valid_strings:
152
+ raise StreamlitInvalidSizeError(size)
153
+ elif isinstance(size, int) and size <= 0:
154
+ raise StreamlitInvalidSizeError(size)
155
+
156
+
157
+ def get_width_config(width: Width | SpaceSize) -> WidthConfig:
121
158
  width_config = WidthConfig()
122
- if isinstance(width, (int, float)):
159
+ if isinstance(width, str) and width in SIZE_TO_REM_MAPPING:
160
+ width_config.rem_width = SIZE_TO_REM_MAPPING[width]
161
+ elif isinstance(width, (int, float)):
123
162
  width_config.pixel_width = int(width)
124
163
  elif width == "content":
125
164
  width_config.use_content = True
@@ -128,9 +167,11 @@ def get_width_config(width: Width) -> WidthConfig:
128
167
  return width_config
129
168
 
130
169
 
131
- def get_height_config(height: Height) -> HeightConfig:
170
+ def get_height_config(height: Height | SpaceSize) -> HeightConfig:
132
171
  height_config = HeightConfig()
133
- if isinstance(height, (int, float)):
172
+ if isinstance(height, str) and height in SIZE_TO_REM_MAPPING:
173
+ height_config.rem_height = SIZE_TO_REM_MAPPING[height]
174
+ elif isinstance(height, (int, float)):
134
175
  height_config.pixel_height = int(height)
135
176
  elif height == "content":
136
177
  height_config.use_content = True
@@ -173,6 +214,24 @@ def validate_vertical_alignment(vertical_alignment: VerticalAlignment) -> None:
173
214
  raise StreamlitInvalidVerticalAlignmentError(vertical_alignment, "st.container")
174
215
 
175
216
 
217
+ def validate_text_alignment(text_alignment: TextAlignment) -> None:
218
+ """Validate the text_alignment parameter.
219
+
220
+ Parameters
221
+ ----------
222
+ text_alignment : TextAlignment
223
+ The text alignment value to validate.
224
+
225
+ Raises
226
+ ------
227
+ StreamlitInvalidTextAlignmentError
228
+ If the text_alignment value is invalid.
229
+ """
230
+ valid_alignments = ["left", "center", "right", "justify"]
231
+ if text_alignment not in valid_alignments:
232
+ raise StreamlitInvalidTextAlignmentError(text_alignment)
233
+
234
+
176
235
  map_to_flex_terminology = {
177
236
  "left": "start",
178
237
  "center": "center",
@@ -212,3 +271,31 @@ def get_align(
212
271
  "Block.FlexContainer.Align.ValueType",
213
272
  getattr(Block.FlexContainer.Align, f"ALIGN_{align.upper()}"),
214
273
  )
274
+
275
+
276
+ def get_text_alignment_config(
277
+ text_alignment: TextAlignment,
278
+ ) -> TextAlignmentConfig:
279
+ """Convert text alignment string to proto config.
280
+
281
+ Parameters
282
+ ----------
283
+ text_alignment : TextAlignment
284
+ The text alignment value ("left", "center", "right", "justify").
285
+
286
+ Returns
287
+ -------
288
+ TextAlignmentConfig
289
+ Proto message with alignment set.
290
+ """
291
+
292
+ alignment_mapping = {
293
+ "left": TextAlignmentConfig.Alignment.LEFT,
294
+ "center": TextAlignmentConfig.Alignment.CENTER,
295
+ "right": TextAlignmentConfig.Alignment.RIGHT,
296
+ "justify": TextAlignmentConfig.Alignment.JUSTIFY,
297
+ }
298
+
299
+ config = TextAlignmentConfig()
300
+ config.alignment = alignment_mapping[text_alignment]
301
+ return config
@@ -15,9 +15,9 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import time
18
- from typing import TYPE_CHECKING, Literal, cast
18
+ from typing import TYPE_CHECKING, Literal, TypeAlias, cast
19
19
 
20
- from typing_extensions import Self, TypeAlias
20
+ from typing_extensions import Self
21
21
 
22
22
  from streamlit.delta_generator import DeltaGenerator
23
23
  from streamlit.elements.lib.layout_utils import (
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from enum import Enum, EnumMeta
18
- from typing import TYPE_CHECKING, Any, Callable, Final, TypeVar, overload
18
+ from typing import TYPE_CHECKING, Any, Final, TypeVar, overload
19
19
 
20
20
  from streamlit import config, logger
21
21
  from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
@@ -26,7 +26,7 @@ from streamlit.type_util import (
26
26
  )
27
27
 
28
28
  if TYPE_CHECKING:
29
- from collections.abc import Iterable, Sequence
29
+ from collections.abc import Callable, Iterable, Sequence
30
30
 
31
31
  _LOGGER: Final = logger.get_logger(__name__)
32
32
 
@@ -47,7 +47,7 @@ def marshall_styler(proto: ArrowProto, styler: Styler, default_uuid: str) -> Non
47
47
  """
48
48
  import pandas as pd
49
49
 
50
- styler_data_df: pd.DataFrame = styler.data
50
+ styler_data_df: pd.DataFrame = styler.data # type: ignore[attr-defined]
51
51
  if styler_data_df.size > int(pd.options.styler.render.max_elements):
52
52
  raise StreamlitAPIException(
53
53
  f"The dataframe has `{styler_data_df.size}` cells, but the maximum number "
@@ -62,9 +62,9 @@ def marshall_styler(proto: ArrowProto, styler: Styler, default_uuid: str) -> Non
62
62
 
63
63
  # We're using protected members of pandas.Styler to get styles,
64
64
  # which is not ideal and could break if the interface changes.
65
- styler._compute()
65
+ styler._compute() # type: ignore
66
66
 
67
- pandas_styles = styler._translate(False, False)
67
+ pandas_styles = styler._translate(False, False) # type: ignore
68
68
 
69
69
  _marshall_caption(proto, styler)
70
70
  _marshall_styles(proto, styler, pandas_styles)
@@ -86,10 +86,10 @@ def _marshall_uuid(proto: ArrowProto, styler: Styler, default_uuid: str) -> None
86
86
  If pandas.Styler uuid is not provided, this value will be used.
87
87
 
88
88
  """
89
- if styler.uuid is None:
89
+ if styler.uuid is None: # type: ignore[attr-defined]
90
90
  styler.set_uuid(default_uuid)
91
91
 
92
- proto.styler.uuid = str(styler.uuid)
92
+ proto.styler.uuid = str(styler.uuid) # type: ignore[attr-defined]
93
93
 
94
94
 
95
95
  def _marshall_caption(proto: ArrowProto, styler: Styler) -> None:
@@ -104,8 +104,8 @@ def _marshall_caption(proto: ArrowProto, styler: Styler) -> None:
104
104
  Helps style a DataFrame or Series according to the data with HTML and CSS.
105
105
 
106
106
  """
107
- if styler.caption is not None:
108
- proto.styler.caption = styler.caption
107
+ if styler.caption is not None: # type: ignore[attr-defined]
108
+ proto.styler.caption = styler.caption # type: ignore[attr-defined]
109
109
 
110
110
 
111
111
  def _marshall_styles(
@@ -134,7 +134,10 @@ def _marshall_styles(
134
134
  # styles in "table_styles" have a space
135
135
  # between the uuid and selector.
136
136
  rule = _pandas_style_to_css(
137
- "table_styles", style, styler.uuid, separator=" "
137
+ "table_styles",
138
+ style,
139
+ styler.uuid, # type: ignore[attr-defined]
140
+ separator=" ",
138
141
  )
139
142
  css_rules.append(rule)
140
143
 
@@ -142,7 +145,12 @@ def _marshall_styles(
142
145
  cellstyle = styles["cellstyle"]
143
146
  cellstyle = _trim_pandas_styles(cellstyle)
144
147
  for style in cellstyle:
145
- rule = _pandas_style_to_css("cell_style", style, styler.uuid, separator="_")
148
+ rule = _pandas_style_to_css(
149
+ "cell_style",
150
+ style,
151
+ styler.uuid, # type: ignore[attr-defined]
152
+ separator="_",
153
+ )
146
154
  css_rules.append(rule)
147
155
 
148
156
  if len(css_rules) > 0:
@@ -0,0 +1,152 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import (
19
+ Final,
20
+ )
21
+
22
+ from streamlit.errors import (
23
+ StreamlitAPIException,
24
+ )
25
+
26
+ _MODIFIER_ALIASES: Final[dict[str, str]] = {
27
+ "ctrl": "ctrl",
28
+ "control": "ctrl",
29
+ "cmd": "cmd",
30
+ "command": "cmd",
31
+ "meta": "cmd",
32
+ "alt": "alt",
33
+ "option": "alt",
34
+ "shift": "shift",
35
+ "mod": "ctrl",
36
+ }
37
+
38
+ _MODIFIER_ORDER: Final[tuple[str, ...]] = ("ctrl", "cmd", "alt", "shift")
39
+
40
+ _KEY_ALIASES: Final[dict[str, str]] = {
41
+ "enter": "enter",
42
+ "return": "enter",
43
+ "space": "space",
44
+ "spacebar": "space",
45
+ "tab": "tab",
46
+ "escape": "escape",
47
+ "esc": "escape",
48
+ "backspace": "backspace",
49
+ "delete": "delete",
50
+ "del": "delete",
51
+ "home": "home",
52
+ "end": "end",
53
+ "pageup": "pageup",
54
+ "pagedown": "pagedown",
55
+ "left": "left",
56
+ "arrowleft": "left",
57
+ "right": "right",
58
+ "arrowright": "right",
59
+ "up": "up",
60
+ "arrowup": "up",
61
+ "down": "down",
62
+ "arrowdown": "down",
63
+ }
64
+
65
+ _RESERVED_KEYS: Final[set[str]] = {"c", "r"}
66
+
67
+
68
+ def _normalize_key_token(lower_token: str) -> str:
69
+ """Normalize a key token to a format that can be used on the client side."""
70
+
71
+ if lower_token in _KEY_ALIASES:
72
+ return _KEY_ALIASES[lower_token]
73
+
74
+ if len(lower_token) == 1 and lower_token.isalnum():
75
+ return lower_token
76
+
77
+ if lower_token.startswith("f") and lower_token[1:].isdigit():
78
+ return lower_token
79
+
80
+ raise StreamlitAPIException(
81
+ "shortcut must include a single character or one of the supported keys "
82
+ "(e.g. Enter, Space, Tab, Escape)."
83
+ )
84
+
85
+
86
+ def normalize_shortcut(shortcut: str) -> str:
87
+ """Normalize a shortcut string to a format that can be used on the client side.
88
+
89
+ Parameters
90
+ ----------
91
+ shortcut : str
92
+ The shortcut string to normalize.
93
+
94
+ Returns
95
+ -------
96
+ str
97
+ The normalized shortcut string.
98
+
99
+ Raises
100
+ ------
101
+ StreamlitAPIException
102
+ If the shortcut is not a string value.
103
+ If the shortcut does not contain at least one key or modifier.
104
+ If the shortcut contains a single non-modifier key.
105
+ If the shortcut uses the keys 'C' or 'R', with or without modifiers.
106
+ If the shortcut does not include a non-modifier key.
107
+ """
108
+ if not isinstance(shortcut, str):
109
+ raise StreamlitAPIException("shortcut must be a string value.")
110
+
111
+ tokens = [token.strip() for token in shortcut.split("+") if token.strip()]
112
+ if not tokens:
113
+ raise StreamlitAPIException(
114
+ "The `shortcut` must contain at least one key or modifier."
115
+ )
116
+
117
+ modifiers: list[str] = []
118
+ key: str | None = None
119
+
120
+ for raw_token in tokens:
121
+ lower_token = raw_token.lower()
122
+ if lower_token in _MODIFIER_ALIASES:
123
+ normalized_modifier = _MODIFIER_ALIASES[lower_token]
124
+ if normalized_modifier not in modifiers:
125
+ modifiers.append(normalized_modifier)
126
+ continue
127
+
128
+ if key is not None:
129
+ raise StreamlitAPIException(
130
+ "The `shortcut` may only specify a single non-modifier key."
131
+ )
132
+
133
+ normalized_key = _normalize_key_token(lower_token)
134
+ if normalized_key in _RESERVED_KEYS:
135
+ raise StreamlitAPIException(
136
+ "The `shortcut` cannot use the keys 'C' or 'R', with or without modifiers."
137
+ )
138
+
139
+ key = normalized_key
140
+
141
+ if key is None:
142
+ raise StreamlitAPIException(
143
+ "The `shortcut` must include a non-modifier key such as 'K' or 'Ctrl+K'."
144
+ )
145
+
146
+ normalized_tokens: list[str] = [
147
+ modifier for modifier in _MODIFIER_ORDER if modifier in modifiers
148
+ ]
149
+ if key is not None:
150
+ normalized_tokens.append(key)
151
+
152
+ return "+".join(normalized_tokens)
@@ -20,12 +20,12 @@ from typing import (
20
20
  TYPE_CHECKING,
21
21
  Any,
22
22
  Literal,
23
+ TypeAlias,
23
24
  Union,
24
25
  overload,
25
26
  )
26
27
 
27
28
  from google.protobuf.message import Message
28
- from typing_extensions import TypeAlias
29
29
 
30
30
  from streamlit import config
31
31
  from streamlit.elements.lib.form_utils import current_form_id
@@ -49,12 +49,12 @@ if TYPE_CHECKING:
49
49
  from streamlit.delta_generator import DeltaGenerator
50
50
 
51
51
 
52
- Key: TypeAlias = Union[str, int]
52
+ Key: TypeAlias = str | int
53
53
 
54
54
  LabelVisibility: TypeAlias = Literal["visible", "hidden", "collapsed"]
55
55
 
56
- PROTO_SCALAR_VALUE = Union[float, int, bool, str, bytes]
57
- SAFE_VALUES = Union[
56
+ PROTO_SCALAR_VALUE: TypeAlias = float | int | bool | str | bytes
57
+ SAFE_VALUES: TypeAlias = Union[
58
58
  date,
59
59
  time,
60
60
  datetime,