streamlit 1.49.1__py3-none-any.whl → 1.51.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. streamlit/__init__.py +4 -1
  2. streamlit/column_config.py +2 -0
  3. streamlit/commands/navigation.py +7 -7
  4. streamlit/commands/page_config.py +4 -6
  5. streamlit/components/v1/custom_component.py +17 -42
  6. streamlit/components/v2/__init__.py +458 -0
  7. streamlit/components/v2/bidi_component/__init__.py +20 -0
  8. streamlit/components/v2/bidi_component/constants.py +29 -0
  9. streamlit/components/v2/bidi_component/main.py +386 -0
  10. streamlit/components/v2/bidi_component/serialization.py +265 -0
  11. streamlit/components/v2/bidi_component/state.py +92 -0
  12. streamlit/components/v2/component_definition_resolver.py +143 -0
  13. streamlit/components/v2/component_file_watcher.py +403 -0
  14. streamlit/components/v2/component_manager.py +431 -0
  15. streamlit/components/v2/component_manifest_handler.py +122 -0
  16. streamlit/components/v2/component_path_utils.py +245 -0
  17. streamlit/components/v2/component_registry.py +409 -0
  18. streamlit/components/v2/get_bidi_component_manager.py +51 -0
  19. streamlit/components/v2/manifest_scanner.py +615 -0
  20. streamlit/components/v2/presentation.py +198 -0
  21. streamlit/components/v2/types.py +324 -0
  22. streamlit/config.py +741 -32
  23. streamlit/config_option.py +4 -1
  24. streamlit/config_util.py +650 -1
  25. streamlit/connections/base_connection.py +4 -2
  26. streamlit/dataframe_util.py +18 -10
  27. streamlit/delta_generator.py +8 -7
  28. streamlit/delta_generator_singletons.py +3 -1
  29. streamlit/deprecation_util.py +17 -6
  30. streamlit/elements/arrow.py +90 -42
  31. streamlit/elements/deck_gl_json_chart.py +98 -39
  32. streamlit/elements/dialog_decorator.py +2 -1
  33. streamlit/elements/exception.py +3 -1
  34. streamlit/elements/form.py +6 -6
  35. streamlit/elements/graphviz_chart.py +24 -9
  36. streamlit/elements/heading.py +3 -5
  37. streamlit/elements/iframe.py +0 -2
  38. streamlit/elements/image.py +12 -13
  39. streamlit/elements/layouts.py +89 -22
  40. streamlit/elements/lib/built_in_chart_utils.py +95 -31
  41. streamlit/elements/lib/color_util.py +8 -18
  42. streamlit/elements/lib/column_config_utils.py +9 -8
  43. streamlit/elements/lib/column_types.py +595 -148
  44. streamlit/elements/lib/dialog.py +3 -2
  45. streamlit/elements/lib/image_utils.py +3 -5
  46. streamlit/elements/lib/layout_utils.py +50 -13
  47. streamlit/elements/lib/mutable_status_container.py +2 -2
  48. streamlit/elements/lib/options_selector_utils.py +2 -2
  49. streamlit/elements/lib/pandas_styler_utils.py +30 -14
  50. streamlit/elements/lib/utils.py +21 -9
  51. streamlit/elements/map.py +81 -40
  52. streamlit/elements/media.py +7 -7
  53. streamlit/elements/metric.py +11 -35
  54. streamlit/elements/pdf.py +2 -4
  55. streamlit/elements/plotly_chart.py +142 -26
  56. streamlit/elements/progress.py +2 -4
  57. streamlit/elements/pyplot.py +6 -6
  58. streamlit/elements/space.py +113 -0
  59. streamlit/elements/vega_charts.py +400 -143
  60. streamlit/elements/widgets/audio_input.py +52 -4
  61. streamlit/elements/widgets/button.py +29 -29
  62. streamlit/elements/widgets/button_group.py +33 -6
  63. streamlit/elements/widgets/camera_input.py +3 -4
  64. streamlit/elements/widgets/chat.py +7 -0
  65. streamlit/elements/widgets/checkbox.py +1 -0
  66. streamlit/elements/widgets/color_picker.py +1 -0
  67. streamlit/elements/widgets/data_editor.py +34 -29
  68. streamlit/elements/widgets/file_uploader.py +6 -10
  69. streamlit/elements/widgets/multiselect.py +14 -3
  70. streamlit/elements/widgets/number_input.py +5 -4
  71. streamlit/elements/widgets/radio.py +10 -2
  72. streamlit/elements/widgets/select_slider.py +8 -4
  73. streamlit/elements/widgets/selectbox.py +9 -2
  74. streamlit/elements/widgets/slider.py +38 -41
  75. streamlit/elements/widgets/text_widgets.py +6 -0
  76. streamlit/elements/widgets/time_widgets.py +15 -12
  77. streamlit/elements/write.py +28 -23
  78. streamlit/emojis.py +1 -1
  79. streamlit/errors.py +115 -0
  80. streamlit/git_util.py +65 -43
  81. streamlit/hello/hello.py +8 -0
  82. streamlit/hello/utils.py +2 -1
  83. streamlit/material_icon_names.py +1 -1
  84. streamlit/navigation/page.py +4 -1
  85. streamlit/proto/ArrowData_pb2.py +27 -0
  86. streamlit/proto/ArrowData_pb2.pyi +46 -0
  87. streamlit/proto/Arrow_pb2.py +10 -8
  88. streamlit/proto/Arrow_pb2.pyi +31 -2
  89. streamlit/proto/AudioInput_pb2.py +2 -2
  90. streamlit/proto/AudioInput_pb2.pyi +6 -2
  91. streamlit/proto/BidiComponent_pb2.py +34 -0
  92. streamlit/proto/BidiComponent_pb2.pyi +153 -0
  93. streamlit/proto/Block_pb2.py +11 -11
  94. streamlit/proto/Block_pb2.pyi +9 -1
  95. streamlit/proto/DeckGlJsonChart_pb2.py +10 -4
  96. streamlit/proto/DeckGlJsonChart_pb2.pyi +9 -3
  97. streamlit/proto/Element_pb2.py +5 -3
  98. streamlit/proto/Element_pb2.pyi +14 -4
  99. streamlit/proto/HeightConfig_pb2.py +2 -2
  100. streamlit/proto/HeightConfig_pb2.pyi +6 -3
  101. streamlit/proto/NewSession_pb2.py +18 -16
  102. streamlit/proto/NewSession_pb2.pyi +158 -6
  103. streamlit/proto/PlotlyChart_pb2.py +8 -6
  104. streamlit/proto/PlotlyChart_pb2.pyi +3 -1
  105. streamlit/proto/Space_pb2.py +27 -0
  106. streamlit/proto/Space_pb2.pyi +42 -0
  107. streamlit/proto/WidgetStates_pb2.py +2 -2
  108. streamlit/proto/WidgetStates_pb2.pyi +13 -3
  109. streamlit/proto/WidthConfig_pb2.py +2 -2
  110. streamlit/proto/WidthConfig_pb2.pyi +6 -3
  111. streamlit/runtime/app_session.py +45 -6
  112. streamlit/runtime/caching/cache_data_api.py +4 -4
  113. streamlit/runtime/caching/cache_errors.py +4 -1
  114. streamlit/runtime/caching/cache_resource_api.py +3 -2
  115. streamlit/runtime/caching/cache_utils.py +2 -1
  116. streamlit/runtime/caching/cached_message_replay.py +3 -3
  117. streamlit/runtime/caching/hashing.py +3 -4
  118. streamlit/runtime/caching/legacy_cache_api.py +2 -1
  119. streamlit/runtime/connection_factory.py +1 -3
  120. streamlit/runtime/forward_msg_queue.py +4 -1
  121. streamlit/runtime/fragment.py +2 -1
  122. streamlit/runtime/memory_media_file_storage.py +1 -1
  123. streamlit/runtime/metrics_util.py +6 -2
  124. streamlit/runtime/runtime.py +14 -0
  125. streamlit/runtime/scriptrunner/exec_code.py +2 -1
  126. streamlit/runtime/scriptrunner/script_runner.py +2 -2
  127. streamlit/runtime/scriptrunner_utils/script_run_context.py +3 -6
  128. streamlit/runtime/secrets.py +2 -4
  129. streamlit/runtime/session_manager.py +3 -1
  130. streamlit/runtime/state/common.py +30 -5
  131. streamlit/runtime/state/presentation.py +85 -0
  132. streamlit/runtime/state/safe_session_state.py +2 -2
  133. streamlit/runtime/state/session_state.py +220 -16
  134. streamlit/runtime/state/widgets.py +19 -3
  135. streamlit/runtime/theme_util.py +148 -0
  136. streamlit/runtime/websocket_session_manager.py +3 -1
  137. streamlit/source_util.py +2 -2
  138. streamlit/static/index.html +2 -2
  139. streamlit/static/manifest.json +244 -227
  140. streamlit/static/static/css/{index.C8X8rNzw.css → index.BpABIXK9.css} +1 -1
  141. streamlit/static/static/css/index.DgR7E2CV.css +1 -0
  142. streamlit/static/static/js/{ErrorOutline.esm.DcGrhbBP.js → ErrorOutline.esm.YoJdlW1p.js} +1 -1
  143. streamlit/static/static/js/{FileDownload.esm.DgBvV6Pq.js → FileDownload.esm.Ddx8VEYy.js} +1 -1
  144. streamlit/static/static/js/{FileHelper.M6AAaeuA.js → FileHelper.90EtOmj9.js} +1 -1
  145. streamlit/static/static/js/{FormClearHelper.DHh1GFzm.js → FormClearHelper.BB1Km6eP.js} +1 -1
  146. streamlit/static/static/js/InputInstructions.jhH15PqV.js +1 -0
  147. streamlit/static/static/js/{Particles.DDVT-6Qc.js → Particles.DUsputn1.js} +1 -1
  148. streamlit/static/static/js/{ProgressBar.BEY0cXXV.js → ProgressBar.DLY8H6nE.js} +2 -2
  149. streamlit/static/static/js/Toolbar.D8nHCkuz.js +1 -0
  150. streamlit/static/static/js/{base-input.CK3UVGp1.js → base-input.CJGiNqed.js} +3 -3
  151. streamlit/static/static/js/{checkbox.D8W881TL.js → checkbox.Cpdd482O.js} +1 -1
  152. streamlit/static/static/js/{createSuper.B6W-Dh9S.js → createSuper.CuQIogbW.js} +1 -1
  153. streamlit/static/static/js/data-grid-overlay-editor.2Ufgxc6y.js +1 -0
  154. streamlit/static/static/js/{downloader.DiKpuU_S.js → downloader.CN0K7xlu.js} +1 -1
  155. streamlit/static/static/js/{es6.B8zRNPZ-.js → es6.BJcsVXQ0.js} +2 -2
  156. streamlit/static/static/js/{iframeResizer.contentWindow.DIewJmmh.js → iframeResizer.contentWindow.XzUvQqcZ.js} +1 -1
  157. streamlit/static/static/js/index.B1ZQh4P1.js +1 -0
  158. streamlit/static/static/js/index.BKstZk0M.js +27 -0
  159. streamlit/static/static/js/{index.Bte_9Lyq.js → index.BMcFsUee.js} +1 -1
  160. streamlit/static/static/js/{index.qhs54UAB.js → index.BR-IdcTb.js} +1 -1
  161. streamlit/static/static/js/{index.CejBxbg1.js → index.B_dWA3vd.js} +1 -1
  162. streamlit/static/static/js/{index.D5naqx-J.js → index.BgnZEMVh.js} +1 -1
  163. streamlit/static/static/js/{index.C7fRKRs4.js → index.BohqXifI.js} +1 -1
  164. streamlit/static/static/js/{index.cnnXF7xQ.js → index.Br5nxKNj.js} +1 -1
  165. streamlit/static/static/js/index.BrIKVbNc.js +3 -0
  166. streamlit/static/static/js/index.BtWUPzle.js +1 -0
  167. streamlit/static/static/js/index.C0RLraek.js +1 -0
  168. streamlit/static/static/js/{index.CP5TD2z1.js → index.CAIjskgG.js} +1 -1
  169. streamlit/static/static/js/{index.CD8HuT3N.js → index.CAj-7vWz.js} +135 -162
  170. streamlit/static/static/js/{index.DtYN2x4k.js → index.CMtEit2O.js} +1 -1
  171. streamlit/static/static/js/index.CkRlykEE.js +12 -0
  172. streamlit/static/static/js/{index.Ts_0SdB9.js → index.CmN3FXfI.js} +2 -2
  173. streamlit/static/static/js/{index.BnEpvLEz.js → index.CwbFI1_-.js} +1 -1
  174. streamlit/static/static/js/{index.CcJf6BCU.js → index.CxIUUfab.js} +27 -27
  175. streamlit/static/static/js/index.D2KPNy7e.js +1 -0
  176. streamlit/static/static/js/{index.Ch7MBCx0.js → index.D3GPA5k4.js} +47 -47
  177. streamlit/static/static/js/{index.ho6NIXGl.js → index.DGAh7DMq.js} +1 -1
  178. streamlit/static/static/js/index.DKb_NvmG.js +197 -0
  179. streamlit/static/static/js/{index.CvYYtxD_.js → index.DMqgUYKq.js} +1 -1
  180. streamlit/static/static/js/{index.zecpGxtj.js → index.DOFlg3dS.js} +1 -1
  181. streamlit/static/static/js/{index.B9mjBcgE.js → index.DPUXkcQL.js} +1 -1
  182. streamlit/static/static/js/index.DX1xY89g.js +1 -0
  183. streamlit/static/static/js/index.DYATBCsq.js +2 -0
  184. streamlit/static/static/js/{index.D2-atlaQ.js → index.DaSmGJ76.js} +3 -3
  185. streamlit/static/static/js/index.Dd7bMeLP.js +1 -0
  186. streamlit/static/static/js/{index.4eF4NxG2.js → index.DjmmgI5U.js} +1 -1
  187. streamlit/static/static/js/index.Dq56CyM2.js +1 -0
  188. streamlit/static/static/js/index.DuiXaS5_.js +7 -0
  189. streamlit/static/static/js/index.DvFidMLe.js +2 -0
  190. streamlit/static/static/js/{index.452cqrrL.js → index.DwkhC5Pc.js} +1 -1
  191. streamlit/static/static/js/{index.Dk4C7X3i.js → index.Q-3sFn1v.js} +1 -1
  192. streamlit/static/static/js/{index.CjXWwH-y.js → index.QJ5QO9sJ.js} +1 -1
  193. streamlit/static/static/js/{index.B6U8LQo3.js → index.VwTaeety.js} +1 -1
  194. streamlit/static/static/js/index.YOqQbeX8.js +1 -0
  195. streamlit/static/static/js/{input.nzVJphXi.js → input.D4MN_FzN.js} +1 -1
  196. streamlit/static/static/js/{memory.CjCgTQz3.js → memory.DrZjtdGT.js} +1 -1
  197. streamlit/static/static/js/{number-overlay-editor.DaRFzZEO.js → number-overlay-editor.DRwAw1In.js} +1 -1
  198. streamlit/static/static/js/{possibleConstructorReturn.DgiPnZ9N.js → possibleConstructorReturn.exeeJQEP.js} +1 -1
  199. streamlit/static/static/js/record.B-tDciZb.js +1 -0
  200. streamlit/static/static/js/{sandbox.mithfq7Z.js → sandbox.ClO3IuUr.js} +1 -1
  201. streamlit/static/static/js/{timepicker.Dbl5KFh6.js → timepicker.DAhu-vcF.js} +4 -4
  202. streamlit/static/static/js/{toConsumableArray.D-Dx88BQ.js → toConsumableArray.DNbljYEC.js} +1 -1
  203. streamlit/static/static/js/{uniqueId.Bh26R_3S.js → uniqueId.oG4Gvj1v.js} +1 -1
  204. streamlit/static/static/js/{useBasicWidgetState.DeK-QJpD.js → useBasicWidgetState.D6sOH6oI.js} +1 -1
  205. streamlit/static/static/js/{useTextInputAutoExpand.4iAdLWD-.js → useTextInputAutoExpand.4u3_GcuN.js} +2 -2
  206. streamlit/static/static/js/{useUpdateUiValue.CmT7_nJN.js → useUpdateUiValue.F2R3eTeR.js} +1 -1
  207. streamlit/static/static/js/wavesurfer.esm.vI8Eid4k.js +73 -0
  208. streamlit/static/static/js/withFullScreenWrapper.zothJIsI.js +1 -0
  209. streamlit/static/static/media/MaterialSymbols-Rounded.C7IFxh57.woff2 +0 -0
  210. streamlit/string_util.py +56 -1
  211. streamlit/testing/v1/app_test.py +2 -2
  212. streamlit/testing/v1/element_tree.py +23 -9
  213. streamlit/testing/v1/util.py +2 -2
  214. streamlit/type_util.py +3 -4
  215. streamlit/url_util.py +1 -3
  216. streamlit/user_info.py +1 -2
  217. streamlit/util.py +3 -1
  218. streamlit/watcher/event_based_path_watcher.py +23 -12
  219. streamlit/watcher/local_sources_watcher.py +11 -1
  220. streamlit/watcher/path_watcher.py +9 -6
  221. streamlit/watcher/polling_path_watcher.py +4 -1
  222. streamlit/watcher/util.py +2 -2
  223. streamlit/web/bootstrap.py +0 -31
  224. streamlit/web/cli.py +51 -22
  225. streamlit/web/server/bidi_component_request_handler.py +193 -0
  226. streamlit/web/server/component_file_utils.py +97 -0
  227. streamlit/web/server/component_request_handler.py +8 -21
  228. streamlit/web/server/oidc_mixin.py +3 -1
  229. streamlit/web/server/routes.py +18 -5
  230. streamlit/web/server/server.py +10 -0
  231. streamlit/web/server/server_util.py +3 -1
  232. streamlit/web/server/upload_file_request_handler.py +3 -1
  233. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/METADATA +4 -5
  234. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/RECORD +238 -209
  235. streamlit/static/static/css/index.COe1010n.css +0 -1
  236. streamlit/static/static/js/Hooks.DGu1od_L.js +0 -1
  237. streamlit/static/static/js/InputInstructions.z6sVgyYt.js +0 -1
  238. streamlit/static/static/js/Toolbar.DSnK1fUh.js +0 -1
  239. streamlit/static/static/js/data-grid-overlay-editor.DRTHOydk.js +0 -1
  240. streamlit/static/static/js/index.BXYmrqnf.js +0 -1
  241. streamlit/static/static/js/index.B_8AnktO.js +0 -1
  242. streamlit/static/static/js/index.Bl7zGQSh.js +0 -7
  243. streamlit/static/static/js/index.BnJIOYn9.js +0 -73
  244. streamlit/static/static/js/index.C1HcTl5K.js +0 -1
  245. streamlit/static/static/js/index.C7lSmSOP.js +0 -1
  246. streamlit/static/static/js/index.C_tmcx4B.js +0 -1
  247. streamlit/static/static/js/index.D3K5nOu9.js +0 -197
  248. streamlit/static/static/js/index.DkKT3LUI.js +0 -1
  249. streamlit/static/static/js/index.MTPPBDHk.js +0 -2
  250. streamlit/static/static/js/index.pqW9AMJD.js +0 -3
  251. streamlit/static/static/js/index.urHgTgMQ.js +0 -12
  252. streamlit/static/static/js/index.wzkv_11M.js +0 -1
  253. streamlit/static/static/js/index.yF5AncHY.js +0 -1
  254. streamlit/static/static/js/withFullScreenWrapper.DLp1ENGm.js +0 -1
  255. streamlit/static/static/media/MaterialSymbols-Rounded.CBxVaFdk.woff2 +0 -0
  256. {streamlit-1.49.1.data → streamlit-1.51.0.data}/scripts/streamlit.cmd +0 -0
  257. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/WHEEL +0 -0
  258. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/entry_points.txt +0 -0
  259. {streamlit-1.49.1.dist-info → streamlit-1.51.0.dist-info}/top_level.txt +0 -0
