streamlit 1.45.0__py3-none-any.whl → 1.46.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 (336) hide show
  1. streamlit/__init__.py +5 -1
  2. streamlit/auth_util.py +12 -12
  3. streamlit/cli_util.py +4 -3
  4. streamlit/column_config.py +11 -9
  5. streamlit/commands/echo.py +6 -4
  6. streamlit/commands/execution_control.py +33 -32
  7. streamlit/commands/experimental_query_params.py +2 -2
  8. streamlit/commands/logo.py +9 -4
  9. streamlit/commands/navigation.py +61 -18
  10. streamlit/commands/page_config.py +57 -47
  11. streamlit/components/types/base_custom_component.py +7 -7
  12. streamlit/components/v1/component_registry.py +7 -3
  13. streamlit/components/v1/components.py +1 -1
  14. streamlit/components/v1/custom_component.py +8 -8
  15. streamlit/config.py +289 -144
  16. streamlit/config_option.py +19 -15
  17. streamlit/config_util.py +29 -23
  18. streamlit/connections/__init__.py +2 -2
  19. streamlit/connections/base_connection.py +5 -5
  20. streamlit/connections/snowflake_connection.py +13 -11
  21. streamlit/connections/snowpark_connection.py +3 -3
  22. streamlit/connections/sql_connection.py +20 -18
  23. streamlit/connections/util.py +2 -2
  24. streamlit/cursor.py +6 -6
  25. streamlit/dataframe_util.py +52 -52
  26. streamlit/delta_generator.py +46 -48
  27. streamlit/delta_generator_singletons.py +3 -3
  28. streamlit/deprecation_util.py +6 -6
  29. streamlit/elements/alert.py +37 -29
  30. streamlit/elements/arrow.py +40 -22
  31. streamlit/elements/code.py +46 -13
  32. streamlit/elements/deck_gl_json_chart.py +38 -27
  33. streamlit/elements/dialog_decorator.py +3 -4
  34. streamlit/elements/doc_string.py +64 -58
  35. streamlit/elements/exception.py +23 -27
  36. streamlit/elements/form.py +41 -0
  37. streamlit/elements/graphviz_chart.py +1 -1
  38. streamlit/elements/heading.py +60 -9
  39. streamlit/elements/html.py +3 -4
  40. streamlit/elements/image.py +8 -9
  41. streamlit/elements/json.py +21 -2
  42. streamlit/elements/layouts.py +120 -31
  43. streamlit/elements/lib/built_in_chart_utils.py +96 -73
  44. streamlit/elements/lib/color_util.py +3 -3
  45. streamlit/elements/lib/column_config_utils.py +2 -4
  46. streamlit/elements/lib/column_types.py +14 -8
  47. streamlit/elements/lib/dialog.py +9 -5
  48. streamlit/elements/lib/file_uploader_utils.py +7 -2
  49. streamlit/elements/lib/image_utils.py +39 -40
  50. streamlit/elements/lib/js_number.py +4 -4
  51. streamlit/elements/lib/layout_utils.py +65 -1
  52. streamlit/elements/lib/mutable_status_container.py +14 -3
  53. streamlit/elements/lib/options_selector_utils.py +22 -12
  54. streamlit/elements/lib/pandas_styler_utils.py +25 -21
  55. streamlit/elements/lib/policies.py +6 -5
  56. streamlit/elements/lib/streamlit_plotly_theme.py +54 -53
  57. streamlit/elements/lib/subtitle_utils.py +6 -9
  58. streamlit/elements/lib/utils.py +20 -5
  59. streamlit/elements/map.py +32 -56
  60. streamlit/elements/markdown.py +101 -12
  61. streamlit/elements/media.py +78 -21
  62. streamlit/elements/metric.py +32 -16
  63. streamlit/elements/plotly_chart.py +15 -15
  64. streamlit/elements/progress.py +33 -15
  65. streamlit/elements/spinner.py +31 -6
  66. streamlit/elements/text.py +21 -1
  67. streamlit/elements/toast.py +1 -2
  68. streamlit/elements/vega_charts.py +54 -23
  69. streamlit/elements/widgets/audio_input.py +24 -7
  70. streamlit/elements/widgets/button.py +26 -19
  71. streamlit/elements/widgets/button_group.py +10 -15
  72. streamlit/elements/widgets/camera_input.py +27 -7
  73. streamlit/elements/widgets/chat.py +91 -38
  74. streamlit/elements/widgets/checkbox.py +45 -4
  75. streamlit/elements/widgets/color_picker.py +40 -17
  76. streamlit/elements/widgets/data_editor.py +76 -37
  77. streamlit/elements/widgets/file_uploader.py +42 -13
  78. streamlit/elements/widgets/multiselect.py +7 -10
  79. streamlit/elements/widgets/number_input.py +123 -47
  80. streamlit/elements/widgets/radio.py +59 -13
  81. streamlit/elements/widgets/select_slider.py +35 -30
  82. streamlit/elements/widgets/selectbox.py +56 -9
  83. streamlit/elements/widgets/slider.py +190 -99
  84. streamlit/elements/widgets/text_widgets.py +54 -8
  85. streamlit/elements/widgets/time_widgets.py +53 -14
  86. streamlit/elements/write.py +5 -8
  87. streamlit/env_util.py +2 -7
  88. streamlit/error_util.py +16 -9
  89. streamlit/errors.py +69 -48
  90. streamlit/external/langchain/streamlit_callback_handler.py +10 -5
  91. streamlit/file_util.py +27 -10
  92. streamlit/git_util.py +29 -24
  93. streamlit/hello/animation_demo.py +9 -9
  94. streamlit/hello/dataframe_demo.py +5 -5
  95. streamlit/hello/hello.py +1 -0
  96. streamlit/hello/mapping_demo.py +7 -8
  97. streamlit/hello/plotting_demo.py +3 -3
  98. streamlit/hello/streamlit_app.py +28 -26
  99. streamlit/hello/utils.py +2 -1
  100. streamlit/logger.py +10 -11
  101. streamlit/navigation/page.py +11 -8
  102. streamlit/proto/Audio_pb2.py +4 -3
  103. streamlit/proto/Audio_pb2.pyi +8 -1
  104. streamlit/proto/Block_pb2.py +38 -29
  105. streamlit/proto/Block_pb2.pyi +72 -4
  106. streamlit/proto/ClientState_pb2.py +4 -4
  107. streamlit/proto/ClientState_pb2.pyi +7 -2
  108. streamlit/proto/Code_pb2.py +4 -2
  109. streamlit/proto/Code_pb2.pyi +1 -0
  110. streamlit/proto/DataFrame_pb2.pyi +1 -1
  111. streamlit/proto/DeckGlJsonChart_pb2.pyi +1 -1
  112. streamlit/proto/Element_pb2.py +5 -3
  113. streamlit/proto/Element_pb2.pyi +20 -3
  114. streamlit/proto/GapSize_pb2.py +29 -0
  115. streamlit/proto/GapSize_pb2.pyi +70 -0
  116. streamlit/proto/HeightConfig_pb2.py +27 -0
  117. streamlit/proto/HeightConfig_pb2.pyi +48 -0
  118. streamlit/proto/NamedDataSet_pb2.pyi +1 -1
  119. streamlit/proto/Navigation_pb2.py +3 -3
  120. streamlit/proto/Navigation_pb2.pyi +4 -0
  121. streamlit/proto/NewSession_pb2.py +18 -16
  122. streamlit/proto/NewSession_pb2.pyi +29 -3
  123. streamlit/proto/PageConfig_pb2.py +7 -7
  124. streamlit/proto/PageConfig_pb2.pyi +21 -1
  125. streamlit/proto/Video_pb2.py +8 -7
  126. streamlit/proto/Video_pb2.pyi +8 -1
  127. streamlit/proto/WidthConfig_pb2.py +2 -2
  128. streamlit/proto/WidthConfig_pb2.pyi +15 -1
  129. streamlit/runtime/__init__.py +1 -1
  130. streamlit/runtime/app_session.py +53 -40
  131. streamlit/runtime/caching/__init__.py +9 -9
  132. streamlit/runtime/caching/cache_data_api.py +36 -30
  133. streamlit/runtime/caching/cache_errors.py +4 -4
  134. streamlit/runtime/caching/cache_resource_api.py +8 -8
  135. streamlit/runtime/caching/cache_utils.py +15 -14
  136. streamlit/runtime/caching/cached_message_replay.py +14 -8
  137. streamlit/runtime/caching/hashing.py +91 -97
  138. streamlit/runtime/caching/legacy_cache_api.py +2 -2
  139. streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
  140. streamlit/runtime/caching/storage/dummy_cache_storage.py +1 -1
  141. streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +12 -14
  142. streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -6
  143. streamlit/runtime/connection_factory.py +36 -36
  144. streamlit/runtime/context.py +58 -9
  145. streamlit/runtime/credentials.py +29 -40
  146. streamlit/runtime/forward_msg_queue.py +11 -11
  147. streamlit/runtime/fragment.py +7 -7
  148. streamlit/runtime/media_file_manager.py +3 -4
  149. streamlit/runtime/memory_media_file_storage.py +6 -5
  150. streamlit/runtime/memory_uploaded_file_manager.py +2 -2
  151. streamlit/runtime/metrics_util.py +11 -12
  152. streamlit/runtime/pages_manager.py +4 -6
  153. streamlit/runtime/runtime.py +8 -6
  154. streamlit/runtime/runtime_util.py +7 -6
  155. streamlit/runtime/scriptrunner/__init__.py +4 -4
  156. streamlit/runtime/scriptrunner/exec_code.py +12 -5
  157. streamlit/runtime/scriptrunner/magic.py +16 -12
  158. streamlit/runtime/scriptrunner/script_cache.py +1 -1
  159. streamlit/runtime/scriptrunner/script_runner.py +55 -34
  160. streamlit/runtime/scriptrunner_utils/exceptions.py +1 -1
  161. streamlit/runtime/scriptrunner_utils/script_requests.py +7 -4
  162. streamlit/runtime/scriptrunner_utils/script_run_context.py +10 -23
  163. streamlit/runtime/secrets.py +40 -35
  164. streamlit/runtime/session_manager.py +2 -1
  165. streamlit/runtime/state/__init__.py +5 -5
  166. streamlit/runtime/state/common.py +2 -2
  167. streamlit/runtime/state/query_params.py +13 -15
  168. streamlit/runtime/state/query_params_proxy.py +17 -13
  169. streamlit/runtime/state/safe_session_state.py +2 -2
  170. streamlit/runtime/state/session_state.py +52 -34
  171. streamlit/runtime/stats.py +2 -2
  172. streamlit/runtime/uploaded_file_manager.py +1 -1
  173. streamlit/runtime/websocket_session_manager.py +10 -6
  174. streamlit/source_util.py +8 -6
  175. streamlit/static/index.html +3 -17
  176. streamlit/static/manifest.json +1180 -0
  177. streamlit/static/static/css/{index.DqDwtg6_.css → index.CJVRHjQZ.css} +1 -1
  178. streamlit/static/static/js/{ErrorOutline.esm.DyIfDYvY.js → ErrorOutline.esm.6PVAQvlT.js} +1 -1
  179. streamlit/static/static/js/{FileDownload.esm.kF1FCxeJ.js → FileDownload.esm.BZQHC61b.js} +1 -1
  180. streamlit/static/static/js/{FileHelper.DKt6tIeO.js → FileHelper.Bn1VShMJ.js} +5 -5
  181. streamlit/static/static/js/{FormClearHelper.DpJR9YCu.js → FormClearHelper.CsFEiTNN.js} +1 -1
  182. streamlit/static/static/js/{Hooks.BT6PF2Zi.js → Hooks.DguOHQL1.js} +1 -1
  183. streamlit/static/static/js/{InputInstructions.BmnD4oa3.js → InputInstructions.CTYn2BJQ.js} +1 -1
  184. streamlit/static/static/js/{ProgressBar.Ch7VNdkM.js → ProgressBar.CPOGBKCi.js} +2 -2
  185. streamlit/static/static/js/{RenderInPortalIfExists.43tDswzK.js → RenderInPortalIfExists.BYu_CZaF.js} +1 -1
  186. streamlit/static/static/js/Toolbar.gXKw7ANv.js +1 -0
  187. streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
  188. streamlit/static/static/js/{base-input.BjeC3XFX.js → base-input.DBYPj91R.js} +4 -4
  189. streamlit/static/static/js/{checkbox.DIVN0GOS.js → checkbox.BUm2vnNv.js} +2 -2
  190. streamlit/static/static/js/{createSuper.CKyBiJe0.js → createSuper.KD4RuZ-W.js} +1 -1
  191. streamlit/static/static/js/{data-grid-overlay-editor.CXpaXRk5.js → data-grid-overlay-editor.CUwpDfvI.js} +1 -1
  192. streamlit/static/static/js/{downloader.B-uWAyLB.js → downloader.CkDtclup.js} +1 -1
  193. streamlit/static/static/js/{es6._eGNfJ2i.js → es6.Dlcvh_r0.js} +2 -2
  194. streamlit/static/static/js/{iframeResizer.contentWindow.CebQfV1Q.js → iframeResizer.contentWindow.DOXlFfve.js} +1 -1
  195. streamlit/static/static/js/{index.EbMzSayc.js → index.B0cuGMAB.js} +25 -25
  196. streamlit/static/static/js/index.BCWTclSV.js +73 -0
  197. streamlit/static/static/js/index.BJY_fap7.js +1 -0
  198. streamlit/static/static/js/index.BL3l6dnk.js +1 -0
  199. streamlit/static/static/js/{index.CpV1hnf8.js → index.BMZzRZjB.js} +1 -1
  200. streamlit/static/static/js/{index.l6QfBDTC.js → index.BOzUTGDe.js} +1 -1
  201. streamlit/static/static/js/index.BYI5iO-o.js +1 -0
  202. streamlit/static/static/js/index.BYo0ywlm.js +783 -0
  203. streamlit/static/static/js/{index.CuUJHsRK.js → index.BYz9btsY.js} +1 -1
  204. streamlit/static/static/js/{index.C_nMqHLH.js → index.CCVzQz0Z.js} +2 -2
  205. streamlit/static/static/js/index.CD6FydK9.js +1 -0
  206. streamlit/static/static/js/index.CDYEqgC8.js +2 -0
  207. streamlit/static/static/js/{index.BAdBHmJD.js → index.CMP9c4xA.js} +1 -1
  208. streamlit/static/static/js/index.CN30QAPD.js +1 -0
  209. streamlit/static/static/js/{index.CtTgot1Z.js → index.CNqWQkTe.js} +1 -1
  210. streamlit/static/static/js/index.CaxS67Xz.js +1 -0
  211. streamlit/static/static/js/{index.HsXxdgGd.js → index.CbsT4sGW.js} +1 -1
  212. streamlit/static/static/js/index.ChAVlxpQ.js +1 -0
  213. streamlit/static/static/js/{index.BaYSBSaz.js → index.ClLMMmDd.js} +1 -1
  214. streamlit/static/static/js/{index.CxxktCLw.js → index.D-O9rQmV.js} +1 -1
  215. streamlit/static/static/js/{index.Coc8OVG7.js → index.D4k7VZZL.js} +1 -1
  216. streamlit/static/static/js/index.DLBi0Ar1.js +1 -0
  217. streamlit/static/static/js/index.DVq5XmJo.js +197 -0
  218. streamlit/static/static/js/{index.ClX0ambk.js → index.DZKmKXWw.js} +1 -1
  219. streamlit/static/static/js/index.DkaVx80F.js +1 -0
  220. streamlit/static/static/js/index.Dr968Klx.js +1 -0
  221. streamlit/static/static/js/{index.BaozEIL-.js → index.DtUYLn9j.js} +20 -20
  222. streamlit/static/static/js/index.DwjYSyhs.js +1 -0
  223. streamlit/static/static/js/index.DzrImxu4.js +1 -0
  224. streamlit/static/static/js/index.HyGsn4VM.js +1 -0
  225. streamlit/static/static/js/index.OwxC65od.js +12 -0
  226. streamlit/static/static/js/index.PZs7VZkC.js +1 -0
  227. streamlit/static/static/js/index.Voiqpj4q.js +1 -0
  228. streamlit/static/static/js/index.bSROvR-J.js +3 -0
  229. streamlit/static/static/js/index.oT9GD3l4.js +1 -0
  230. streamlit/static/static/js/{index.schmj9D9.js → index.qb-yAPH6.js} +255 -255
  231. streamlit/static/static/js/index.rJFy_Ygy.js +2 -0
  232. streamlit/static/static/js/{input.VQEe_bZy.js → input.CwQtEnFN.js} +2 -2
  233. streamlit/static/static/js/{memory.DGVHab07.js → memory.C5XaFIjR.js} +1 -1
  234. streamlit/static/static/js/{mergeWith.-RIuUGoA.js → mergeWith.DzwwH6AG.js} +1 -1
  235. streamlit/static/static/js/{number-overlay-editor.wzFLIbEE.js → number-overlay-editor.Dx0XqCkD.js} +1 -1
  236. streamlit/static/static/js/{possibleConstructorReturn.GIObu6rf.js → possibleConstructorReturn.CVfSu9Ws.js} +1 -1
  237. streamlit/static/static/js/{sandbox.DpjSeqe2.js → sandbox.BT0gdMXk.js} +1 -1
  238. streamlit/static/static/js/{textarea.Dz0J9LZe.js → textarea.DNCbrtbM.js} +2 -2
  239. streamlit/static/static/js/{timepicker.BLgJZnzX.js → timepicker.4UYJD9Ts.js} +1 -1
  240. streamlit/static/static/js/{toConsumableArray.0OZlxz7U.js → toConsumableArray.DUmnaVWV.js} +1 -1
  241. streamlit/static/static/js/{uniqueId.DbzplC8D.js → uniqueId.DUvh-GL8.js} +1 -1
  242. streamlit/static/static/js/{useBasicWidgetState.COJZng1S.js → useBasicWidgetState.Cwd7-jJa.js} +1 -1
  243. streamlit/static/static/js/useOnInputChange.DvemQrOM.js +1 -0
  244. streamlit/static/static/js/{withFullScreenWrapper.CzWvNbvi.js → withFullScreenWrapper.CiQ10ByU.js} +1 -1
  245. streamlit/static/static/media/SourceCodeVF-Italic.ttf.Ba1oaZG1.woff2 +0 -0
  246. streamlit/static/static/media/SourceCodeVF-Upright.ttf.BjWn63N-.woff2 +0 -0
  247. streamlit/static/static/media/SourceSansVF-Italic.ttf.Bt9VkdQ3.woff2 +0 -0
  248. streamlit/static/static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2 +0 -0
  249. streamlit/static/static/media/SourceSerifVariable-Italic.ttf.CVdzAtxO.woff2 +0 -0
  250. streamlit/static/static/media/SourceSerifVariable-Roman.ttf.mdpVL9bi.woff2 +0 -0
  251. streamlit/string_util.py +14 -19
  252. streamlit/temporary_directory.py +13 -4
  253. streamlit/testing/v1/app_test.py +15 -10
  254. streamlit/testing/v1/element_tree.py +157 -178
  255. streamlit/testing/v1/local_script_runner.py +11 -15
  256. streamlit/testing/v1/util.py +11 -4
  257. streamlit/type_util.py +8 -12
  258. streamlit/url_util.py +1 -1
  259. streamlit/user_info.py +6 -5
  260. streamlit/util.py +25 -1
  261. streamlit/vendor/pympler/asizeof.py +3 -2
  262. streamlit/watcher/event_based_path_watcher.py +15 -1
  263. streamlit/watcher/folder_black_list.py +2 -2
  264. streamlit/watcher/local_sources_watcher.py +64 -18
  265. streamlit/watcher/path_watcher.py +6 -10
  266. streamlit/watcher/polling_path_watcher.py +8 -7
  267. streamlit/watcher/util.py +7 -6
  268. streamlit/web/bootstrap.py +16 -14
  269. streamlit/web/cli.py +52 -45
  270. streamlit/web/server/__init__.py +7 -3
  271. streamlit/web/server/app_static_file_handler.py +1 -1
  272. streamlit/web/server/authlib_tornado_integration.py +9 -4
  273. streamlit/web/server/browser_websocket_handler.py +8 -2
  274. streamlit/web/server/component_request_handler.py +14 -10
  275. streamlit/web/server/media_file_handler.py +14 -7
  276. streamlit/web/server/oauth_authlib_routes.py +41 -9
  277. streamlit/web/server/oidc_mixin.py +35 -17
  278. streamlit/web/server/routes.py +32 -22
  279. streamlit/web/server/server.py +6 -18
  280. streamlit/web/server/server_util.py +19 -9
  281. streamlit/web/server/stats_request_handler.py +7 -5
  282. streamlit/web/server/upload_file_request_handler.py +22 -19
  283. streamlit/web/server/websocket_headers.py +1 -1
  284. {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/METADATA +4 -4
  285. streamlit-1.46.0.dist-info/RECORD +559 -0
  286. {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/WHEEL +1 -1
  287. streamlit/elements/lib/event_utils.py +0 -39
  288. streamlit/static/static/js/Toolbar.HTGsjfCP.js +0 -1
  289. streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
  290. streamlit/static/static/js/index.B5TWFN5r.js +0 -1
  291. streamlit/static/static/js/index.BI9-p_-s.js +0 -3
  292. streamlit/static/static/js/index.BYHnDZYn.js +0 -1
  293. streamlit/static/static/js/index.B_M97aPz.js +0 -1
  294. streamlit/static/static/js/index.BdN5swP0.js +0 -1
  295. streamlit/static/static/js/index.BfCAp_Sj.js +0 -1
  296. streamlit/static/static/js/index.BqDl3eRM.js +0 -779
  297. streamlit/static/static/js/index.C0VtYb3T.js +0 -2
  298. streamlit/static/static/js/index.C1qW_Owy.js +0 -1
  299. streamlit/static/static/js/index.C4AcBARa.js +0 -1
  300. streamlit/static/static/js/index.CCOiJRk1.js +0 -1
  301. streamlit/static/static/js/index.COvpza5W.js +0 -1
  302. streamlit/static/static/js/index.C_9qGjbK.js +0 -2
  303. streamlit/static/static/js/index.CqISBfsc.js +0 -197
  304. streamlit/static/static/js/index.D1WOs2Ce.js +0 -1
  305. streamlit/static/static/js/index.DQljs-9e.js +0 -1
  306. streamlit/static/static/js/index.DZqX4P_2.js +0 -1
  307. streamlit/static/static/js/index.DajIfBOb.js +0 -1
  308. streamlit/static/static/js/index.DuOXre0H.js +0 -1
  309. streamlit/static/static/js/index.EWD98YhP.js +0 -1
  310. streamlit/static/static/js/index.LaZloCTl.js +0 -73
  311. streamlit/static/static/js/index.S_1klBoy.js +0 -1
  312. streamlit/static/static/js/index.b0Gf958T.js +0 -12
  313. streamlit/static/static/js/index.t--hEgTQ.js +0 -6
  314. streamlit/static/static/js/useOnInputChange.CgOwAHyw.js +0 -1
  315. streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
  316. streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
  317. streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
  318. streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
  319. streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
  320. streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
  321. streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
  322. streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
  323. streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
  324. streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
  325. streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
  326. streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
  327. streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
  328. streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
  329. streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
  330. streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
  331. streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
  332. streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
  333. streamlit-1.45.0.dist-info/RECORD +0 -568
  334. {streamlit-1.45.0.data → streamlit-1.46.0.data}/scripts/streamlit.cmd +0 -0
  335. {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/entry_points.txt +0 -0
  336. {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/top_level.txt +0 -0
@@ -20,6 +20,11 @@ from textwrap import dedent
20
20
  from typing import TYPE_CHECKING, cast
21
21
 
22
22
  from streamlit.elements.lib.form_utils import current_form_id
23
+ from streamlit.elements.lib.layout_utils import (
24
+ LayoutConfig,
25
+ Width,
26
+ validate_width,
27
+ )
23
28
  from streamlit.elements.lib.policies import (
24
29
  check_widget_policies,
25
30
  maybe_raise_label_warnings,
@@ -53,7 +58,7 @@ class ColorPickerSerde:
53
58
  def serialize(self, v: str) -> str:
54
59
  return str(v)
55
60
 
56
- def deserialize(self, ui_value: str | None, widget_id: str = "") -> str:
61
+ def deserialize(self, ui_value: str | None) -> str:
57
62
  return str(ui_value if ui_value is not None else self.value)
58
63
 
59
64
 
@@ -71,6 +76,7 @@ class ColorPickerMixin:
71
76
  *, # keyword-only arguments:
72
77
  disabled: bool = False,
73
78
  label_visibility: LabelVisibility = "visible",
79
+ width: Width = "content",
74
80
  ) -> str:
75
81
  r"""Display a color picker widget.
76
82
 
@@ -133,9 +139,23 @@ class ColorPickerMixin:
133
139
  label_visibility : "visible", "hidden", or "collapsed"
134
140
  The visibility of the label. The default is ``"visible"``. If this
135
141
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
136
- label, which can help keep the widget alligned with other widgets.
142
+ label, which can help keep the widget aligned with other widgets.
137
143
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
138
144
 
145
+ width : "content", "stretch", or int
146
+ The width of the color picker widget. This can be one of the
147
+ following:
148
+
149
+ - ``"content"`` (default): The width of the widget matches the
150
+ width of its content, but doesn't exceed the width of the parent
151
+ container.
152
+ - ``"stretch"``: The width of the widget matches the width of the
153
+ parent container.
154
+ - An integer specifying the width in pixels: The widget has a
155
+ fixed width. If the specified width is greater than the width of
156
+ the parent container, the width of the widget matches the width
157
+ of the parent container.
158
+
139
159
  Returns
140
160
  -------
141
161
  str
@@ -164,6 +184,7 @@ class ColorPickerMixin:
164
184
  kwargs=kwargs,
165
185
  disabled=disabled,
166
186
  label_visibility=label_visibility,
187
+ width=width,
167
188
  ctx=ctx,
168
189
  )
169
190
 
@@ -179,6 +200,7 @@ class ColorPickerMixin:
179
200
  *, # keyword-only arguments:
180
201
  disabled: bool = False,
181
202
  label_visibility: LabelVisibility = "visible",
203
+ width: Width = "content",
182
204
  ctx: ScriptRunContext | None = None,
183
205
  ) -> str:
184
206
  key = to_key(key)
@@ -191,13 +213,18 @@ class ColorPickerMixin:
191
213
  )
192
214
  maybe_raise_label_warnings(label, label_visibility)
193
215
 
216
+ validate_width(width, allow_content=True)
217
+ layout_config = LayoutConfig(width=width)
218
+
194
219
  element_id = compute_and_register_element_id(
195
220
  "color_picker",
196
221
  user_key=key,
197
222
  form_id=current_form_id(self.dg),
223
+ dg=self.dg,
198
224
  label=label,
199
225
  value=str(value),
200
226
  help=help,
227
+ width=width,
201
228
  )
202
229
 
203
230
  # set value default
@@ -206,25 +233,19 @@ class ColorPickerMixin:
206
233
 
207
234
  # make sure the value is a string
208
235
  if not isinstance(value, str):
209
- raise StreamlitAPIException(
210
- """
211
- Color Picker Value has invalid type: %s. Expects a hex string
212
- like '#00FFAA' or '#000'.
213
- """
214
- % type(value).__name__
215
- )
236
+ raise StreamlitAPIException(f"""
237
+ Color Picker Value has invalid type: {type(value).__name__}. Expects a hex string
238
+ like '#00FFAA' or '#000'.
239
+ """)
216
240
 
217
241
  # validate the value and expects a hex string
218
242
  match = re.match(r"^#(?:[0-9a-fA-F]{3}){1,2}$", value)
219
243
 
220
244
  if not match:
221
- raise StreamlitAPIException(
222
- """
223
- '%s' is not a valid hex code for colors. Valid ones are like
224
- '#00FFAA' or '#000'.
225
- """
226
- % value
227
- )
245
+ raise StreamlitAPIException(f"""
246
+ '{value}' is not a valid hex code for colors. Valid ones are like
247
+ '#00FFAA' or '#000'.
248
+ """)
228
249
 
229
250
  color_picker_proto = ColorPickerProto()
230
251
  color_picker_proto.id = element_id
@@ -256,7 +277,9 @@ class ColorPickerMixin:
256
277
  color_picker_proto.value = widget_state.value
257
278
  color_picker_proto.set_value = True
258
279
 
259
- self.dg._enqueue("color_picker", color_picker_proto)
280
+ self.dg._enqueue(
281
+ "color_picker", color_picker_proto, layout_config=layout_config
282
+ )
260
283
  return widget_state.value
261
284
 
262
285
  @property
@@ -137,7 +137,7 @@ class EditingState(TypedDict, total=False):
137
137
  class DataEditorSerde:
138
138
  """DataEditorSerde is used to serialize and deserialize the data editor state."""
139
139
 
140
- def deserialize(self, ui_value: str | None, widget_id: str = "") -> EditingState:
140
+ def deserialize(self, ui_value: str | None) -> EditingState:
141
141
  data_editor_state: EditingState = (
142
142
  {
143
143
  "edited_rows": {},
@@ -270,8 +270,11 @@ def _apply_cell_edits(
270
270
  # The edited cell is part of the index
271
271
  # TODO(lukasmasuch): To support multi-index in the future:
272
272
  # use a tuple of values here instead of a single value
273
- df.index.to_numpy()[row_pos] = _parse_value(
274
- value, dataframe_schema[INDEX_IDENTIFIER]
273
+ old_idx_value = df.index[row_pos]
274
+ new_idx_value = _parse_value(value, dataframe_schema[INDEX_IDENTIFIER])
275
+ df.rename(
276
+ index={old_idx_value: new_idx_value},
277
+ inplace=True, # noqa: PD002
275
278
  )
276
279
  else:
277
280
  col_pos = df.columns.get_loc(col_name)
@@ -280,6 +283,26 @@ def _apply_cell_edits(
280
283
  )
281
284
 
282
285
 
286
+ def _parse_added_row(
287
+ df: pd.DataFrame,
288
+ added_row: dict[str, Any],
289
+ dataframe_schema: DataframeSchema,
290
+ ) -> tuple[Any, list[Any]]:
291
+ """Parse the added row into an optional index value and a list of row values."""
292
+ index_value = None
293
+ new_row: list[Any] = [None for _ in range(df.shape[1])]
294
+ for col_name, value in added_row.items():
295
+ if col_name == INDEX_IDENTIFIER:
296
+ # TODO(lukasmasuch): To support multi-index in the future:
297
+ # use a tuple of values here instead of a single value
298
+ index_value = _parse_value(value, dataframe_schema[INDEX_IDENTIFIER])
299
+ else:
300
+ col_pos = cast("int", df.columns.get_loc(col_name))
301
+ new_row[col_pos] = _parse_value(value, dataframe_schema[col_name])
302
+
303
+ return index_value, new_row
304
+
305
+
283
306
  def _apply_row_additions(
284
307
  df: pd.DataFrame,
285
308
  added_rows: list[dict[str, Any]],
@@ -305,39 +328,54 @@ def _apply_row_additions(
305
328
 
306
329
  import pandas as pd
307
330
 
308
- # This is only used if the dataframe has a range index:
309
- # There seems to be a bug in older pandas versions with RangeIndex in
310
- # combination with loc. As a workaround, we manually track the values here:
311
- range_index_stop = None
312
- range_index_step = None
331
+ index_type: Literal["range", "integer", "other"] = "other"
332
+ # This is only used if the dataframe has a range or integer index that can be
333
+ # auto incremented:
334
+ index_stop: int | None = None
335
+ index_step: int | None = None
336
+
313
337
  if isinstance(df.index, pd.RangeIndex):
314
- range_index_stop = df.index.stop
315
- range_index_step = df.index.step
338
+ # Extract metadata from the range index:
339
+ index_type = "range"
340
+ index_stop = cast("int", df.index.stop)
341
+ index_step = cast("int", df.index.step)
342
+ elif isinstance(df.index, pd.Index) and pd.api.types.is_integer_dtype(
343
+ df.index.dtype
344
+ ):
345
+ # Get highest integer value and increment it by 1 to get unique index value.
346
+ index_type = "integer"
347
+ index_stop = 0 if df.index.empty else df.index.max() + 1
348
+ index_step = 1
316
349
 
317
350
  for added_row in added_rows:
318
- index_value = None
319
- new_row: list[Any] = [None for _ in range(df.shape[1])]
320
- for col_name in added_row.keys():
321
- value = added_row[col_name]
322
- if col_name == INDEX_IDENTIFIER:
323
- # TODO(lukasmasuch): To support multi-index in the future:
324
- # use a tuple of values here instead of a single value
325
- index_value = _parse_value(value, dataframe_schema[INDEX_IDENTIFIER])
326
- else:
327
- col_pos = df.columns.get_loc(col_name)
328
- new_row[col_pos] = _parse_value(value, dataframe_schema[col_name])
329
- # Append the new row to the dataframe
330
- if range_index_stop is not None:
331
- df.loc[range_index_stop, :] = new_row
332
- # Increment to the next range index value
333
- range_index_stop += range_index_step
334
- elif index_value is not None:
335
- # TODO(lukasmasuch): we are only adding rows that have a non-None index
336
- # value to prevent issues in the frontend component. Also, it just overwrites
337
- # the row in case the index value already exists in the dataframe.
338
- # In the future, it would be better to require users to provide unique
339
- # non-None values for the index with some kind of visual indications.
351
+ index_value, new_row = _parse_added_row(df, added_row, dataframe_schema)
352
+
353
+ if index_value is not None and index_type != "range":
354
+ # Case 1: Non-range index with an explicitly provided index value
355
+ # Add row using the user-provided index value.
356
+ # This handles any type of index that cannot be auto incremented.
357
+
358
+ # Note: this just overwrites the row in case the index value
359
+ # already exists. In the future, it would be better to
360
+ # require users to provide unique non-None values for the index with
361
+ # some kind of visual indications.
340
362
  df.loc[index_value, :] = new_row
363
+ continue
364
+
365
+ if index_stop is not None and index_step is not None:
366
+ # Case 2: Range or integer index that can be auto incremented.
367
+ # Add row using the next value in the sequence
368
+ df.loc[index_stop, :] = new_row
369
+ # Increment to the next range index value
370
+ index_stop += index_step
371
+ continue
372
+
373
+ # Row cannot be added -> skip it and log a warning.
374
+ _LOGGER.warning(
375
+ "Cannot automatically add row for the index "
376
+ "of type %s without an explicit index value. Row addition skipped.",
377
+ type(df.index).__name__,
378
+ )
341
379
 
342
380
 
343
381
  def _apply_row_deletions(df: pd.DataFrame, deleted_rows: list[int]) -> None:
@@ -442,7 +480,7 @@ def _fix_column_headers(data_df: pd.DataFrame) -> None:
442
480
  )
443
481
 
444
482
 
445
- def _check_column_names(data_df: pd.DataFrame):
483
+ def _check_column_names(data_df: pd.DataFrame) -> None:
446
484
  """Check if the column names in the provided dataframe are valid.
447
485
 
448
486
  It's not allowed to have duplicate column names or column names that are
@@ -476,7 +514,7 @@ def _check_type_compatibilities(
476
514
  data_df: pd.DataFrame,
477
515
  columns_config: ColumnConfigMapping,
478
516
  dataframe_schema: DataframeSchema,
479
- ):
517
+ ) -> None:
480
518
  """Check column type to data type compatibility.
481
519
 
482
520
  Iterates the index and all columns of the dataframe to check if
@@ -631,7 +669,7 @@ class DataEditorMixin:
631
669
  Desired height of the data editor expressed in pixels. If ``height``
632
670
  is ``None`` (default), Streamlit sets the height to show at most
633
671
  ten rows. Vertical scrolling within the data editor element is
634
- enabled when the height does not accomodate all rows.
672
+ enabled when the height does not accommodate all rows.
635
673
 
636
674
  use_container_width : bool
637
675
  Whether to override ``width`` with the width of the parent
@@ -662,7 +700,7 @@ class DataEditorMixin:
662
700
  - A string to set the display label of the column.
663
701
 
664
702
  - One of the column types defined under ``st.column_config``, e.g.
665
- ``st.column_config.NumberColumn("Dollar values”, format=”$ %d")`` to show
703
+ ``st.column_config.NumberColumn("Dollar values", format="$ %d")`` to show
666
704
  a column as dollar amounts. See more info on the available column types
667
705
  and config options `here <https://docs.streamlit.io/develop/api-reference/data/st.column_config>`_.
668
706
 
@@ -898,6 +936,7 @@ class DataEditorMixin:
898
936
  "data_editor",
899
937
  user_key=key,
900
938
  form_id=current_form_id(self.dg),
939
+ dg=self.dg,
901
940
  data=arrow_bytes,
902
941
  width=width,
903
942
  height=height,
@@ -914,7 +953,7 @@ class DataEditorMixin:
914
953
  if use_container_width is None:
915
954
  # If use_container_width was not explicitly set by the user, we set
916
955
  # it to True if width was not set explicitly, and False otherwise.
917
- use_container_width = True if width is None else False
956
+ use_container_width = width is None
918
957
 
919
958
  proto.use_container_width = use_container_width
920
959
 
@@ -26,6 +26,11 @@ from streamlit.elements.lib.file_uploader_utils import (
26
26
  normalize_upload_file_type,
27
27
  )
28
28
  from streamlit.elements.lib.form_utils import current_form_id
29
+ from streamlit.elements.lib.layout_utils import (
30
+ LayoutConfig,
31
+ WidthWithoutContent,
32
+ validate_width,
33
+ )
29
34
  from streamlit.elements.lib.policies import (
30
35
  check_widget_policies,
31
36
  maybe_raise_label_warnings,
@@ -102,9 +107,7 @@ class FileUploaderSerde:
102
107
  accept_multiple_files: bool
103
108
  allowed_types: Sequence[str] | None = None
104
109
 
105
- def deserialize(
106
- self, ui_value: FileUploaderStateProto | None, widget_id: str
107
- ) -> SomeUploadedFiles:
110
+ def deserialize(self, ui_value: FileUploaderStateProto | None) -> SomeUploadedFiles:
108
111
  upload_files = _get_upload_files(ui_value)
109
112
 
110
113
  for file in upload_files:
@@ -127,7 +130,7 @@ class FileUploaderSerde:
127
130
 
128
131
  if not files:
129
132
  return state_proto
130
- elif not isinstance(files, list):
133
+ if not isinstance(files, list):
131
134
  files = [files]
132
135
 
133
136
  for f in files:
@@ -169,7 +172,8 @@ class FileUploaderMixin:
169
172
  *,
170
173
  disabled: bool = False,
171
174
  label_visibility: LabelVisibility = "visible",
172
- ) -> list[UploadedFile] | None: ...
175
+ width: WidthWithoutContent = "stretch",
176
+ ) -> list[UploadedFile]: ...
173
177
 
174
178
  # 1. type is given as not a keyword-only argument
175
179
  # 2. accept_multiple_files = False or omitted
@@ -187,6 +191,7 @@ class FileUploaderMixin:
187
191
  *,
188
192
  disabled: bool = False,
189
193
  label_visibility: LabelVisibility = "visible",
194
+ width: WidthWithoutContent = "stretch",
190
195
  ) -> UploadedFile | None: ...
191
196
 
192
197
  # The following 2 overloads represent the cases where
@@ -210,7 +215,8 @@ class FileUploaderMixin:
210
215
  kwargs: WidgetKwargs | None = None,
211
216
  disabled: bool = False,
212
217
  label_visibility: LabelVisibility = "visible",
213
- ) -> list[UploadedFile] | None: ...
218
+ width: WidthWithoutContent = "stretch",
219
+ ) -> list[UploadedFile]: ...
214
220
 
215
221
  # 1. type is skipped or a keyword argument
216
222
  # 2. accept_multiple_files = False or omitted
@@ -228,6 +234,7 @@ class FileUploaderMixin:
228
234
  kwargs: WidgetKwargs | None = None,
229
235
  disabled: bool = False,
230
236
  label_visibility: LabelVisibility = "visible",
237
+ width: WidthWithoutContent = "stretch",
231
238
  ) -> UploadedFile | None: ...
232
239
 
233
240
  @gather_metrics("file_uploader")
@@ -244,6 +251,7 @@ class FileUploaderMixin:
244
251
  *, # keyword-only arguments:
245
252
  disabled: bool = False,
246
253
  label_visibility: LabelVisibility = "visible",
254
+ width: WidthWithoutContent = "stretch",
247
255
  ) -> UploadedFile | list[UploadedFile] | None:
248
256
  r"""Display a file uploader widget.
249
257
  By default, uploaded files are limited to 200 MB each. You can
@@ -325,9 +333,20 @@ class FileUploaderMixin:
325
333
  label_visibility : "visible", "hidden", or "collapsed"
326
334
  The visibility of the label. The default is ``"visible"``. If this
327
335
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
328
- label, which can help keep the widget alligned with other widgets.
336
+ label, which can help keep the widget aligned with other widgets.
329
337
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
330
338
 
339
+ width : "stretch" or int
340
+ The width of the file uploader widget. This can be one of the
341
+ following:
342
+
343
+ - ``"stretch"`` (default): The width of the widget matches the
344
+ width of the parent container.
345
+ - An integer specifying the width in pixels: The widget has a
346
+ fixed width. If the specified width is greater than the width of
347
+ the parent container, the width of the widget matches the width
348
+ of the parent container.
349
+
331
350
  Returns
332
351
  -------
333
352
  None, UploadedFile, or list of UploadedFile
@@ -396,6 +415,7 @@ class FileUploaderMixin:
396
415
  kwargs=kwargs,
397
416
  disabled=disabled,
398
417
  label_visibility=label_visibility,
418
+ width=width,
399
419
  ctx=ctx,
400
420
  )
401
421
 
@@ -413,6 +433,7 @@ class FileUploaderMixin:
413
433
  label_visibility: LabelVisibility = "visible",
414
434
  disabled: bool = False,
415
435
  ctx: ScriptRunContext | None = None,
436
+ width: WidthWithoutContent = "stretch",
416
437
  ) -> UploadedFile | list[UploadedFile] | None:
417
438
  key = to_key(key)
418
439
 
@@ -429,19 +450,22 @@ class FileUploaderMixin:
429
450
  "file_uploader",
430
451
  user_key=key,
431
452
  form_id=current_form_id(self.dg),
453
+ dg=self.dg,
432
454
  label=label,
433
455
  type=type,
434
456
  accept_multiple_files=accept_multiple_files,
435
457
  help=help,
458
+ width=width,
436
459
  )
