streamlit 1.49.0__py3-none-any.whl → 1.50.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 (156) hide show
  1. streamlit/column_config.py +2 -0
  2. streamlit/commands/navigation.py +3 -1
  3. streamlit/components/v1/custom_component.py +17 -42
  4. streamlit/config.py +306 -0
  5. streamlit/connections/base_connection.py +4 -2
  6. streamlit/dataframe_util.py +3 -2
  7. streamlit/delta_generator.py +2 -3
  8. streamlit/elements/arrow.py +63 -43
  9. streamlit/elements/deck_gl_json_chart.py +1 -0
  10. streamlit/elements/form.py +6 -6
  11. streamlit/elements/graphviz_chart.py +23 -6
  12. streamlit/elements/iframe.py +0 -2
  13. streamlit/elements/image.py +10 -9
  14. streamlit/elements/layouts.py +58 -11
  15. streamlit/elements/lib/built_in_chart_utils.py +95 -29
  16. streamlit/elements/lib/column_config_utils.py +5 -0
  17. streamlit/elements/lib/column_types.py +563 -144
  18. streamlit/elements/lib/dialog.py +1 -0
  19. streamlit/elements/lib/layout_utils.py +4 -4
  20. streamlit/elements/lib/pandas_styler_utils.py +30 -14
  21. streamlit/elements/lib/utils.py +17 -5
  22. streamlit/elements/map.py +1 -3
  23. streamlit/elements/media.py +2 -0
  24. streamlit/elements/metric.py +10 -32
  25. streamlit/elements/plotly_chart.py +17 -9
  26. streamlit/elements/pyplot.py +6 -6
  27. streamlit/elements/vega_charts.py +110 -44
  28. streamlit/elements/widgets/audio_input.py +48 -0
  29. streamlit/elements/widgets/button.py +27 -25
  30. streamlit/elements/widgets/button_group.py +1 -0
  31. streamlit/elements/widgets/camera_input.py +1 -0
  32. streamlit/elements/widgets/chat.py +1 -0
  33. streamlit/elements/widgets/checkbox.py +1 -0
  34. streamlit/elements/widgets/color_picker.py +1 -0
  35. streamlit/elements/widgets/data_editor.py +6 -5
  36. streamlit/elements/widgets/file_uploader.py +1 -0
  37. streamlit/elements/widgets/multiselect.py +10 -0
  38. streamlit/elements/widgets/number_input.py +3 -0
  39. streamlit/elements/widgets/radio.py +1 -0
  40. streamlit/elements/widgets/select_slider.py +1 -0
  41. streamlit/elements/widgets/selectbox.py +4 -0
  42. streamlit/elements/widgets/slider.py +1 -0
  43. streamlit/elements/widgets/text_widgets.py +6 -0
  44. streamlit/elements/widgets/time_widgets.py +9 -0
  45. streamlit/elements/write.py +1 -17
  46. streamlit/git_util.py +65 -43
  47. streamlit/material_icon_names.py +1 -1
  48. streamlit/proto/Arrow_pb2.py +10 -8
  49. streamlit/proto/Arrow_pb2.pyi +31 -2
  50. streamlit/proto/AudioInput_pb2.py +2 -2
  51. streamlit/proto/AudioInput_pb2.pyi +6 -2
  52. streamlit/proto/Block_pb2.py +11 -11
  53. streamlit/proto/Block_pb2.pyi +5 -0
  54. streamlit/proto/NewSession_pb2.py +18 -16
  55. streamlit/proto/NewSession_pb2.pyi +135 -2
  56. streamlit/runtime/app_session.py +18 -5
  57. streamlit/runtime/theme_util.py +148 -0
  58. streamlit/static/index.html +2 -2
  59. streamlit/static/manifest.json +221 -221
  60. streamlit/static/static/css/index.CHEnSPGk.css +1 -0
  61. streamlit/static/static/css/{index.C8X8rNzw.css → index.CIiu7Ygf.css} +1 -1
  62. streamlit/static/static/js/{ErrorOutline.esm.u9XvzxL8.js → ErrorOutline.esm.DUpR0_Ka.js} +1 -1
  63. streamlit/static/static/js/{FileDownload.esm.CaRyZ-b2.js → FileDownload.esm.CN4j9-1w.js} +1 -1
  64. streamlit/static/static/js/{FileHelper.Dk2SwIi3.js → FileHelper.CaIUKG91.js} +1 -1
  65. streamlit/static/static/js/{FormClearHelper.l_UPPvkg.js → FormClearHelper.DTcdrasw.js} +1 -1
  66. streamlit/static/static/js/{Hooks.BxrVEftw.js → Hooks.BRba_Own.js} +1 -1
  67. streamlit/static/static/js/InputInstructions.xnSDuYeQ.js +1 -0
  68. streamlit/static/static/js/{Particles.DkY6FDnc.js → Particles.CElH0XX2.js} +1 -1
  69. streamlit/static/static/js/{ProgressBar.BPtSM82n.js → ProgressBar.DetlP5aY.js} +2 -2
  70. streamlit/static/static/js/Toolbar.C77ar7rq.js +1 -0
  71. streamlit/static/static/js/{base-input.egUI4LjJ.js → base-input.BQft14La.js} +3 -3
  72. streamlit/static/static/js/{checkbox.ButpszcE.js → checkbox.yZOfXCeX.js} +1 -1
  73. streamlit/static/static/js/{createSuper.DYJA5xa6.js → createSuper.Dh9w1cs8.js} +1 -1
  74. streamlit/static/static/js/data-grid-overlay-editor.DcuHuCyW.js +1 -0
  75. streamlit/static/static/js/{downloader.B3TjsSPZ.js → downloader.MeHtkq8r.js} +1 -1
  76. streamlit/static/static/js/{es6.BYSNuG4D.js → es6.VpBPGCnM.js} +2 -2
  77. streamlit/static/static/js/{iframeResizer.contentWindow.CNPHJsF2.js → iframeResizer.contentWindow.yMw_ARIL.js} +1 -1
  78. streamlit/static/static/js/{index.DgpIMUsr.js → index.64ejlaaT.js} +1 -1
  79. streamlit/static/static/js/{index.BBnWuh07.js → index.6xX1278W.js} +90 -91
  80. streamlit/static/static/js/index.B-hiXRzw.js +1 -0
  81. streamlit/static/static/js/{index.DtwkPJs5.js → index.B0H9IXUJ.js} +47 -47
  82. streamlit/static/static/js/{index.0tDq1WXk.js → index.B4cAbHP6.js} +1 -1
  83. streamlit/static/static/js/{index.CFjU0x00.js → index.B4dUQfni.js} +1 -1
  84. streamlit/static/static/js/{index.BrD9sbpx.js → index.BPQo7BKk.js} +1 -1
  85. streamlit/static/static/js/index.Baqa90pe.js +2 -0
  86. streamlit/static/static/js/{index.uInpwWAP.js → index.Bj9JgOEC.js} +1 -1
  87. streamlit/static/static/js/index.BjCwMzj4.js +3 -0
  88. streamlit/static/static/js/{index.C3EXAI-u.js → index.Bm3VbPB5.js} +1 -1
  89. streamlit/static/static/js/{index.DGcW849X.js → index.Bxz2yX3P.js} +1 -1
  90. streamlit/static/static/js/{index.CeXLlclc.js → index.BycLveZ4.js} +1 -1
  91. streamlit/static/static/js/{index.CjQnYKID.js → index.C9BdUqTi.js} +1 -1
  92. streamlit/static/static/js/index.CFMf5_ez.js +197 -0
  93. streamlit/static/static/js/index.CGYqqs6j.js +1 -0
  94. streamlit/static/static/js/{index.CFePF7s4.js → index.CH1tqnSs.js} +1 -1
  95. streamlit/static/static/js/{index.BoJaJReB.js → index.CMItVsFA.js} +1 -1
  96. streamlit/static/static/js/{index.CuEFSQ-o.js → index.CTBk8Vk2.js} +1 -1
  97. streamlit/static/static/js/index.CiAQIz1H.js +7 -0
  98. streamlit/static/static/js/index.Cj7DSzVR.js +73 -0
  99. streamlit/static/static/js/index.Ck8rQ9OL.js +1 -0
  100. streamlit/static/static/js/{index.CqSRo6zQ.js → index.ClELlchS.js} +2 -2
  101. streamlit/static/static/js/{index.DP1rDFP0.js → index.Cnpi3o3E.js} +1 -1
  102. streamlit/static/static/js/{index.Cl_966eE.js → index.Ctn27_AE.js} +1 -1
  103. streamlit/static/static/js/{index.D4jR1m1z.js → index.D2QEXQq_.js} +1 -1
  104. streamlit/static/static/js/index.DH71Ezyj.js +1 -0
  105. streamlit/static/static/js/{index.CfiZGqj3.js → index.DHh-U0dK.js} +2 -2
  106. streamlit/static/static/js/{index.Bp1Of6L8.js → index.DK7hD7_w.js} +1 -1
  107. streamlit/static/static/js/{index.MQLQLR5Z.js → index.DKv_lNO7.js} +1 -1
  108. streamlit/static/static/js/index.DNLrMXgm.js +12 -0
  109. streamlit/static/static/js/index.DW0Grddz.js +1 -0
  110. streamlit/static/static/js/{index.Cb9gN2T2.js → index.Dbe-Q3C-.js} +1 -1
  111. streamlit/static/static/js/index.DcPNYEUo.js +1 -0
  112. streamlit/static/static/js/index.DuxqVQpd.js +1 -0
  113. streamlit/static/static/js/{index.BH79B25f.js → index.FFOzOWzC.js} +1 -1
  114. streamlit/static/static/js/{index.DWedOrkQ.js → index.GRUzrudl.js} +1 -1
  115. streamlit/static/static/js/{input.CbP5ZuQ7.js → input.s6pjQ49A.js} +1 -1
  116. streamlit/static/static/js/{memory.BuacVo2L.js → memory.Cuvsdfrl.js} +1 -1
  117. streamlit/static/static/js/{number-overlay-editor.BZb9zRl_.js → number-overlay-editor.DdgVR5m3.js} +1 -1
  118. streamlit/static/static/js/{possibleConstructorReturn.DSM84rOS.js → possibleConstructorReturn.CqidKeei.js} +1 -1
  119. streamlit/static/static/js/{sandbox.C480llMG.js → sandbox.CCQREcJx.js} +1 -1
  120. streamlit/static/static/js/{timepicker.BunxCVp7.js → timepicker.mkJF97Bb.js} +4 -4
  121. streamlit/static/static/js/{toConsumableArray.B4o8rEx1.js → toConsumableArray.De7I7KVR.js} +1 -1
  122. streamlit/static/static/js/{uniqueId.tii0yosY.js → uniqueId.RI1LJdtz.js} +1 -1
  123. streamlit/static/static/js/{useBasicWidgetState.Bnm4FD6K.js → useBasicWidgetState.CedkNjUW.js} +1 -1
  124. streamlit/static/static/js/{useTextInputAutoExpand.Dgtwc1m0.js → useTextInputAutoExpand.Ca7w8dVs.js} +2 -2
  125. streamlit/static/static/js/{useUpdateUiValue.DjXdMFGw.js → useUpdateUiValue.DeXelfRH.js} +1 -1
  126. streamlit/static/static/js/withFullScreenWrapper.C3561XxJ.js +1 -0
  127. streamlit/static/static/media/MaterialSymbols-Rounded.DeCZgS-4.woff2 +0 -0
  128. streamlit/string_util.py +58 -1
  129. streamlit/web/bootstrap.py +0 -31
  130. streamlit/web/server/routes.py +17 -4
  131. streamlit/web/server/server.py +1 -0
  132. {streamlit-1.49.0.dist-info → streamlit-1.50.0.dist-info}/METADATA +1 -1
  133. {streamlit-1.49.0.dist-info → streamlit-1.50.0.dist-info}/RECORD +137 -136
  134. streamlit/static/static/css/index.COe1010n.css +0 -1
  135. streamlit/static/static/js/InputInstructions.C254RU9X.js +0 -1
  136. streamlit/static/static/js/Toolbar.BO_3WBaS.js +0 -1
  137. streamlit/static/static/js/data-grid-overlay-editor.C9gQLEnU.js +0 -1
  138. streamlit/static/static/js/index.BDZorv41.js +0 -1
  139. streamlit/static/static/js/index.BeTC4Yl-.js +0 -197
  140. streamlit/static/static/js/index.BnOd05Ko.js +0 -2
  141. streamlit/static/static/js/index.Bpe4-O2W.js +0 -1
  142. streamlit/static/static/js/index.C1qCS-sd.js +0 -1
  143. streamlit/static/static/js/index.C77g9sAQ.js +0 -3
  144. streamlit/static/static/js/index.Ca3y4ztK.js +0 -1
  145. streamlit/static/static/js/index.CbwuUwu4.js +0 -12
  146. streamlit/static/static/js/index.DKb-BAE2.js +0 -1
  147. streamlit/static/static/js/index.DStzYLqM.js +0 -73
  148. streamlit/static/static/js/index.DVKQKDLu.js +0 -1
  149. streamlit/static/static/js/index.DYbRPmVF.js +0 -1
  150. streamlit/static/static/js/index.z992t-BQ.js +0 -7
  151. streamlit/static/static/js/withFullScreenWrapper.0cy2pVf5.js +0 -1
  152. streamlit/static/static/media/MaterialSymbols-Rounded.CBxVaFdk.woff2 +0 -0
  153. {streamlit-1.49.0.data → streamlit-1.50.0.data}/scripts/streamlit.cmd +0 -0
  154. {streamlit-1.49.0.dist-info → streamlit-1.50.0.dist-info}/WHEEL +0 -0
  155. {streamlit-1.49.0.dist-info → streamlit-1.50.0.dist-info}/entry_points.txt +0 -0
  156. {streamlit-1.49.0.dist-info → streamlit-1.50.0.dist-info}/top_level.txt +0 -0