@@ -30,14 +30,14 @@ from typing import (
30
30
  Any,
31
31
  Final,
32
32
  Protocol,
33
+ TypeAlias,
34
+ TypeGuard,
33
35
  TypeVar,
34
36
  Union,
35
37
  cast,
36
38
  runtime_checkable,
37
39
  )
38
40
 
39
- from typing_extensions import TypeAlias, TypeGuard
40
-
41
41
  from streamlit import config, errors, logger, string_util
42
42
  from streamlit.type_util import (
43
43
  CustomDict,
@@ -74,7 +74,8 @@ _DASK_INDEX: Final = "dask.dataframe.dask_expr._collection.Index"
74
74
  _DASK_DATAFRAME_LEGACY: Final = "dask.dataframe.core.DataFrame"
75
75
  _DASK_SERIES_LEGACY: Final = "dask.dataframe.core.Series"
76
76
  _DASK_INDEX_LEGACY: Final = "dask.dataframe.core.Index"
77
- _DUCKDB_RELATION: Final = "duckdb.duckdb.DuckDBPyRelation"
77
+ _DUCKDB_RELATION: Final = "_duckdb.DuckDBPyRelation"
78
+ _DUCKDB_RELATION_LEGACY: Final = "duckdb.duckdb.DuckDBPyRelation"
78
79
  _MODIN_DF_TYPE_STR: Final = "modin.pandas.dataframe.DataFrame"
79
80
  _MODIN_SERIES_TYPE_STR: Final = "modin.pandas.series.Series"
80
81
  _PANDAS_STYLER_TYPE_STR: Final = "pandas.io.formats.style.Styler"
@@ -164,12 +165,12 @@ class DataframeInterchangeCompatible(Protocol):
164
165
  def __dataframe__(self, allow_copy: bool) -> Any: ...
165
166
 
166
167
 
167
- OptionSequence: TypeAlias = Union[
168
- Iterable[V_co],
169
- DataFrameGenericAlias[V_co],
170
- PandasCompatible,
171
- DataframeInterchangeCompatible,
172
- ]
168
+ OptionSequence: TypeAlias = (
169
+ Iterable[V_co]
170
+ | DataFrameGenericAlias[V_co]
171
+ | PandasCompatible
172
+ | DataframeInterchangeCompatible
173
+ )
173
174
 
174
175
  # Various data types supported by our dataframe processing
175
176
  # used for commands like `st.dataframe`, `st.table`, `st.map`,
@@ -452,7 +453,7 @@ def is_duckdb_relation(obj: object) -> bool:
452
453
  https://duckdb.org/docs/api/python/relational_api
453
454
  """
454
455
 
455
- return is_type(obj, _DUCKDB_RELATION)
456
+ return is_type(obj, _DUCKDB_RELATION) or is_type(obj, _DUCKDB_RELATION_LEGACY)
456
457
 
457
458
 
458
459
  def _is_list_of_scalars(data: Iterable[Any]) -> bool:
@@ -527,6 +528,13 @@ def _dict_to_pandas_df(data: dict[Any, Any]) -> DataFrame:
527
528
  return _fix_column_naming(pd.DataFrame.from_dict(data, orient="index"))
528
529
 
529
530
 
531
+ def has_range_index(df: DataFrame) -> bool:
532
+ """True if the dataframe has a range index."""
533
+ from pandas import RangeIndex
534
+
535
+ return isinstance(df.index, RangeIndex)
536
+
537
+
530
538
  def convert_anything_to_pandas_df(
531
539
  data: Any,
532
540
  max_unevaluated_rows: int = _MAX_UNEVALUATED_DF_ROWS,
@@ -17,21 +17,19 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import sys
20
- from collections.abc import Iterable
20
+ from collections.abc import Callable, Iterable
21
21
  from copy import deepcopy
22
22
  from typing import (
23
23
  TYPE_CHECKING,
24
24
  Any,
25
- Callable,
26
25
  Final,
27
26
  Literal,
28
27
  NoReturn,
28
+ TypeAlias,
29
29
  TypeVar,
30
30
  cast,
31
31
  )
32
32
 
33
- from typing_extensions import TypeAlias
34
-
35
33
  from streamlit import (
36
34
  cli_util,
37
35
  config,
@@ -41,6 +39,7 @@ from streamlit import (
41
39
  runtime,
42
40
  util,
43
41
  )
42
+ from streamlit.components.v2.bidi_component import BidiComponentMixin
44
43
  from streamlit.delta_generator_singletons import (
45
44
  context_dg_stack,
46
45
  get_last_dg_added_to_context_stack,
@@ -76,6 +75,7 @@ from streamlit.elements.plotly_chart import PlotlyMixin
76
75
  from streamlit.elements.progress import ProgressMixin
77
76
  from streamlit.elements.pyplot import PyplotMixin
78
77
  from streamlit.elements.snow import SnowMixin
78
+ from streamlit.elements.space import SpaceMixin
79
79
  from streamlit.elements.text import TextMixin
80
80
  from streamlit.elements.toast import ToastMixin
81
81
  from streamlit.elements.vega_charts import VegaChartsMixin
@@ -207,6 +207,7 @@ class DeltaGenerator(
207
207
  SelectSliderMixin,
208
208
  SliderMixin,
209
209
  SnowMixin,
210
+ SpaceMixin,
210
211
  JsonMixin,
211
212
  TextMixin,
212
213
  TextWidgetsMixin,
@@ -216,6 +217,7 @@ class DeltaGenerator(
216
217
  ArrowMixin,
217
218
  VegaChartsMixin,
218
219
  DataEditorMixin,
220
+ BidiComponentMixin,
219
221
  ):
220
222
  """Creator of Delta protobuf messages.
221
223
 
@@ -485,12 +487,11 @@ class DeltaGenerator(
485
487
  msg_el_proto.CopyFrom(element_proto)
486
488
 
487
489
  if layout_config:
488
- if layout_config.height:
490
+ if layout_config.height is not None:
489
491
  msg.delta.new_element.height_config.CopyFrom(
490
492
  get_height_config(layout_config.height)
491
493
  )
492
-
493
- if layout_config.width:
494
+ if layout_config.width is not None:
494
495
  msg.delta.new_element.width_config.CopyFrom(
495
496
  get_width_config(layout_config.width)
496
497
  )
@@ -20,11 +20,13 @@ cycle between streamlit.delta_generator and some elements.
20
20
  from __future__ import annotations
21
21
 
22
22
  from contextvars import ContextVar, Token
23
- from typing import TYPE_CHECKING, Callable, Generic, TypeVar
23
+ from typing import TYPE_CHECKING, Generic, TypeVar
24
24
 
25
25
  from streamlit.proto.RootContainer_pb2 import RootContainer as _RootContainer
26
26
 
27
27
  if TYPE_CHECKING:
28
+ from collections.abc import Callable
29
+
28
30
  from streamlit.delta_generator import DeltaGenerator
29
31
  from streamlit.elements.lib.dialog import Dialog
30
32
  from streamlit.elements.lib.mutable_status_container import StatusContainer
@@ -15,7 +15,8 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import functools
18
- from typing import Any, Callable, Final, TypeVar, cast
18
+ from collections.abc import Callable
19
+ from typing import Any, Final, TypeVar, cast
19
20
 
20
21
  import streamlit
21
22
  from streamlit import config
@@ -28,8 +29,17 @@ TObj = TypeVar("TObj", bound=object)
28
29
 
29
30
 
30
31
  def _error_details_in_browser_enabled() -> bool:
31
- """True if we should print deprecation warnings to the browser."""
32
- return bool(config.get_option("client.showErrorDetails"))
32
+ """True if we should print deprecation warnings to the browser.
33
+
34
+ Deprecation warnings are only shown when showErrorDetails is set to "full"
35
+ or the legacy True value. All other values ("stacktrace", "type", "none",
36
+ False) hide deprecation warnings in the browser.
37
+ """
38
+ show_error_details = config.get_option("client.showErrorDetails")
39
+ return (
40
+ show_error_details == config.ShowErrorDetailsConfigOptions.FULL
41
+ or config.ShowErrorDetailsConfigOptions.is_true_variation(show_error_details)
42
+ )
33
43
 
34
44
 
35
45
  def show_deprecation_warning(message: str, show_in_browser: bool = True) -> None:
@@ -41,9 +51,10 @@ def show_deprecation_warning(message: str, show_in_browser: bool = True) -> None
41
51
  The deprecation warning message.
42
52
  show_in_browser : bool, default=True
43
53
  Whether to show the deprecation warning in the browser. When this is True,
44
- we will show the deprecation warning in the browser unless the user has
45
- disabled error details in the browser by setting the `client.showErrorDetails`
46
- config option to "none".
54
+ we will show the deprecation warning in the browser only if the user has
55
+ set `client.showErrorDetails` to "full" or the legacy True value. All
56
+ other values ("stacktrace", "type", "none", False) will hide deprecation
57
+ warnings in the browser (but still log them to the console).
47
58
  """
48
59
  if _error_details_in_browser_enabled() and show_in_browser:
49
60
  streamlit.warning(message)
@@ -21,13 +21,12 @@ 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 dataframe_util
32
31
  from streamlit.deprecation_util import (
33
32
  make_deprecated_name_warning,
@@ -43,6 +42,7 @@ from streamlit.elements.lib.column_config_utils import (
43
42
  )
44
43
  from streamlit.elements.lib.form_utils import current_form_id
45
44
  from streamlit.elements.lib.layout_utils import (
45
+ HeightWithoutContent,
46
46
  LayoutConfig,
47
47
  Width,
48
48
  validate_height,
@@ -51,7 +51,7 @@ from streamlit.elements.lib.layout_utils import (
51
51
  from streamlit.elements.lib.pandas_styler_utils import marshall_styler
52
52
  from streamlit.elements.lib.policies import check_widget_policies
53
53
  from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
54
- from streamlit.errors import StreamlitAPIException
54
+ from streamlit.errors import StreamlitAPIException, StreamlitValueError
55
55
  from streamlit.proto.Arrow_pb2 import Arrow as ArrowProto
56
56
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
57
57
  from streamlit.runtime.metrics_util import gather_metrics
@@ -270,13 +270,24 @@ def parse_selection_mode(
270
270
  return set(parsed_selection_modes)
271
271
 
272
272
 
273
+ def parse_border_mode(
274
+ border: bool | Literal["horizontal"],
275
+ ) -> ArrowProto.BorderMode.ValueType:
276
+ """Parse and check the user provided border mode."""
277
+ if isinstance(border, bool):
278
+ return ArrowProto.BorderMode.ALL if border else ArrowProto.BorderMode.NONE
279
+ if border == "horizontal":
280
+ return ArrowProto.BorderMode.HORIZONTAL
281
+ raise StreamlitValueError("border", ["True", "False", "'horizontal'"])
282
+
283
+
273
284
  class ArrowMixin:
274
285
  @overload
275
286
  def dataframe(
276
287
  self,
277
288
  data: Data = None,
278
289
  width: Width = "stretch",
279
- height: int | Literal["auto"] = "auto",
290
+ height: HeightWithoutContent | Literal["auto"] = "auto",
280
291
  *,
281
292
  use_container_width: bool | None = None,
282
293
  hide_index: bool | None = None,
@@ -293,7 +304,7 @@ class ArrowMixin:
293
304
  self,
294
305
  data: Data = None,
295
306
  width: Width = "stretch",
296
- height: int | Literal["auto"] = "auto",
307
+ height: HeightWithoutContent | Literal["auto"] = "auto",
297
308
  *,
298
309
  use_container_width: bool | None = None,
299
310
  hide_index: bool | None = None,
@@ -310,7 +321,7 @@ class ArrowMixin:
310
321
  self,
311
322
  data: Data = None,
312
323
  width: Width = "stretch",
313
- height: int | Literal["auto"] = "auto",
324
+ height: HeightWithoutContent | Literal["auto"] = "auto",
314
325
  *,
315
326
  use_container_width: bool | None = None,
316
327
  hide_index: bool | None = None,
@@ -378,11 +389,18 @@ class ArrowMixin:
378
389
  the parent container, the width of the element matches the width
379
390
  of the parent container.
380
391
 
381
- height : int or "auto"
392
+ height : "auto", "stretch", or int
382
393
  The height of the dataframe element. This can be one of the following:
383
394
 
384
395
  - ``"auto"`` (default): Streamlit sets the height to show at most
385
396
  ten rows.
397
+ - ``"stretch"``: The height of the element expands to fill the
398
+ available vertical space in its parent container. When multiple
399
+ elements with stretch height are in the same container, they
400
+ share the available vertical space evenly. The dataframe will
401
+ maintain a minimum height to display up to three rows, but
402
+ otherwise won't exceed the available height in its parent
403
+ container.
386
404
  - An integer specifying the height in pixels: The element has a
387
405
  fixed height.
388
406
 
@@ -396,10 +414,15 @@ class ArrowMixin:
396
414
  this is ``False``, Streamlit sets the dataframe's width according
397
415
  to ``width``.
398
416
 
417
+ .. deprecated::
418
+ ``use_container_width`` is deprecated and will be removed in a
419
+ future release. For ``use_container_width=True``, use
420
+ ``width="stretch"``.
421
+
399
422
  hide_index : bool or None
400
423
  Whether to hide the index column(s). If ``hide_index`` is ``None``
401
424
  (default), the visibility of index columns is automatically
402
- determined based on the data.
425
+ determined based on the data and other configurations.
403
426
 
404
427
  column_order : Iterable[str] or None
405
428
  The ordered list of columns to display. If this is ``None``
@@ -487,11 +510,6 @@ class ArrowMixin:
487
510
  is ``None`` (default), Streamlit will use a default row height,
488
511
  which fits one line of text.
489
512
 
490
- .. deprecated::
491
- ``use_container_width`` is deprecated and will be removed in a
492
- future release. For ``use_container_width=True``, use
493
- ``width="stretch"``.
494
-
495
513
  Returns
496
514
  -------
497
515
  element or dict
@@ -659,7 +677,6 @@ class ArrowMixin:
659
677
  validate_height(
660
678
  height,
661
679
  allow_content=False,
662
- allow_stretch=False,
663
680
  additional_allowed=["auto"],
664
681
  )
665
682
 
@@ -676,6 +693,7 @@ class ArrowMixin:
676
693
 
677
694
  proto.editing_mode = ArrowProto.EditingMode.READ_ONLY
678
695
 
696
+ has_range_index: bool = False
679
697
  if isinstance(data, pa.Table):
680
698
  # For pyarrow tables, we can just serialize the table directly
681
699
  proto.data = dataframe_util.convert_arrow_table_to_arrow_bytes(data)
@@ -698,6 +716,7 @@ class ArrowMixin:
698
716
  data_df = dataframe_util.convert_anything_to_pandas_df(
699
717
  data, ensure_copy=False
700
718
  )
719
+ has_range_index = dataframe_util.has_range_index(data_df)
701
720
  apply_data_specific_configs(column_config_mapping, data_format)
702
721
  # Serialize the data to bytes:
703
722
  proto.data = dataframe_util.convert_pandas_df_to_arrow_bytes(data_df)
@@ -706,6 +725,18 @@ class ArrowMixin:
706
725
  update_column_config(
707
726
  column_config_mapping, INDEX_IDENTIFIER, {"hidden": hide_index}
708
727
  )
728
+
729
+ elif (
730
+ # Hide index column if row selections are activated and the dataframe has a range index.
731
+ # The range index usually does not add a lot of value.
732
+ is_selection_activated
733
+ and selection_mode in ["multi-row", "single-row"]
734
+ and has_range_index
735
+ ):
736
+ update_column_config(
737
+ column_config_mapping, INDEX_IDENTIFIER, {"hidden": True}
738
+ )
739
+
709
740
  marshall_column_config(proto, column_config_mapping)
710
741
 
711
742
  # Create layout configuration
@@ -725,6 +756,7 @@ class ArrowMixin:
725
756
  proto.id = compute_and_register_element_id(
726
757
  "dataframe",
727
758
  user_key=key,
759
+ key_as_main_identity=False,
728
760
  dg=self.dg,
729
761
  data=proto.data,
730
762
  width=width,
@@ -751,7 +783,9 @@ class ArrowMixin:
751
783
  return self.dg._enqueue("arrow_data_frame", proto, layout_config=layout_config)
752
784
 
753
785
  @gather_metrics("table")
754
- def table(self, data: Data = None) -> DeltaGenerator:
786
+ def table(
787
+ self, data: Data = None, *, border: bool | Literal["horizontal"] = True
788
+ ) -> DeltaGenerator:
755
789
  """Display a static table.
756
790
 
757
791
  While ``st.dataframe`` is geared towards large datasets and interactive
@@ -775,49 +809,60 @@ class ArrowMixin:
775
809
  .. |st.markdown| replace:: ``st.markdown``
776
810
  .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown
777
811
 
812
+ border : bool or "horizontal"
813
+ Whether to show borders around the table and between cells. This can be one
814
+ of the following:
815
+
816
+ - ``True`` (default): Show borders around the table and between cells.
817
+ - ``False``: Don't show any borders.
818
+ - ``"horizontal"``: Show only horizontal borders between rows.
819
+
778
820
  Examples
779
821
  --------
780
- **Example 1: Display a simple dataframe as a static table**
822
+ **Example 1: Display a confusion matrix as a static table**
781
823
 
782
824
  >>> import pandas as pd
783
825
  >>> import streamlit as st
784
- >>> from numpy.random import default_rng as rng
785
826
  >>>
786
- >>> df = pd.DataFrame(
787
- ... rng(0).standard_normal(size=(10, 5)),
788
- ... columns=("col %d" % i for i in range(5)),
827
+ >>> confusion_matrix = pd.DataFrame(
828
+ ... {
829
+ ... "Predicted Cat": [85, 3, 2, 1],
830
+ ... "Predicted Dog": [2, 78, 4, 0],
831
+ ... "Predicted Bird": [1, 5, 72, 3],
832
+ ... "Predicted Fish": [0, 2, 1, 89],
833
+ ... },
834
+ ... index=["Actual Cat", "Actual Dog", "Actual Bird", "Actual Fish"],
789
835
  ... )
790
- >>>
791
- >>> st.table(df)
836
+ >>> st.table(confusion_matrix)
792
837
 
793
838
  .. output::
794
- https://doc-table.streamlit.app/
795
- height: 480px
839
+ https://doc-table-confusion.streamlit.app/
840
+ height: 250px
796
841
 
797
- **Example 2: Display a table of Markdown strings**
842
+ **Example 2: Display a product leaderboard with Markdown and horizontal borders**
798
843
 
799
- >>> import pandas as pd
800
844
  >>> import streamlit as st
801
845
  >>>
802
- >>> df = pd.DataFrame(
803
- ... {
804
- ... "Command": ["**st.table**", "*st.dataframe*"],
805
- ... "Type": ["`static`", "`interactive`"],
806
- ... "Docs": [
807
- ... "[:rainbow[docs]](https://docs.streamlit.io"
808
- ... "/develop/api-reference/data/st.dataframe)",
809
- ... "[:open_book:](https://docs.streamlit.io"
810
- ... "/develop/api-reference/data/st.table)",
811
- ... ],
812
- ... }
813
- ... )
814
- >>>
815
- >>> st.table(df)
846
+ >>> product_data = {
847
+ ... "Product": [
848
+ ... ":material/devices: Widget Pro",
849
+ ... ":material/smart_toy: Smart Device",
850
+ ... ":material/inventory: Premium Kit",
851
+ ... ],
852
+ ... "Category": [":blue[Electronics]", ":green[IoT]", ":violet[Bundle]"],
853
+ ... "Stock": ["🟢 Full", "🟡 Low", "🔴 Empty"],
854
+ ... "Units sold": [1247, 892, 654],
855
+ ... "Revenue": [125000, 89000, 98000],
856
+ ... }
857
+ >>> st.table(product_data, border="horizontal")
816
858
 
817
859
  .. output::
818
- https://doc-table-markdown.streamlit.app/
860
+ https://doc-table-horizontal-border.streamlit.app/
819
861
  height: 200px
862
+
820
863
  """
864
+ # Parse border parameter to enum value
865
+ border_mode = parse_border_mode(border)
821
866
 
822
867
  # Check if data is uncollected, and collect it but with 100 rows max, instead of
823
868
  # 10k rows, which is done in all other cases.
@@ -843,6 +888,7 @@ class ArrowMixin:
843
888
 
844
889
  proto = ArrowProto()
845
890
  marshall(proto, data, default_uuid)
891
+ proto.border_mode = border_mode
846
892
  return self.dg._enqueue("arrow_table", proto, layout_config=layout_config)
847
893
 
848
894
  @gather_metrics("add_rows")
@@ -1034,8 +1080,10 @@ def _arrow_add_rows(
1034
1080
 
1035
1081
  if metadata.chart_command == "bar_chart":
1036
1082
  kwargs["horizontal"] = metadata.horizontal
1083
+ kwargs["sort"] = metadata.sort
1037
1084
 
1038
- kwargs["use_container_width"] = metadata.use_container_width
1085
+ if metadata.use_container_width is not None:
1086
+ kwargs["use_container_width"] = metadata.use_container_width
1039
1087
 
1040
1088
  st_method(data, **kwargs)
1041
1089
  return None