437
460
 
438
- if type:
439
- type = normalize_upload_file_type(type)
461
+ normalized_type = normalize_upload_file_type(type) if type else None
440
462
 
441
463
  file_uploader_proto = FileUploaderProto()
442
464
  file_uploader_proto.id = element_id
443
465
  file_uploader_proto.label = label
444
- file_uploader_proto.type[:] = type if type is not None else []
466
+ file_uploader_proto.type[:] = (
467
+ normalized_type if normalized_type is not None else []
468
+ )
445
469
  file_uploader_proto.max_upload_size_mb = config.get_option(
446
470
  "server.maxUploadSize"
447
471
  )
@@ -455,7 +479,7 @@ class FileUploaderMixin:
455
479
  if help is not None:
456
480
  file_uploader_proto.help = dedent(help)
457
481
 
458
- serde = FileUploaderSerde(accept_multiple_files, allowed_types=type)
482
+ serde = FileUploaderSerde(accept_multiple_files, allowed_types=normalized_type)
459
483
 
460
484
  # FileUploader's widget value is a list of file IDs
461
485
  # representing the current set of files that this uploader should
@@ -471,11 +495,16 @@ class FileUploaderMixin:
471
495
  value_type="file_uploader_state_value",
472
496
  )
473
497
 
474
- self.dg._enqueue("file_uploader", file_uploader_proto)
498
+ validate_width(width)
499
+ layout_config = LayoutConfig(width=width)
500
+
501
+ self.dg._enqueue(
502
+ "file_uploader", file_uploader_proto, layout_config=layout_config
503
+ )
475
504
 
