streamlit-nightly 1.45.1.dev20250504__py3-none-any.whl → 1.45.1.dev20250505__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 (102) hide show
  1. streamlit/column_config.py +8 -8
  2. streamlit/commands/execution_control.py +2 -5
  3. streamlit/components/v1/components.py +1 -1
  4. streamlit/connections/__init__.py +2 -2
  5. streamlit/delta_generator.py +2 -2
  6. streamlit/elements/alert.py +1 -1
  7. streamlit/elements/json.py +1 -1
  8. streamlit/elements/lib/built_in_chart_utils.py +14 -6
  9. streamlit/elements/lib/column_config_utils.py +1 -3
  10. streamlit/elements/lib/file_uploader_utils.py +7 -2
  11. streamlit/elements/lib/options_selector_utils.py +1 -1
  12. streamlit/elements/metric.py +4 -4
  13. streamlit/elements/progress.py +1 -1
  14. streamlit/elements/widgets/time_widgets.py +43 -0
  15. streamlit/proto/DateInput_pb2.py +4 -3
  16. streamlit/proto/DateInput_pb2.pyi +8 -2
  17. streamlit/proto/TimeInput_pb2.py +4 -3
  18. streamlit/proto/TimeInput_pb2.pyi +9 -2
  19. streamlit/runtime/__init__.py +1 -1
  20. streamlit/runtime/caching/__init__.py +6 -6
  21. streamlit/runtime/caching/hashing.py +1 -1
  22. streamlit/runtime/connection_factory.py +1 -1
  23. streamlit/runtime/credentials.py +1 -1
  24. streamlit/runtime/scriptrunner/__init__.py +4 -4
  25. streamlit/runtime/scriptrunner/script_runner.py +3 -6
  26. streamlit/runtime/secrets.py +1 -1
  27. streamlit/runtime/state/__init__.py +5 -5
  28. streamlit/static/index.html +1 -1
  29. streamlit/static/static/js/{ErrorOutline.esm.Bp4VdNOc.js → ErrorOutline.esm.BgsGCsV4.js} +1 -1
  30. streamlit/static/static/js/{FileDownload.esm.hVzDDDNS.js → FileDownload.esm.CCKezPn5.js} +1 -1
  31. streamlit/static/static/js/{FileHelper.BGcyDQ_S.js → FileHelper.CprSF_kT.js} +1 -1
  32. streamlit/static/static/js/{FormClearHelper.a0IiSXcn.js → FormClearHelper.DiwQ0EtT.js} +1 -1
  33. streamlit/static/static/js/{Hooks.C2dZkryw.js → Hooks.DDqhyZ1_.js} +1 -1
  34. streamlit/static/static/js/{InputInstructions.Cn0WICoN.js → InputInstructions.BCEZxme4.js} +1 -1
  35. streamlit/static/static/js/{ProgressBar.VRmRPHtW.js → ProgressBar.CGdY94g_.js} +1 -1
  36. streamlit/static/static/js/{RenderInPortalIfExists.CZa97lrw.js → RenderInPortalIfExists.uGJp_Q0v.js} +1 -1
  37. streamlit/static/static/js/{Toolbar.DJZBBDvl.js → Toolbar.hTlw0-K1.js} +1 -1
  38. streamlit/static/static/js/{base-input.CzerGAEH.js → base-input.mGTY3-qU.js} +1 -1
  39. streamlit/static/static/js/{checkbox.C6Sj4eVw.js → checkbox.Cg-5cKAh.js} +1 -1
  40. streamlit/static/static/js/{createSuper.C7yhRETi.js → createSuper.-HPb1oYT.js} +1 -1
  41. streamlit/static/static/js/{data-grid-overlay-editor.DAgcbVks.js → data-grid-overlay-editor.BpNYxiTp.js} +1 -1
  42. streamlit/static/static/js/{downloader.B8HL-u_1.js → downloader.DS9891pS.js} +1 -1
  43. streamlit/static/static/js/{es6.BxAW_jrO.js → es6.CU1PEL2w.js} +2 -2
  44. streamlit/static/static/js/{iframeResizer.contentWindow.CS8fz-W7.js → iframeResizer.contentWindow.CgJE2bJN.js} +1 -1
  45. streamlit/static/static/js/{index.BwnckS8e.js → index.B209tswL.js} +1 -1
  46. streamlit/static/static/js/{index.C7t1-CQQ.js → index.BC0ueJ8H.js} +1 -1
  47. streamlit/static/static/js/{index.DWb5kgxt.js → index.BHVQ94t4.js} +1 -1
  48. streamlit/static/static/js/{index.DgOrPDFa.js → index.BT0p7gAu.js} +1 -1
  49. streamlit/static/static/js/{index.uOOdkOMl.js → index.BTTj6ld4.js} +1 -1
  50. streamlit/static/static/js/{index.CG2pASlR.js → index.BVjgrQ4R.js} +1 -1
  51. streamlit/static/static/js/{index.6jptdEp6.js → index.BXYstdPh.js} +1 -1
  52. streamlit/static/static/js/{index.Dt0FtS-M.js → index.BZ9mqzEJ.js} +1 -1
  53. streamlit/static/static/js/{index.CSAdYIt3.js → index.Bb-Ukg41.js} +1 -1
  54. streamlit/static/static/js/{index.B2tTSlE1.js → index.BhTok8vt.js} +1 -1
  55. streamlit/static/static/js/{index.DIZcktIN.js → index.Bph6ZoI5.js} +1 -1
  56. streamlit/static/static/js/{index.B7UKH_JX.js → index.CJPcdxPe.js} +1 -1
  57. streamlit/static/static/js/{index.D6KElXAI.js → index.CMOA-8Q2.js} +1 -1
  58. streamlit/static/static/js/{index.Cxp7siQJ.js → index.CN91oQMB.js} +5 -5
  59. streamlit/static/static/js/{index.Cr1JUXmf.js → index.CtoDsUtq.js} +1 -1
  60. streamlit/static/static/js/{index.C4KrRG3c.js → index.CvFsF3FD.js} +1 -1
  61. streamlit/static/static/js/{index.DDCep3pE.js → index.CyGuL4If.js} +1 -1
  62. streamlit/static/static/js/{index.ChOkUAuD.js → index.CzGUd4IN.js} +1 -1
  63. streamlit/static/static/js/{index.A_t8lw--.js → index.DAxf3_iz.js} +1 -1
  64. streamlit/static/static/js/{index.DG9Swsby.js → index.DJHUlWgy.js} +1 -1
  65. streamlit/static/static/js/{index.CHL4u91M.js → index.DLTqo4pp.js} +1 -1
  66. streamlit/static/static/js/{index.o12m2E2P.js → index.DPJBu2uZ.js} +1 -1
  67. streamlit/static/static/js/{index.CLFopaXS.js → index.DVpzZJNg.js} +1 -1
  68. streamlit/static/static/js/{index.vdE-PayY.js → index.DWV80Vyw.js} +1 -1
  69. streamlit/static/static/js/{index.DR2lTx8N.js → index.DZ6oX-v9.js} +5 -5
  70. streamlit/static/static/js/{index.DtY8dAVN.js → index.Dh4RKl-F.js} +1 -1
  71. streamlit/static/static/js/{index.BRtyx04t.js → index.Dn76KVNf.js} +1 -1
  72. streamlit/static/static/js/{index.qMnAjj-G.js → index.DtqvdV-p.js} +1 -1
  73. streamlit/static/static/js/{index.BwlA1Cf_.js → index.ErkF0SoX.js} +1 -1
  74. streamlit/static/static/js/{index.QdRaJV_a.js → index.GSYBrzVp.js} +1 -1
  75. streamlit/static/static/js/{index.CSPC2m_c.js → index.OngWTN39.js} +1 -1
  76. streamlit/static/static/js/{index.CGzwdjEF.js → index.PSwG8ayC.js} +1 -1
  77. streamlit/static/static/js/{index.D_0HKLRm.js → index.UTlCdasa.js} +1 -1
  78. streamlit/static/static/js/{index.aBgCjIEX.js → index.eR_vQpeg.js} +1 -1
  79. streamlit/static/static/js/{index.BBClg-gm.js → index.fLsU9uCJ.js} +1 -1
  80. streamlit/static/static/js/{index.BDzCUpOG.js → index.hPjr68pz.js} +1 -1
  81. streamlit/static/static/js/{index.CgzjjllY.js → index.kXOZCC_6.js} +1 -1
  82. streamlit/static/static/js/{input.qNZgmgfK.js → input.DY17i94N.js} +1 -1
  83. streamlit/static/static/js/{memory.DifcSUze.js → memory.DsIIcbSd.js} +1 -1
  84. streamlit/static/static/js/{mergeWith.Bykfc0n-.js → mergeWith.cRgGdgvI.js} +1 -1
  85. streamlit/static/static/js/{number-overlay-editor.D_L9PQiU.js → number-overlay-editor.B8Xi2dYq.js} +1 -1
  86. streamlit/static/static/js/{possibleConstructorReturn.Cyeph4pU.js → possibleConstructorReturn.BgDi5nUm.js} +1 -1
  87. streamlit/static/static/js/{sandbox.DT6zcSKI.js → sandbox.BH9emp13.js} +1 -1
  88. streamlit/static/static/js/{textarea.C46FrViu.js → textarea.DAyShsGG.js} +1 -1
  89. streamlit/static/static/js/{timepicker.N6lFakQJ.js → timepicker.CCH2R2Y0.js} +1 -1
  90. streamlit/static/static/js/{toConsumableArray.DwaNiLbv.js → toConsumableArray.CNffSDCu.js} +1 -1
  91. streamlit/static/static/js/{uniqueId.bNZuA9Mz.js → uniqueId.B49CstkV.js} +1 -1
  92. streamlit/static/static/js/{useBasicWidgetState.qUuCVRZV.js → useBasicWidgetState.CkThOkF9.js} +1 -1
  93. streamlit/static/static/js/{useOnInputChange.CylEhpc7.js → useOnInputChange.BqEq0xFZ.js} +1 -1
  94. streamlit/static/static/js/{withFullScreenWrapper.BQay_j7X.js → withFullScreenWrapper.UsvF_Jwr.js} +1 -1
  95. streamlit/web/bootstrap.py +3 -2
  96. streamlit/web/server/__init__.py +2 -2
  97. {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/METADATA +1 -1
  98. {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/RECORD +102 -102
  99. {streamlit_nightly-1.45.1.dev20250504.data → streamlit_nightly-1.45.1.dev20250505.data}/scripts/streamlit.cmd +0 -0
  100. {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/WHEEL +0 -0
  101. {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/entry_points.txt +0 -0
  102. {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/top_level.txt +0 -0
@@ -18,21 +18,21 @@ from __future__ import annotations
18
18
 
19
19
  __all__ = [
20
20
  "AreaChartColumn",
21
- "Column",
22
- "TextColumn",
23
- "NumberColumn",
24
21
  "BarChartColumn",
25
22
  "CheckboxColumn",
23
+ "Column",
24
+ "DateColumn",
26
25
  "DatetimeColumn",
27
26
  "ImageColumn",
28
- "SelectboxColumn",
29
- "ProgressColumn",
30
- "LinkColumn",
27
+ "JsonColumn",
31
28
  "LineChartColumn",
29
+ "LinkColumn",
32
30
  "ListColumn",
33
- "DateColumn",
31
+ "NumberColumn",
32
+ "ProgressColumn",
33
+ "SelectboxColumn",
34
+ "TextColumn",
34
35
  "TimeColumn",
35
- "JsonColumn",
36
36
  ]
37
37
 
38
38
 
@@ -90,11 +90,8 @@ def _new_fragment_id_queue(
90
90
  "functions during fragment reruns."
91
91
  )
92
92
 
93
- assert (
94
- new_queue := list(
95
- dropwhile(lambda x: x != ctx.current_fragment_id, curr_queue)
96
- )
97
- ), (
93
+ new_queue = list(dropwhile(lambda x: x != ctx.current_fragment_id, curr_queue))
94
+ assert new_queue, (
98
95
  "Could not find current_fragment_id in fragment_id_queue. This should never happen."
99
96
  )
100
97
 
@@ -32,7 +32,7 @@ from streamlit.runtime.state import register_widget
32
32
 
33
33
  __all__ = [
34
34
  "CustomComponent",
35
- "declare_component",
36
35
  "MarshallComponentException",
36
+ "declare_component",
37
37
  "register_widget",
38
38
  ]
@@ -21,8 +21,8 @@ ExperimentalBaseConnection = BaseConnection
21
21
 
22
22
  __all__ = [
23
23
  "BaseConnection",
24
+ "ExperimentalBaseConnection",
25
+ "SQLConnection",
24
26
  "SnowflakeConnection",
25
27
  "SnowparkConnection",
26
- "SQLConnection",
27
- "ExperimentalBaseConnection",
28
28
  ]
@@ -284,7 +284,7 @@ class DeltaGenerator(
284
284
 
285
285
  def __enter__(self) -> None:
286
286
  # with block started
287
- context_dg_stack.set(context_dg_stack.get() + (self,))
287
+ context_dg_stack.set((*context_dg_stack.get(), self))
288
288
 
289
289
  def __exit__(
290
290
  self,
@@ -530,7 +530,7 @@ class DeltaGenerator(
530
530
  # a brand new cursor for this new block we're creating.
531
531
  block_cursor = cursor.RunningCursor(
532
532
  root_container=dg._root_container,
533
- parent_path=dg._cursor.parent_path + (dg._cursor.index,),
533
+ parent_path=(*dg._cursor.parent_path, dg._cursor.index),
534
534
  )
535
535
 
536
536
  # `dg_type` param added for st.status container. It allows us to
@@ -221,7 +221,7 @@ class AlertMixin:
221
221
  >>>
222
222
  >>> st.info('This is a purely informational message', icon="ℹ️")
223
223
 
224
- """
224
+ """ # noqa: RUF002
225
225
 
226
226
  alert_proto = AlertProto()
227
227
  alert_proto.body = clean_text(body)
@@ -134,7 +134,7 @@ class JsonMixin:
134
134
  json_proto.max_expand_depth = expanded
135
135
  else:
136
136
  raise TypeError(
137
- f"The type {str(type(expanded))} of `expanded` is not supported"
137
+ f"The type {type(expanded)} of `expanded` is not supported"
138
138
  ", must be bool or int."
139
139
  )
140
140
 
@@ -74,11 +74,19 @@ class AddRowsMetadata:
74
74
 
75
75
 
76
76
  class ChartType(Enum):
77
- AREA = {"mark_type": "area", "command": "area_chart"}
78
- VERTICAL_BAR = {"mark_type": "bar", "command": "bar_chart", "horizontal": False}
79
- HORIZONTAL_BAR = {"mark_type": "bar", "command": "bar_chart", "horizontal": True}
80
- LINE = {"mark_type": "line", "command": "line_chart"}
81
- SCATTER = {"mark_type": "circle", "command": "scatter_chart"}
77
+ AREA: Final = {"mark_type": "area", "command": "area_chart"}
78
+ VERTICAL_BAR: Final = {
79
+ "mark_type": "bar",
80
+ "command": "bar_chart",
81
+ "horizontal": False,
82
+ }
83
+ HORIZONTAL_BAR: Final = {
84
+ "mark_type": "bar",
85
+ "command": "bar_chart",
86
+ "horizontal": True,
87
+ }
88
+ LINE: Final = {"mark_type": "line", "command": "line_chart"}
89
+ SCATTER: Final = {"mark_type": "circle", "command": "scatter_chart"}
82
90
 
83
91
 
84
92
  # Color and size legends need different title paddings in order for them
@@ -1035,7 +1043,7 @@ def _get_size_encoding(
1035
1043
  return alt.SizeValue(100)
1036
1044
  else:
1037
1045
  raise StreamlitAPIException(
1038
- f"This does not look like a valid size: {repr(size_value)}"
1046
+ f"This does not look like a valid size: {size_value!r}"
1039
1047
  )
1040
1048
 
1041
1049
  elif size_column is not None or size_value is not None:
@@ -509,9 +509,7 @@ def _convert_column_config_to_json(column_config_mapping: ColumnConfigMapping) -
509
509
  # Ignore all None values and prefix columns specified by numerical index:
510
510
  return json.dumps(
511
511
  {
512
- (
513
- f"{_NUMERICAL_POSITION_PREFIX}{str(k)}" if isinstance(k, int) else k
514
- ): v
512
+ (f"{_NUMERICAL_POSITION_PREFIX}{k!s}" if isinstance(k, int) else k): v
515
513
  for (k, v) in remove_none_values(column_config_mapping).items()
516
514
  },
517
515
  allow_nan=False,
@@ -59,9 +59,14 @@ def enforce_filename_restriction(filename: str, allowed_types: Sequence[str]) ->
59
59
  enforce file type check by extension on the frontend, but we check it on backend
60
60
  before returning file to the user to protect ourselves.
61
61
  """
62
- base_name, extension = os.path.splitext(filename.lower())
62
+ normalized_filename = filename.lower()
63
+ base_name, extension = os.path.splitext(normalized_filename)
64
+ normalized_allowed_types = [allowed_type.lower() for allowed_type in allowed_types]
63
65
 
64
- if not any(filename.endswith(allowed_type) for allowed_type in allowed_types):
66
+ if not any(
67
+ normalized_filename.endswith(allowed_type)
68
+ for allowed_type in normalized_allowed_types
69
+ ):
65
70
  raise StreamlitAPIException(
66
71
  f"Invalid file extension: `{extension}`. Allowed: {allowed_types}"
67
72
  )
@@ -57,7 +57,7 @@ def index_(iterable: Iterable[_Value], x: _Value) -> int:
57
57
  elif isinstance(value, float) and isinstance(x, float):
58
58
  if abs(x - value) < _FLOAT_EQUALITY_EPSILON:
59
59
  return i
60
- raise ValueError(f"{str(x)} is not in iterable")
60
+ raise ValueError(f"{x} is not in iterable")
61
61
 
62
62
 
63
63
  def check_and_convert_to_indices(
@@ -214,7 +214,7 @@ class MetricMixin:
214
214
  def _parse_label(label: str) -> str:
215
215
  if not isinstance(label, str):
216
216
  raise TypeError(
217
- f"'{str(label)}' is of type {str(type(label))}, which is not an accepted type."
217
+ f"'{label}' is of type {type(label)}, which is not an accepted type."
218
218
  " label only accepts: str. Please convert the label to an accepted type."
219
219
  )
220
220
  return label
@@ -236,7 +236,7 @@ def _parse_value(value: Value) -> str:
236
236
  pass
237
237
 
238
238
  raise TypeError(
239
- f"'{str(value)}' is of type {str(type(value))}, which is not an accepted type."
239
+ f"'{value}' is of type {type(value)}, which is not an accepted type."
240
240
  " value only accepts: int, float, str, or None."
241
241
  " Please convert the value to an accepted type."
242
242
  )
@@ -251,7 +251,7 @@ def _parse_delta(delta: Delta) -> str:
251
251
  return str(delta)
252
252
  else:
253
253
  raise TypeError(
254
- f"'{str(delta)}' is of type {str(type(delta))}, which is not an accepted type."
254
+ f"'{delta}' is of type {type(delta)}, which is not an accepted type."
255
255
  " delta only accepts: int, float, str, or None."
256
256
  " Please convert the value to an accepted type."
257
257
  )
@@ -263,7 +263,7 @@ def _determine_delta_color_and_direction(
263
263
  ) -> MetricColorAndDirection:
264
264
  if delta_color not in {"normal", "inverse", "off"}:
265
265
  raise StreamlitAPIException(
266
- f"'{str(delta_color)}' is not an accepted value. delta_color only accepts: "
266
+ f"'{delta_color}' is not an accepted value. delta_color only accepts: "
267
267
  "'normal', 'inverse', or 'off'"
268
268
  )
269
269
 
@@ -89,7 +89,7 @@ def _get_text(text: str | None) -> str | None:
89
89
  if isinstance(text, str):
90
90
  return clean_text(text)
91
91
  raise StreamlitAPIException(
92
- f"Progress Text is of type {str(type(text))}, which is not an accepted type."
92
+ f"Progress Text is of type {type(text)}, which is not an accepted type."
93
93
  "Text only accepts: str. Please convert the text to an accepted type."
94
94
  )
95
95
 
@@ -31,6 +31,7 @@ from typing import (
31
31
  from typing_extensions import TypeAlias
32
32
 
33
33
  from streamlit.elements.lib.form_utils import current_form_id
34
+ from streamlit.elements.lib.layout_utils import WidthWithoutContent, validate_width
34
35
  from streamlit.elements.lib.policies import (
35
36
  check_widget_policies,
36
37
  maybe_raise_label_warnings,
@@ -45,6 +46,7 @@ from streamlit.elements.lib.utils import (
45
46
  from streamlit.errors import StreamlitAPIException
46
47
  from streamlit.proto.DateInput_pb2 import DateInput as DateInputProto
47
48
  from streamlit.proto.TimeInput_pb2 import TimeInput as TimeInputProto
49
+ from streamlit.proto.WidthConfig_pb2 import WidthConfig
48
50
  from streamlit.runtime.metrics_util import gather_metrics
49
51
  from streamlit.runtime.scriptrunner import ScriptRunContext, get_script_run_ctx
50
52
  from streamlit.runtime.state import (
@@ -321,6 +323,7 @@ class TimeWidgetsMixin:
321
323
  disabled: bool = False,
322
324
  label_visibility: LabelVisibility = "visible",
323
325
  step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
326
+ width: WidthWithoutContent = "stretch",
324
327
  ) -> time:
325
328
  pass
326
329
 
@@ -338,6 +341,7 @@ class TimeWidgetsMixin:
338
341
  disabled: bool = False,
339
342
  label_visibility: LabelVisibility = "visible",
340
343
  step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
344
+ width: WidthWithoutContent = "stretch",
341
345
  ) -> time | None:
342
346
  pass
343
347
 
@@ -355,6 +359,7 @@ class TimeWidgetsMixin:
355
359
  disabled: bool = False,
356
360
  label_visibility: LabelVisibility = "visible",
357
361
  step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
362
+ width: WidthWithoutContent = "stretch",
358
363
  ) -> time | None:
359
364
  r"""Display a time input widget.
360
365
 
@@ -432,6 +437,11 @@ class TimeWidgetsMixin:
432
437
  The stepping interval in seconds. Defaults to 900, i.e. 15 minutes.
433
438
  You can also pass a datetime.timedelta object.
434
439
 
440
+ width : "stretch" or int
441
+ The width of the time input. If "stretch", the time input will stretch
442
+ to fill the available space. If a number, the time input will have a
443
+ fixed width of that many pixels. Defaults to "stretch".
444
+
435
445
  Returns
436
446
  -------
437
447
  datetime.time or None
@@ -475,6 +485,7 @@ class TimeWidgetsMixin:
475
485
  disabled=disabled,
476
486
  label_visibility=label_visibility,
477
487
  step=step,
488
+ width=width,
478
489
  ctx=ctx,
479
490
  )
480
491
 
@@ -491,6 +502,7 @@ class TimeWidgetsMixin:
491
502
  disabled: bool = False,
492
503
  label_visibility: LabelVisibility = "visible",
493
504
  step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
505
+ width: WidthWithoutContent = "stretch",
494
506
  ctx: ScriptRunContext | None = None,
495
507
  ) -> time | None:
496
508
  key = to_key(key)
@@ -502,6 +514,7 @@ class TimeWidgetsMixin:
502
514
  default_value=value if value != "now" else None,
503
515
  )
504
516
  maybe_raise_label_warnings(label, label_visibility)
517
+ validate_width(width)
505
518
 
506
519
  parsed_time: time | None
507
520
  if value is None:
@@ -517,6 +530,7 @@ class TimeWidgetsMixin:
517
530
  value=parsed_time if isinstance(value, (datetime, time)) else value,
518
531
  help=help,
519
532
  step=step,
533
+ width=width,
520
534
  )
521
535
  del value
522
536
 
@@ -549,6 +563,14 @@ class TimeWidgetsMixin:
549
563
  if help is not None:
550
564
  time_input_proto.help = dedent(help)
551
565
 
566
+ # Set up width configuration
567
+ width_config = WidthConfig()
568
+ if isinstance(width, int):
569
+ width_config.pixel_width = width
570
+ else:
571
+ width_config.use_stretch = True
572
+ time_input_proto.width_config.CopyFrom(width_config)
573
+
552
574
  serde = TimeInputSerde(parsed_time)
553
575
  widget_state = register_widget(
554
576
  time_input_proto.id,
@@ -585,6 +607,7 @@ class TimeWidgetsMixin:
585
607
  format: str = "YYYY/MM/DD",
586
608
  disabled: bool = False,
587
609
  label_visibility: LabelVisibility = "visible",
610
+ width: WidthWithoutContent = "stretch",
588
611
  ) -> date: ...
589
612
 
590
613
  @overload
@@ -603,6 +626,7 @@ class TimeWidgetsMixin:
603
626
  format: str = "YYYY/MM/DD",
604
627
  disabled: bool = False,
605
628
  label_visibility: LabelVisibility = "visible",
629
+ width: WidthWithoutContent = "stretch",
606
630
  ) -> date | None: ...
607
631
 
608
632
  @overload
@@ -623,6 +647,7 @@ class TimeWidgetsMixin:
623
647
  format: str = "YYYY/MM/DD",
624
648
  disabled: bool = False,
625
649
  label_visibility: LabelVisibility = "visible",
650
+ width: WidthWithoutContent = "stretch",
626
651
  ) -> DateWidgetRangeReturn: ...
627
652
 
628
653
  @gather_metrics("date_input")
@@ -641,6 +666,7 @@ class TimeWidgetsMixin:
641
666
  format: str = "YYYY/MM/DD",
642
667
  disabled: bool = False,
643
668
  label_visibility: LabelVisibility = "visible",
669
+ width: WidthWithoutContent = "stretch",
644
670
  ) -> DateWidgetReturn:
645
671
  r"""Display a date input widget.
646
672
 
@@ -748,6 +774,11 @@ class TimeWidgetsMixin:
748
774
  label, which can help keep the widget alligned with other widgets.
749
775
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
750
776
 
777
+ width : "stretch" or int
778
+ The width of the date input. If "stretch", the date input will stretch
779
+ to fill the available space. If a number, the date input will have a
780
+ fixed width of that many pixels. Defaults to "stretch".
781
+
751
782
  Returns
752
783
  -------
753
784
  datetime.date or a tuple with 0-2 dates or None
@@ -814,6 +845,7 @@ class TimeWidgetsMixin:
814
845
  disabled=disabled,
815
846
  label_visibility=label_visibility,
816
847
  format=format,
848
+ width=width,
817
849
  ctx=ctx,
818
850
  )
819
851
 
@@ -832,6 +864,7 @@ class TimeWidgetsMixin:
832
864
  format: str = "YYYY/MM/DD",
833
865
  disabled: bool = False,
834
866
  label_visibility: LabelVisibility = "visible",
867
+ width: WidthWithoutContent = "stretch",
835
868
  ctx: ScriptRunContext | None = None,
836
869
  ) -> DateWidgetReturn:
837
870
  key = to_key(key)
@@ -843,6 +876,7 @@ class TimeWidgetsMixin:
843
876
  default_value=value if value != "today" else None,
844
877
  )
845
878
  maybe_raise_label_warnings(label, label_visibility)
879
+ validate_width(width)
846
880
 
847
881
  def parse_date_deterministic_for_id(v: NullableScalarDateValue) -> str | None:
848
882
  if v == "today":
@@ -884,6 +918,7 @@ class TimeWidgetsMixin:
884
918
  max_value=parsed_max_date,
885
919
  help=help,
886
920
  format=format,
921
+ width=width,
887
922
  )
888
923
  if not bool(ALLOWED_DATE_FORMATS.match(format)):
889
924
  raise StreamlitAPIException(
@@ -941,6 +976,14 @@ class TimeWidgetsMixin:
941
976
  if help is not None:
942
977
  date_input_proto.help = dedent(help)
943
978
 
979
+ # Set up width configuration
980
+ width_config = WidthConfig()
981
+ if isinstance(width, int):
982
+ width_config.pixel_width = width
983
+ else:
984
+ width_config.use_stretch = True
985
+ date_input_proto.width_config.CopyFrom(width_config)
986
+
944
987
  serde = DateInputSerde(parsed_values)
945
988
 
946
989
  widget_state = register_widget(
@@ -13,9 +13,10 @@ _sym_db = _symbol_database.Default()
13
13
 
14
14
 
15
15
  from streamlit.proto import LabelVisibilityMessage_pb2 as streamlit_dot_proto_dot_LabelVisibilityMessage__pb2
16
+ from streamlit.proto import WidthConfig_pb2 as streamlit_dot_proto_dot_WidthConfig__pb2
16
17
 
17
18
 
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fstreamlit/proto/DateInput.proto\x1a,streamlit/proto/LabelVisibilityMessage.proto\"\xf9\x01\n\tDateInput\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65\x66\x61ult\x18\x03 \x03(\t\x12\x0b\n\x03min\x18\x04 \x01(\t\x12\x0b\n\x03max\x18\x05 \x01(\t\x12\x10\n\x08is_range\x18\x06 \x01(\x08\x12\x0c\n\x04help\x18\x07 \x01(\t\x12\x0f\n\x07\x66orm_id\x18\x08 \x01(\t\x12\r\n\x05value\x18\t \x03(\t\x12\x11\n\tset_value\x18\n \x01(\x08\x12\x10\n\x08\x64isabled\x18\x0b \x01(\x08\x12\x31\n\x10label_visibility\x18\x0c \x01(\x0b\x32\x17.LabelVisibilityMessage\x12\x0e\n\x06\x66ormat\x18\r \x01(\tB.\n\x1c\x63om.snowflake.apps.streamlitB\x0e\x44\x61teInputProtob\x06proto3')
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fstreamlit/proto/DateInput.proto\x1a,streamlit/proto/LabelVisibilityMessage.proto\x1a!streamlit/proto/WidthConfig.proto\"\xbd\x02\n\tDateInput\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x0f\n\x07\x64\x65\x66\x61ult\x18\x03 \x03(\t\x12\x0b\n\x03min\x18\x04 \x01(\t\x12\x0b\n\x03max\x18\x05 \x01(\t\x12\x10\n\x08is_range\x18\x06 \x01(\x08\x12\x0c\n\x04help\x18\x07 \x01(\t\x12\x0f\n\x07\x66orm_id\x18\x08 \x01(\t\x12\r\n\x05value\x18\t \x03(\t\x12\x11\n\tset_value\x18\n \x01(\x08\x12\x10\n\x08\x64isabled\x18\x0b \x01(\x08\x12\x31\n\x10label_visibility\x18\x0c \x01(\x0b\x32\x17.LabelVisibilityMessage\x12\x0e\n\x06\x66ormat\x18\r \x01(\t\x12\x31\n\x0cwidth_config\x18\x0e \x01(\x0b\x32\x16.streamlit.WidthConfigH\x00\x88\x01\x01\x42\x0f\n\r_width_configB.\n\x1c\x63om.snowflake.apps.streamlitB\x0e\x44\x61teInputProtob\x06proto3')
19
20
 
20
21
  _globals = globals()
21
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -23,6 +24,6 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'streamlit.proto.DateInput_p
23
24
  if not _descriptor._USE_C_DESCRIPTORS:
24
25
  _globals['DESCRIPTOR']._loaded_options = None
25
26
  _globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\016DateInputProto'
26
- _globals['_DATEINPUT']._serialized_start=82
27
- _globals['_DATEINPUT']._serialized_end=331
27
+ _globals['_DATEINPUT']._serialized_start=117
28
+ _globals['_DATEINPUT']._serialized_end=434
28
29
  # @@protoc_insertion_point(module_scope)
@@ -23,6 +23,7 @@ import google.protobuf.descriptor
23
23
  import google.protobuf.internal.containers
24
24
  import google.protobuf.message
25
25
  import streamlit.proto.LabelVisibilityMessage_pb2
26
+ import streamlit.proto.WidthConfig_pb2
26
27
  import typing
27
28
 
28
29
  DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
@@ -44,6 +45,7 @@ class DateInput(google.protobuf.message.Message):
44
45
  DISABLED_FIELD_NUMBER: builtins.int
45
46
  LABEL_VISIBILITY_FIELD_NUMBER: builtins.int
46
47
  FORMAT_FIELD_NUMBER: builtins.int
48
+ WIDTH_CONFIG_FIELD_NUMBER: builtins.int
47
49
  id: builtins.str
48
50
  label: builtins.str
49
51
  min: builtins.str
@@ -60,6 +62,8 @@ class DateInput(google.protobuf.message.Message):
60
62
  def value(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ...
61
63
  @property
62
64
  def label_visibility(self) -> streamlit.proto.LabelVisibilityMessage_pb2.LabelVisibilityMessage: ...
65
+ @property
66
+ def width_config(self) -> streamlit.proto.WidthConfig_pb2.WidthConfig: ...
63
67
  def __init__(
64
68
  self,
65
69
  *,
@@ -76,8 +80,10 @@ class DateInput(google.protobuf.message.Message):
76
80
  disabled: builtins.bool = ...,
77
81
  label_visibility: streamlit.proto.LabelVisibilityMessage_pb2.LabelVisibilityMessage | None = ...,
78
82
  format: builtins.str = ...,
83
+ width_config: streamlit.proto.WidthConfig_pb2.WidthConfig | None = ...,
79
84
  ) -> None: ...
80
- def HasField(self, field_name: typing.Literal["label_visibility", b"label_visibility"]) -> builtins.bool: ...
81
- def ClearField(self, field_name: typing.Literal["default", b"default", "disabled", b"disabled", "form_id", b"form_id", "format", b"format", "help", b"help", "id", b"id", "is_range", b"is_range", "label", b"label", "label_visibility", b"label_visibility", "max", b"max", "min", b"min", "set_value", b"set_value", "value", b"value"]) -> None: ...
85
+ def HasField(self, field_name: typing.Literal["_width_config", b"_width_config", "label_visibility", b"label_visibility", "width_config", b"width_config"]) -> builtins.bool: ...
86
+ def ClearField(self, field_name: typing.Literal["_width_config", b"_width_config", "default", b"default", "disabled", b"disabled", "form_id", b"form_id", "format", b"format", "help", b"help", "id", b"id", "is_range", b"is_range", "label", b"label", "label_visibility", b"label_visibility", "max", b"max", "min", b"min", "set_value", b"set_value", "value", b"value", "width_config", b"width_config"]) -> None: ...
87
+ def WhichOneof(self, oneof_group: typing.Literal["_width_config", b"_width_config"]) -> typing.Literal["width_config"] | None: ...
82
88
 
83
89
  global___DateInput = DateInput
@@ -13,9 +13,10 @@ _sym_db = _symbol_database.Default()
13
13
 
14
14
 
15
15
  from streamlit.proto import LabelVisibilityMessage_pb2 as streamlit_dot_proto_dot_LabelVisibilityMessage__pb2
16
+ from streamlit.proto import WidthConfig_pb2 as streamlit_dot_proto_dot_WidthConfig__pb2
16
17
 
17
18
 
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fstreamlit/proto/TimeInput.proto\x1a,streamlit/proto/LabelVisibilityMessage.proto\"\xeb\x01\n\tTimeInput\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x14\n\x07\x64\x65\x66\x61ult\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x0c\n\x04help\x18\x04 \x01(\t\x12\x0f\n\x07\x66orm_id\x18\x05 \x01(\t\x12\x12\n\x05value\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x11\n\tset_value\x18\x07 \x01(\x08\x12\x10\n\x08\x64isabled\x18\x08 \x01(\x08\x12\x31\n\x10label_visibility\x18\t \x01(\x0b\x32\x17.LabelVisibilityMessage\x12\x0c\n\x04step\x18\n \x01(\x03\x42\n\n\x08_defaultB\x08\n\x06_valueB.\n\x1c\x63om.snowflake.apps.streamlitB\x0eTimeInputProtob\x06proto3')
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fstreamlit/proto/TimeInput.proto\x1a,streamlit/proto/LabelVisibilityMessage.proto\x1a!streamlit/proto/WidthConfig.proto\"\xaf\x02\n\tTimeInput\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x14\n\x07\x64\x65\x66\x61ult\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x0c\n\x04help\x18\x04 \x01(\t\x12\x0f\n\x07\x66orm_id\x18\x05 \x01(\t\x12\x12\n\x05value\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x11\n\tset_value\x18\x07 \x01(\x08\x12\x10\n\x08\x64isabled\x18\x08 \x01(\x08\x12\x31\n\x10label_visibility\x18\t \x01(\x0b\x32\x17.LabelVisibilityMessage\x12\x0c\n\x04step\x18\n \x01(\x03\x12\x31\n\x0cwidth_config\x18\x0b \x01(\x0b\x32\x16.streamlit.WidthConfigH\x02\x88\x01\x01\x42\n\n\x08_defaultB\x08\n\x06_valueB\x0f\n\r_width_configB.\n\x1c\x63om.snowflake.apps.streamlitB\x0eTimeInputProtob\x06proto3')
19
20
 
20
21
  _globals = globals()
21
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -23,6 +24,6 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'streamlit.proto.TimeInput_p
23
24
  if not _descriptor._USE_C_DESCRIPTORS:
24
25
  _globals['DESCRIPTOR']._loaded_options = None
25
26
  _globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\016TimeInputProto'
26
- _globals['_TIMEINPUT']._serialized_start=82
27
- _globals['_TIMEINPUT']._serialized_end=317
27
+ _globals['_TIMEINPUT']._serialized_start=117
28
+ _globals['_TIMEINPUT']._serialized_end=420
28
29
  # @@protoc_insertion_point(module_scope)
@@ -21,6 +21,7 @@ import builtins
21
21
  import google.protobuf.descriptor
22
22
  import google.protobuf.message
23
23
  import streamlit.proto.LabelVisibilityMessage_pb2
24
+ import streamlit.proto.WidthConfig_pb2
24
25
  import typing
25
26
 
26
27
  DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
@@ -39,6 +40,7 @@ class TimeInput(google.protobuf.message.Message):
39
40
  DISABLED_FIELD_NUMBER: builtins.int
40
41
  LABEL_VISIBILITY_FIELD_NUMBER: builtins.int
41
42
  STEP_FIELD_NUMBER: builtins.int
43
+ WIDTH_CONFIG_FIELD_NUMBER: builtins.int
42
44
  id: builtins.str
43
45
  label: builtins.str
44
46
  default: builtins.str
@@ -50,6 +52,8 @@ class TimeInput(google.protobuf.message.Message):
50
52
  step: builtins.int
51
53
  @property
52
54
  def label_visibility(self) -> streamlit.proto.LabelVisibilityMessage_pb2.LabelVisibilityMessage: ...
55
+ @property
56
+ def width_config(self) -> streamlit.proto.WidthConfig_pb2.WidthConfig: ...
53
57
  def __init__(
54
58
  self,
55
59
  *,
@@ -63,12 +67,15 @@ class TimeInput(google.protobuf.message.Message):
63
67
  disabled: builtins.bool = ...,
64
68
  label_visibility: streamlit.proto.LabelVisibilityMessage_pb2.LabelVisibilityMessage | None = ...,
65
69
  step: builtins.int = ...,
70
+ width_config: streamlit.proto.WidthConfig_pb2.WidthConfig | None = ...,
66
71
  ) -> None: ...
67
- def HasField(self, field_name: typing.Literal["_default", b"_default", "_value", b"_value", "default", b"default", "label_visibility", b"label_visibility", "value", b"value"]) -> builtins.bool: ...
68
- def ClearField(self, field_name: typing.Literal["_default", b"_default", "_value", b"_value", "default", b"default", "disabled", b"disabled", "form_id", b"form_id", "help", b"help", "id", b"id", "label", b"label", "label_visibility", b"label_visibility", "set_value", b"set_value", "step", b"step", "value", b"value"]) -> None: ...
72
+ def HasField(self, field_name: typing.Literal["_default", b"_default", "_value", b"_value", "_width_config", b"_width_config", "default", b"default", "label_visibility", b"label_visibility", "value", b"value", "width_config", b"width_config"]) -> builtins.bool: ...
73
+ def ClearField(self, field_name: typing.Literal["_default", b"_default", "_value", b"_value", "_width_config", b"_width_config", "default", b"default", "disabled", b"disabled", "form_id", b"form_id", "help", b"help", "id", b"id", "label", b"label", "label_visibility", b"label_visibility", "set_value", b"set_value", "step", b"step", "value", b"value", "width_config", b"width_config"]) -> None: ...
69
74
  @typing.overload
70
75
  def WhichOneof(self, oneof_group: typing.Literal["_default", b"_default"]) -> typing.Literal["default"] | None: ...
71
76
  @typing.overload
72
77
  def WhichOneof(self, oneof_group: typing.Literal["_value", b"_value"]) -> typing.Literal["value"] | None: ...
78
+ @typing.overload
79
+ def WhichOneof(self, oneof_group: typing.Literal["_width_config", b"_width_config"]) -> typing.Literal["width_config"] | None: ...
73
80
 
74
81
  global___TimeInput = TimeInput
@@ -45,6 +45,6 @@ __all__ = [
45
45
  "RuntimeState",
46
46
  "SessionClient",
47
47
  "SessionClientDisconnectedError",
48
- "get_instance",
49
48
  "exists",
49
+ "get_instance",
50
50
  ]
@@ -86,13 +86,13 @@ cache = _cache
86
86
 
87
87
 
88
88
  __all__ = [
89
- "cache",
90
89
  "CACHE_DOCS_URL",
91
- "save_element_message",
92
- "save_block_message",
93
- "save_media_data",
94
- "get_data_cache_stats_provider",
95
- "get_resource_cache_stats_provider",
90
+ "cache",
96
91
  "cache_data",
97
92
  "cache_resource",
93
+ "get_data_cache_stats_provider",
94
+ "get_resource_cache_stats_provider",
95
+ "save_block_message",
96
+ "save_element_message",
97
+ "save_media_data",
98
98
  ]
@@ -194,7 +194,7 @@ class _HashStack:
194
194
  def pretty_print(self) -> str:
195
195
  def to_str(v: Any) -> str:
196
196
  try:
197
- return f"Object of type {type_util.get_fqn_type(v)}: {str(v)}"
197
+ return f"Object of type {type_util.get_fqn_type(v)}: {v}"
198
198
  except Exception:
199
199
  return "<Unable to convert item to string>"
200
200
 
@@ -432,4 +432,4 @@ def connection_factory(
432
432
  if pypi_package:
433
433
  extra_info = f"You need to install the '{pypi_package}' package to use this connection."
434
434
 
435
- raise ModuleNotFoundError(f"{str(e)}. {extra_info}")
435
+ raise ModuleNotFoundError(f"{e}. {extra_info}")
@@ -53,7 +53,7 @@ def email_prompt() -> str:
53
53
  return f"""
54
54
  {"👋 " if show_emoji else ""}{cli_util.style_for_cli("Welcome to Streamlit!", bold=True)}
55
55
 
56
- If youd like to receive helpful onboarding emails, news, offers, promotions,
56
+ If you'd like to receive helpful onboarding emails, news, offers, promotions,
57
57
  and the occasional swag, please enter your email address below. Otherwise,
58
58
  leave this field blank.
59
59
 
@@ -27,12 +27,12 @@ from streamlit.runtime.scriptrunner_utils.script_run_context import (
27
27
 
28
28
  __all__ = [
29
29
  "RerunData",
30
- "ScriptRunContext",
31
- "add_script_run_ctx",
32
- "get_script_run_ctx",
33
- "enqueue_message",
34
30
  "RerunException",
31
+ "ScriptRunContext",
35
32
  "ScriptRunner",
36
33
  "ScriptRunnerEvent",
37
34
  "StopException",
35
+ "add_script_run_ctx",
36
+ "enqueue_message",
37
+ "get_script_run_ctx",
38
38
  ]
@@ -161,11 +161,7 @@ def _mpa_v1(main_script_path: str):
161
161
  expanded=False,
162
162
  )
163
163
 
164
- if page._page != main_page._page:
165
- # Only run the page if it is not pointing to this script:
166
- page.run()
167
- # Finish the script execution here to only run the selected page
168
- raise StopException()
164
+ page.run()
169
165
 
170
166
 
171
167
  class ScriptRunner:
@@ -645,7 +641,8 @@ class ScriptRunner:
645
641
  else:
646
642
  if PagesManager.uses_pages_directory:
647
643
  _mpa_v1(self._main_script_path)
648
- exec(code, module.__dict__) # noqa: S102
644
+ else:
645
+ exec(code, module.__dict__) # noqa: S102
649
646
  self._fragment_storage.clear(
650
647
  new_fragment_ids=ctx.new_fragment_ids
651
648
  )
@@ -310,7 +310,7 @@ class Secrets(Mapping[str, Any]):
310
310
 
311
311
  if len(sub_secrets) == 1:
312
312
  # if there's just one file, collapse it so it's directly under `dirname`
313
- secrets[dirname] = sub_secrets[list(sub_secrets.keys())[0]]
313
+ secrets[dirname] = sub_secrets[next(iter(sub_secrets.keys()))]
314
314
  else:
315
315
  secrets[dirname] = sub_secrets
316
316