streamlit-nightly 1.45.2.dev20250514__py3-none-any.whl → 1.45.2.dev20250516__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/connections/sql_connection.py +10 -7
- streamlit/connections/util.py +2 -2
- streamlit/elements/lib/options_selector_utils.py +10 -2
- streamlit/elements/markdown.py +1 -1
- streamlit/elements/plotly_chart.py +7 -7
- streamlit/elements/vega_charts.py +7 -7
- streamlit/elements/widgets/file_uploader.py +2 -2
- streamlit/elements/widgets/number_input.py +3 -3
- streamlit/elements/widgets/radio.py +21 -0
- streamlit/elements/widgets/select_slider.py +1 -13
- streamlit/elements/widgets/selectbox.py +22 -0
- streamlit/elements/widgets/slider.py +35 -9
- streamlit/runtime/caching/cache_data_api.py +18 -14
- streamlit/runtime/connection_factory.py +1 -1
- streamlit/runtime/scriptrunner/script_runner.py +1 -2
- streamlit/runtime/secrets.py +10 -8
- streamlit/runtime/state/query_params_proxy.py +14 -12
- streamlit/runtime/state/session_state.py +2 -2
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.DbGVRvJi.js → ErrorOutline.esm.NoyWdcXX.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.Dsazfko3.js → FileDownload.esm.swCXF6kF.js} +1 -1
- streamlit/static/static/js/{FileHelper.MycXbml-.js → FileHelper.Dx5K4a9E.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.BBCnWP4b.js → FormClearHelper.BOuxElPh.js} +1 -1
- streamlit/static/static/js/{Hooks.Cogxcj3O.js → Hooks.C-dTwIN4.js} +1 -1
- streamlit/static/static/js/{InputInstructions.DmFmv5Ss.js → InputInstructions.DGm-30R7.js} +1 -1
- streamlit/static/static/js/{ProgressBar.CL8D7fKU.js → ProgressBar.BhDlWZOq.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.BIF2_x-k.js → RenderInPortalIfExists.B1fTBW4u.js} +1 -1
- streamlit/static/static/js/{Toolbar.BiePqUs0.js → Toolbar.BFnK5L1F.js} +1 -1
- streamlit/static/static/js/{base-input.9-IewVJN.js → base-input.-TX15L8w.js} +1 -1
- streamlit/static/static/js/{checkbox.CvxVkFoK.js → checkbox.DTBzWBar.js} +1 -1
- streamlit/static/static/js/{createSuper.CcYwpbOm.js → createSuper.CYbmN691.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.DVakjLUQ.js → data-grid-overlay-editor.B7iyFRkb.js} +1 -1
- streamlit/static/static/js/{downloader.DUDYpW4X.js → downloader.0M4t3MS8.js} +1 -1
- streamlit/static/static/js/{es6.Dd8C3gJG.js → es6.CnBJxoS-.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.ElqrcVSG.js → iframeResizer.contentWindow.B1Cm-yCx.js} +1 -1
- streamlit/static/static/js/{index.8U8I-dVE.js → index.-CAfcaTJ.js} +1 -1
- streamlit/static/static/js/{index.Dxf51cqQ.js → index.B-w5NlhA.js} +1 -1
- streamlit/static/static/js/{index.CkOK3vMg.js → index.B15kcUzJ.js} +1 -1
- streamlit/static/static/js/{index.DNeEyPk6.js → index.B6FtB0_2.js} +1 -1
- streamlit/static/static/js/{index.CwLlrvyN.js → index.B9RXX8pn.js} +1 -1
- streamlit/static/static/js/{index.Bud-F2Rk.js → index.BH6BVmJz.js} +1 -1
- streamlit/static/static/js/{index.Ogd9LUng.js → index.BHpD_hOw.js} +1 -1
- streamlit/static/static/js/{index.DX_Td1Hq.js → index.BNVMahIE.js} +1 -1
- streamlit/static/static/js/{index.C-wDYZmi.js → index.BTKNtQ5e.js} +1 -1
- streamlit/static/static/js/{index.y8UOtxmw.js → index.BaXjHhfo.js} +1 -1
- streamlit/static/static/js/{index.uT7_kc4D.js → index.Bcq_Dqng.js} +1 -1
- streamlit/static/static/js/{index.DrVpZAT_.js → index.BpDSKaO3.js} +1 -1
- streamlit/static/static/js/{index.Bgid2lLN.js → index.C-JknFAL.js} +1 -1
- streamlit/static/static/js/{index.CM8qhnIu.js → index.C5dNjck1.js} +5 -5
- streamlit/static/static/js/{index.B5gxNAgv.js → index.CEWd5P5L.js} +1 -1
- streamlit/static/static/js/{index.CDxF0FlW.js → index.CZFbePOv.js} +1 -1
- streamlit/static/static/js/{index.PYQDVW05.js → index.C_JbdxeV.js} +1 -1
- streamlit/static/static/js/{index.D0fj09K-.js → index.CfBT3VZM.js} +1 -1
- streamlit/static/static/js/{index.DfYxhBCm.js → index.CmTFJnyq.js} +1 -1
- streamlit/static/static/js/{index.BkpDVBQw.js → index.Cn2Htof5.js} +1 -1
- streamlit/static/static/js/{index.DgQ-i_4o.js → index.CvIS8mbe.js} +12 -12
- streamlit/static/static/js/{index.DWL3vnFa.js → index.D1sNm3Y-.js} +1 -1
- streamlit/static/static/js/{index.DiE_wY_P.js → index.D46OlHvo.js} +1 -1
- streamlit/static/static/js/{index.C44ecW4y.js → index.DF-_4n5K.js} +1 -1
- streamlit/static/static/js/{index.3TsDLcVz.js → index.DFqEbTqh.js} +1 -1
- streamlit/static/static/js/{index.BRTdJWEL.js → index.DK6vs4Di.js} +1 -1
- streamlit/static/static/js/{index.D5Y8GQ-0.js → index.DOMm5x54.js} +1 -1
- streamlit/static/static/js/{index.DWBlm6kP.js → index.DTuHVhBz.js} +1 -1
- streamlit/static/static/js/{index.DK1C5mv_.js → index.DZYh8f7_.js} +1 -1
- streamlit/static/static/js/{index.BYGvkzYg.js → index.DajYErBx.js} +1 -1
- streamlit/static/static/js/{index.D8g5_NeN.js → index.DiqYkNBc.js} +1 -1
- streamlit/static/static/js/{index.BANNX-Et.js → index.DyD4Uz_R.js} +1 -1
- streamlit/static/static/js/{index.CtEWZzBM.js → index.DzFtbI0B.js} +1 -1
- streamlit/static/static/js/{index.CssifhIa.js → index.K58oz6IJ.js} +1 -1
- streamlit/static/static/js/{index.QqgppQA_.js → index.oE_T3Dq1.js} +1 -1
- streamlit/static/static/js/{index.Chn8rXFO.js → index.rQxcH6vP.js} +1 -1
- streamlit/static/static/js/{index.rR2rxOdw.js → index.v-rD-Hng.js} +1 -1
- streamlit/static/static/js/{input.D1uIuNvR.js → input.qzQht_jN.js} +1 -1
- streamlit/static/static/js/{memory.C_YLF4Fx.js → memory.CyBxDLiR.js} +1 -1
- streamlit/static/static/js/{mergeWith.BrhEAUIQ.js → mergeWith.DmD-T2-i.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.Cl4hS5U2.js → number-overlay-editor.Dt5fG9N0.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.BizCfnoE.js → possibleConstructorReturn.CRudR7k5.js} +1 -1
- streamlit/static/static/js/{sandbox.BYlf4D-n.js → sandbox.CHQGgKVf.js} +1 -1
- streamlit/static/static/js/{textarea.BvMrgzVs.js → textarea.CH313Ypj.js} +1 -1
- streamlit/static/static/js/{timepicker.8sMF8VpM.js → timepicker.BhjK2nDc.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.Cl96Bc5x.js → toConsumableArray.3iVpQ6Sl.js} +1 -1
- streamlit/static/static/js/{uniqueId.BoXr82qs.js → uniqueId.DHpRy8Eo.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.DYpB4KjS.js → useBasicWidgetState.ChmMQiYn.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.D17AAeVI.js → useOnInputChange.yXh9wSmS.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.Lq8QUQxx.js → withFullScreenWrapper.Bv9KCRY5.js} +1 -1
- streamlit/string_util.py +1 -5
- streamlit/type_util.py +1 -1
- streamlit/vendor/pympler/asizeof.py +2 -1
- streamlit/watcher/local_sources_watcher.py +3 -3
- streamlit/web/server/oidc_mixin.py +2 -2
- {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250516.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250516.dist-info}/RECORD +96 -96
- {streamlit_nightly-1.45.2.dev20250514.data → streamlit_nightly-1.45.2.dev20250516.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250516.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250516.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250516.dist-info}/top_level.txt +0 -0
@@ -319,13 +319,16 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
319
319
|
import pandas as pd
|
320
320
|
|
321
321
|
instance = self._instance.connect()
|
322
|
-
return
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
322
|
+
return cast(
|
323
|
+
"DataFrame",
|
324
|
+
pd.read_sql(
|
325
|
+
text(sql),
|
326
|
+
instance,
|
327
|
+
index_col=index_col,
|
328
|
+
chunksize=chunksize,
|
329
|
+
params=params,
|
330
|
+
**kwargs,
|
331
|
+
),
|
329
332
|
)
|
330
333
|
|
331
334
|
# We modify our helper function's `__qualname__` here to work around default
|
streamlit/connections/util.py
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
from __future__ import annotations
|
22
22
|
|
23
23
|
import os
|
24
|
-
from typing import TYPE_CHECKING, Any
|
24
|
+
from typing import TYPE_CHECKING, Any
|
25
25
|
|
26
26
|
if TYPE_CHECKING:
|
27
27
|
from collections.abc import Collection
|
@@ -92,6 +92,6 @@ def running_in_sis() -> bool:
|
|
92
92
|
is_in_stored_procedure,
|
93
93
|
)
|
94
94
|
|
95
|
-
return
|
95
|
+
return is_in_stored_procedure() # type: ignore
|
96
96
|
except ModuleNotFoundError:
|
97
97
|
return False
|
@@ -185,7 +185,11 @@ def maybe_coerce_enum(
|
|
185
185
|
) -> RegisterWidgetResult[T]: ...
|
186
186
|
|
187
187
|
|
188
|
-
def maybe_coerce_enum(
|
188
|
+
def maybe_coerce_enum(
|
189
|
+
register_widget_result: RegisterWidgetResult[Any],
|
190
|
+
options: OptionSequence[Any],
|
191
|
+
opt_sequence: Sequence[Any],
|
192
|
+
) -> RegisterWidgetResult[Any]:
|
189
193
|
"""Maybe Coerce a RegisterWidgetResult with an Enum member value to
|
190
194
|
RegisterWidgetResult[option] if option is an EnumType, otherwise just return
|
191
195
|
the original RegisterWidgetResult.
|
@@ -227,7 +231,11 @@ def maybe_coerce_enum_sequence(
|
|
227
231
|
) -> RegisterWidgetResult[tuple[T, T]]: ...
|
228
232
|
|
229
233
|
|
230
|
-
def maybe_coerce_enum_sequence(
|
234
|
+
def maybe_coerce_enum_sequence(
|
235
|
+
register_widget_result: RegisterWidgetResult[list[Any] | tuple[Any, ...]],
|
236
|
+
options: OptionSequence[Any],
|
237
|
+
opt_sequence: Sequence[Any],
|
238
|
+
) -> RegisterWidgetResult[list[Any] | tuple[Any, ...]]:
|
231
239
|
"""Maybe Coerce a RegisterWidgetResult with a sequence of Enum members as value
|
232
240
|
to RegisterWidgetResult[Sequence[option]] if option is an EnumType, otherwise just
|
233
241
|
return the original RegisterWidgetResult.
|
streamlit/elements/markdown.py
CHANGED
@@ -22,7 +22,7 @@ from streamlit.string_util import clean_text, validate_icon_or_emoji
|
|
22
22
|
from streamlit.type_util import SupportsStr, is_sympy_expression
|
23
23
|
|
24
24
|
if TYPE_CHECKING:
|
25
|
-
import sympy
|
25
|
+
import sympy
|
26
26
|
|
27
27
|
from streamlit.delta_generator import DeltaGenerator
|
28
28
|
|
@@ -29,7 +29,7 @@ from typing import (
|
|
29
29
|
overload,
|
30
30
|
)
|
31
31
|
|
32
|
-
from typing_extensions import TypeAlias
|
32
|
+
from typing_extensions import Required, TypeAlias
|
33
33
|
|
34
34
|
from streamlit import type_util
|
35
35
|
from streamlit.deprecation_util import show_deprecation_warning
|
@@ -159,10 +159,10 @@ class PlotlySelectionState(TypedDict, total=False):
|
|
159
159
|
|
160
160
|
"""
|
161
161
|
|
162
|
-
points: list[dict[str, Any]]
|
163
|
-
point_indices: list[int]
|
164
|
-
box: list[dict[str, Any]]
|
165
|
-
lasso: list[dict[str, Any]]
|
162
|
+
points: Required[list[dict[str, Any]]]
|
163
|
+
point_indices: Required[list[int]]
|
164
|
+
box: Required[list[dict[str, Any]]]
|
165
|
+
lasso: Required[list[dict[str, Any]]]
|
166
166
|
|
167
167
|
|
168
168
|
class PlotlyState(TypedDict, total=False):
|
@@ -205,7 +205,7 @@ class PlotlyState(TypedDict, total=False):
|
|
205
205
|
|
206
206
|
"""
|
207
207
|
|
208
|
-
selection: PlotlySelectionState
|
208
|
+
selection: Required[PlotlySelectionState]
|
209
209
|
|
210
210
|
|
211
211
|
@dataclass
|
@@ -231,7 +231,7 @@ class PlotlyChartSelectionSerde:
|
|
231
231
|
)
|
232
232
|
|
233
233
|
if "selection" not in selection_state:
|
234
|
-
selection_state = empty_selection_state
|
234
|
+
selection_state = empty_selection_state # type: ignore[unreachable]
|
235
235
|
|
236
236
|
return cast("PlotlyState", AttributeDictionary(selection_state))
|
237
237
|
|
@@ -31,7 +31,7 @@ from typing import (
|
|
31
31
|
overload,
|
32
32
|
)
|
33
33
|
|
34
|
-
from typing_extensions import TypeAlias
|
34
|
+
from typing_extensions import Required, TypeAlias
|
35
35
|
|
36
36
|
from streamlit import dataframe_util, type_util
|
37
37
|
from streamlit.elements.lib import dicttools
|
@@ -218,7 +218,7 @@ class VegaLiteState(TypedDict, total=False):
|
|
218
218
|
|
219
219
|
"""
|
220
220
|
|
221
|
-
selection: AttributeDictionary
|
221
|
+
selection: Required[AttributeDictionary]
|
222
222
|
|
223
223
|
|
224
224
|
@dataclass
|
@@ -242,7 +242,7 @@ class VegaLiteStateSerde:
|
|
242
242
|
)
|
243
243
|
|
244
244
|
if "selection" not in selection_state:
|
245
|
-
selection_state = empty_selection_state
|
245
|
+
selection_state = empty_selection_state # type: ignore[unreachable]
|
246
246
|
|
247
247
|
return cast("VegaLiteState", AttributeDictionary(selection_state))
|
248
248
|
|
@@ -1479,7 +1479,7 @@ class VegaChartsMixin:
|
|
1479
1479
|
use_container_width: bool | None = None,
|
1480
1480
|
theme: Literal["streamlit"] | None = "streamlit",
|
1481
1481
|
key: Key | None = None,
|
1482
|
-
on_select: Literal["ignore"]
|
1482
|
+
on_select: Literal["ignore"] = "ignore",
|
1483
1483
|
selection_mode: str | Iterable[str] | None = None,
|
1484
1484
|
) -> DeltaGenerator: ...
|
1485
1485
|
|
@@ -1492,7 +1492,7 @@ class VegaChartsMixin:
|
|
1492
1492
|
use_container_width: bool | None = None,
|
1493
1493
|
theme: Literal["streamlit"] | None = "streamlit",
|
1494
1494
|
key: Key | None = None,
|
1495
|
-
on_select: Literal["rerun"] | WidgetCallback
|
1495
|
+
on_select: Literal["rerun"] | WidgetCallback,
|
1496
1496
|
selection_mode: str | Iterable[str] | None = None,
|
1497
1497
|
) -> VegaLiteState: ...
|
1498
1498
|
|
@@ -1638,7 +1638,7 @@ class VegaChartsMixin:
|
|
1638
1638
|
use_container_width: bool | None = None,
|
1639
1639
|
theme: Literal["streamlit"] | None = "streamlit",
|
1640
1640
|
key: Key | None = None,
|
1641
|
-
on_select: Literal["ignore"]
|
1641
|
+
on_select: Literal["ignore"] = "ignore",
|
1642
1642
|
selection_mode: str | Iterable[str] | None = None,
|
1643
1643
|
**kwargs: Any,
|
1644
1644
|
) -> DeltaGenerator: ...
|
@@ -1653,7 +1653,7 @@ class VegaChartsMixin:
|
|
1653
1653
|
use_container_width: bool | None = None,
|
1654
1654
|
theme: Literal["streamlit"] | None = "streamlit",
|
1655
1655
|
key: Key | None = None,
|
1656
|
-
on_select: Literal["rerun"] | WidgetCallback
|
1656
|
+
on_select: Literal["rerun"] | WidgetCallback,
|
1657
1657
|
selection_mode: str | Iterable[str] | None = None,
|
1658
1658
|
**kwargs: Any,
|
1659
1659
|
) -> VegaLiteState: ...
|
@@ -170,7 +170,7 @@ class FileUploaderMixin:
|
|
170
170
|
disabled: bool = False,
|
171
171
|
label_visibility: LabelVisibility = "visible",
|
172
172
|
width: WidthWithoutContent = "stretch",
|
173
|
-
) -> list[UploadedFile]
|
173
|
+
) -> list[UploadedFile]: ...
|
174
174
|
|
175
175
|
# 1. type is given as not a keyword-only argument
|
176
176
|
# 2. accept_multiple_files = False or omitted
|
@@ -213,7 +213,7 @@ class FileUploaderMixin:
|
|
213
213
|
disabled: bool = False,
|
214
214
|
label_visibility: LabelVisibility = "visible",
|
215
215
|
width: WidthWithoutContent = "stretch",
|
216
|
-
) -> list[UploadedFile]
|
216
|
+
) -> list[UploadedFile]: ...
|
217
217
|
|
218
218
|
# 1. type is skipped or a keyword argument
|
219
219
|
# 2. accept_multiple_files = False or omitted
|
@@ -116,7 +116,7 @@ class NumberInputMixin:
|
|
116
116
|
def number_input(
|
117
117
|
self,
|
118
118
|
label: str,
|
119
|
-
min_value:
|
119
|
+
min_value: None = None,
|
120
120
|
*,
|
121
121
|
max_value: int,
|
122
122
|
value: IntOrNone | Literal["min"] = "min",
|
@@ -166,8 +166,8 @@ class NumberInputMixin:
|
|
166
166
|
def number_input(
|
167
167
|
self,
|
168
168
|
label: str,
|
169
|
-
min_value:
|
170
|
-
max_value:
|
169
|
+
min_value: None = None,
|
170
|
+
max_value: None = None,
|
171
171
|
value: IntOrNone | Literal["min"] = "min",
|
172
172
|
*,
|
173
173
|
step: int,
|
@@ -18,6 +18,8 @@ from dataclasses import dataclass
|
|
18
18
|
from textwrap import dedent
|
19
19
|
from typing import TYPE_CHECKING, Any, Callable, Generic, cast, overload
|
20
20
|
|
21
|
+
from typing_extensions import Never
|
22
|
+
|
21
23
|
from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
|
22
24
|
from streamlit.elements.lib.form_utils import current_form_id
|
23
25
|
from streamlit.elements.lib.options_selector_utils import index_, maybe_coerce_enum
|
@@ -79,6 +81,25 @@ class RadioSerde(Generic[T]):
|
|
79
81
|
|
80
82
|
|
81
83
|
class RadioMixin:
|
84
|
+
@overload
|
85
|
+
def radio(
|
86
|
+
self,
|
87
|
+
label: str,
|
88
|
+
options: Sequence[Never],
|
89
|
+
index: int = 0,
|
90
|
+
format_func: Callable[[Any], Any] = str,
|
91
|
+
key: Key | None = None,
|
92
|
+
help: str | None = None,
|
93
|
+
on_change: WidgetCallback | None = None,
|
94
|
+
args: WidgetArgs | None = None,
|
95
|
+
kwargs: WidgetKwargs | None = None,
|
96
|
+
*, # keyword-only args:
|
97
|
+
disabled: bool = False,
|
98
|
+
horizontal: bool = False,
|
99
|
+
captions: Sequence[str] | None = None,
|
100
|
+
label_visibility: LabelVisibility = "visible",
|
101
|
+
) -> None: ...
|
102
|
+
|
82
103
|
@overload
|
83
104
|
def radio(
|
84
105
|
self,
|
@@ -107,7 +107,7 @@ class SelectSliderSerde(Generic[T]):
|
|
107
107
|
|
108
108
|
class SelectSliderMixin:
|
109
109
|
@overload
|
110
|
-
def select_slider(
|
110
|
+
def select_slider(
|
111
111
|
self,
|
112
112
|
label: str,
|
113
113
|
options: OptionSequence[T],
|
@@ -124,18 +124,6 @@ class SelectSliderMixin:
|
|
124
124
|
width: WidthWithoutContent = "stretch",
|
125
125
|
) -> tuple[T, T]: ...
|
126
126
|
|
127
|
-
# The overload-overlap error given by mypy here stems from
|
128
|
-
# the fact that
|
129
|
-
#
|
130
|
-
# > opt:List[object] = [1, 2, "3"]
|
131
|
-
# > select_slider("foo", options=opt, value=[1, 2])
|
132
|
-
#
|
133
|
-
# matches both overloads; "opt" matches
|
134
|
-
# OptionsSequence[T] in each case, binding T to object.
|
135
|
-
# However, the list[int] type of "value" can be interpreted
|
136
|
-
# as subtype of object, or as a subtype of List[object],
|
137
|
-
# meaning it matches both signatures.
|
138
|
-
|
139
127
|
@overload
|
140
128
|
def select_slider(
|
141
129
|
self,
|
@@ -16,6 +16,8 @@ from __future__ import annotations
|
|
16
16
|
from textwrap import dedent
|
17
17
|
from typing import TYPE_CHECKING, Any, Callable, Generic, Literal, cast, overload
|
18
18
|
|
19
|
+
from typing_extensions import Never
|
20
|
+
|
19
21
|
from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
|
20
22
|
from streamlit.elements.lib.form_utils import current_form_id
|
21
23
|
from streamlit.elements.lib.layout_utils import WidthWithoutContent, validate_width
|
@@ -132,6 +134,26 @@ class SelectboxSerde(Generic[T]):
|
|
132
134
|
|
133
135
|
|
134
136
|
class SelectboxMixin:
|
137
|
+
@overload
|
138
|
+
def selectbox(
|
139
|
+
self,
|
140
|
+
label: str,
|
141
|
+
options: Sequence[Never], # Type for empty or Never-inferred options
|
142
|
+
index: int = 0,
|
143
|
+
format_func: Callable[[Any], str] = str,
|
144
|
+
key: Key | None = None,
|
145
|
+
help: str | None = None,
|
146
|
+
on_change: WidgetCallback | None = None,
|
147
|
+
args: WidgetArgs | None = None,
|
148
|
+
kwargs: WidgetKwargs | None = None,
|
149
|
+
*, # keyword-only arguments:
|
150
|
+
placeholder: str | None = None,
|
151
|
+
disabled: bool = False,
|
152
|
+
label_visibility: LabelVisibility = "visible",
|
153
|
+
accept_new_options: Literal[False] = False,
|
154
|
+
width: WidthWithoutContent = "stretch",
|
155
|
+
) -> None: ... # Returns None if options is empty and accept_new_options is False
|
156
|
+
|
135
157
|
@overload
|
136
158
|
def selectbox(
|
137
159
|
self,
|
@@ -23,6 +23,7 @@ from typing import (
|
|
23
23
|
TYPE_CHECKING,
|
24
24
|
Any,
|
25
25
|
Final,
|
26
|
+
TypedDict,
|
26
27
|
TypeVar,
|
27
28
|
Union,
|
28
29
|
cast,
|
@@ -155,6 +156,13 @@ def _micros_to_datetime(micros: int, orig_tz: tzinfo | None) -> datetime:
|
|
155
156
|
return utc_dt.replace(tzinfo=orig_tz)
|
156
157
|
|
157
158
|
|
159
|
+
class SliderDefaultValues(TypedDict):
|
160
|
+
min_value: SliderScalar
|
161
|
+
max_value: SliderScalar
|
162
|
+
step: SliderStep
|
163
|
+
format: str
|
164
|
+
|
165
|
+
|
158
166
|
@dataclass
|
159
167
|
class SliderSerde:
|
160
168
|
value: list[float]
|
@@ -192,14 +200,21 @@ class SliderSerde:
|
|
192
200
|
|
193
201
|
def serialize(self, v: Any) -> list[Any]:
|
194
202
|
range_value = isinstance(v, (list, tuple))
|
195
|
-
|
203
|
+
# Convert to list to handle tuples
|
204
|
+
processed_value = list(v) if range_value else [v]
|
205
|
+
|
196
206
|
if self.data_type == SliderProto.DATE:
|
197
|
-
|
207
|
+
return [
|
208
|
+
_datetime_to_micros(_date_to_datetime(val)) for val in processed_value
|
209
|
+
]
|
198
210
|
if self.data_type == SliderProto.TIME:
|
199
|
-
|
211
|
+
return [
|
212
|
+
_datetime_to_micros(_time_to_datetime(val)) for val in processed_value
|
213
|
+
]
|
200
214
|
if self.data_type == SliderProto.DATETIME:
|
201
|
-
|
202
|
-
|
215
|
+
return [_datetime_to_micros(val) for val in processed_value]
|
216
|
+
# For numeric types, ensure they are floats if not already
|
217
|
+
return [float(val) for val in processed_value]
|
203
218
|
|
204
219
|
|
205
220
|
class SliderMixin:
|
@@ -222,6 +237,7 @@ class SliderMixin:
|
|
222
237
|
*,
|
223
238
|
disabled: bool = False,
|
224
239
|
label_visibility: LabelVisibility = "visible",
|
240
|
+
width: WidthWithoutContent = "stretch",
|
225
241
|
) -> int: ...
|
226
242
|
|
227
243
|
# If min-value or max_value is provided and a numeric type, and value (if provided)
|
@@ -243,6 +259,7 @@ class SliderMixin:
|
|
243
259
|
*,
|
244
260
|
disabled: bool = False,
|
245
261
|
label_visibility: LabelVisibility = "visible",
|
262
|
+
width: WidthWithoutContent = "stretch",
|
246
263
|
) -> SliderNumericT: ...
|
247
264
|
|
248
265
|
# If value is provided and a sequence of numeric type,
|
@@ -264,6 +281,7 @@ class SliderMixin:
|
|
264
281
|
kwargs: WidgetKwargs | None = None,
|
265
282
|
disabled: bool = False,
|
266
283
|
label_visibility: LabelVisibility = "visible",
|
284
|
+
width: WidthWithoutContent = "stretch",
|
267
285
|
) -> tuple[SliderNumericT, SliderNumericT]: ...
|
268
286
|
|
269
287
|
# If value is provided positionally and a sequence of numeric type,
|
@@ -285,6 +303,7 @@ class SliderMixin:
|
|
285
303
|
*,
|
286
304
|
disabled: bool = False,
|
287
305
|
label_visibility: LabelVisibility = "visible",
|
306
|
+
width: WidthWithoutContent = "stretch",
|
288
307
|
) -> tuple[SliderNumericT, SliderNumericT]: ...
|
289
308
|
|
290
309
|
# If min-value is provided and a datelike type, and value (if provided)
|
@@ -306,6 +325,7 @@ class SliderMixin:
|
|
306
325
|
*,
|
307
326
|
disabled: bool = False,
|
308
327
|
label_visibility: LabelVisibility = "visible",
|
328
|
+
width: WidthWithoutContent = "stretch",
|
309
329
|
) -> SliderDatelikeT: ...
|
310
330
|
|
311
331
|
# If max-value is provided and a datelike type, and value (if provided)
|
@@ -314,7 +334,7 @@ class SliderMixin:
|
|
314
334
|
def slider(
|
315
335
|
self,
|
316
336
|
label: str,
|
317
|
-
min_value:
|
337
|
+
min_value: None = None,
|
318
338
|
*,
|
319
339
|
max_value: SliderDatelikeT,
|
320
340
|
value: SliderDatelikeT | None = None,
|
@@ -327,6 +347,7 @@ class SliderMixin:
|
|
327
347
|
kwargs: WidgetKwargs | None = None,
|
328
348
|
disabled: bool = False,
|
329
349
|
label_visibility: LabelVisibility = "visible",
|
350
|
+
width: WidthWithoutContent = "stretch",
|
330
351
|
) -> SliderDatelikeT: ...
|
331
352
|
|
332
353
|
# If value is provided and a datelike type, return the same datelike type.
|
@@ -334,8 +355,8 @@ class SliderMixin:
|
|
334
355
|
def slider(
|
335
356
|
self,
|
336
357
|
label: str,
|
337
|
-
min_value:
|
338
|
-
max_value:
|
358
|
+
min_value: None = None,
|
359
|
+
max_value: None = None,
|
339
360
|
*,
|
340
361
|
value: SliderDatelikeT,
|
341
362
|
step: StepDatelikeT | None = None,
|
@@ -347,6 +368,7 @@ class SliderMixin:
|
|
347
368
|
kwargs: WidgetKwargs | None = None,
|
348
369
|
disabled: bool = False,
|
349
370
|
label_visibility: LabelVisibility = "visible",
|
371
|
+
width: WidthWithoutContent = "stretch",
|
350
372
|
) -> SliderDatelikeT: ...
|
351
373
|
|
352
374
|
# If value is provided and a sequence of datelike type,
|
@@ -358,7 +380,9 @@ class SliderMixin:
|
|
358
380
|
min_value: SliderDatelikeT | None = None,
|
359
381
|
max_value: SliderDatelikeT | None = None,
|
360
382
|
*,
|
361
|
-
value:
|
383
|
+
value: list[SliderDatelikeT]
|
384
|
+
| tuple[SliderDatelikeT]
|
385
|
+
| tuple[SliderDatelikeT, SliderDatelikeT],
|
362
386
|
step: StepDatelikeT | None = None,
|
363
387
|
format: str | None = None,
|
364
388
|
key: Key | None = None,
|
@@ -368,6 +392,7 @@ class SliderMixin:
|
|
368
392
|
kwargs: WidgetKwargs | None = None,
|
369
393
|
disabled: bool = False,
|
370
394
|
label_visibility: LabelVisibility = "visible",
|
395
|
+
width: WidthWithoutContent = "stretch",
|
371
396
|
) -> tuple[SliderDatelikeT, SliderDatelikeT]: ...
|
372
397
|
|
373
398
|
# If value is provided positionally and a sequence of datelike type,
|
@@ -390,6 +415,7 @@ class SliderMixin:
|
|
390
415
|
*,
|
391
416
|
disabled: bool = False,
|
392
417
|
label_visibility: LabelVisibility = "visible",
|
418
|
+
width: WidthWithoutContent = "stretch",
|
393
419
|
) -> tuple[SliderDatelikeT, SliderDatelikeT]: ...
|
394
420
|
|
395
421
|
# https://github.com/python/mypy/issues/17614
|
@@ -316,6 +316,11 @@ def get_data_cache_stats_provider() -> CacheStatsProvider:
|
|
316
316
|
return _data_caches
|
317
317
|
|
318
318
|
|
319
|
+
# Type-annotate the decorator function.
|
320
|
+
# (See https://mypy.readthedocs.io/en/stable/generics.html#decorator-factories)
|
321
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
322
|
+
|
323
|
+
|
319
324
|
class CacheDataAPI:
|
320
325
|
"""Implements the public st.cache_data API: the @st.cache_data decorator, and
|
321
326
|
st.cache_data.clear().
|
@@ -336,10 +341,6 @@ class CacheDataAPI:
|
|
336
341
|
decorator_metric_name, self._decorator
|
337
342
|
)
|
338
343
|
|
339
|
-
# Type-annotate the decorator function.
|
340
|
-
# (See https://mypy.readthedocs.io/en/stable/generics.html#decorator-factories)
|
341
|
-
F = TypeVar("F", bound=Callable[..., Any])
|
342
|
-
|
343
344
|
# Bare decorator usage
|
344
345
|
@overload
|
345
346
|
def __call__(self, func: F) -> F: ...
|
@@ -566,16 +567,19 @@ class CacheDataAPI:
|
|
566
567
|
if experimental_allow_widgets:
|
567
568
|
show_widget_replay_deprecation("cache_data")
|
568
569
|
|
569
|
-
def wrapper(f
|
570
|
-
return
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
570
|
+
def wrapper(f: F) -> F:
|
571
|
+
return cast(
|
572
|
+
"F",
|
573
|
+
make_cached_func_wrapper(
|
574
|
+
CachedDataFuncInfo(
|
575
|
+
func=f, # type: ignore
|
576
|
+
persist=persist_string,
|
577
|
+
show_spinner=show_spinner,
|
578
|
+
max_entries=max_entries,
|
579
|
+
ttl=ttl,
|
580
|
+
hash_funcs=hash_funcs,
|
581
|
+
)
|
582
|
+
),
|
579
583
|
)
|
580
584
|
|
581
585
|
if func is None:
|
@@ -134,11 +134,10 @@ def _mpa_v1(main_script_path: str) -> None:
|
|
134
134
|
PAGES_FOLDER = MAIN_SCRIPT_PATH.parent / "pages"
|
135
135
|
|
136
136
|
# Read out the my_pages folder and create a page for every script:
|
137
|
-
pages = PAGES_FOLDER.glob("*.py")
|
138
137
|
pages = sorted(
|
139
138
|
[
|
140
139
|
page
|
141
|
-
for page in
|
140
|
+
for page in PAGES_FOLDER.glob("*.py")
|
142
141
|
if page.name.endswith(".py")
|
143
142
|
and not page.name.startswith(".")
|
144
143
|
and page.name != "__init__.py"
|
streamlit/runtime/secrets.py
CHANGED
@@ -45,29 +45,31 @@ class SecretErrorMessages:
|
|
45
45
|
"""
|
46
46
|
|
47
47
|
def __init__(self) -> None:
|
48
|
-
self.missing_attr_message = lambda attr_name: (
|
48
|
+
self.missing_attr_message: Callable[[str], str] = lambda attr_name: (
|
49
49
|
f'st.secrets has no attribute "{attr_name}". '
|
50
50
|
"Did you forget to add it to secrets.toml, mount it to secret directory, or the app settings "
|
51
51
|
"on Streamlit Cloud? More info: "
|
52
52
|
"https://docs.streamlit.io/deploy/streamlit-community-cloud/deploy-your-app/secrets-management"
|
53
53
|
)
|
54
|
-
self.missing_key_message = lambda key: (
|
54
|
+
self.missing_key_message: Callable[[str], str] = lambda key: (
|
55
55
|
f'st.secrets has no key "{key}". '
|
56
56
|
"Did you forget to add it to secrets.toml, mount it to secret directory, or the app settings "
|
57
57
|
"on Streamlit Cloud? More info: "
|
58
58
|
"https://docs.streamlit.io/deploy/streamlit-community-cloud/deploy-your-app/secrets-management"
|
59
59
|
)
|
60
|
-
self.no_secrets_found = lambda file_paths: (
|
60
|
+
self.no_secrets_found: Callable[[list[str]], str] = lambda file_paths: (
|
61
61
|
f"No secrets found. Valid paths for a secrets.toml file or secret directories are: {', '.join(file_paths)}"
|
62
62
|
)
|
63
|
-
self.error_parsing_file_at_path = (
|
63
|
+
self.error_parsing_file_at_path: Callable[[str, Exception], str] = (
|
64
64
|
lambda path, ex: f"Error parsing secrets file at {path}: {ex}"
|
65
65
|
)
|
66
|
-
self.subfolder_path_is_not_a_folder
|
67
|
-
|
68
|
-
|
66
|
+
self.subfolder_path_is_not_a_folder: Callable[[str], str] = (
|
67
|
+
lambda sub_folder_path: (
|
68
|
+
f"{sub_folder_path} is not a folder. "
|
69
|
+
"To use directory based secrets, mount every secret in a subfolder under the secret directory"
|
70
|
+
)
|
69
71
|
)
|
70
|
-
self.invalid_secret_path = lambda path: (
|
72
|
+
self.invalid_secret_path: Callable[[str], str] = lambda path: (
|
71
73
|
f"Invalid secrets path: {path}: path is not a .toml file or a directory"
|
72
74
|
)
|
73
75
|
|
@@ -15,7 +15,7 @@
|
|
15
15
|
from __future__ import annotations
|
16
16
|
|
17
17
|
from collections.abc import Iterable, Iterator, MutableMapping
|
18
|
-
from typing import TYPE_CHECKING, overload
|
18
|
+
from typing import TYPE_CHECKING, Any, overload
|
19
19
|
|
20
20
|
from streamlit.runtime.metrics_util import gather_metrics
|
21
21
|
from streamlit.runtime.state.session_state_proxy import get_session_state
|
@@ -55,7 +55,7 @@ class QueryParamsProxy(MutableMapping[str, str]):
|
|
55
55
|
del qp[key]
|
56
56
|
|
57
57
|
@gather_metrics("query_params.set_item")
|
58
|
-
def __setitem__(self, key: str, value:
|
58
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
59
59
|
with get_session_state().query_params() as qp:
|
60
60
|
qp[key] = value
|
61
61
|
|
@@ -76,18 +76,18 @@ class QueryParamsProxy(MutableMapping[str, str]):
|
|
76
76
|
|
77
77
|
@overload
|
78
78
|
def update(
|
79
|
-
self,
|
79
|
+
self, params: SupportsKeysAndGetItem[str, str | Iterable[str]], /, **kwds: str
|
80
80
|
) -> None: ...
|
81
81
|
|
82
82
|
@overload
|
83
83
|
def update(
|
84
|
-
self,
|
84
|
+
self, params: Iterable[tuple[str, str | Iterable[str]]], /, **kwds: str
|
85
85
|
) -> None: ...
|
86
86
|
|
87
87
|
@overload
|
88
88
|
def update(self, **kwds: str | Iterable[str]) -> None: ...
|
89
89
|
|
90
|
-
def update(self,
|
90
|
+
def update(self, params=(), /, **kwds) -> None: # type: ignore
|
91
91
|
"""
|
92
92
|
Update one or more values in query_params at once from a dictionary or
|
93
93
|
dictionary-like object.
|
@@ -102,10 +102,10 @@ class QueryParamsProxy(MutableMapping[str, str]):
|
|
102
102
|
Additional key/value pairs to update passed as keyword arguments.
|
103
103
|
"""
|
104
104
|
with get_session_state().query_params() as qp:
|
105
|
-
qp.update(
|
105
|
+
qp.update(params, **kwds)
|
106
106
|
|
107
107
|
@gather_metrics("query_params.set_attr")
|
108
|
-
def __setattr__(self, key: str, value:
|
108
|
+
def __setattr__(self, key: str, value: Any) -> None:
|
109
109
|
with get_session_state().query_params() as qp:
|
110
110
|
qp[key] = value
|
111
111
|
|
@@ -165,17 +165,19 @@ class QueryParamsProxy(MutableMapping[str, str]):
|
|
165
165
|
return qp.to_dict()
|
166
166
|
|
167
167
|
@overload
|
168
|
-
def from_dict(
|
169
|
-
self, keys_and_values: Iterable[tuple[str, str | Iterable[str]]]
|
170
|
-
) -> None: ...
|
168
|
+
def from_dict(self, params: Iterable[tuple[str, str | Iterable[str]]]) -> None: ...
|
171
169
|
|
172
170
|
@overload
|
173
171
|
def from_dict(
|
174
|
-
self,
|
172
|
+
self, params: SupportsKeysAndGetItem[str, str | Iterable[str]]
|
175
173
|
) -> None: ...
|
176
174
|
|
177
175
|
@gather_metrics("query_params.from_dict")
|
178
|
-
def from_dict(
|
176
|
+
def from_dict(
|
177
|
+
self,
|
178
|
+
params: SupportsKeysAndGetItem[str, str | Iterable[str]]
|
179
|
+
| Iterable[tuple[str, str | Iterable[str]]],
|
180
|
+
) -> None:
|
179
181
|
"""
|
180
182
|
Set all of the query parameters from a dictionary or dictionary-like object.
|
181
183
|
|