476
505
  if isinstance(widget_state.value, DeletedFile):
477
506
  return None
478
- elif isinstance(widget_state.value, list):
507
+ if isinstance(widget_state.value, list):
479
508
  return [f for f in widget_state.value if not isinstance(f, DeletedFile)]
480
509
 
481
510
  return widget_state.value
@@ -75,7 +75,7 @@ class MultiSelectSerde(Generic[T]):
75
75
  formatted_options: list[str],
76
76
  formatted_option_to_option_index: dict[str, int],
77
77
  default_options_indices: list[int] | None = None,
78
- ):
78
+ ) -> None:
79
79
  """Initialize the MultiSelectSerde.
80
80
 
81
81
  We do not store an option_to_formatted_option mapping because the generic
@@ -110,17 +110,13 @@ class MultiSelectSerde(Generic[T]):
110
110
  try:
111
111
  option_index = self.options.index(v)
112
112
  values.append(self.formatted_options[option_index])
113
- except ValueError:
113
+ except ValueError: # noqa: PERF203
114
114
  # at this point we know that v is a string, otherwise
115
115
  # it would have been found in the options
116
116
  values.append(cast("str", v))
117
117
  return values
118
118
 
119
- def deserialize(
120
- self,
121
- ui_value: list[str] | None,
122
- widget_id: str = "",
123
- ) -> list[T | str] | list[T]:
119
+ def deserialize(self, ui_value: list[str] | None) -> list[T | str] | list[T]:
124
120
  if ui_value is None:
125
121
  return [self.options[i] for i in self.default_options_indices]
126
122
 
@@ -129,7 +125,7 @@ class MultiSelectSerde(Generic[T]):
129
125
  try:
130
126
  option_index = self.formatted_options.index(v)
131
127
  values.append(self.options[option_index])
132
- except ValueError:
128
+ except ValueError: # noqa: PERF203
133
129
  values.append(v)
134
130
  return values
135
131
 
@@ -144,7 +140,7 @@ def _get_default_count(default: Sequence[Any] | Any | None) -> int:
144
140
 
145
141
  def _check_max_selections(
146
142
  selections: Sequence[Any] | Any | None, max_selections: int | None
147
- ):
143
+ ) -> None:
148
144
  if max_selections is None:
149
145
  return
150
146
 
@@ -320,7 +316,7 @@ class MultiSelectMixin:
320
316
  label_visibility: "visible", "hidden", or "collapsed"
321
317
  The visibility of the label. The default is ``"visible"``. If this
322
318
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
323
- label, which can help keep the widget alligned with other widgets.
319
+ label, which can help keep the widget aligned with other widgets.
324
320
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
325
321
 
326
322
  accept_new_options: bool
@@ -453,6 +449,7 @@ class MultiSelectMixin:
453
449
  widget_name,
454
450
  user_key=key,
455
451
  form_id=form_id,
452
+ dg=self.dg,
456
453
  label=label,
457
454
  options=formatted_options,
458
455
  default=default_values,