streamlit 1.44.1__py3-none-any.whl → 1.45.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/__init__.py +5 -2
- streamlit/commands/execution_control.py +4 -0
- 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 +45 -47
- streamlit/config_util.py +1 -1
- streamlit/delta_generator.py +5 -1
- streamlit/deprecation_util.py +3 -3
- streamlit/elements/alert.py +83 -0
- streamlit/elements/exception.py +35 -6
- streamlit/elements/html.py +58 -6
- streamlit/elements/iframe.py +65 -0
- streamlit/elements/lib/built_in_chart_utils.py +47 -36
- streamlit/elements/lib/dicttools.py +2 -4
- streamlit/elements/lib/event_utils.py +7 -5
- streamlit/elements/lib/file_uploader_utils.py +3 -2
- streamlit/elements/lib/layout_utils.py +51 -0
- streamlit/elements/lib/options_selector_utils.py +26 -5
- streamlit/elements/lib/policies.py +1 -1
- streamlit/elements/markdown.py +1 -2
- streamlit/elements/toast.py +1 -1
- streamlit/elements/vega_charts.py +1 -1
- streamlit/elements/widgets/audio_input.py +0 -42
- streamlit/elements/widgets/button_group.py +42 -11
- streamlit/elements/widgets/chat.py +1 -1
- streamlit/elements/widgets/multiselect.py +211 -31
- streamlit/elements/widgets/number_input.py +31 -5
- streamlit/elements/widgets/selectbox.py +225 -42
- streamlit/elements/widgets/text_widgets.py +29 -4
- streamlit/elements/widgets/time_widgets.py +3 -2
- streamlit/elements/write.py +14 -4
- streamlit/env_util.py +4 -4
- streamlit/errors.py +15 -0
- streamlit/logger.py +1 -1
- streamlit/material_icon_names.py +1 -1
- streamlit/net_util.py +2 -2
- streamlit/proto/Alert_pb2.py +6 -5
- streamlit/proto/Alert_pb2.pyi +9 -1
- streamlit/proto/ClientState_pb2.py +4 -4
- streamlit/proto/ClientState_pb2.pyi +23 -3
- 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/ForwardMsg_pb2.pyi +4 -7
- 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 +23 -11
- streamlit/proto/MultiSelect_pb2.py +4 -2
- streamlit/proto/MultiSelect_pb2.pyi +14 -2
- streamlit/proto/NewSession_pb2.py +4 -4
- streamlit/proto/NewSession_pb2.pyi +20 -2
- streamlit/proto/NumberInput_pb2.py +4 -4
- streamlit/proto/NumberInput_pb2.pyi +4 -1
- streamlit/proto/Selectbox_pb2.py +4 -2
- streamlit/proto/Selectbox_pb2.pyi +15 -2
- streamlit/proto/TextInput_pb2.py +4 -4
- streamlit/proto/TextInput_pb2.pyi +4 -1
- streamlit/proto/WidthConfig_pb2.py +27 -0
- streamlit/proto/WidthConfig_pb2.pyi +34 -0
- streamlit/runtime/app_session.py +20 -12
- streamlit/runtime/caching/cache_errors.py +1 -1
- streamlit/runtime/context.py +100 -0
- streamlit/runtime/context_util.py +49 -0
- streamlit/runtime/forward_msg_cache.py +35 -230
- streamlit/runtime/forward_msg_queue.py +41 -23
- streamlit/runtime/metrics_util.py +40 -6
- streamlit/runtime/runtime.py +2 -60
- streamlit/runtime/runtime_util.py +17 -16
- streamlit/runtime/scriptrunner/script_runner.py +9 -1
- streamlit/runtime/scriptrunner_utils/script_requests.py +3 -0
- streamlit/runtime/scriptrunner_utils/script_run_context.py +25 -3
- streamlit/runtime/session_manager.py +5 -6
- streamlit/runtime/state/session_state_proxy.py +2 -2
- streamlit/static/index.html +2 -2
- streamlit/static/static/css/{index.BOl9eq08.css → index.DqDwtg6_.css} +1 -1
- streamlit/static/static/js/ErrorOutline.esm.DyIfDYvY.js +1 -0
- streamlit/static/static/js/{FileDownload.esm.urHTnoG1.js → FileDownload.esm.kF1FCxeJ.js} +1 -1
- streamlit/static/static/js/{FileHelper.C9xUPdMQ.js → FileHelper.DKt6tIeO.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.B56TOIUD.js → FormClearHelper.DpJR9YCu.js} +1 -1
- streamlit/static/static/js/{Hooks.CmfGcI8T.js → Hooks.BT6PF2Zi.js} +1 -1
- streamlit/static/static/js/{InputInstructions.55wIEZQg.js → InputInstructions.BmnD4oa3.js} +1 -1
- streamlit/static/static/js/{ProgressBar.CCmWmhAk.js → ProgressBar.Ch7VNdkM.js} +2 -2
- streamlit/static/static/js/{RenderInPortalIfExists.RD5lXr52.js → RenderInPortalIfExists.43tDswzK.js} +1 -1
- streamlit/static/static/js/Toolbar.HTGsjfCP.js +1 -0
- streamlit/static/static/js/{base-input.CPpHElOA.js → base-input.BjeC3XFX.js} +4 -4
- streamlit/static/static/js/{checkbox.CFqAmEFb.js → checkbox.DIVN0GOS.js} +2 -2
- streamlit/static/static/js/{createSuper.CsgKz_Fb.js → createSuper.CKyBiJe0.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.Ca14Ol57.js → data-grid-overlay-editor.CXpaXRk5.js} +1 -1
- streamlit/static/static/js/{downloader.zKHUWJjs.js → downloader.B-uWAyLB.js} +1 -1
- streamlit/static/static/js/{es6.BxIE0hzV.js → es6._eGNfJ2i.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.DDXicIFm.js → iframeResizer.contentWindow.CebQfV1Q.js} +1 -1
- streamlit/static/static/js/index.B5TWFN5r.js +1 -0
- streamlit/static/static/js/{index.DHfKVVrC.js → index.BAdBHmJD.js} +1 -1
- streamlit/static/static/js/{index.CmrEO5y1.js → index.BI9-p_-s.js} +3 -3
- streamlit/static/static/js/index.BYHnDZYn.js +1 -0
- streamlit/static/static/js/index.B_M97aPz.js +1 -0
- streamlit/static/static/js/{index.KqOtBFCd.js → index.BaYSBSaz.js} +1 -1
- streamlit/static/static/js/{index.CdkbqTPi.js → index.BaozEIL-.js} +14 -14
- streamlit/static/static/js/{index.Cs9td93t.js → index.BdN5swP0.js} +1 -1
- streamlit/static/static/js/index.BfCAp_Sj.js +1 -0
- streamlit/static/static/js/{index.B-cSXLfy.js → index.BqDl3eRM.js} +143 -143
- streamlit/static/static/js/index.C0VtYb3T.js +2 -0
- streamlit/static/static/js/{index.LZYrKXpZ.js → index.C1qW_Owy.js} +1 -1
- streamlit/static/static/js/index.C4AcBARa.js +1 -0
- streamlit/static/static/js/index.CCOiJRk1.js +1 -0
- streamlit/static/static/js/index.COvpza5W.js +1 -0
- streamlit/static/static/js/{index.CDo4zkBx.js → index.C_9qGjbK.js} +2 -2
- streamlit/static/static/js/{index.VDXwgnpn.js → index.C_nMqHLH.js} +2 -2
- streamlit/static/static/js/{index.DOrPk35C.js → index.ClX0ambk.js} +1 -1
- streamlit/static/static/js/{index.Dhuj2eHv.js → index.Coc8OVG7.js} +1 -1
- streamlit/static/static/js/index.CpV1hnf8.js +3 -0
- streamlit/static/static/js/{index.DsopOKvk.js → index.CqISBfsc.js} +54 -54
- streamlit/static/static/js/index.CtTgot1Z.js +3 -0
- streamlit/static/static/js/{index.D_Qa2jw1.js → index.CuUJHsRK.js} +1 -1
- streamlit/static/static/js/{index.DKn_lTbw.js → index.CxxktCLw.js} +1 -1
- streamlit/static/static/js/index.D1WOs2Ce.js +1 -0
- streamlit/static/static/js/index.DQljs-9e.js +1 -0
- streamlit/static/static/js/index.DZqX4P_2.js +1 -0
- streamlit/static/static/js/index.DajIfBOb.js +1 -0
- streamlit/static/static/js/{index.Bi19R12v.js → index.DuOXre0H.js} +1 -1
- streamlit/static/static/js/index.EWD98YhP.js +1 -0
- streamlit/static/static/js/{index.DXwmtOFz.js → index.EbMzSayc.js} +1 -1
- streamlit/static/static/js/{index.CdNWl5UD.js → index.HsXxdgGd.js} +1 -1
- streamlit/static/static/js/index.LaZloCTl.js +73 -0
- streamlit/static/static/js/{index.Cc4G8Rqb.js → index.S_1klBoy.js} +1 -1
- streamlit/static/static/js/index.b0Gf958T.js +12 -0
- streamlit/static/static/js/{index.DsxUfkY2.js → index.l6QfBDTC.js} +1 -1
- streamlit/static/static/js/{index.D8rTof6f.js → index.schmj9D9.js} +1051 -223
- streamlit/static/static/js/{index.D8rVyQy1.js → index.t--hEgTQ.js} +2 -2
- streamlit/static/static/js/{input.DG8cw326.js → input.VQEe_bZy.js} +2 -2
- streamlit/static/static/js/{memory.8AYDhEw0.js → memory.DGVHab07.js} +1 -1
- streamlit/static/static/js/{mergeWith.DA0rAJcB.js → mergeWith.-RIuUGoA.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.CfuWV-Nu.js → number-overlay-editor.wzFLIbEE.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.cdV2PGO5.js → possibleConstructorReturn.GIObu6rf.js} +1 -1
- streamlit/static/static/js/{sandbox.D3iuhIxb.js → sandbox.DpjSeqe2.js} +1 -1
- streamlit/static/static/js/{textarea.aafhCY26.js → textarea.Dz0J9LZe.js} +2 -2
- streamlit/static/static/js/{timepicker.B4X4SBBg.js → timepicker.BLgJZnzX.js} +4 -4
- streamlit/static/static/js/{toConsumableArray.BXMHXdEK.js → toConsumableArray.0OZlxz7U.js} +1 -1
- streamlit/static/static/js/{uniqueId.Dd1Zs3iN.js → uniqueId.DbzplC8D.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.fZnKVVgz.js → useBasicWidgetState.COJZng1S.js} +1 -1
- streamlit/static/static/js/useOnInputChange.CgOwAHyw.js +1 -0
- streamlit/static/static/js/withFullScreenWrapper.CzWvNbvi.js +1 -0
- streamlit/static/static/media/MaterialSymbols-Rounded.DsbC8sYI.woff2 +0 -0
- streamlit/testing/v1/element_tree.py +8 -3
- streamlit/type_util.py +2 -3
- streamlit/user_info.py +72 -33
- streamlit/watcher/local_sources_watcher.py +1 -1
- streamlit/watcher/util.py +6 -6
- streamlit/web/cli.py +6 -3
- streamlit/web/server/routes.py +1 -59
- streamlit/web/server/server.py +7 -8
- streamlit/web/server/server_util.py +7 -6
- {streamlit-1.44.1.dist-info → streamlit-1.45.0.dist-info}/METADATA +4 -4
- {streamlit-1.44.1.dist-info → streamlit-1.45.0.dist-info}/RECORD +161 -156
- {streamlit-1.44.1.dist-info → streamlit-1.45.0.dist-info}/WHEEL +1 -1
- streamlit/static/static/js/Toolbar.BDz48EIu.js +0 -1
- streamlit/static/static/js/index.57sI0PzI.js +0 -1
- streamlit/static/static/js/index.6E7GR8Jv.js +0 -1
- streamlit/static/static/js/index.6w1bxtr_.js +0 -3
- streamlit/static/static/js/index.B4xKWXb9.js +0 -1
- streamlit/static/static/js/index.BJbw2HY2.js +0 -3
- streamlit/static/static/js/index.BUT1S9DN.js +0 -1
- streamlit/static/static/js/index.Be1QaPWo.js +0 -2
- streamlit/static/static/js/index.Bl-BqJMM.js +0 -1
- streamlit/static/static/js/index.C5lSqAd6.js +0 -1
- streamlit/static/static/js/index.CC6uDm-p.js +0 -1
- streamlit/static/static/js/index.DtVI4O5R.js +0 -1
- streamlit/static/static/js/index.GZTHUQjY.js +0 -1
- streamlit/static/static/js/index.LxKV_y1F.js +0 -73
- streamlit/static/static/js/index.Y1tjChmn.js +0 -12
- streamlit/static/static/js/index.ZZuB32lN.js +0 -1
- streamlit/static/static/js/index.lOHJHD2E.js +0 -1
- streamlit/static/static/js/index.sbUaFfd3.js +0 -1
- streamlit/static/static/js/useOnInputChange.CNxfGIgD.js +0 -1
- streamlit/static/static/js/withFullScreenWrapper.BvDb1IYP.js +0 -1
- streamlit/static/static/media/MaterialSymbols-Rounded.BFCIvovZ.woff2 +0 -0
- {streamlit-1.44.1.data → streamlit-1.45.0.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.44.1.dist-info → streamlit-1.45.0.dist-info}/entry_points.txt +0 -0
- {streamlit-1.44.1.dist-info → streamlit-1.45.0.dist-info}/top_level.txt +0 -0
streamlit/__init__.py
CHANGED
|
@@ -117,6 +117,7 @@ from streamlit.runtime.state import (
|
|
|
117
117
|
)
|
|
118
118
|
from streamlit.user_info import (
|
|
119
119
|
UserInfoProxy as _UserInfoProxy,
|
|
120
|
+
DeprecatedUserInfoProxy as _DeprecatedUserInfoProxy,
|
|
120
121
|
login as _login,
|
|
121
122
|
logout as _logout,
|
|
122
123
|
)
|
|
@@ -277,11 +278,13 @@ fragment = _fragment
|
|
|
277
278
|
login = _login
|
|
278
279
|
logout = _logout
|
|
279
280
|
|
|
281
|
+
# User
|
|
282
|
+
user = _UserInfoProxy()
|
|
283
|
+
|
|
280
284
|
# Experimental APIs
|
|
281
|
-
experimental_audio_input = _main.experimental_audio_input
|
|
282
285
|
experimental_dialog = _experimental_dialog_decorator
|
|
283
286
|
experimental_fragment = _experimental_fragment
|
|
284
|
-
experimental_user =
|
|
287
|
+
experimental_user = _DeprecatedUserInfoProxy()
|
|
285
288
|
|
|
286
289
|
_EXPERIMENTAL_QUERY_PARAMS_DEPRECATE_MSG = "Refer to our [docs page](https://docs.streamlit.io/develop/api-reference/caching-and-state/st.query_params) for more information."
|
|
287
290
|
|
|
@@ -140,6 +140,7 @@ def rerun( # type: ignore[misc]
|
|
|
140
140
|
if ctx and ctx.script_requests:
|
|
141
141
|
query_string = ctx.query_string
|
|
142
142
|
page_script_hash = ctx.page_script_hash
|
|
143
|
+
cached_message_hashes = ctx.cached_message_hashes
|
|
143
144
|
|
|
144
145
|
ctx.script_requests.request_rerun(
|
|
145
146
|
RerunData(
|
|
@@ -147,6 +148,8 @@ def rerun( # type: ignore[misc]
|
|
|
147
148
|
page_script_hash=page_script_hash,
|
|
148
149
|
fragment_id_queue=_new_fragment_id_queue(ctx, scope),
|
|
149
150
|
is_fragment_scoped_rerun=scope == "fragment",
|
|
151
|
+
cached_message_hashes=cached_message_hashes,
|
|
152
|
+
context_info=ctx.context_info,
|
|
150
153
|
)
|
|
151
154
|
)
|
|
152
155
|
# Force a yield point so the runner can do the rerun
|
|
@@ -232,6 +235,7 @@ def switch_page(page: str | Path | StreamlitPage) -> NoReturn: # type: ignore[m
|
|
|
232
235
|
RerunData(
|
|
233
236
|
query_string=ctx.query_string,
|
|
234
237
|
page_script_hash=page_script_hash,
|
|
238
|
+
cached_message_hashes=ctx.cached_message_hashes,
|
|
235
239
|
)
|
|
236
240
|
)
|
|
237
241
|
# Force a yield point so the runner can do the rerun
|
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
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import copy
|
|
20
|
+
import logging
|
|
20
21
|
import os
|
|
21
22
|
import secrets
|
|
22
23
|
import threading
|
|
23
24
|
from collections import OrderedDict
|
|
24
25
|
from enum import Enum
|
|
25
|
-
from typing import Any, Callable, Literal
|
|
26
|
+
from typing import Any, Callable, Final, Literal
|
|
26
27
|
|
|
27
28
|
from blinker import Signal
|
|
28
29
|
|
|
@@ -55,14 +56,16 @@ _config_options: dict[str, ConfigOption] | None = None
|
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
# Indicates that a config option was defined by the user.
|
|
58
|
-
_USER_DEFINED = "<user defined>"
|
|
59
|
+
_USER_DEFINED: Final = "<user defined>"
|
|
59
60
|
|
|
60
61
|
# Indicates that a config option was defined either in an environment variable
|
|
61
62
|
# or via command-line flag.
|
|
62
|
-
_DEFINED_BY_FLAG = "command-line argument or environment variable"
|
|
63
|
+
_DEFINED_BY_FLAG: Final = "command-line argument or environment variable"
|
|
63
64
|
|
|
64
65
|
# Indicates that a config option was defined in an environment variable
|
|
65
|
-
_DEFINED_BY_ENV_VAR = "environment variable"
|
|
66
|
+
_DEFINED_BY_ENV_VAR: Final = "environment variable"
|
|
67
|
+
|
|
68
|
+
_LOGGER: Final = logging.getLogger(__name__)
|
|
66
69
|
|
|
67
70
|
|
|
68
71
|
class ShowErrorDetailsConfigOptions(str, Enum):
|
|
@@ -82,8 +85,9 @@ class ShowErrorDetailsConfigOptions(str, Enum):
|
|
|
82
85
|
return val in ["false", "False", False]
|
|
83
86
|
|
|
84
87
|
# Config options can be set from several places including the command-line and
|
|
85
|
-
# the user's script. Legacy config options (true/false) will have type string
|
|
86
|
-
# command-line and bool when set via user script
|
|
88
|
+
# the user's script. Legacy config options (true/false) will have type string
|
|
89
|
+
# when set via command-line and bool when set via user script
|
|
90
|
+
# (e.g. st.set_option("client.showErrorDetails", False)).
|
|
87
91
|
|
|
88
92
|
|
|
89
93
|
class CustomThemeCategories(str, Enum):
|
|
@@ -162,7 +166,8 @@ def set_user_option(key: str, value: Any) -> None:
|
|
|
162
166
|
return
|
|
163
167
|
|
|
164
168
|
raise StreamlitAPIException(
|
|
165
|
-
f"{key} cannot be set on the fly. Set as command line option, e.g.
|
|
169
|
+
f"{key} cannot be set on the fly. Set as command line option, e.g. "
|
|
170
|
+
"streamlit run script.py --{key}, or in config.toml instead."
|
|
166
171
|
)
|
|
167
172
|
|
|
168
173
|
|
|
@@ -308,8 +313,11 @@ def _create_theme_options(
|
|
|
308
313
|
type_: type = str,
|
|
309
314
|
) -> None:
|
|
310
315
|
"""
|
|
311
|
-
Create ConfigOption(s) for a theme-related config option and store it globally in
|
|
312
|
-
|
|
316
|
+
Create ConfigOption(s) for a theme-related config option and store it globally in
|
|
317
|
+
this module.
|
|
318
|
+
|
|
319
|
+
The same config option can be supported for multiple categories, e.g. "theme"
|
|
320
|
+
and "theme.sidebar".
|
|
313
321
|
"""
|
|
314
322
|
for cat in categories:
|
|
315
323
|
section = cat if cat == "theme" else f"theme.{cat.value}"
|
|
@@ -444,32 +452,6 @@ _create_option(
|
|
|
444
452
|
type_=int,
|
|
445
453
|
)
|
|
446
454
|
|
|
447
|
-
_create_option(
|
|
448
|
-
"global.storeCachedForwardMessagesInMemory",
|
|
449
|
-
description="""
|
|
450
|
-
If True, store cached ForwardMsgs in backend memory. This is an
|
|
451
|
-
internal flag to validate a potential removal of the in-memory
|
|
452
|
-
forward message cache.
|
|
453
|
-
""",
|
|
454
|
-
visibility="hidden",
|
|
455
|
-
default_val=True,
|
|
456
|
-
type_=bool,
|
|
457
|
-
)
|
|
458
|
-
|
|
459
|
-
_create_option(
|
|
460
|
-
"global.includeFragmentRunsInForwardMessageCacheCount",
|
|
461
|
-
description="""
|
|
462
|
-
If True, the server will include fragment runs in the count for the
|
|
463
|
-
forward message cache. The implication is that apps with fragments may
|
|
464
|
-
see messages being removed from the cache faster. This aligns the server
|
|
465
|
-
count with the frontend count. This is a temporary fix while we assess the
|
|
466
|
-
design of the cache.
|
|
467
|
-
""",
|
|
468
|
-
visibility="hidden",
|
|
469
|
-
default_val=False,
|
|
470
|
-
type_=bool,
|
|
471
|
-
)
|
|
472
|
-
|
|
473
455
|
|
|
474
456
|
# Config Section: Logger #
|
|
475
457
|
_create_section("logger", "Settings to customize Streamlit log messages.")
|
|
@@ -729,7 +711,11 @@ def _server_headless() -> bool:
|
|
|
729
711
|
Default: false unless (1) we are on a Linux box where DISPLAY is unset, or
|
|
730
712
|
(2) we are running in the Streamlit Atom plugin.
|
|
731
713
|
"""
|
|
732
|
-
if
|
|
714
|
+
if (
|
|
715
|
+
env_util.IS_LINUX_OR_BSD
|
|
716
|
+
and not os.getenv("DISPLAY")
|
|
717
|
+
and not os.getenv("WAYLAND_DISPLAY")
|
|
718
|
+
):
|
|
733
719
|
# We're running in Linux and DISPLAY is unset
|
|
734
720
|
return True
|
|
735
721
|
|
|
@@ -836,7 +822,9 @@ _create_option(
|
|
|
836
822
|
description="""
|
|
837
823
|
Max size, in megabytes, for files uploaded with the file_uploader.
|
|
838
824
|
""",
|
|
839
|
-
|
|
825
|
+
# If this default is changed, please also update the docstring
|
|
826
|
+
# for `DeltaGenerator.file_uploader`.
|
|
827
|
+
default_val=200,
|
|
840
828
|
type_=int,
|
|
841
829
|
)
|
|
842
830
|
|
|
@@ -853,8 +841,9 @@ _create_option(
|
|
|
853
841
|
_create_option(
|
|
854
842
|
"server.enableArrowTruncation",
|
|
855
843
|
description="""
|
|
856
|
-
Enable automatically truncating all data structures that get serialized
|
|
857
|
-
to ensure that the size is under
|
|
844
|
+
Enable automatically truncating all data structures that get serialized
|
|
845
|
+
into Arrow (e.g. DataFrames) to ensure that the size is under
|
|
846
|
+
`server.maxMessageSize`.
|
|
858
847
|
""",
|
|
859
848
|
visibility="hidden",
|
|
860
849
|
default_val=False,
|
|
@@ -1233,8 +1222,8 @@ _create_option(
|
|
|
1233
1222
|
will take precedence over earlier ones.
|
|
1234
1223
|
""",
|
|
1235
1224
|
default_val=[
|
|
1236
|
-
# NOTE: The order here is important! Project-level secrets should overwrite
|
|
1237
|
-
# secrets.
|
|
1225
|
+
# NOTE: The order here is important! Project-level secrets should overwrite
|
|
1226
|
+
# global secrets.
|
|
1238
1227
|
file_util.get_streamlit_file_path("secrets.toml"),
|
|
1239
1228
|
file_util.get_project_streamlit_file_path("secrets.toml"),
|
|
1240
1229
|
],
|
|
@@ -1370,9 +1359,18 @@ def _update_config_with_toml(raw_toml: str, where_defined: str) -> None:
|
|
|
1370
1359
|
Tells the config system where this was set.
|
|
1371
1360
|
|
|
1372
1361
|
"""
|
|
1373
|
-
|
|
1362
|
+
try:
|
|
1363
|
+
import toml
|
|
1374
1364
|
|
|
1375
|
-
|
|
1365
|
+
parsed_config_file = toml.loads(raw_toml)
|
|
1366
|
+
except Exception:
|
|
1367
|
+
# Catching any parsing exception to prevent this from breaking our
|
|
1368
|
+
# config change watcher logic.
|
|
1369
|
+
_LOGGER.exception(
|
|
1370
|
+
"Error parsing config toml. This is most likely due to a syntax error "
|
|
1371
|
+
"in the config.toml file. Please fix it and try again.",
|
|
1372
|
+
)
|
|
1373
|
+
return
|
|
1376
1374
|
|
|
1377
1375
|
def process_section(section_path: str, section_data: dict[str, Any]) -> None:
|
|
1378
1376
|
"""Recursively process nested sections of the config file.
|
|
@@ -1415,8 +1413,7 @@ def _update_config_with_toml(raw_toml: str, where_defined: str) -> None:
|
|
|
1415
1413
|
process_section(option_name, value)
|
|
1416
1414
|
else:
|
|
1417
1415
|
# It's a regular config option, set it
|
|
1418
|
-
|
|
1419
|
-
_set_option(option_name, value, where_defined)
|
|
1416
|
+
_set_option(option_name, _maybe_read_env_variable(value), where_defined)
|
|
1420
1417
|
|
|
1421
1418
|
for section, options in parsed_config_file.items():
|
|
1422
1419
|
process_section(section, options)
|
|
@@ -1508,7 +1505,7 @@ def get_config_options(
|
|
|
1508
1505
|
dict[str, ConfigOption]
|
|
1509
1506
|
An ordered dict that maps config option names to their values.
|
|
1510
1507
|
"""
|
|
1511
|
-
global _config_options
|
|
1508
|
+
global _config_options # noqa: PLW0603
|
|
1512
1509
|
|
|
1513
1510
|
if not options_from_flags:
|
|
1514
1511
|
options_from_flags = {}
|
|
@@ -1586,7 +1583,8 @@ def _check_conflicts() -> None:
|
|
|
1586
1583
|
if not get_option("server.enableCORS") or get_option("global.developmentMode"):
|
|
1587
1584
|
LOGGER.warning(
|
|
1588
1585
|
"""
|
|
1589
|
-
Warning: the config option 'server.enableCORS=false' is not compatible with
|
|
1586
|
+
Warning: the config option 'server.enableCORS=false' is not compatible with
|
|
1587
|
+
'server.enableXsrfProtection=true'.
|
|
1590
1588
|
As a result, 'server.enableCORS' is being overridden to 'true'.
|
|
1591
1589
|
|
|
1592
1590
|
More information:
|
streamlit/config_util.py
CHANGED
|
@@ -87,7 +87,7 @@ def show_config(
|
|
|
87
87
|
append_section("[%s]" % section)
|
|
88
88
|
out.append("")
|
|
89
89
|
|
|
90
|
-
for
|
|
90
|
+
for _, option in section_options.items():
|
|
91
91
|
key = option.key.split(".")[-1]
|
|
92
92
|
description_paragraphs = _clean_paragraphs(option.description or "")
|
|
93
93
|
|
streamlit/delta_generator.py
CHANGED
|
@@ -121,7 +121,7 @@ def _maybe_print_use_warning() -> None:
|
|
|
121
121
|
"""Print a warning if Streamlit is imported but not being run with `streamlit run`.
|
|
122
122
|
The warning is printed only once, and is printed using the root logger.
|
|
123
123
|
"""
|
|
124
|
-
global _use_warning_has_been_displayed
|
|
124
|
+
global _use_warning_has_been_displayed # noqa: PLW0603
|
|
125
125
|
|
|
126
126
|
if not _use_warning_has_been_displayed:
|
|
127
127
|
_use_warning_has_been_displayed = True
|
|
@@ -487,6 +487,10 @@ class DeltaGenerator(
|
|
|
487
487
|
cursor=new_cursor,
|
|
488
488
|
parent=dg,
|
|
489
489
|
)
|
|
490
|
+
|
|
491
|
+
# Elements inherit their parent form ids.
|
|
492
|
+
# NOTE: Form ids aren't set in dg constructor.
|
|
493
|
+
output_dg._form_data = FormData(current_form_id(dg))
|
|
490
494
|
else:
|
|
491
495
|
# If the message was not enqueued, just return self since it's a
|
|
492
496
|
# no-op from the point of view of the app.
|
streamlit/deprecation_util.py
CHANGED
|
@@ -139,7 +139,7 @@ def deprecate_obj_name(
|
|
|
139
139
|
|
|
140
140
|
include_st_prefix
|
|
141
141
|
If False, does not prefix each of the object names in the deprecation
|
|
142
|
-
|
|
142
|
+
message with `st.*`. Defaults to True.
|
|
143
143
|
"""
|
|
144
144
|
|
|
145
145
|
return _create_deprecated_obj_wrapper(
|
|
@@ -188,13 +188,13 @@ def _create_deprecated_obj_wrapper(obj: TObj, show_warning: Callable[[], Any]) -
|
|
|
188
188
|
return getattr(obj, attr)
|
|
189
189
|
|
|
190
190
|
@staticmethod
|
|
191
|
-
def _get_magic_functions(
|
|
191
|
+
def _get_magic_functions(self_cls) -> list[str]:
|
|
192
192
|
# ignore the handful of magic functions we cannot override without
|
|
193
193
|
# breaking the Wrapper.
|
|
194
194
|
ignore = ("__class__", "__dict__", "__getattribute__", "__getattr__")
|
|
195
195
|
return [
|
|
196
196
|
name
|
|
197
|
-
for name in dir(
|
|
197
|
+
for name in dir(self_cls)
|
|
198
198
|
if name not in ignore and name.startswith("__")
|
|
199
199
|
]
|
|
200
200
|
|
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,13 @@ 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 desired width of the alert expressed in pixels. If this is
|
|
71
|
+
``"stretch"`` (default), Streamlit sets the width of the alert to
|
|
72
|
+
match the width of the parent container. Otherwise, this must be an
|
|
73
|
+
integer. If the specified width is greater than the width of the
|
|
74
|
+
parent container, Streamlit sets the width of the alert to match
|
|
75
|
+
the width of the parent container.
|
|
65
76
|
|
|
66
77
|
Example
|
|
67
78
|
-------
|
|
@@ -75,6 +86,18 @@ class AlertMixin:
|
|
|
75
86
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
|
76
87
|
alert_proto.body = clean_text(body)
|
|
77
88
|
alert_proto.format = AlertProto.ERROR
|
|
89
|
+
|
|
90
|
+
validate_width(width)
|
|
91
|
+
|
|
92
|
+
width_config = WidthConfig()
|
|
93
|
+
|
|
94
|
+
if isinstance(width, int):
|
|
95
|
+
width_config.pixel_width = width
|
|
96
|
+
else:
|
|
97
|
+
width_config.use_stretch = True
|
|
98
|
+
|
|
99
|
+
alert_proto.width_config.CopyFrom(width_config)
|
|
100
|
+
|
|
78
101
|
return self.dg._enqueue("alert", alert_proto)
|
|
79
102
|
|
|
80
103
|
@gather_metrics("warning")
|
|
@@ -83,6 +106,7 @@ class AlertMixin:
|
|
|
83
106
|
body: SupportsStr,
|
|
84
107
|
*, # keyword-only args:
|
|
85
108
|
icon: str | None = None,
|
|
109
|
+
width: WidthWithoutContent = "stretch",
|
|
86
110
|
) -> DeltaGenerator:
|
|
87
111
|
"""Display warning message.
|
|
88
112
|
|
|
@@ -113,6 +137,13 @@ class AlertMixin:
|
|
|
113
137
|
Thumb Up icon. Find additional icons in the `Material Symbols \
|
|
114
138
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
115
139
|
font library.
|
|
140
|
+
width : int or "stretch"
|
|
141
|
+
The desired width of the alert expressed in pixels. If this is
|
|
142
|
+
``"stretch"`` (default), Streamlit sets the width of the alert to
|
|
143
|
+
match the width of the parent container. Otherwise, this must be an
|
|
144
|
+
integer. If the specified width is greater than the width of the
|
|
145
|
+
parent container, Streamlit sets the width of the alert to match
|
|
146
|
+
the width of the parent container.
|
|
116
147
|
|
|
117
148
|
Example
|
|
118
149
|
-------
|
|
@@ -125,6 +156,18 @@ class AlertMixin:
|
|
|
125
156
|
alert_proto.body = clean_text(body)
|
|
126
157
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
|
127
158
|
alert_proto.format = AlertProto.WARNING
|
|
159
|
+
|
|
160
|
+
validate_width(width)
|
|
161
|
+
|
|
162
|
+
width_config = WidthConfig()
|
|
163
|
+
|
|
164
|
+
if isinstance(width, int):
|
|
165
|
+
width_config.pixel_width = width
|
|
166
|
+
else:
|
|
167
|
+
width_config.use_stretch = True
|
|
168
|
+
|
|
169
|
+
alert_proto.width_config.CopyFrom(width_config)
|
|
170
|
+
|
|
128
171
|
return self.dg._enqueue("alert", alert_proto)
|
|
129
172
|
|
|
130
173
|
@gather_metrics("info")
|
|
@@ -133,6 +176,7 @@ class AlertMixin:
|
|
|
133
176
|
body: SupportsStr,
|
|
134
177
|
*, # keyword-only args:
|
|
135
178
|
icon: str | None = None,
|
|
179
|
+
width: WidthWithoutContent = "stretch",
|
|
136
180
|
) -> DeltaGenerator:
|
|
137
181
|
"""Display an informational message.
|
|
138
182
|
|
|
@@ -163,6 +207,13 @@ class AlertMixin:
|
|
|
163
207
|
Thumb Up icon. Find additional icons in the `Material Symbols \
|
|
164
208
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
165
209
|
font library.
|
|
210
|
+
width : int or "stretch"
|
|
211
|
+
The desired width of the alert expressed in pixels. If this is
|
|
212
|
+
``"stretch"`` (default), Streamlit sets the width of the alert to
|
|
213
|
+
match the width of the parent container. Otherwise, this must be an
|
|
214
|
+
integer. If the specified width is greater than the width of the
|
|
215
|
+
parent container, Streamlit sets the width of the alert to match
|
|
216
|
+
the width of the parent container.
|
|
166
217
|
|
|
167
218
|
Example
|
|
168
219
|
-------
|
|
@@ -176,6 +227,18 @@ class AlertMixin:
|
|
|
176
227
|
alert_proto.body = clean_text(body)
|
|
177
228
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
|
178
229
|
alert_proto.format = AlertProto.INFO
|
|
230
|
+
|
|
231
|
+
validate_width(width)
|
|
232
|
+
|
|
233
|
+
width_config = WidthConfig()
|
|
234
|
+
|
|
235
|
+
if isinstance(width, int):
|
|
236
|
+
width_config.pixel_width = width
|
|
237
|
+
else:
|
|
238
|
+
width_config.use_stretch = True
|
|
239
|
+
|
|
240
|
+
alert_proto.width_config.CopyFrom(width_config)
|
|
241
|
+
|
|
179
242
|
return self.dg._enqueue("alert", alert_proto)
|
|
180
243
|
|
|
181
244
|
@gather_metrics("success")
|
|
@@ -184,6 +247,7 @@ class AlertMixin:
|
|
|
184
247
|
body: SupportsStr,
|
|
185
248
|
*, # keyword-only args:
|
|
186
249
|
icon: str | None = None,
|
|
250
|
+
width: WidthWithoutContent = "stretch",
|
|
187
251
|
) -> DeltaGenerator:
|
|
188
252
|
"""Display a success message.
|
|
189
253
|
|
|
@@ -214,6 +278,13 @@ class AlertMixin:
|
|
|
214
278
|
Thumb Up icon. Find additional icons in the `Material Symbols \
|
|
215
279
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
216
280
|
font library.
|
|
281
|
+
width : int or "stretch"
|
|
282
|
+
The desired width of the alert expressed in pixels. If this is
|
|
283
|
+
``"stretch"`` (default), Streamlit sets the width of the alert to
|
|
284
|
+
match the width of the parent container. Otherwise, this must be an
|
|
285
|
+
integer. If the specified width is greater than the width of the
|
|
286
|
+
parent container, Streamlit sets the width of the alert to match
|
|
287
|
+
the width of the parent container.
|
|
217
288
|
|
|
218
289
|
Example
|
|
219
290
|
-------
|
|
@@ -226,6 +297,18 @@ class AlertMixin:
|
|
|
226
297
|
alert_proto.body = clean_text(body)
|
|
227
298
|
alert_proto.icon = validate_icon_or_emoji(icon)
|
|
228
299
|
alert_proto.format = AlertProto.SUCCESS
|
|
300
|
+
|
|
301
|
+
validate_width(width)
|
|
302
|
+
|
|
303
|
+
width_config = WidthConfig()
|
|
304
|
+
|
|
305
|
+
if isinstance(width, int):
|
|
306
|
+
width_config.pixel_width = width
|
|
307
|
+
else:
|
|
308
|
+
width_config.use_stretch = True
|
|
309
|
+
|
|
310
|
+
alert_proto.width_config.CopyFrom(width_config)
|
|
311
|
+
|
|
229
312
|
return self.dg._enqueue("alert", alert_proto)
|
|
230
313
|
|
|
231
314
|
@property
|