streamlit-nightly 1.44.2.dev20250421__py3-none-any.whl → 1.44.2.dev20250423__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/commands/navigation.py +2 -1
- streamlit/components/types/base_custom_component.py +9 -0
- streamlit/components/v1/custom_component.py +21 -0
- streamlit/config.py +5 -1
- streamlit/elements/alert.py +67 -0
- streamlit/elements/exception.py +28 -3
- streamlit/elements/iframe.py +35 -0
- streamlit/elements/lib/layout_utils.py +51 -0
- streamlit/env_util.py +4 -4
- streamlit/errors.py +15 -0
- streamlit/proto/Alert_pb2.py +6 -5
- streamlit/proto/Alert_pb2.pyi +9 -1
- streamlit/proto/Components_pb2.py +10 -10
- streamlit/proto/Components_pb2.pyi +6 -1
- streamlit/proto/Exception_pb2.py +4 -3
- streamlit/proto/Exception_pb2.pyi +9 -1
- streamlit/proto/IFrame_pb2.py +3 -3
- streamlit/proto/IFrame_pb2.pyi +8 -2
- streamlit/proto/MetricsEvent_pb2.py +4 -4
- streamlit/proto/MetricsEvent_pb2.pyi +10 -1
- streamlit/proto/NewSession_pb2.py +2 -2
- streamlit/proto/NewSession_pb2.pyi +16 -1
- streamlit/proto/WidthConfig_pb2.py +27 -0
- streamlit/proto/WidthConfig_pb2.pyi +34 -0
- streamlit/runtime/app_session.py +6 -1
- streamlit/runtime/context.py +72 -4
- streamlit/runtime/context_util.py +49 -0
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.BRFl1bVT.js → ErrorOutline.esm.kwxUkJiQ.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.BlVcbv80.js → FileDownload.esm.B4NSS6Sl.js} +1 -1
- streamlit/static/static/js/{FileHelper.Cu8b3qYc.js → FileHelper.D70RJhDu.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.D0_ew-pr.js → FormClearHelper.C-xLj6rB.js} +1 -1
- streamlit/static/static/js/{Hooks.DskP_qUg.js → Hooks.BB7DtXCF.js} +1 -1
- streamlit/static/static/js/{InputInstructions.B57U_Pck.js → InputInstructions.CGY1oTmu.js} +1 -1
- streamlit/static/static/js/{ProgressBar.B5UexUoj.js → ProgressBar.BMrZcYD1.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.CCx_j2kS.js → RenderInPortalIfExists.C7BYLlpF.js} +1 -1
- streamlit/static/static/js/Toolbar.JI3o5o7J.js +1 -0
- streamlit/static/static/js/{base-input.vMZreRbs.js → base-input.ppk9zgs1.js} +1 -1
- streamlit/static/static/js/{checkbox.BvzLW9mz.js → checkbox.49raiX_Q.js} +1 -1
- streamlit/static/static/js/{createSuper.Bw1znQ_0.js → createSuper.87fVAqEV.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.D7LIqz-H.js → data-grid-overlay-editor.B1NKPOjN.js} +1 -1
- streamlit/static/static/js/{downloader.wxNZEkm4.js → downloader.BcfN0KsR.js} +1 -1
- streamlit/static/static/js/{es6.CUH1kXnl.js → es6.SM-d8IW7.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.D1Um7X41.js → iframeResizer.contentWindow.BiLXSNCc.js} +1 -1
- streamlit/static/static/js/{index.DiU_iAr0.js → index.-XsjpKIw.js} +1 -1
- streamlit/static/static/js/{index.DeTKJCBX.js → index.23z_CL39.js} +1 -1
- streamlit/static/static/js/{index.BJ6Emr34.js → index.B5QZmtKU.js} +1 -1
- streamlit/static/static/js/{index.EKcIoWDD.js → index.BHUccop_.js} +1 -1
- streamlit/static/static/js/{index.ClJO7cQG.js → index.BJXqcYGa.js} +119 -119
- streamlit/static/static/js/{index.CZUFT1MU.js → index.BK6Q5McP.js} +1 -1
- streamlit/static/static/js/{index.ByJVLduZ.js → index.BMHV-2Ba.js} +1 -1
- streamlit/static/static/js/index.BMkGp3A8.js +1 -0
- streamlit/static/static/js/{index.DocZB9LB.js → index.BWA7mhkD.js} +54 -54
- streamlit/static/static/js/{index.B-Cvaa60.js → index.BbUIsbcG.js} +1 -1
- streamlit/static/static/js/{index.B8eIzqFV.js → index.BlguKOUW.js} +1 -1
- streamlit/static/static/js/{index.BXIy_sno.js → index.BpwS_2vg.js} +1 -1
- streamlit/static/static/js/{index.DyMFPM-N.js → index.Bpzbt0XE.js} +1 -1
- streamlit/static/static/js/{index.B8aTojaJ.js → index.BtSh2qF2.js} +1 -1
- streamlit/static/static/js/{index.C6Ddq_0T.js → index.C555txyo.js} +1 -1
- streamlit/static/static/js/{index.8SbOAOpf.js → index.C5lCQ63O.js} +1 -1
- streamlit/static/static/js/{index.DbLDusYd.js → index.CCSljmFB.js} +1 -1
- streamlit/static/static/js/{index.DhCNOffY.js → index.CWgDSgiP.js} +1 -1
- streamlit/static/static/js/{index.CLIjAXFe.js → index.CgJwml-l.js} +1 -1
- streamlit/static/static/js/{index.DIVoc7sf.js → index.Chh_6WO_.js} +1 -1
- streamlit/static/static/js/{index.IKI2QU6M.js → index.CpYhueoB.js} +1 -1
- streamlit/static/static/js/{index.Dykp8DiM.js → index.Cs0BKVkf.js} +1 -1
- streamlit/static/static/js/{index.EqUN-1C8.js → index.Cu7GDmYZ.js} +1 -1
- streamlit/static/static/js/{index.J03z7hBk.js → index.CyYnsaI7.js} +1 -1
- streamlit/static/static/js/index.DKW03_hE.js +1 -0
- streamlit/static/static/js/{index.C0-tCzek.js → index.DOW8qES0.js} +1 -1
- streamlit/static/static/js/{index.C0kRoccm.js → index.DOfuaf_0.js} +1 -1
- streamlit/static/static/js/{index.D1Ywuv8r.js → index.DQ8pk-Cx.js} +1 -1
- streamlit/static/static/js/{index.CixhwxuT.js → index.D_eW5hqT.js} +1 -1
- streamlit/static/static/js/{index.Csw8C3i3.js → index.DdB-Sih0.js} +1 -1
- streamlit/static/static/js/{index.DcXPvVuL.js → index.DmyMOJie.js} +1 -1
- streamlit/static/static/js/{index.CR-jcBpI.js → index.DyvfAcMU.js} +1 -1
- streamlit/static/static/js/{index.CYrMenWX.js → index.Gze6P7P8.js} +1 -1
- streamlit/static/static/js/{index.CCgmQo2Y.js → index.esYPLQWk.js} +1 -1
- streamlit/static/static/js/{index._x_ll-5l.js → index.tXJ66r45.js} +1 -1
- streamlit/static/static/js/{index.BLmWFo9v.js → index.tz3no0C-.js} +1 -1
- streamlit/static/static/js/{index.DbSwoQrX.js → index.vUKKnPLN.js} +1 -1
- streamlit/static/static/js/{input.CfYPTrU0.js → input.B1adH3Tq.js} +1 -1
- streamlit/static/static/js/{memory.C6WsZ9vL.js → memory._j_IEh4p.js} +1 -1
- streamlit/static/static/js/{mergeWith.BEl-rFPc.js → mergeWith.CaxCG68D.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.Da6_ovQT.js → number-overlay-editor.CQ4il8-u.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.DrzRVntz.js → possibleConstructorReturn.BeSJyC-R.js} +1 -1
- streamlit/static/static/js/{sandbox.BDmQFJ29.js → sandbox.CJ8UEQ_8.js} +1 -1
- streamlit/static/static/js/{textarea.B1KRwam8.js → textarea.BoKsAt5U.js} +1 -1
- streamlit/static/static/js/{timepicker.CJQu2ZZT.js → timepicker.zqbF1i9c.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.c1K-jW6k.js → toConsumableArray.BlqVQ7Zt.js} +1 -1
- streamlit/static/static/js/{uniqueId.DQubPWuJ.js → uniqueId.CB2jSt-Y.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.Bnt7ikdj.js → useBasicWidgetState.CCJRj7uP.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.Dq_CVqBo.js → useOnInputChange.Cgjf7qmr.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.5xnZ4GI8.js → withFullScreenWrapper.B-OvwjED.js} +1 -1
- {streamlit_nightly-1.44.2.dev20250421.dist-info → streamlit_nightly-1.44.2.dev20250423.dist-info}/METADATA +2 -2
- {streamlit_nightly-1.44.2.dev20250421.dist-info → streamlit_nightly-1.44.2.dev20250423.dist-info}/RECORD +100 -96
- {streamlit_nightly-1.44.2.dev20250421.dist-info → streamlit_nightly-1.44.2.dev20250423.dist-info}/WHEEL +1 -1
- streamlit/static/static/js/Toolbar.D3gt1ynD.js +0 -1
- streamlit/static/static/js/index.B4uSRoDZ.js +0 -1
- streamlit/static/static/js/index.BUcUcSdx.js +0 -1
- {streamlit_nightly-1.44.2.dev20250421.data → streamlit_nightly-1.44.2.dev20250423.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.44.2.dev20250421.dist-info → streamlit_nightly-1.44.2.dev20250423.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.44.2.dev20250421.dist-info → streamlit_nightly-1.44.2.dev20250423.dist-info}/top_level.txt +0 -0
streamlit/commands/navigation.py
CHANGED
@@ -31,6 +31,7 @@ from streamlit.runtime.scriptrunner_utils.script_run_context import (
|
|
31
31
|
ScriptRunContext,
|
32
32
|
get_script_run_ctx,
|
33
33
|
)
|
34
|
+
from streamlit.string_util import is_emoji
|
34
35
|
|
35
36
|
if TYPE_CHECKING:
|
36
37
|
from streamlit.source_util import PageHash, PageInfo
|
@@ -349,7 +350,7 @@ def _navigation(
|
|
349
350
|
p = msg.navigation.app_pages.add()
|
350
351
|
p.page_script_hash = page._script_hash
|
351
352
|
p.page_name = page.title
|
352
|
-
p.icon = page.icon
|
353
|
+
p.icon = f"emoji:{page.icon}" if is_emoji(page.icon) else page.icon
|
353
354
|
p.is_default = page._default
|
354
355
|
p.section_header = section_header
|
355
356
|
p.url_pathname = page.url_path
|
@@ -60,6 +60,7 @@ class BaseCustomComponent(ABC):
|
|
60
60
|
default: Any = None,
|
61
61
|
key: str | None = None,
|
62
62
|
on_change: WidgetCallback | None = None,
|
63
|
+
tab_index: int | None = None,
|
63
64
|
**kwargs,
|
64
65
|
) -> Any:
|
65
66
|
"""An alias for create_instance."""
|
@@ -68,6 +69,7 @@ class BaseCustomComponent(ABC):
|
|
68
69
|
default=default,
|
69
70
|
key=key,
|
70
71
|
on_change=on_change,
|
72
|
+
tab_index=tab_index,
|
71
73
|
**kwargs,
|
72
74
|
)
|
73
75
|
|
@@ -113,6 +115,7 @@ class BaseCustomComponent(ABC):
|
|
113
115
|
default: Any = None,
|
114
116
|
key: str | None = None,
|
115
117
|
on_change: WidgetCallback | None = None,
|
118
|
+
tab_index: int | None = None,
|
116
119
|
**kwargs,
|
117
120
|
) -> Any:
|
118
121
|
"""Create a new instance of the component.
|
@@ -131,6 +134,12 @@ class BaseCustomComponent(ABC):
|
|
131
134
|
component's "widget ID".
|
132
135
|
on_change: WidgetCallback or None
|
133
136
|
An optional callback invoked when the widget's value changes. No arguments are passed to it.
|
137
|
+
tab_index: int or None
|
138
|
+
Specifies the tab order of the iframe containing the component.
|
139
|
+
Possible values are:
|
140
|
+
- ``None`` (default): Browser default behavior.
|
141
|
+
- ``-1``: Removes the iframe from the natural tab order, but it can still be focused programmatically.
|
142
|
+
- ``0`` or positive integer: Includes the iframe in the natural tab order.
|
134
143
|
**kwargs
|
135
144
|
Keyword args to pass to the component.
|
136
145
|
|
@@ -52,6 +52,7 @@ class CustomComponent(BaseCustomComponent):
|
|
52
52
|
default: Any = None,
|
53
53
|
key: str | None = None,
|
54
54
|
on_change: WidgetCallback | None = None,
|
55
|
+
tab_index: int | None = None,
|
55
56
|
**kwargs,
|
56
57
|
) -> Any:
|
57
58
|
"""An alias for create_instance."""
|
@@ -60,6 +61,7 @@ class CustomComponent(BaseCustomComponent):
|
|
60
61
|
default=default,
|
61
62
|
key=key,
|
62
63
|
on_change=on_change,
|
64
|
+
tab_index=tab_index,
|
63
65
|
**kwargs,
|
64
66
|
)
|
65
67
|
|
@@ -70,6 +72,7 @@ class CustomComponent(BaseCustomComponent):
|
|
70
72
|
default: Any = None,
|
71
73
|
key: str | None = None,
|
72
74
|
on_change: WidgetCallback | None = None,
|
75
|
+
tab_index: int | None = None,
|
73
76
|
**kwargs,
|
74
77
|
) -> Any:
|
75
78
|
"""Create a new instance of the component.
|
@@ -88,6 +91,12 @@ class CustomComponent(BaseCustomComponent):
|
|
88
91
|
component's "widget ID".
|
89
92
|
on_change: WidgetCallback or None
|
90
93
|
An optional callback invoked when the widget's value changes. No arguments are passed to it.
|
94
|
+
tab_index : int, optional
|
95
|
+
Specifies the tab order of the iframe containing the component.
|
96
|
+
Possible values are:
|
97
|
+
- ``None`` (default): Browser default behavior.
|
98
|
+
- ``-1``: Removes the iframe from the natural tab order, but it can still be focused programmatically.
|
99
|
+
- ``0`` or positive integer: Includes the iframe in the natural tab order.
|
91
100
|
**kwargs
|
92
101
|
Keyword args to pass to the component.
|
93
102
|
|
@@ -100,6 +109,16 @@ class CustomComponent(BaseCustomComponent):
|
|
100
109
|
if len(args) > 0:
|
101
110
|
raise MarshallComponentException(f"Argument '{args[0]}' needs a label")
|
102
111
|
|
112
|
+
# Validate tab_index according to web specifications
|
113
|
+
if tab_index is not None and not (
|
114
|
+
isinstance(tab_index, int)
|
115
|
+
and not isinstance(tab_index, bool)
|
116
|
+
and tab_index >= -1
|
117
|
+
):
|
118
|
+
raise StreamlitAPIException(
|
119
|
+
"tab_index must be None, -1, or a non-negative integer."
|
120
|
+
)
|
121
|
+
|
103
122
|
try:
|
104
123
|
import pyarrow # noqa: F401, ICN001
|
105
124
|
|
@@ -148,6 +167,8 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
|
|
148
167
|
element.component_instance.form_id = current_form_id(dg)
|
149
168
|
if self.url is not None:
|
150
169
|
element.component_instance.url = self.url
|
170
|
+
if tab_index is not None:
|
171
|
+
element.component_instance.tab_index = tab_index
|
151
172
|
|
152
173
|
# Normally, a widget's element_hash (which determines
|
153
174
|
# its identity across multiple runs of an app) is computed
|
streamlit/config.py
CHANGED
@@ -711,7 +711,11 @@ def _server_headless() -> bool:
|
|
711
711
|
Default: false unless (1) we are on a Linux box where DISPLAY is unset, or
|
712
712
|
(2) we are running in the Streamlit Atom plugin.
|
713
713
|
"""
|
714
|
-
if
|
714
|
+
if (
|
715
|
+
env_util.IS_LINUX_OR_BSD
|
716
|
+
and not os.getenv("DISPLAY")
|
717
|
+
and not os.getenv("WAYLAND_DISPLAY")
|
718
|
+
):
|
715
719
|
# We're running in Linux and DISPLAY is unset
|
716
720
|
return True
|
717
721
|
|
streamlit/elements/alert.py
CHANGED
@@ -16,12 +16,15 @@ from __future__ import annotations
|
|
16
16
|
|
17
17
|
from typing import TYPE_CHECKING, cast
|
18
18
|
|
19
|
+
from streamlit.elements.lib.layout_utils import validate_width
|
19
20
|
from streamlit.proto.Alert_pb2 import Alert as AlertProto
|
21
|
+
from streamlit.proto.WidthConfig_pb2 import WidthConfig
|
20
22
|
from streamlit.runtime.metrics_util import gather_metrics
|
21
23
|
from streamlit.string_util import clean_text, validate_icon_or_emoji
|
22
24
|
|
23
25
|
if TYPE_CHECKING:
|
24
26
|
from streamlit.delta_generator import DeltaGenerator
|
27
|
+
from streamlit.elements.lib.layout_utils import WidthWithoutContent
|
25
28
|
from streamlit.type_util import SupportsStr
|
26
29
|
|
27
30
|
|
@@ -32,6 +35,7 @@ class AlertMixin:
|
|
32
35
|
body: SupportsStr,
|
33
36
|
*, # keyword-only args:
|
34
37
|
icon: str | None = None,
|
38
|
+
width: WidthWithoutContent = "stretch",
|
35
39
|
) -> DeltaGenerator:
|
36
40
|
"""Display error message.
|
37
41
|
|
@@ -62,6 +66,9 @@ class AlertMixin:
|
|
62
66
|
Thumb Up icon. Find additional icons in the `Material Symbols \
|
63
67
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
64
68
|
font library.
|
69
|
+
width : int or "stretch"
|
70
|
+
The width of the alert. Can be either an integer (pixels) or "stretch".
|
71
|
+
Defaults to "stretch".
|
65
72
|
|
66
73
|
Example
|
67
74
|
-------
|
@@ -75,6 +82,18 @@ class AlertMixin:
|
|
75
82
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
76
83
|
alert_proto.body = clean_text(body)
|
77
84
|
alert_proto.format = AlertProto.ERROR
|
85
|
+
|
86
|
+
validate_width(width)
|
87
|
+
|
88
|
+
width_config = WidthConfig()
|
89
|
+
|
90
|
+
if isinstance(width, int):
|
91
|
+
width_config.pixel_width = width
|
92
|
+
else:
|
93
|
+
width_config.use_stretch = True
|
94
|
+
|
95
|
+
alert_proto.width_config.CopyFrom(width_config)
|
96
|
+
|
78
97
|
return self.dg._enqueue("alert", alert_proto)
|
79
98
|
|
80
99
|
@gather_metrics("warning")
|
@@ -83,6 +102,7 @@ class AlertMixin:
|
|
83
102
|
body: SupportsStr,
|
84
103
|
*, # keyword-only args:
|
85
104
|
icon: str | None = None,
|
105
|
+
width: WidthWithoutContent = "stretch",
|
86
106
|
) -> DeltaGenerator:
|
87
107
|
"""Display warning message.
|
88
108
|
|
@@ -113,6 +133,9 @@ class AlertMixin:
|
|
113
133
|
Thumb Up icon. Find additional icons in the `Material Symbols \
|
114
134
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
115
135
|
font library.
|
136
|
+
width : int or "stretch"
|
137
|
+
The width of the alert. Can be either an integer (pixels) or "stretch".
|
138
|
+
Defaults to "stretch".
|
116
139
|
|
117
140
|
Example
|
118
141
|
-------
|
@@ -125,6 +148,18 @@ class AlertMixin:
|
|
125
148
|
alert_proto.body = clean_text(body)
|
126
149
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
127
150
|
alert_proto.format = AlertProto.WARNING
|
151
|
+
|
152
|
+
validate_width(width)
|
153
|
+
|
154
|
+
width_config = WidthConfig()
|
155
|
+
|
156
|
+
if isinstance(width, int):
|
157
|
+
width_config.pixel_width = width
|
158
|
+
else:
|
159
|
+
width_config.use_stretch = True
|
160
|
+
|
161
|
+
alert_proto.width_config.CopyFrom(width_config)
|
162
|
+
|
128
163
|
return self.dg._enqueue("alert", alert_proto)
|
129
164
|
|
130
165
|
@gather_metrics("info")
|
@@ -133,6 +168,7 @@ class AlertMixin:
|
|
133
168
|
body: SupportsStr,
|
134
169
|
*, # keyword-only args:
|
135
170
|
icon: str | None = None,
|
171
|
+
width: WidthWithoutContent = "stretch",
|
136
172
|
) -> DeltaGenerator:
|
137
173
|
"""Display an informational message.
|
138
174
|
|
@@ -163,6 +199,9 @@ class AlertMixin:
|
|
163
199
|
Thumb Up icon. Find additional icons in the `Material Symbols \
|
164
200
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
165
201
|
font library.
|
202
|
+
width : int or "stretch"
|
203
|
+
The width of the alert. Can be either an integer (pixels) or "stretch".
|
204
|
+
Defaults to "stretch".
|
166
205
|
|
167
206
|
Example
|
168
207
|
-------
|
@@ -176,6 +215,18 @@ class AlertMixin:
|
|
176
215
|
alert_proto.body = clean_text(body)
|
177
216
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
178
217
|
alert_proto.format = AlertProto.INFO
|
218
|
+
|
219
|
+
validate_width(width)
|
220
|
+
|
221
|
+
width_config = WidthConfig()
|
222
|
+
|
223
|
+
if isinstance(width, int):
|
224
|
+
width_config.pixel_width = width
|
225
|
+
else:
|
226
|
+
width_config.use_stretch = True
|
227
|
+
|
228
|
+
alert_proto.width_config.CopyFrom(width_config)
|
229
|
+
|
179
230
|
return self.dg._enqueue("alert", alert_proto)
|
180
231
|
|
181
232
|
@gather_metrics("success")
|
@@ -184,6 +235,7 @@ class AlertMixin:
|
|
184
235
|
body: SupportsStr,
|
185
236
|
*, # keyword-only args:
|
186
237
|
icon: str | None = None,
|
238
|
+
width: WidthWithoutContent = "stretch",
|
187
239
|
) -> DeltaGenerator:
|
188
240
|
"""Display a success message.
|
189
241
|
|
@@ -214,6 +266,9 @@ class AlertMixin:
|
|
214
266
|
Thumb Up icon. Find additional icons in the `Material Symbols \
|
215
267
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
216
268
|
font library.
|
269
|
+
width : int or "stretch"
|
270
|
+
The width of the alert. Can be either an integer (pixels) or "stretch".
|
271
|
+
Defaults to "stretch".
|
217
272
|
|
218
273
|
Example
|
219
274
|
-------
|
@@ -226,6 +281,18 @@ class AlertMixin:
|
|
226
281
|
alert_proto.body = clean_text(body)
|
227
282
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
228
283
|
alert_proto.format = AlertProto.SUCCESS
|
284
|
+
|
285
|
+
validate_width(width)
|
286
|
+
|
287
|
+
width_config = WidthConfig()
|
288
|
+
|
289
|
+
if isinstance(width, int):
|
290
|
+
width_config.pixel_width = width
|
291
|
+
else:
|
292
|
+
width_config.use_stretch = True
|
293
|
+
|
294
|
+
alert_proto.width_config.CopyFrom(width_config)
|
295
|
+
|
229
296
|
return self.dg._enqueue("alert", alert_proto)
|
230
297
|
|
231
298
|
@property
|
streamlit/elements/exception.py
CHANGED
@@ -19,17 +19,20 @@ import traceback
|
|
19
19
|
from typing import TYPE_CHECKING, Callable, Final, TypeVar, cast
|
20
20
|
|
21
21
|
from streamlit import config
|
22
|
+
from streamlit.elements.lib.layout_utils import validate_width
|
22
23
|
from streamlit.errors import (
|
23
24
|
MarkdownFormattedException,
|
24
25
|
StreamlitAPIWarning,
|
25
26
|
)
|
26
27
|
from streamlit.logger import get_logger
|
27
28
|
from streamlit.proto.Exception_pb2 import Exception as ExceptionProto
|
29
|
+
from streamlit.proto.WidthConfig_pb2 import WidthConfig
|
28
30
|
from streamlit.runtime.metrics_util import gather_metrics
|
29
31
|
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
30
32
|
|
31
33
|
if TYPE_CHECKING:
|
32
34
|
from streamlit.delta_generator import DeltaGenerator
|
35
|
+
from streamlit.elements.lib.layout_utils import WidthWithoutContent
|
33
36
|
|
34
37
|
_LOGGER: Final = get_logger(__name__)
|
35
38
|
|
@@ -40,7 +43,9 @@ _GENERIC_UNCAUGHT_EXCEPTION_TEXT: Final = "This app has encountered an error. Th
|
|
40
43
|
|
41
44
|
class ExceptionMixin:
|
42
45
|
@gather_metrics("exception")
|
43
|
-
def exception(
|
46
|
+
def exception(
|
47
|
+
self, exception: BaseException, width: WidthWithoutContent = "stretch"
|
48
|
+
) -> DeltaGenerator:
|
44
49
|
"""Display an exception.
|
45
50
|
|
46
51
|
In the lower-right corner of the exception, Streamlit displays links to
|
@@ -51,6 +56,9 @@ class ExceptionMixin:
|
|
51
56
|
----------
|
52
57
|
exception : Exception
|
53
58
|
The exception to display.
|
59
|
+
width : int or "stretch"
|
60
|
+
The width of the exception display. Can be either an integer (pixels) or "stretch".
|
61
|
+
Defaults to "stretch".
|
54
62
|
|
55
63
|
Example
|
56
64
|
-------
|
@@ -64,7 +72,7 @@ class ExceptionMixin:
|
|
64
72
|
height: 220px
|
65
73
|
|
66
74
|
"""
|
67
|
-
return _exception(self.dg, exception)
|
75
|
+
return _exception(self.dg, exception, width=width)
|
68
76
|
|
69
77
|
@property
|
70
78
|
def dg(self) -> DeltaGenerator:
|
@@ -77,16 +85,18 @@ class ExceptionMixin:
|
|
77
85
|
def _exception(
|
78
86
|
dg: DeltaGenerator,
|
79
87
|
exception: BaseException,
|
88
|
+
width: WidthWithoutContent = "stretch",
|
80
89
|
is_uncaught_app_exception: bool = False,
|
81
90
|
) -> DeltaGenerator:
|
82
91
|
exception_proto = ExceptionProto()
|
83
|
-
marshall(exception_proto, exception, is_uncaught_app_exception)
|
92
|
+
marshall(exception_proto, exception, width, is_uncaught_app_exception)
|
84
93
|
return dg._enqueue("exception", exception_proto)
|
85
94
|
|
86
95
|
|
87
96
|
def marshall(
|
88
97
|
exception_proto: ExceptionProto,
|
89
98
|
exception: BaseException,
|
99
|
+
width: WidthWithoutContent = "stretch",
|
90
100
|
is_uncaught_app_exception: bool = False,
|
91
101
|
) -> None:
|
92
102
|
"""Marshalls an Exception.proto message.
|
@@ -99,9 +109,15 @@ def marshall(
|
|
99
109
|
exception : BaseException
|
100
110
|
The exception whose data we're extracting.
|
101
111
|
|
112
|
+
width : int or "stretch"
|
113
|
+
The width of the exception display. Can be either an integer (pixels) or "stretch".
|
114
|
+
Defaults to "stretch".
|
115
|
+
|
102
116
|
is_uncaught_app_exception: bool
|
103
117
|
The exception originates from an uncaught error during script execution.
|
104
118
|
"""
|
119
|
+
validate_width(width)
|
120
|
+
|
105
121
|
is_markdown_exception = isinstance(exception, MarkdownFormattedException)
|
106
122
|
|
107
123
|
# Some exceptions (like UserHashError) have an alternate_name attribute so
|
@@ -116,6 +132,15 @@ def marshall(
|
|
116
132
|
exception_proto.stack_trace.extend(stack_trace)
|
117
133
|
exception_proto.is_warning = isinstance(exception, Warning)
|
118
134
|
|
135
|
+
width_config = WidthConfig()
|
136
|
+
|
137
|
+
if isinstance(width, int):
|
138
|
+
width_config.pixel_width = width
|
139
|
+
else:
|
140
|
+
width_config.use_stretch = True
|
141
|
+
|
142
|
+
exception_proto.width_config.CopyFrom(width_config)
|
143
|
+
|
119
144
|
try:
|
120
145
|
if isinstance(exception, SyntaxError):
|
121
146
|
# SyntaxErrors have additional fields (filename, text, lineno,
|
streamlit/elements/iframe.py
CHANGED
@@ -16,6 +16,7 @@ from __future__ import annotations
|
|
16
16
|
|
17
17
|
from typing import TYPE_CHECKING, cast
|
18
18
|
|
19
|
+
from streamlit.errors import StreamlitAPIException
|
19
20
|
from streamlit.proto.IFrame_pb2 import IFrame as IFrameProto
|
20
21
|
from streamlit.runtime.metrics_util import gather_metrics
|
21
22
|
|
@@ -31,6 +32,8 @@ class IframeMixin:
|
|
31
32
|
width: int | None = None,
|
32
33
|
height: int | None = None,
|
33
34
|
scrolling: bool = False,
|
35
|
+
*,
|
36
|
+
tab_index: int | None = None,
|
34
37
|
) -> DeltaGenerator:
|
35
38
|
"""Load a remote URL in an iframe.
|
36
39
|
|
@@ -59,6 +62,12 @@ class IframeMixin:
|
|
59
62
|
does not show a scrollbar. If this is ``True``, Streamlit shows a
|
60
63
|
scrollbar when the content is larger than the iframe.
|
61
64
|
|
65
|
+
tab_index : int, optional
|
66
|
+
Specifies the tab order of the iframe. Possible values are:
|
67
|
+
- ``None`` (default): Browser default behavior.
|
68
|
+
- ``-1``: Removes the iframe from the natural tab order, but it can still be focused programmatically.
|
69
|
+
- ``0`` or positive integer: Includes the iframe in the natural tab order.
|
70
|
+
|
62
71
|
Example
|
63
72
|
-------
|
64
73
|
|
@@ -74,6 +83,7 @@ class IframeMixin:
|
|
74
83
|
width=width,
|
75
84
|
height=height,
|
76
85
|
scrolling=scrolling,
|
86
|
+
tab_index=tab_index,
|
77
87
|
)
|
78
88
|
return self.dg._enqueue("iframe", iframe_proto)
|
79
89
|
|
@@ -84,6 +94,8 @@ class IframeMixin:
|
|
84
94
|
width: int | None = None,
|
85
95
|
height: int | None = None,
|
86
96
|
scrolling: bool = False,
|
97
|
+
*,
|
98
|
+
tab_index: int | None = None,
|
87
99
|
) -> DeltaGenerator:
|
88
100
|
"""Display an HTML string in an iframe.
|
89
101
|
|
@@ -115,6 +127,12 @@ class IframeMixin:
|
|
115
127
|
does not show a scrollbar. If this is ``True``, Streamlit shows a
|
116
128
|
scrollbar when the content is larger than the iframe.
|
117
129
|
|
130
|
+
tab_index : int, optional
|
131
|
+
Specifies the tab order of the iframe. Possible values are:
|
132
|
+
- ``None`` (default): Browser default behavior.
|
133
|
+
- ``-1``: Removes the iframe from the natural tab order, but it can still be focused programmatically.
|
134
|
+
- ``0`` or positive integer: Includes the iframe in the natural tab order.
|
135
|
+
|
118
136
|
Example
|
119
137
|
-------
|
120
138
|
|
@@ -132,6 +150,7 @@ class IframeMixin:
|
|
132
150
|
width=width,
|
133
151
|
height=height,
|
134
152
|
scrolling=scrolling,
|
153
|
+
tab_index=tab_index,
|
135
154
|
)
|
136
155
|
return self.dg._enqueue("iframe", iframe_proto)
|
137
156
|
|
@@ -148,6 +167,7 @@ def marshall(
|
|
148
167
|
width: int | None = None,
|
149
168
|
height: int | None = None,
|
150
169
|
scrolling: bool = False,
|
170
|
+
tab_index: int | None = None,
|
151
171
|
) -> None:
|
152
172
|
"""Marshalls data into an IFrame proto.
|
153
173
|
|
@@ -171,6 +191,8 @@ def marshall(
|
|
171
191
|
scrolling : bool
|
172
192
|
If true, show a scrollbar when the content is larger than the iframe.
|
173
193
|
Otherwise, never show a scrollbar.
|
194
|
+
tab_index : int, optional
|
195
|
+
Specifies the tab order of the iframe.
|
174
196
|
|
175
197
|
"""
|
176
198
|
if src is not None:
|
@@ -189,3 +211,16 @@ def marshall(
|
|
189
211
|
proto.height = 150
|
190
212
|
|
191
213
|
proto.scrolling = scrolling
|
214
|
+
|
215
|
+
if tab_index is not None:
|
216
|
+
# Validate tab_index according to web specifications
|
217
|
+
if not (
|
218
|
+
isinstance(tab_index, int)
|
219
|
+
and not isinstance(tab_index, bool)
|
220
|
+
and tab_index >= -1
|
221
|
+
):
|
222
|
+
raise StreamlitAPIException(
|
223
|
+
"tab_index must be None, -1, or a non-negative integer."
|
224
|
+
)
|
225
|
+
|
226
|
+
proto.tab_index = tab_index
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from typing import Literal, Union
|
16
|
+
|
17
|
+
from typing_extensions import TypeAlias
|
18
|
+
|
19
|
+
from streamlit.errors import StreamlitInvalidWidthError
|
20
|
+
|
21
|
+
WidthWithoutContent: TypeAlias = Union[int, Literal["stretch"]]
|
22
|
+
Width: TypeAlias = Union[int, Literal["stretch", "content"]]
|
23
|
+
|
24
|
+
|
25
|
+
def validate_width(width: Width, allow_content: bool = False) -> None:
|
26
|
+
"""Validate the width parameter.
|
27
|
+
|
28
|
+
Parameters
|
29
|
+
----------
|
30
|
+
width : Any
|
31
|
+
The width value to validate.
|
32
|
+
allow_content : bool
|
33
|
+
Whether to allow "content" as a valid width value.
|
34
|
+
|
35
|
+
Raises
|
36
|
+
------
|
37
|
+
StreamlitInvalidWidthError
|
38
|
+
If the width value is invalid.
|
39
|
+
"""
|
40
|
+
if not isinstance(width, (int, str)):
|
41
|
+
raise StreamlitInvalidWidthError(width, allow_content)
|
42
|
+
|
43
|
+
if isinstance(width, str):
|
44
|
+
valid_strings = ["stretch"]
|
45
|
+
if allow_content:
|
46
|
+
valid_strings.append("content")
|
47
|
+
|
48
|
+
if width not in valid_strings:
|
49
|
+
raise StreamlitInvalidWidthError(width, allow_content)
|
50
|
+
elif width <= 0:
|
51
|
+
raise StreamlitInvalidWidthError(width, allow_content)
|
streamlit/env_util.py
CHANGED
@@ -19,10 +19,10 @@ import platform
|
|
19
19
|
import re
|
20
20
|
import sys
|
21
21
|
|
22
|
-
|
23
|
-
IS_WINDOWS =
|
24
|
-
IS_DARWIN =
|
25
|
-
IS_LINUX_OR_BSD = (
|
22
|
+
SYSTEM = platform.system().lower()
|
23
|
+
IS_WINDOWS = SYSTEM == "windows"
|
24
|
+
IS_DARWIN = SYSTEM == "darwin"
|
25
|
+
IS_LINUX_OR_BSD = (SYSTEM == "linux") or ("bsd" in SYSTEM)
|
26
26
|
|
27
27
|
|
28
28
|
def is_pex() -> bool:
|
streamlit/errors.py
CHANGED
@@ -459,3 +459,18 @@ class StreamlitSecretNotFoundError(LocalizableStreamlitException, FileNotFoundEr
|
|
459
459
|
|
460
460
|
def __init__(self, message: str):
|
461
461
|
super().__init__(message)
|
462
|
+
|
463
|
+
|
464
|
+
class StreamlitInvalidWidthError(LocalizableStreamlitException):
|
465
|
+
"""Exception raised when an invalid width value is provided."""
|
466
|
+
|
467
|
+
def __init__(self, width: Any, allow_content: bool = False):
|
468
|
+
valid_values = "an integer (pixels) or 'stretch'"
|
469
|
+
if allow_content:
|
470
|
+
valid_values = "an integer (pixels), 'stretch', or 'content'"
|
471
|
+
|
472
|
+
super().__init__(
|
473
|
+
"Invalid width value: {width}. Width must be either {valid_values}.",
|
474
|
+
width=repr(width),
|
475
|
+
valid_values=valid_values,
|
476
|
+
)
|
streamlit/proto/Alert_pb2.py
CHANGED
@@ -12,9 +12,10 @@ from google.protobuf.internal import builder as _builder
|
|
12
12
|
_sym_db = _symbol_database.Default()
|
13
13
|
|
14
14
|
|
15
|
+
from streamlit.proto import WidthConfig_pb2 as streamlit_dot_proto_dot_WidthConfig__pb2
|
15
16
|
|
16
17
|
|
17
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bstreamlit/proto/Alert.proto\"\
|
18
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bstreamlit/proto/Alert.proto\x1a!streamlit/proto/WidthConfig.proto\"\xb5\x01\n\x05\x41lert\x12\x0c\n\x04\x62ody\x18\x01 \x01(\t\x12\x1d\n\x06\x66ormat\x18\x02 \x01(\x0e\x32\r.Alert.Format\x12\x0c\n\x04icon\x18\x03 \x01(\t\x12,\n\x0cwidth_config\x18\x04 \x01(\x0b\x32\x16.streamlit.WidthConfig\"C\n\x06\x46ormat\x12\n\n\x06UNUSED\x10\x00\x12\t\n\x05\x45RROR\x10\x01\x12\x0b\n\x07WARNING\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\x0b\n\x07SUCCESS\x10\x04\x42*\n\x1c\x63om.snowflake.apps.streamlitB\nAlertProtob\x06proto3')
|
18
19
|
|
19
20
|
_globals = globals()
|
20
21
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
@@ -22,8 +23,8 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'streamlit.proto.Alert_pb2',
|
|
22
23
|
if not _descriptor._USE_C_DESCRIPTORS:
|
23
24
|
_globals['DESCRIPTOR']._loaded_options = None
|
24
25
|
_globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\nAlertProto'
|
25
|
-
_globals['_ALERT']._serialized_start=
|
26
|
-
_globals['_ALERT']._serialized_end=
|
27
|
-
_globals['_ALERT_FORMAT']._serialized_start=
|
28
|
-
_globals['_ALERT_FORMAT']._serialized_end=
|
26
|
+
_globals['_ALERT']._serialized_start=67
|
27
|
+
_globals['_ALERT']._serialized_end=248
|
28
|
+
_globals['_ALERT_FORMAT']._serialized_start=181
|
29
|
+
_globals['_ALERT_FORMAT']._serialized_end=248
|
29
30
|
# @@protoc_insertion_point(module_scope)
|
streamlit/proto/Alert_pb2.pyi
CHANGED
@@ -21,6 +21,7 @@ import builtins
|
|
21
21
|
import google.protobuf.descriptor
|
22
22
|
import google.protobuf.internal.enum_type_wrapper
|
23
23
|
import google.protobuf.message
|
24
|
+
import streamlit.proto.WidthConfig_pb2
|
24
25
|
import sys
|
25
26
|
import typing
|
26
27
|
|
@@ -74,17 +75,24 @@ class Alert(google.protobuf.message.Message):
|
|
74
75
|
BODY_FIELD_NUMBER: builtins.int
|
75
76
|
FORMAT_FIELD_NUMBER: builtins.int
|
76
77
|
ICON_FIELD_NUMBER: builtins.int
|
78
|
+
WIDTH_CONFIG_FIELD_NUMBER: builtins.int
|
77
79
|
body: builtins.str
|
78
80
|
"""Content to display."""
|
79
81
|
format: global___Alert.Format.ValueType
|
80
82
|
icon: builtins.str
|
83
|
+
@property
|
84
|
+
def width_config(self) -> streamlit.proto.WidthConfig_pb2.WidthConfig:
|
85
|
+
"""Indicates the width setting: "stetch", "content" or a pixel value."""
|
86
|
+
|
81
87
|
def __init__(
|
82
88
|
self,
|
83
89
|
*,
|
84
90
|
body: builtins.str = ...,
|
85
91
|
format: global___Alert.Format.ValueType = ...,
|
86
92
|
icon: builtins.str = ...,
|
93
|
+
width_config: streamlit.proto.WidthConfig_pb2.WidthConfig | None = ...,
|
87
94
|
) -> None: ...
|
88
|
-
def
|
95
|
+
def HasField(self, field_name: typing.Literal["width_config", b"width_config"]) -> builtins.bool: ...
|
96
|
+
def ClearField(self, field_name: typing.Literal["body", b"body", "format", b"format", "icon", b"icon", "width_config", b"width_config"]) -> None: ...
|
89
97
|
|
90
98
|
global___Alert = Alert
|
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
|
|
14
14
|
|
15
15
|
|
16
16
|
|
17
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n streamlit/proto/Components.proto\"\
|
17
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n streamlit/proto/Components.proto\"\xb1\x01\n\x11\x43omponentInstance\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tjson_args\x18\x02 \x01(\t\x12!\n\x0cspecial_args\x18\x03 \x03(\x0b\x32\x0b.SpecialArg\x12\x16\n\x0e\x63omponent_name\x18\x04 \x01(\t\x12\x0b\n\x03url\x18\x05 \x01(\t\x12\x0f\n\x07\x66orm_id\x18\x06 \x01(\t\x12\x16\n\ttab_index\x18\x07 \x01(\x05H\x00\x88\x01\x01\x42\x0c\n\n_tab_index\"_\n\nSpecialArg\x12\x0b\n\x03key\x18\x01 \x01(\t\x12*\n\x0f\x61rrow_dataframe\x18\x02 \x01(\x0b\x32\x0f.ArrowDataframeH\x00\x12\x0f\n\x05\x62ytes\x18\x03 \x01(\x0cH\x00\x42\x07\n\x05value\"J\n\x0e\x41rrowDataframe\x12\x19\n\x04\x64\x61ta\x18\x01 \x01(\x0b\x32\x0b.ArrowTable\x12\x0e\n\x06height\x18\x02 \x01(\r\x12\r\n\x05width\x18\x03 \x01(\r\"]\n\nArrowTable\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\r\n\x05index\x18\x02 \x01(\x0c\x12\x0f\n\x07\x63olumns\x18\x03 \x01(\x0c\x12!\n\x06styler\x18\x05 \x01(\x0b\x32\x11.ArrowTableStyler\"Y\n\x10\x41rrowTableStyler\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0f\n\x07\x63\x61ption\x18\x02 \x01(\t\x12\x0e\n\x06styles\x18\x03 \x01(\t\x12\x16\n\x0e\x64isplay_values\x18\x04 \x01(\x0c\x42/\n\x1c\x63om.snowflake.apps.streamlitB\x0f\x43omponentsProtob\x06proto3')
|
18
18
|
|
19
19
|
_globals = globals()
|
20
20
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
@@ -23,13 +23,13 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
23
23
|
_globals['DESCRIPTOR']._loaded_options = None
|
24
24
|
_globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\017ComponentsProto'
|
25
25
|
_globals['_COMPONENTINSTANCE']._serialized_start=37
|
26
|
-
_globals['_COMPONENTINSTANCE']._serialized_end=
|
27
|
-
_globals['_SPECIALARG']._serialized_start=
|
28
|
-
_globals['_SPECIALARG']._serialized_end=
|
29
|
-
_globals['_ARROWDATAFRAME']._serialized_start=
|
30
|
-
_globals['_ARROWDATAFRAME']._serialized_end=
|
31
|
-
_globals['_ARROWTABLE']._serialized_start=
|
32
|
-
_globals['_ARROWTABLE']._serialized_end=
|
33
|
-
_globals['_ARROWTABLESTYLER']._serialized_start=
|
34
|
-
_globals['_ARROWTABLESTYLER']._serialized_end=
|
26
|
+
_globals['_COMPONENTINSTANCE']._serialized_end=214
|
27
|
+
_globals['_SPECIALARG']._serialized_start=216
|
28
|
+
_globals['_SPECIALARG']._serialized_end=311
|
29
|
+
_globals['_ARROWDATAFRAME']._serialized_start=313
|
30
|
+
_globals['_ARROWDATAFRAME']._serialized_end=387
|
31
|
+
_globals['_ARROWTABLE']._serialized_start=389
|
32
|
+
_globals['_ARROWTABLE']._serialized_end=482
|
33
|
+
_globals['_ARROWTABLESTYLER']._serialized_start=484
|
34
|
+
_globals['_ARROWTABLESTYLER']._serialized_end=573
|
35
35
|
# @@protoc_insertion_point(module_scope)
|