@@ -112,6 +112,7 @@ class Dialog(DeltaGenerator):
112
112
  element_id = compute_and_register_element_id(
113
113
  "dialog",
114
114
  user_key=None,
115
+ key_as_main_identity=False,
115
116
  dg=parent,
116
117
  title=title,
117
118
  dismissible=dismissible,
@@ -119,8 +119,8 @@ def validate_height(
119
119
 
120
120
  def get_width_config(width: Width) -> WidthConfig:
121
121
  width_config = WidthConfig()
122
- if isinstance(width, int):
123
- width_config.pixel_width = width
122
+ if isinstance(width, (int, float)):
123
+ width_config.pixel_width = int(width)
124
124
  elif width == "content":
125
125
  width_config.use_content = True
126
126
  else:
@@ -130,8 +130,8 @@ def get_width_config(width: Width) -> WidthConfig:
130
130
 
131
131
  def get_height_config(height: Height) -> HeightConfig:
132
132
  height_config = HeightConfig()
133
- if isinstance(height, int):
134
- height_config.pixel_height = height
133
+ if isinstance(height, (int, float)):
134
+ height_config.pixel_height = int(height)
135
135
  elif height == "content":
136
136
  height_config.use_content = True
137
137
  else:
@@ -14,6 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ from collections import defaultdict
17
18
  from collections.abc import Mapping
18
19
  from typing import TYPE_CHECKING, Any, TypeVar
19
20
 
@@ -258,21 +259,36 @@ def _use_display_values(df: DataFrame, styles: Mapping[str, Any]) -> DataFrame:
258
259
  # If values in a column are not of the same type, Arrow
259
260
  # serialization would fail. Thus, we need to cast all values
260
261
  # of the dataframe to strings before assigning them display values.
261
- new_df = df.astype(str)
262
262
 
263
+ new_df = df.astype(str)
263
264
  cell_selector_regex = re.compile(r"row(\d+)_col(\d+)")
264
- if "body" in styles:
265
- rows = styles["body"]
266
- for row in rows:
267
- for cell in row:
268
- if "id" in cell and (match := cell_selector_regex.match(cell["id"])):
269
- r, c = map(int, match.groups())
270
- # Check if the display value is an Enum type. Enum values need to be
271
- # converted to their `.value` attribute to ensure proper serialization
272
- # and display logic.
273
- if isinstance(cell["display_value"], Enum):
274
- new_df.iloc[r, c] = str(cell["display_value"].value)
275
- else:
276
- new_df.iloc[r, c] = str(cell["display_value"])
265
+ # Outer key = column index; inner key = row index -> target string value
266
+ updates_by_col: defaultdict[int, dict[int, str]] = defaultdict(dict)
267
+ for row in styles.get("body", []):
268
+ for cell in row:
269
+ cell_id = cell.get("id")
270
+ if not cell_id:
271
+ continue
272
+ match = cell_selector_regex.match(cell_id)
273
+ if not match:
274
+ continue
275
+ row_idx, col_idx = map(int, match.groups())
276
+ display_value = cell.get("display_value")
277
+
278
+ str_value = (
279
+ str(display_value.value)
280
+ # Check if the display value is an Enum type. Enum values need to be
281
+ # converted to their `.value` attribute to ensure proper serialization
282
+ # and display logic.
283
+ if isinstance(display_value, Enum)
284
+ else str(display_value)
285
+ )
286
+ updates_by_col[col_idx][row_idx] = str_value
287
+
288
+ for col_idx, values_by_row in updates_by_col.items():
289
+ row_indices = list(values_by_row.keys())
290
+ values = list(values_by_row.values())
291
+ # Batch-assign updates for this column using iloc for performance.
292
+ new_df.iloc[row_indices, col_idx] = values
277
293
 
278
294
  return new_df
@@ -187,7 +187,7 @@ def compute_and_register_element_id(
187
187
  *,
188
188
  user_key: str | None,
189
189
  dg: DeltaGenerator | None,
190
- key_as_main_identity: bool = False,
190
+ key_as_main_identity: bool | set[str],
191
191
  **kwargs: SAFE_VALUES | Iterable[SAFE_VALUES],
192
192
  ) -> str:
193
193
  """Compute and register the ID for the given element.
@@ -224,15 +224,27 @@ def compute_and_register_element_id(
224
224
  format_func, label_visibility, args, kwargs, on_change, and
225
225
  the active_script_hash are not supposed to be added here
226
226
 
227
- key_as_main_identity : bool
228
- If True, if a key is provided by the user, we don't include
227
+ key_as_main_identity : bool | set[str]
228
+ If True and a key is provided by the user, we don't include
229
229
  command kwargs in the element ID computation.
230
+ If a set of kwarg names is provided and a key is provided,
231
+ only the kwargs with names in this set will be included
232
+ in the element ID computation.
230
233
  """
231
234
  ctx = get_script_run_ctx()
232
235
 
233
- ignore_command_kwargs = key_as_main_identity and user_key
236
+ # When a user_key is present and key_as_main_identity is True OR a set (even empty),
237
+ # we should ignore general command kwargs and form/sidebar context. For the set case,
238
+ # only explicitly whitelisted kwargs will be included below.
239
+ ignore_command_kwargs = user_key is not None and (
240
+ (key_as_main_identity is True) or isinstance(key_as_main_identity, set)
241
+ )
234
242
 
235
- kwargs_to_use = {} if ignore_command_kwargs else {**kwargs}
243
+ if isinstance(key_as_main_identity, set) and user_key:
244
+ # Only include the explicitly whitelisted kwargs in the computation
245
+ kwargs_to_use = {k: v for k, v in kwargs.items() if k in key_as_main_identity}
246
+ else:
247
+ kwargs_to_use = {} if ignore_command_kwargs else {**kwargs}
236
248
 
237
249
  if ctx:
238
250
  # Add the active script hash to give elements on different
streamlit/elements/map.py CHANGED
@@ -399,9 +399,7 @@ def _convert_color_arg_or_column(
399
399
 
400
400
  if color_col_name is not None:
401
401
  # Convert color column to the right format.
402
- if len(data[color_col_name]) > 0 and is_color_like(
403
- data[color_col_name].iloc[0]
404
- ):
402
+ if len(data[color_col_name]) > 0 and is_color_like(data[color_col_name].iat[0]):
405
403
  # Use .loc[] to avoid a SettingWithCopyWarning in some cases.
406
404
  data.loc[:, color_col_name] = data.loc[:, color_col_name].map(
407
405
  to_int_color_tuple
@@ -639,6 +639,7 @@ def marshall_video(
639
639
  "video",
640
640
  # video does not yet allow setting a user-defined key
641
641
  user_key=None,
642
+ key_as_main_identity=False,
642
643
  dg=dg,
643
644
  url=proto.url,
644
645
  mimetype=mimetype,
@@ -831,6 +832,7 @@ def marshall_audio(
831
832
  proto.id = compute_and_register_element_id(
832
833
  "audio",
833
834
  user_key=None,
835
+ key_as_main_identity=False,
834
836
  dg=dg,
835
837
  url=proto.url,
836
838
  mimetype=mimetype,
@@ -36,16 +36,14 @@ from streamlit.elements.lib.utils import (
36
36
  from streamlit.errors import StreamlitAPIException
37
37
  from streamlit.proto.Metric_pb2 import Metric as MetricProto
38
38
  from streamlit.runtime.metrics_util import gather_metrics
39
- from streamlit.string_util import clean_text
39
+ from streamlit.string_util import AnyNumber, clean_text, from_number
40
40
 
41
41
  if TYPE_CHECKING:
42
- import numpy as np
43
-
44
42
  from streamlit.delta_generator import DeltaGenerator
45
43
 
46
44
 
47
- Value: TypeAlias = Union["np.integer[Any]", "np.floating[Any]", float, int, str, None]
48
- Delta: TypeAlias = Union[float, int, str, None]
45
+ Value: TypeAlias = Union[AnyNumber, str, None]
46
+ Delta: TypeAlias = Union[AnyNumber, str, None]
49
47
  DeltaColor: TypeAlias = Literal["normal", "inverse", "off"]
50
48
 
51
49
 
@@ -98,10 +96,10 @@ class MetricMixin:
98
96
  .. |st.markdown| replace:: ``st.markdown``
99
97
  .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown
100
98
 
101
- value : int, float, str, or None
102
- Value of the metric. None is rendered as a long dash.
99
+ value : int, float, decimal.Decimal, str, or None
100
+ Value of the metric. ``None`` is rendered as a long dash.
103
101
 
104
- delta : int, float, str, or None
102
+ delta : int, float, decimal.Decimal, str, or None
105
103
  Indicator of how the metric changed, rendered with an arrow below
106
104
  the metric. If delta is negative (int/float) or starts with a minus
107
105
  sign (str), the arrow points down and the text is red; else the
@@ -338,23 +336,9 @@ def _parse_label(label: str) -> str:
338
336
  def _parse_value(value: Value) -> str:
339
337
  if value is None:
340
338
  return "—"
341
- if isinstance(value, (int, float, str)):
342
- return str(value)
343
- if hasattr(value, "item"):
344
- # Add support for numpy values (e.g. int16, float64, etc.)
345
- try:
346
- # Item could also be just a variable, so we use try, except
347
- if isinstance(value.item(), (float, int)):
348
- return str(value.item())
349
- except Exception: # noqa: S110
350
- # If the numpy item is not a valid value, the TypeError below will be raised.
351
- pass
352
-
353
- raise TypeError(
354
- f"'{value}' is of type {type(value)}, which is not an accepted type."
355
- " value only accepts: int, float, str, or None."
356
- " Please convert the value to an accepted type."
357
- )
339
+ if isinstance(value, str):
340
+ return value
341
+ return from_number(value)
358
342
 
359
343
 
360
344
  def _parse_delta(delta: Delta) -> str:
@@ -362,13 +346,7 @@ def _parse_delta(delta: Delta) -> str:
362
346
  return ""
363
347
  if isinstance(delta, str):
364
348
  return dedent(delta)
365
- if isinstance(delta, (int, float)):
366
- return str(delta)
367
- raise TypeError(
368
- f"'{delta}' is of type {type(delta)}, which is not an accepted type."
369
- " delta only accepts: int, float, str, or None."
370
- " Please convert the value to an accepted type."
371
- )
349
+ return from_number(delta)
372
350
 
373
351
 
374
352
  def _determine_delta_color_and_direction(
@@ -316,6 +316,7 @@ class PlotlyMixin:
316
316
  "box",
317
317
  "lasso",
318
318
  ),
319
+ config: dict[str, Any] | None = None,
319
320
  **kwargs: Any,
320
321
  ) -> DeltaGenerator | PlotlyState:
321
322
  """Display an interactive Plotly chart.
@@ -415,6 +416,12 @@ class PlotlyMixin:
415
416
 
416
417
  All selections modes are activated by default.
417
418
 
419
+ config : dict or None
420
+ A dictionary of Plotly configuration options. This is passed to
421
+ Plotly's ``show()`` function. For more information about Plotly
422
+ configuration options, see Plotly's documentation on `Configuration
423
+ in Python <https://plotly.com/python/configuration-options/>`_.
424
+
418
425
  **kwargs
419
426
  Additional arguments accepted by Plotly's ``plot()`` function.
420
427
 
@@ -423,6 +430,10 @@ class PlotlyMixin:
423
430
  see Plotly's documentation on `Configuration in Python
424
431
  <https://plotly.com/python/configuration-options/>`_.
425
432
 
433
+ .. deprecated::
434
+ ``**kwargs`` are deprecated and will be removed in a future
435
+ release. Use ``config`` instead.
436
+
426
437
  Returns
427
438
  -------
428
439
  element or dict
@@ -493,11 +504,11 @@ class PlotlyMixin:
493
504
  # for their main parameter. I don't like the name, but it's best to
494
505
  # keep it in sync with what Plotly calls it.
495
506
 
496
- if "sharing" in kwargs:
507
+ if kwargs:
497
508
  show_deprecation_warning(
498
- "The `sharing` parameter has been deprecated and will be removed "
499
- "in a future release. Plotly charts will always be rendered using "
500
- "Streamlit's offline mode."
509
+ "The keyword arguments have been deprecated and will be removed "
510
+ "in a future release. Use `config` instead to specify Plotly "
511
+ "configuration options."
501
512
  )
502
513
 
503
514
  if theme not in ["streamlit", None]:
@@ -542,11 +553,7 @@ class PlotlyMixin:
542
553
  plotly_chart_proto.theme = theme or ""
543
554
  plotly_chart_proto.form_id = current_form_id(self.dg)
544
555
 
545
- config = dict(kwargs.get("config", {}))
546
- # Copy over some kwargs to config dict. Plotly does the same in plot().
547
- config.setdefault("showLink", kwargs.get("show_link", False))
548
- config.setdefault("linkText", kwargs.get("link_text", False))
549
-
556
+ config = config or {}
550
557
  plotly_chart_proto.spec = plotly.io.to_json(figure, validate=False)
551
558
  plotly_chart_proto.config = json.dumps(config)
552
559
 
@@ -558,6 +565,7 @@ class PlotlyMixin:
558
565
  plotly_chart_proto.id = compute_and_register_element_id(
559
566
  "plotly_chart",
560
567
  user_key=key,
568
+ key_as_main_identity=False,
561
569
  dg=self.dg,
562
570
  plotly_spec=plotly_chart_proto.spec,
563
571
  plotly_config=plotly_chart_proto.config,
@@ -99,15 +99,15 @@ class PyplotMixin:
99
99
  contents according to the plotting library, up to the width of the
100
100
  parent container.
101
101
 
102
+ .. deprecated::
103
+ ``use_container_width`` is deprecated and will be removed in a
104
+ future release. For ``use_container_width=True``, use
105
+ ``width="stretch"``. For ``use_container_width=False``, use
106
+ ``width="content"``.
107
+
102
108
  **kwargs : any
103
109
  Arguments to pass to Matplotlib's savefig function.
104
110
 
105
- .. deprecated::
106
- ``use_container_width`` is deprecated and will be removed in a
107
- future release. For ``use_container_width=True``, use
108
- ``width="stretch"``. For ``use_container_width=False``, use
109
- ``width="content"``.
110
-
111
111
  Example
112
112
  -------
113
113
  >>> import matplotlib.pyplot as plt
@@ -20,20 +20,15 @@ import json
20
20
  import re
21
21
  from contextlib import nullcontext
22
22
  from dataclasses import dataclass
23
- from typing import (
24
- TYPE_CHECKING,
25
- Any,
26
- Final,
27
- Literal,
28
- TypedDict,
29
- Union,
30
- cast,
31
- overload,
32
- )
23
+ from typing import TYPE_CHECKING, Any, Final, Literal, TypedDict, Union, cast, overload
33
24
 
34
25
  from typing_extensions import Required, TypeAlias
35
26
 
36
27
  from streamlit import dataframe_util, type_util
28
+ from streamlit.deprecation_util import (
29
+ make_deprecated_name_warning,
30
+ show_deprecation_warning,
31
+ )
37
32
  from streamlit.elements.lib import dicttools
38
33
  from streamlit.elements.lib.built_in_chart_utils import (
39
34
  AddRowsMetadata,
@@ -43,6 +38,13 @@ from streamlit.elements.lib.built_in_chart_utils import (
43
38
  maybe_raise_stack_warning,
44
39
  )
45
40
  from streamlit.elements.lib.form_utils import current_form_id
41
+ from streamlit.elements.lib.layout_utils import (
42
+ Height,
43
+ LayoutConfig,
44
+ Width,
45
+ validate_height,
46
+ validate_width,
47
+ )
46
48
  from streamlit.elements.lib.policies import check_widget_policies
47
49
  from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
48
50
  from streamlit.errors import StreamlitAPIException
@@ -596,9 +598,9 @@ class VegaChartsMixin:
596
598
  x_label: str | None = None,
597
599
  y_label: str | None = None,
598
600
  color: str | Color | list[Color] | None = None,
599
- width: int | None = None,
600
- height: int | None = None,
601
- use_container_width: bool = True,
601
+ width: Width = "stretch",
602
+ height: Height = "content",
603
+ use_container_width: bool | None = None,
602
604
  ) -> DeltaGenerator:
603
605
  """Display a line chart.
604
606
 
@@ -607,9 +609,6 @@ class VegaChartsMixin:
607
609
  the chart's Altair spec. As a result this is easier to use for many
608
610
  "just plot this" scenarios, while being less customizable.
609
611
 
610
- If ``st.line_chart`` does not guess the data specification
611
- correctly, try specifying your desired chart using ``st.altair_chart``.
612
-
613
612
  Parameters
614
613
  ----------
615
614
  data : Anything supported by st.dataframe
@@ -680,20 +679,30 @@ class VegaChartsMixin:
680
679
  You can set the default colors in the ``theme.chartCategoryColors``
681
680
  configuration option.
682
681
 
683
- width : int or None
684
- Desired width of the chart expressed in pixels. If ``width`` is
685
- ``None`` (default), Streamlit sets the width of the chart to fit
686
- its contents according to the plotting library, up to the width of
687
- the parent container. If ``width`` is greater than the width of the
688
- parent container, Streamlit sets the chart width to match the width
689
- of the parent container.
690
-
691
- To use ``width``, you must set ``use_container_width=False``.
682
+ width : "stretch", "content", or int
683
+ The width of the chart element. This can be one of the following:
692
684
 
693
- height : int or None
694
- Desired height of the chart expressed in pixels. If ``height`` is
695
- ``None`` (default), Streamlit sets the height of the chart to fit
696
- its contents according to the plotting library.
685
+ - ``"stretch"`` (default): The width of the element matches the
686
+ width of the parent container.
687
+ - ``"content"``: The width of the element matches the width of its
688
+ content, but doesn't exceed the width of the parent container.
689
+ - An integer specifying the width in pixels: The element has a
690
+ fixed width. If the specified width is greater than the width of
691
+ the parent container, the width of the element matches the width
692
+ of the parent container.
693
+
694
+ height : "content", "stretch", or int
695
+ The height of the chart element. This can be one of the following:
696
+
697
+ - ``"content"`` (default): The height of the element matches the
698
+ height of its content.
699
+ - ``"stretch"``: The height of the element matches the height of
700
+ its content or the height of the parent container, whichever is
701
+ larger. If the element is not in a parent container, the height
702
+ of the element matches the height of its content.
703
+ - An integer specifying the height in pixels: The element has a
704
+ fixed height. If the content is larger than the specified
705
+ height, scrolling is enabled.
697
706
 
698
707
  use_container_width : bool
699
708
  Whether to override ``width`` with the width of the parent
@@ -702,6 +711,11 @@ class VegaChartsMixin:
702
711
  parent container. If ``use_container_width`` is ``False``,
703
712
  Streamlit sets the chart's width according to ``width``.
704
713
 
714
+ .. deprecated::
715
+ The ``use_container_width`` parameter is deprecated and will
716
+ be removed in a future version. Use the ``width`` parameter
717
+ with ``width="stretch"`` instead.
718
+
705
719
  Examples
706
720
  --------
707
721
  **Example 1: Basic line chart from a dataframe**
@@ -777,6 +791,24 @@ class VegaChartsMixin:
777
791
  height: 440px
778
792
 
779
793
  """
794
+ if use_container_width is not None:
795
+ show_deprecation_warning(
796
+ make_deprecated_name_warning(
797
+ "use_container_width",
798
+ "width",
799
+ "2025-12-31",
800
+ "For `use_container_width=True`, use `width='stretch'`. "
801
+ "For `use_container_width=False`, use `width='content'`.",
802
+ include_st_prefix=False,
803
+ ),
804
+ show_in_browser=False,
805
+ )
806
+ if use_container_width:
807
+ width = "stretch"
808
+ elif not isinstance(width, int):
809
+ # This preserves the existing behavior of setting use_container_width
810
+ # to False combined with an integer width.
811
+ width = "content"
780
812
 
781
813
  chart, add_rows_metadata = generate_chart(
782
814
  chart_type=ChartType.LINE,
@@ -789,15 +821,19 @@ class VegaChartsMixin:
789
821
  size_from_user=None,
790
822
  width=width,
791
823
  height=height,
792
- use_container_width=use_container_width,
824
+ use_container_width=(width == "stretch"),
793
825
  )
826
+
827
+ validate_width(width, allow_content=True)
828
+ validate_height(height, allow_content=True)
794
829
  return cast(
795
830
  "DeltaGenerator",
796
831
  self._altair_chart(
797
832
  chart,
798
- use_container_width=use_container_width,
799
833
  theme="streamlit",
800
834
  add_rows_metadata=add_rows_metadata,
835
+ width=width,
836
+ height=height,
801
837
  ),
802
838
  )
803
839
 
@@ -823,9 +859,6 @@ class VegaChartsMixin:
823
859
  the chart's Altair spec. As a result this is easier to use for many
824
860
  "just plot this" scenarios, while being less customizable.
825
861
 
826
- If ``st.area_chart`` does not guess the data specification
827
- correctly, try specifying your desired chart using ``st.altair_chart``.
828
-
829
862
  Parameters
830
863
  ----------
831
864
  data : Anything supported by st.dataframe
@@ -1082,6 +1115,7 @@ class VegaChartsMixin:
1082
1115
  y_label: str | None = None,
1083
1116
  color: str | Color | list[Color] | None = None,
1084
1117
  horizontal: bool = False,
1118
+ sort: bool | str = True,
1085
1119
  stack: bool | ChartStackType | None = None,
1086
1120
  width: int | None = None,
1087
1121
  height: int | None = None,
@@ -1094,9 +1128,6 @@ class VegaChartsMixin:
1094
1128
  the chart's Altair spec. As a result this is easier to use for many
1095
1129
  "just plot this" scenarios, while being less customizable.
1096
1130
 
1097
- If ``st.bar_chart`` does not guess the data specification
1098
- correctly, try specifying your desired chart using ``st.altair_chart``.
1099
-
1100
1131
  Parameters
1101
1132
  ----------
1102
1133
  data : Anything supported by st.dataframe
@@ -1173,6 +1204,19 @@ class VegaChartsMixin:
1173
1204
  Streamlit swaps the x-axis and y-axis and the bars display
1174
1205
  horizontally.
1175
1206
 
1207
+ sort : bool or str
1208
+ How to sort the bars. This can be one of the following:
1209
+
1210
+ - ``True`` (default): The bars are sorted automatically along the
1211
+ independent/categorical axis with Altair's default sorting. This
1212
+ also correctly sorts ordered categorical columns
1213
+ (``pd.Categorical``).
1214
+ - ``False``: The bars are shown in data order without sorting.
1215
+ - The name of a column (e.g. ``"col1"``): The bars are sorted by
1216
+ that column in ascending order.
1217
+ - The name of a column with a minus-sign prefix (e.g. ``"-col1"``):
1218
+ The bars are sorted by that column in descending order.
1219
+
1176
1220
  stack : bool, "normalize", "center", "layered", or None
1177
1221
  Whether to stack the bars. If this is ``None`` (default),
1178
1222
  Streamlit uses Vega's default. Other values can be as follows:
@@ -1357,6 +1401,7 @@ class VegaChartsMixin:
1357
1401
  use_container_width=use_container_width,
1358
1402
  stack=stack,
1359
1403
  horizontal=horizontal,
1404
+ sort_from_user=sort,
1360
1405
  )
1361
1406
  return cast(
1362
1407
  "DeltaGenerator",
@@ -1390,9 +1435,6 @@ class VegaChartsMixin:
1390
1435
  the chart's Altair spec. As a result this is easier to use for many
1391
1436
  "just plot this" scenarios, while being less customizable.
1392
1437
 
1393
- If ``st.scatter_chart`` does not guess the data specification correctly,
1394
- try specifying your desired chart using ``st.altair_chart``.
1395
-
1396
1438
  Parameters
1397
1439
  ----------
1398
1440
  data : Anything supported by st.dataframe
@@ -1956,6 +1998,8 @@ class VegaChartsMixin:
1956
1998
  on_select: Literal["rerun", "ignore"] | WidgetCallback = "ignore",
1957
1999
  selection_mode: str | Iterable[str] | None = None,
1958
2000
  add_rows_metadata: AddRowsMetadata | None = None,
2001
+ width: Width | None = None,
2002
+ height: Height | None = None,
1959
2003
  ) -> DeltaGenerator | VegaLiteState:
1960
2004
  """Internal method to enqueue a vega-lite chart element based on an Altair chart.
1961
2005
 
@@ -1980,6 +2024,8 @@ class VegaChartsMixin:
1980
2024
  on_select=on_select,
1981
2025
  selection_mode=selection_mode,
1982
2026
  add_rows_metadata=add_rows_metadata,
2027
+ width=width,
2028
+ height=height,
1983
2029
  )
1984
2030
 
1985
2031
  def _vega_lite_chart(
@@ -1992,6 +2038,8 @@ class VegaChartsMixin:
1992
2038
  on_select: Literal["rerun", "ignore"] | WidgetCallback = "ignore",
1993
2039
  selection_mode: str | Iterable[str] | None = None,
1994
2040
  add_rows_metadata: AddRowsMetadata | None = None,
2041
+ width: Width | None = None,
2042
+ height: Height | None = None,
1995
2043
  **kwargs: Any,
1996
2044
  ) -> DeltaGenerator | VegaLiteState:
1997
2045
  """Internal method to enqueue a vega-lite chart element based on a vega-lite spec.
@@ -2038,13 +2086,13 @@ class VegaChartsMixin:
2038
2086
  spec = {}
2039
2087
 
2040
2088
  # Set the default value for `use_container_width`.
2041
- if use_container_width is None:
2089
+ if use_container_width is None and width is None:
2042
2090
  # Some multi-view charts (facet, horizontal concatenation, and repeat;
2043
2091
  # see https://altair-viz.github.io/user_guide/compound_charts.html)
2044
2092
  # don't work well with `use_container_width=True`, so we disable it for
2045
2093
  # those charts (see https://github.com/streamlit/streamlit/issues/9091).
2046
2094
  # All other charts (including vertical concatenation) default to
2047
- # `use_container_width=True`.
2095
+ # `use_container_width=True` unless width is provided.
2048
2096
  is_facet_chart = "facet" in spec or (
2049
2097
  "encoding" in spec
2050
2098
  and (any(x in spec["encoding"] for x in ["row", "column", "facet"]))
@@ -2055,12 +2103,18 @@ class VegaChartsMixin:
2055
2103
 
2056
2104
  vega_lite_proto = ArrowVegaLiteChartProto()
2057
2105
 
2058
- spec = _prepare_vega_lite_spec(spec, use_container_width, **kwargs)
2106
+ use_container_width_for_spec = (
2107
+ use_container_width
2108
+ if use_container_width is not None
2109
+ else width == "stretch"
2110
+ )
2111
+ spec = _prepare_vega_lite_spec(spec, use_container_width_for_spec, **kwargs)
2059
2112
  _marshall_chart_data(vega_lite_proto, spec, data)
2060
2113
 
2061
2114
  # Prevent the spec from changing across reruns:
2062
2115
  vega_lite_proto.spec = _stabilize_vega_json_spec(json.dumps(spec))
2063
- vega_lite_proto.use_container_width = use_container_width
2116
+ if use_container_width is not None:
2117
+ vega_lite_proto.use_container_width = use_container_width
2064
2118
  vega_lite_proto.theme = theme or ""
2065
2119
 
2066
2120
  if is_selection_activated:
@@ -2079,6 +2133,7 @@ class VegaChartsMixin:
2079
2133
  vega_lite_proto.id = compute_and_register_element_id(
2080
2134
  "arrow_vega_lite_chart",
2081
2135
  user_key=key,
2136
+ key_as_main_identity=False,
2082
2137
  dg=self.dg,
2083
2138
  vega_lite_spec=vega_lite_proto.spec,
2084
2139
  # The data is either in vega_lite_proto.data.data
@@ -2109,6 +2164,17 @@ class VegaChartsMixin:
2109
2164
  add_rows_metadata=add_rows_metadata,
2110
2165
  )
2111
2166
  return widget_state.value
2167
+
2168
+ # Handle layout config for width/height parameters
2169
+ if width is not None or height is not None:
2170
+ layout_config = LayoutConfig(width=width, height=height)
2171
+ return self.dg._enqueue(
2172
+ "arrow_vega_lite_chart",
2173
+ vega_lite_proto,
2174
+ add_rows_metadata=add_rows_metadata,
2175
+ layout_config=layout_config,
2176
+ )
2177
+
2112
2178
  # If its not used with selections activated, just return
2113
2179
  # the delta generator related to this element.
2114
2180
  return self.dg._enqueue(