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.
- streamlit/column_config.py +8 -8
- streamlit/commands/execution_control.py +2 -5
- streamlit/components/v1/components.py +1 -1
- streamlit/connections/__init__.py +2 -2
- streamlit/delta_generator.py +2 -2
- streamlit/elements/alert.py +1 -1
- streamlit/elements/json.py +1 -1
- streamlit/elements/lib/built_in_chart_utils.py +14 -6
- streamlit/elements/lib/column_config_utils.py +1 -3
- streamlit/elements/lib/file_uploader_utils.py +7 -2
- streamlit/elements/lib/options_selector_utils.py +1 -1
- streamlit/elements/metric.py +4 -4
- streamlit/elements/progress.py +1 -1
- streamlit/elements/widgets/time_widgets.py +43 -0
- streamlit/proto/DateInput_pb2.py +4 -3
- streamlit/proto/DateInput_pb2.pyi +8 -2
- streamlit/proto/TimeInput_pb2.py +4 -3
- streamlit/proto/TimeInput_pb2.pyi +9 -2
- streamlit/runtime/__init__.py +1 -1
- streamlit/runtime/caching/__init__.py +6 -6
- streamlit/runtime/caching/hashing.py +1 -1
- streamlit/runtime/connection_factory.py +1 -1
- streamlit/runtime/credentials.py +1 -1
- streamlit/runtime/scriptrunner/__init__.py +4 -4
- streamlit/runtime/scriptrunner/script_runner.py +3 -6
- streamlit/runtime/secrets.py +1 -1
- streamlit/runtime/state/__init__.py +5 -5
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.Bp4VdNOc.js → ErrorOutline.esm.BgsGCsV4.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.hVzDDDNS.js → FileDownload.esm.CCKezPn5.js} +1 -1
- streamlit/static/static/js/{FileHelper.BGcyDQ_S.js → FileHelper.CprSF_kT.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.a0IiSXcn.js → FormClearHelper.DiwQ0EtT.js} +1 -1
- streamlit/static/static/js/{Hooks.C2dZkryw.js → Hooks.DDqhyZ1_.js} +1 -1
- streamlit/static/static/js/{InputInstructions.Cn0WICoN.js → InputInstructions.BCEZxme4.js} +1 -1
- streamlit/static/static/js/{ProgressBar.VRmRPHtW.js → ProgressBar.CGdY94g_.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.CZa97lrw.js → RenderInPortalIfExists.uGJp_Q0v.js} +1 -1
- streamlit/static/static/js/{Toolbar.DJZBBDvl.js → Toolbar.hTlw0-K1.js} +1 -1
- streamlit/static/static/js/{base-input.CzerGAEH.js → base-input.mGTY3-qU.js} +1 -1
- streamlit/static/static/js/{checkbox.C6Sj4eVw.js → checkbox.Cg-5cKAh.js} +1 -1
- streamlit/static/static/js/{createSuper.C7yhRETi.js → createSuper.-HPb1oYT.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.DAgcbVks.js → data-grid-overlay-editor.BpNYxiTp.js} +1 -1
- streamlit/static/static/js/{downloader.B8HL-u_1.js → downloader.DS9891pS.js} +1 -1
- streamlit/static/static/js/{es6.BxAW_jrO.js → es6.CU1PEL2w.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.CS8fz-W7.js → iframeResizer.contentWindow.CgJE2bJN.js} +1 -1
- streamlit/static/static/js/{index.BwnckS8e.js → index.B209tswL.js} +1 -1
- streamlit/static/static/js/{index.C7t1-CQQ.js → index.BC0ueJ8H.js} +1 -1
- streamlit/static/static/js/{index.DWb5kgxt.js → index.BHVQ94t4.js} +1 -1
- streamlit/static/static/js/{index.DgOrPDFa.js → index.BT0p7gAu.js} +1 -1
- streamlit/static/static/js/{index.uOOdkOMl.js → index.BTTj6ld4.js} +1 -1
- streamlit/static/static/js/{index.CG2pASlR.js → index.BVjgrQ4R.js} +1 -1
- streamlit/static/static/js/{index.6jptdEp6.js → index.BXYstdPh.js} +1 -1
- streamlit/static/static/js/{index.Dt0FtS-M.js → index.BZ9mqzEJ.js} +1 -1
- streamlit/static/static/js/{index.CSAdYIt3.js → index.Bb-Ukg41.js} +1 -1
- streamlit/static/static/js/{index.B2tTSlE1.js → index.BhTok8vt.js} +1 -1
- streamlit/static/static/js/{index.DIZcktIN.js → index.Bph6ZoI5.js} +1 -1
- streamlit/static/static/js/{index.B7UKH_JX.js → index.CJPcdxPe.js} +1 -1
- streamlit/static/static/js/{index.D6KElXAI.js → index.CMOA-8Q2.js} +1 -1
- streamlit/static/static/js/{index.Cxp7siQJ.js → index.CN91oQMB.js} +5 -5
- streamlit/static/static/js/{index.Cr1JUXmf.js → index.CtoDsUtq.js} +1 -1
- streamlit/static/static/js/{index.C4KrRG3c.js → index.CvFsF3FD.js} +1 -1
- streamlit/static/static/js/{index.DDCep3pE.js → index.CyGuL4If.js} +1 -1
- streamlit/static/static/js/{index.ChOkUAuD.js → index.CzGUd4IN.js} +1 -1
- streamlit/static/static/js/{index.A_t8lw--.js → index.DAxf3_iz.js} +1 -1
- streamlit/static/static/js/{index.DG9Swsby.js → index.DJHUlWgy.js} +1 -1
- streamlit/static/static/js/{index.CHL4u91M.js → index.DLTqo4pp.js} +1 -1
- streamlit/static/static/js/{index.o12m2E2P.js → index.DPJBu2uZ.js} +1 -1
- streamlit/static/static/js/{index.CLFopaXS.js → index.DVpzZJNg.js} +1 -1
- streamlit/static/static/js/{index.vdE-PayY.js → index.DWV80Vyw.js} +1 -1
- streamlit/static/static/js/{index.DR2lTx8N.js → index.DZ6oX-v9.js} +5 -5
- streamlit/static/static/js/{index.DtY8dAVN.js → index.Dh4RKl-F.js} +1 -1
- streamlit/static/static/js/{index.BRtyx04t.js → index.Dn76KVNf.js} +1 -1
- streamlit/static/static/js/{index.qMnAjj-G.js → index.DtqvdV-p.js} +1 -1
- streamlit/static/static/js/{index.BwlA1Cf_.js → index.ErkF0SoX.js} +1 -1
- streamlit/static/static/js/{index.QdRaJV_a.js → index.GSYBrzVp.js} +1 -1
- streamlit/static/static/js/{index.CSPC2m_c.js → index.OngWTN39.js} +1 -1
- streamlit/static/static/js/{index.CGzwdjEF.js → index.PSwG8ayC.js} +1 -1
- streamlit/static/static/js/{index.D_0HKLRm.js → index.UTlCdasa.js} +1 -1
- streamlit/static/static/js/{index.aBgCjIEX.js → index.eR_vQpeg.js} +1 -1
- streamlit/static/static/js/{index.BBClg-gm.js → index.fLsU9uCJ.js} +1 -1
- streamlit/static/static/js/{index.BDzCUpOG.js → index.hPjr68pz.js} +1 -1
- streamlit/static/static/js/{index.CgzjjllY.js → index.kXOZCC_6.js} +1 -1
- streamlit/static/static/js/{input.qNZgmgfK.js → input.DY17i94N.js} +1 -1
- streamlit/static/static/js/{memory.DifcSUze.js → memory.DsIIcbSd.js} +1 -1
- streamlit/static/static/js/{mergeWith.Bykfc0n-.js → mergeWith.cRgGdgvI.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.D_L9PQiU.js → number-overlay-editor.B8Xi2dYq.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.Cyeph4pU.js → possibleConstructorReturn.BgDi5nUm.js} +1 -1
- streamlit/static/static/js/{sandbox.DT6zcSKI.js → sandbox.BH9emp13.js} +1 -1
- streamlit/static/static/js/{textarea.C46FrViu.js → textarea.DAyShsGG.js} +1 -1
- streamlit/static/static/js/{timepicker.N6lFakQJ.js → timepicker.CCH2R2Y0.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.DwaNiLbv.js → toConsumableArray.CNffSDCu.js} +1 -1
- streamlit/static/static/js/{uniqueId.bNZuA9Mz.js → uniqueId.B49CstkV.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.qUuCVRZV.js → useBasicWidgetState.CkThOkF9.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.CylEhpc7.js → useOnInputChange.BqEq0xFZ.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.BQay_j7X.js → withFullScreenWrapper.UsvF_Jwr.js} +1 -1
- streamlit/web/bootstrap.py +3 -2
- streamlit/web/server/__init__.py +2 -2
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/RECORD +102 -102
- {streamlit_nightly-1.45.1.dev20250504.data → streamlit_nightly-1.45.1.dev20250505.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250505.dist-info}/top_level.txt +0 -0
streamlit/column_config.py
CHANGED
@@ -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
|
-
"
|
29
|
-
"ProgressColumn",
|
30
|
-
"LinkColumn",
|
27
|
+
"JsonColumn",
|
31
28
|
"LineChartColumn",
|
29
|
+
"LinkColumn",
|
32
30
|
"ListColumn",
|
33
|
-
"
|
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
|
-
|
94
|
-
|
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
|
|
streamlit/delta_generator.py
CHANGED
@@ -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()
|
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
|
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
|
streamlit/elements/alert.py
CHANGED
streamlit/elements/json.py
CHANGED
@@ -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 {
|
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 = {
|
79
|
-
|
80
|
-
|
81
|
-
|
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: {
|
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
|
-
|
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(
|
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"{
|
60
|
+
raise ValueError(f"{x} is not in iterable")
|
61
61
|
|
62
62
|
|
63
63
|
def check_and_convert_to_indices(
|
streamlit/elements/metric.py
CHANGED
@@ -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"'{
|
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"'{
|
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"'{
|
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"'{
|
266
|
+
f"'{delta_color}' is not an accepted value. delta_color only accepts: "
|
267
267
|
"'normal', 'inverse', or 'off'"
|
268
268
|
)
|
269
269
|
|
streamlit/elements/progress.py
CHANGED
@@ -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 {
|
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(
|
streamlit/proto/DateInput_pb2.py
CHANGED
@@ -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\"\
|
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=
|
27
|
-
_globals['_DATEINPUT']._serialized_end=
|
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
|
streamlit/proto/TimeInput_pb2.py
CHANGED
@@ -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\"\
|
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=
|
27
|
-
_globals['_TIMEINPUT']._serialized_end=
|
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
|
streamlit/runtime/__init__.py
CHANGED
@@ -86,13 +86,13 @@ cache = _cache
|
|
86
86
|
|
87
87
|
|
88
88
|
__all__ = [
|
89
|
-
"cache",
|
90
89
|
"CACHE_DOCS_URL",
|
91
|
-
"
|
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)}: {
|
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
|
|
streamlit/runtime/credentials.py
CHANGED
@@ -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 you
|
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
|
-
|
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
|
-
|
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
|
)
|
streamlit/runtime/secrets.py
CHANGED
@@ -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[
|
313
|
+
secrets[dirname] = sub_secrets[next(iter(sub_secrets.keys()))]
|
314
314
|
else:
|
315
315
|
secrets[dirname] = sub_secrets
|
316
316
|
|