streamlit-nightly 1.45.1.dev20250505__py3-none-any.whl → 1.45.1.dev20250507__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 +4 -1
- streamlit/column_config.py +3 -1
- streamlit/commands/execution_control.py +3 -1
- streamlit/commands/logo.py +7 -2
- streamlit/connections/base_connection.py +2 -2
- streamlit/connections/snowflake_connection.py +4 -3
- streamlit/dataframe_util.py +2 -1
- streamlit/delta_generator.py +15 -35
- streamlit/elements/arrow.py +3 -3
- streamlit/elements/deck_gl_json_chart.py +1 -1
- streamlit/elements/exception.py +5 -1
- streamlit/elements/layouts.py +3 -9
- streamlit/elements/lib/column_types.py +2 -2
- streamlit/elements/lib/dialog.py +2 -1
- streamlit/elements/lib/js_number.py +4 -4
- streamlit/elements/lib/options_selector_utils.py +8 -5
- streamlit/elements/media.py +8 -7
- streamlit/elements/vega_charts.py +2 -2
- streamlit/elements/widgets/button.py +5 -6
- streamlit/elements/widgets/number_input.py +81 -28
- streamlit/elements/widgets/slider.py +87 -35
- streamlit/errors.py +9 -6
- streamlit/runtime/caching/cache_data_api.py +7 -9
- streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
- streamlit/runtime/credentials.py +3 -3
- streamlit/runtime/fragment.py +2 -2
- streamlit/runtime/metrics_util.py +2 -2
- streamlit/runtime/runtime.py +1 -1
- streamlit/runtime/runtime_util.py +2 -1
- streamlit/runtime/scriptrunner/script_runner.py +3 -3
- streamlit/runtime/scriptrunner_utils/script_run_context.py +1 -0
- streamlit/runtime/secrets.py +14 -7
- streamlit/runtime/state/query_params.py +8 -8
- streamlit/runtime/state/session_state.py +8 -1
- streamlit/string_util.py +8 -5
- streamlit/web/bootstrap.py +2 -2
- streamlit/web/cli.py +2 -1
- streamlit/web/server/browser_websocket_handler.py +3 -2
- streamlit/web/server/component_request_handler.py +7 -7
- streamlit/web/server/media_file_handler.py +2 -2
- streamlit/web/server/oauth_authlib_routes.py +3 -3
- streamlit/web/server/routes.py +2 -2
- streamlit/web/server/server.py +4 -4
- streamlit/web/server/upload_file_request_handler.py +4 -3
- streamlit/web/server/websocket_headers.py +1 -1
- {streamlit_nightly-1.45.1.dev20250505.dist-info → streamlit_nightly-1.45.1.dev20250507.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.45.1.dev20250505.dist-info → streamlit_nightly-1.45.1.dev20250507.dist-info}/RECORD +51 -51
- {streamlit_nightly-1.45.1.dev20250505.data → streamlit_nightly-1.45.1.dev20250507.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.1.dev20250505.dist-info → streamlit_nightly-1.45.1.dev20250507.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.45.1.dev20250505.dist-info → streamlit_nightly-1.45.1.dev20250507.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.1.dev20250505.dist-info → streamlit_nightly-1.45.1.dev20250507.dist-info}/top_level.txt +0 -0
streamlit/__init__.py
CHANGED
@@ -286,7 +286,10 @@ experimental_dialog = _experimental_dialog_decorator
|
|
286
286
|
experimental_fragment = _experimental_fragment
|
287
287
|
experimental_user = _DeprecatedUserInfoProxy()
|
288
288
|
|
289
|
-
_EXPERIMENTAL_QUERY_PARAMS_DEPRECATE_MSG =
|
289
|
+
_EXPERIMENTAL_QUERY_PARAMS_DEPRECATE_MSG = (
|
290
|
+
"Refer to our [docs page](https://docs.streamlit.io/develop/api-reference/caching-and-state/st.query_params) "
|
291
|
+
"for more information."
|
292
|
+
)
|
290
293
|
|
291
294
|
experimental_get_query_params = _deprecate_func_name(
|
292
295
|
_get_query_params,
|
streamlit/column_config.py
CHANGED
@@ -12,7 +12,9 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
"""Column types that can be configured via the ``column_config`` parameter of
|
15
|
+
"""Column types that can be configured via the ``column_config`` parameter of
|
16
|
+
``st.dataframe`` and ``st.data_editor``.
|
17
|
+
"""
|
16
18
|
|
17
19
|
from __future__ import annotations
|
18
20
|
|
@@ -219,7 +219,9 @@ def switch_page(page: str | Path | StreamlitPage) -> NoReturn: # type: ignore[m
|
|
219
219
|
|
220
220
|
if len(matched_pages) == 0:
|
221
221
|
raise StreamlitAPIException(
|
222
|
-
f"Could not find page: `{page}`. Must be the file path relative to the main script,
|
222
|
+
f"Could not find page: `{page}`. Must be the file path relative to the main script, "
|
223
|
+
f"from the directory: `{os.path.basename(main_script_directory)}`. Only the main app file "
|
224
|
+
"and files in the `pages/` directory are supported."
|
223
225
|
)
|
224
226
|
|
225
227
|
page_script_hash = matched_pages[0]["page_script_hash"]
|
streamlit/commands/logo.py
CHANGED
@@ -27,7 +27,11 @@ from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_r
|
|
27
27
|
|
28
28
|
|
29
29
|
def _invalid_logo_text(field_name: str):
|
30
|
-
return
|
30
|
+
return (
|
31
|
+
f"The {field_name} passed to st.logo is invalid - See "
|
32
|
+
"[documentation](https://docs.streamlit.io/develop/api-reference/media/st.logo) "
|
33
|
+
"for more information on valid types"
|
34
|
+
)
|
31
35
|
|
32
36
|
|
33
37
|
@gather_metrics("logo")
|
@@ -154,7 +158,8 @@ def logo(
|
|
154
158
|
fwd_msg.logo.link = link
|
155
159
|
else:
|
156
160
|
raise StreamlitAPIException(
|
157
|
-
f"Invalid link: {link} - the link param supports external links only and must
|
161
|
+
f"Invalid link: {link} - the link param supports external links only and must "
|
162
|
+
f"start with either http:// or https://."
|
158
163
|
)
|
159
164
|
|
160
165
|
if icon_image:
|
@@ -78,12 +78,12 @@ class BaseConnection(ABC, Generic[RawConnectionT]):
|
|
78
78
|
def __getattribute__(self, name: str) -> Any:
|
79
79
|
try:
|
80
80
|
return object.__getattribute__(self, name)
|
81
|
-
except AttributeError
|
81
|
+
except AttributeError:
|
82
82
|
if hasattr(self._instance, name):
|
83
83
|
raise AttributeError(
|
84
84
|
f"`{name}` doesn't exist here, but you can call `._instance.{name}` instead"
|
85
85
|
)
|
86
|
-
raise
|
86
|
+
raise
|
87
87
|
|
88
88
|
# Methods with default implementations that we don't expect subclasses to want or
|
89
89
|
# need to overwrite.
|
@@ -263,16 +263,17 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
263
263
|
return snowflake.connector.connect()
|
264
264
|
|
265
265
|
return snowflake.connector.connect(**kwargs)
|
266
|
-
except SnowflakeError
|
266
|
+
except SnowflakeError:
|
267
267
|
if not len(st_secrets) and not kwargs:
|
268
268
|
raise StreamlitAPIException(
|
269
269
|
"Missing Snowflake connection configuration. "
|
270
270
|
"Did you forget to set this in `secrets.toml`, a Snowflake configuration file, "
|
271
271
|
"or as kwargs to `st.connection`? "
|
272
|
-
"See the [SnowflakeConnection configuration documentation]
|
272
|
+
"See the [SnowflakeConnection configuration documentation]"
|
273
|
+
"(https://docs.streamlit.io/st.connections.snowflakeconnection-configuration) "
|
273
274
|
"for more details and examples."
|
274
275
|
)
|
275
|
-
raise
|
276
|
+
raise
|
276
277
|
|
277
278
|
def query(
|
278
279
|
self,
|
streamlit/dataframe_util.py
CHANGED
@@ -1319,7 +1319,8 @@ def convert_pandas_df_to_data_format(
|
|
1319
1319
|
|
1320
1320
|
Returns
|
1321
1321
|
-------
|
1322
|
-
pd.DataFrame, pd.Series, pyarrow.Table, np.ndarray, xarray.Dataset,
|
1322
|
+
pd.DataFrame, pd.Series, pyarrow.Table, np.ndarray, xarray.Dataset,
|
1323
|
+
xarray.DataArray, polars.Dataframe, polars.Series, list, set, tuple, or dict.
|
1323
1324
|
The converted dataframe.
|
1324
1325
|
"""
|
1325
1326
|
|
streamlit/delta_generator.py
CHANGED
@@ -147,6 +147,19 @@ def _maybe_print_use_warning() -> None:
|
|
147
147
|
)
|
148
148
|
|
149
149
|
|
150
|
+
def _maybe_print_fragment_callback_warning() -> None:
|
151
|
+
"""Print a warning if elements are being modified during a fragment callback."""
|
152
|
+
ctx = get_script_run_ctx()
|
153
|
+
if ctx and getattr(ctx, "in_fragment_callback", False):
|
154
|
+
warning = cli_util.style_for_cli("Warning:", bold=True, fg="yellow")
|
155
|
+
|
156
|
+
logger.get_logger("root").warning(
|
157
|
+
f"\n {warning} A fragment rerun was triggered with a callback that displays one or more elements. "
|
158
|
+
"During a fragment rerun, within a callback, displaying elements is not officially supported because "
|
159
|
+
"those elements will replace the existing elements at the top of your app."
|
160
|
+
)
|
161
|
+
|
162
|
+
|
150
163
|
class DeltaGenerator(
|
151
164
|
AlertMixin,
|
152
165
|
AudioInputMixin,
|
@@ -454,6 +467,8 @@ class DeltaGenerator(
|
|
454
467
|
|
455
468
|
# Warn if an element is being changed but the user isn't running the streamlit server.
|
456
469
|
_maybe_print_use_warning()
|
470
|
+
# Warn if an element is being changed during a fragment callback.
|
471
|
+
_maybe_print_fragment_callback_warning()
|
457
472
|
|
458
473
|
# Copy the marshalled proto into the overall msg proto
|
459
474
|
msg = ForwardMsg_pb2.ForwardMsg()
|
@@ -514,9 +529,6 @@ class DeltaGenerator(
|
|
514
529
|
|
515
530
|
# Prevent nested columns & expanders by checking all parents.
|
516
531
|
block_type = block_proto.WhichOneof("type")
|
517
|
-
# Convert the generator to a list, so we can use it multiple times.
|
518
|
-
ancestor_block_types = list(dg._ancestor_block_types)
|
519
|
-
_check_nested_element_violation(self, block_type, ancestor_block_types)
|
520
532
|
|
521
533
|
if dg._root_container is None or dg._cursor is None:
|
522
534
|
return dg
|
@@ -569,35 +581,3 @@ def _writes_directly_to_sidebar(dg: DeltaGenerator) -> bool:
|
|
569
581
|
in_sidebar = any(a._root_container == RootContainer.SIDEBAR for a in dg._ancestors)
|
570
582
|
has_container = bool(list(dg._ancestor_block_types))
|
571
583
|
return in_sidebar and not has_container
|
572
|
-
|
573
|
-
|
574
|
-
def _check_nested_element_violation(
|
575
|
-
dg: DeltaGenerator, block_type: str | None, ancestor_block_types: list[BlockType]
|
576
|
-
) -> None:
|
577
|
-
"""Check if elements are nested in a forbidden way.
|
578
|
-
|
579
|
-
Raises
|
580
|
-
------
|
581
|
-
StreamlitAPIException: throw if an invalid element nesting is detected.
|
582
|
-
"""
|
583
|
-
|
584
|
-
if block_type == "column":
|
585
|
-
num_of_parent_columns = dg._count_num_of_parent_columns(ancestor_block_types)
|
586
|
-
if dg._root_container == RootContainer.SIDEBAR and num_of_parent_columns > 0:
|
587
|
-
raise StreamlitAPIException(
|
588
|
-
"Columns cannot be placed inside other columns in the sidebar. This is only possible in the main area of the app."
|
589
|
-
)
|
590
|
-
if num_of_parent_columns > 1:
|
591
|
-
raise StreamlitAPIException(
|
592
|
-
"Columns can only be placed inside other columns up to one level of nesting."
|
593
|
-
)
|
594
|
-
if block_type == "chat_message" and block_type in ancestor_block_types:
|
595
|
-
raise StreamlitAPIException(
|
596
|
-
"Chat messages cannot nested inside other chat messages."
|
597
|
-
)
|
598
|
-
if block_type == "expandable" and block_type in ancestor_block_types:
|
599
|
-
raise StreamlitAPIException(
|
600
|
-
"Expanders may not be nested inside other expanders."
|
601
|
-
)
|
602
|
-
if block_type == "popover" and block_type in ancestor_block_types:
|
603
|
-
raise StreamlitAPIException("Popovers may not be nested inside other popovers.")
|
streamlit/elements/arrow.py
CHANGED
@@ -370,7 +370,7 @@ class ArrowMixin:
|
|
370
370
|
|
371
371
|
- A column type within ``st.column_config``: Streamlit applies the
|
372
372
|
defined configuration to the column. For example, use
|
373
|
-
``st.column_config.NumberColumn("Dollar values
|
373
|
+
``st.column_config.NumberColumn("Dollar values", format="$ %d")``
|
374
374
|
to change the displayed name of the column to "Dollar values"
|
375
375
|
and add a "$" prefix in each cell. For more info on the
|
376
376
|
available column types and config options, see
|
@@ -789,7 +789,7 @@ class ArrowMixin:
|
|
789
789
|
... )
|
790
790
|
>>> my_chart.add_rows(some_fancy_name=df2) # <-- name used as keyword
|
791
791
|
|
792
|
-
"""
|
792
|
+
""" # noqa: E501
|
793
793
|
return _arrow_add_rows(self.dg, data, **kwargs)
|
794
794
|
|
795
795
|
@property
|
@@ -948,7 +948,7 @@ def marshall(proto: ArrowProto, data: Data, default_uuid: str | None = None) ->
|
|
948
948
|
This attribute is optional and only used for pandas.Styler, other elements
|
949
949
|
(e.g. charts) can ignore it.
|
950
950
|
|
951
|
-
"""
|
951
|
+
""" # noqa: E501
|
952
952
|
|
953
953
|
if dataframe_util.is_pandas_styler(data):
|
954
954
|
# default_uuid is a string only if the data is a `Styler`,
|
@@ -268,7 +268,7 @@ class PydeckMixin:
|
|
268
268
|
height: int | None = None,
|
269
269
|
selection_mode: Literal[
|
270
270
|
"single-object"
|
271
|
-
], # Selection mode will only be activated by on_select param
|
271
|
+
], # Selection mode will only be activated by on_select param; default value here to make it work with mypy
|
272
272
|
on_select: Literal["ignore"], # No default value here to make it work with mypy
|
273
273
|
key: Key | None = None,
|
274
274
|
) -> DeltaGenerator: ...
|
streamlit/elements/exception.py
CHANGED
@@ -38,7 +38,11 @@ _LOGGER: Final = get_logger(__name__)
|
|
38
38
|
|
39
39
|
# When client.showErrorDetails is False, we show a generic warning in the
|
40
40
|
# frontend when we encounter an uncaught app exception.
|
41
|
-
_GENERIC_UNCAUGHT_EXCEPTION_TEXT: Final =
|
41
|
+
_GENERIC_UNCAUGHT_EXCEPTION_TEXT: Final = (
|
42
|
+
"This app has encountered an error. The original error message is redacted "
|
43
|
+
"to prevent data leaks. Full error details have been recorded in the logs "
|
44
|
+
"(if you're on Streamlit Cloud, click on 'Manage app' in the lower right of your app)."
|
45
|
+
)
|
42
46
|
|
43
47
|
|
44
48
|
class ExceptionMixin:
|
streamlit/elements/layouts.py
CHANGED
@@ -191,11 +191,8 @@ class LayoutsMixin:
|
|
191
191
|
(preferred) or just call methods directly on the returned object. See
|
192
192
|
examples below.
|
193
193
|
|
194
|
-
|
195
|
-
|
196
|
-
.. warning::
|
197
|
-
Columns cannot be placed inside other columns in the sidebar. This
|
198
|
-
is only possible in the main area of the app.
|
194
|
+
.. note::
|
195
|
+
We recommend against nesting columns more than once since it might look bad on smaller devices.
|
199
196
|
|
200
197
|
Parameters
|
201
198
|
----------
|
@@ -503,9 +500,6 @@ class LayoutsMixin:
|
|
503
500
|
(preferred) or just call methods directly on the returned object. See
|
504
501
|
examples below.
|
505
502
|
|
506
|
-
.. warning::
|
507
|
-
Currently, you may not put expanders inside another expander.
|
508
|
-
|
509
503
|
Parameters
|
510
504
|
----------
|
511
505
|
label : str
|
@@ -624,7 +618,7 @@ class LayoutsMixin:
|
|
624
618
|
See examples below.
|
625
619
|
|
626
620
|
.. warning::
|
627
|
-
|
621
|
+
We strongly advise against nesting popovers.
|
628
622
|
|
629
623
|
Parameters
|
630
624
|
----------
|
@@ -485,7 +485,7 @@ def NumberColumn(
|
|
485
485
|
.. output::
|
486
486
|
https://doc-number-column.streamlit.app/
|
487
487
|
height: 300px
|
488
|
-
"""
|
488
|
+
""" # noqa: E501
|
489
489
|
|
490
490
|
return ColumnConfig(
|
491
491
|
label=label,
|
@@ -2058,7 +2058,7 @@ def ProgressColumn(
|
|
2058
2058
|
.. output::
|
2059
2059
|
https://doc-progress-column.streamlit.app/
|
2060
2060
|
height: 300px
|
2061
|
-
"""
|
2061
|
+
""" # noqa: E501
|
2062
2062
|
|
2063
2063
|
return ColumnConfig(
|
2064
2064
|
label=label,
|
streamlit/elements/lib/dialog.py
CHANGED
@@ -67,7 +67,8 @@ def _assert_first_dialog_to_be_opened(should_open: bool) -> None:
|
|
67
67
|
if should_open and script_run_ctx:
|
68
68
|
if script_run_ctx.has_dialog_opened:
|
69
69
|
raise StreamlitAPIException(
|
70
|
-
"Only one dialog is allowed to be opened at the same time.
|
70
|
+
"Only one dialog is allowed to be opened at the same time. "
|
71
|
+
"Please make sure to not call a dialog-decorated function more than once in a script run."
|
71
72
|
)
|
72
73
|
script_run_ctx.has_dialog_opened = True
|
73
74
|
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
17
17
|
import numbers
|
18
18
|
|
19
19
|
|
20
|
-
class JSNumberBoundsException(Exception):
|
20
|
+
class JSNumberBoundsException(Exception): # noqa: N818
|
21
21
|
pass
|
22
22
|
|
23
23
|
|
@@ -67,7 +67,7 @@ class JSNumber:
|
|
67
67
|
raise JSNumberBoundsException(
|
68
68
|
f"{value_name} ({value}) must be >= -((1 << 53) - 1)"
|
69
69
|
)
|
70
|
-
|
70
|
+
if value > cls.MAX_SAFE_INTEGER:
|
71
71
|
raise JSNumberBoundsException(
|
72
72
|
f"{value_name} ({value}) must be <= (1 << 53) - 1"
|
73
73
|
)
|
@@ -95,11 +95,11 @@ class JSNumber:
|
|
95
95
|
|
96
96
|
if not isinstance(value, (numbers.Integral, float)):
|
97
97
|
raise JSNumberBoundsException(f"{value_name} ({value}) is not a float")
|
98
|
-
|
98
|
+
if value < cls.MIN_NEGATIVE_VALUE:
|
99
99
|
raise JSNumberBoundsException(
|
100
100
|
f"{value_name} ({value}) must be >= -1.797e+308"
|
101
101
|
)
|
102
|
-
|
102
|
+
if value > cls.MAX_VALUE:
|
103
103
|
raise JSNumberBoundsException(
|
104
104
|
f"{value_name} ({value}) must be <= 1.797e+308"
|
105
105
|
)
|
@@ -54,9 +54,12 @@ def index_(iterable: Iterable[_Value], x: _Value) -> int:
|
|
54
54
|
for i, value in enumerate(iterable):
|
55
55
|
if x == value:
|
56
56
|
return i
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
if (
|
58
|
+
isinstance(value, float)
|
59
|
+
and isinstance(x, float)
|
60
|
+
and abs(x - value) < _FLOAT_EQUALITY_EPSILON
|
61
|
+
):
|
62
|
+
return i
|
60
63
|
raise ValueError(f"{x} is not in iterable")
|
61
64
|
|
62
65
|
|
@@ -107,11 +110,11 @@ def _coerce_enum(from_enum_value: E1, to_enum_class: type[E2]) -> E1 | E2:
|
|
107
110
|
match as well. (This is configurable in streamlist configs)
|
108
111
|
"""
|
109
112
|
if not isinstance(from_enum_value, Enum):
|
110
|
-
raise ValueError(
|
113
|
+
raise ValueError( # noqa: TRY004
|
111
114
|
f"Expected an Enum in the first argument. Got {type(from_enum_value)}"
|
112
115
|
)
|
113
116
|
if not isinstance(to_enum_class, EnumMeta):
|
114
|
-
raise ValueError(
|
117
|
+
raise ValueError( # noqa: TRY004
|
115
118
|
f"Expected an EnumMeta/Type in the second argument. Got {type(to_enum_class)}"
|
116
119
|
)
|
117
120
|
if isinstance(from_enum_value, to_enum_class):
|
streamlit/elements/media.py
CHANGED
@@ -350,8 +350,9 @@ class MediaMixin:
|
|
350
350
|
`video subtitles feature demo <https://doc-video-subtitle-inputs.streamlit.app/>`_.
|
351
351
|
|
352
352
|
.. note::
|
353
|
-
Some videos may not display if they are encoded using MP4V (which is an export option in OpenCV),
|
354
|
-
not widely supported by browsers. Converting your video to H.264 will allow
|
353
|
+
Some videos may not display if they are encoded using MP4V (which is an export option in OpenCV),
|
354
|
+
as this codec is not widely supported by browsers. Converting your video to H.264 will allow
|
355
|
+
the video to be displayed in Streamlit.
|
355
356
|
See this `StackOverflow post <https://stackoverflow.com/a/49535220/2394542>`_ or this
|
356
357
|
`Streamlit forum post <https://discuss.streamlit.io/t/st-video-doesnt-show-opencv-generated-mp4/3193/2>`_
|
357
358
|
for more information.
|
@@ -453,8 +454,7 @@ def _marshall_av_media(
|
|
453
454
|
read_data = data.read()
|
454
455
|
if read_data is None:
|
455
456
|
return
|
456
|
-
|
457
|
-
data_or_filename = read_data
|
457
|
+
data_or_filename = read_data
|
458
458
|
elif type_util.is_type(data, "numpy.ndarray"):
|
459
459
|
data_or_filename = data.tobytes()
|
460
460
|
else:
|
@@ -505,8 +505,9 @@ def marshall_video(
|
|
505
505
|
subtitles: str, dict, or io.BytesIO
|
506
506
|
Optional subtitle data for the video, supporting several input types:
|
507
507
|
- None (default): No subtitles.
|
508
|
-
- A string: File path to a subtitle file in '.vtt' or '.srt' formats, or the raw content
|
509
|
-
If providing raw content, the string must
|
508
|
+
- A string: File path to a subtitle file in '.vtt' or '.srt' formats, or the raw content
|
509
|
+
of subtitles conforming to these formats. If providing raw content, the string must
|
510
|
+
adhere to the WebVTT or SRT format specifications.
|
510
511
|
- A dictionary: Pairs of labels and file paths or raw subtitle content in '.vtt' or '.srt' formats.
|
511
512
|
Enables multiple subtitle tracks. The label will be shown in the video player.
|
512
513
|
Example: {'English': 'path/to/english.vtt', 'French': 'path/to/french.srt'}
|
@@ -621,7 +622,7 @@ def _parse_start_time_end_time(
|
|
621
622
|
try:
|
622
623
|
maybe_start_time = time_to_seconds(start_time, coerce_none_to_inf=False)
|
623
624
|
if maybe_start_time is None:
|
624
|
-
raise ValueError
|
625
|
+
raise ValueError # noqa: TRY301
|
625
626
|
start_time = int(maybe_start_time)
|
626
627
|
except (StreamlitAPIException, ValueError):
|
627
628
|
error_msg = TIMEDELTA_PARSE_ERROR_MESSAGE.format(
|
@@ -442,8 +442,8 @@ def _parse_selection_mode(
|
|
442
442
|
raise StreamlitAPIException(
|
443
443
|
"Selections are activated, but the provided chart spec does not "
|
444
444
|
"have any selections defined. To add selections to `st.altair_chart`, check out the documentation "
|
445
|
-
"[here](https://altair-viz.github.io/user_guide/interactions.html#selections-capturing-chart-interactions).
|
446
|
-
"For adding selections to `st.vega_lite_chart`, take a look "
|
445
|
+
"[here](https://altair-viz.github.io/user_guide/interactions.html#selections-capturing-chart-interactions)."
|
446
|
+
" For adding selections to `st.vega_lite_chart`, take a look "
|
447
447
|
"at the specification [here](https://vega.github.io/vega-lite/docs/selection.html)."
|
448
448
|
)
|
449
449
|
|
@@ -940,10 +940,9 @@ class ButtonMixin:
|
|
940
940
|
if is_url(page):
|
941
941
|
if label is None or label == "":
|
942
942
|
raise StreamlitMissingPageLabelError()
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
return self.dg._enqueue("page_link", page_link_proto)
|
943
|
+
page_link_proto.page = page
|
944
|
+
page_link_proto.external = True
|
945
|
+
return self.dg._enqueue("page_link", page_link_proto)
|
947
946
|
|
948
947
|
ctx_main_script = ""
|
949
948
|
all_app_pages = {}
|
@@ -1028,7 +1027,7 @@ class ButtonMixin:
|
|
1028
1027
|
raise StreamlitAPIException(
|
1029
1028
|
f"`st.button()` can't be used in an `st.form()`.{FORM_DOCS_INFO}"
|
1030
1029
|
)
|
1031
|
-
|
1030
|
+
if not is_in_form(self.dg) and is_form_submitter:
|
1032
1031
|
raise StreamlitAPIException(
|
1033
1032
|
f"`st.form_submit_button()` must be used inside an `st.form()`.{FORM_DOCS_INFO}"
|
1034
1033
|
)
|
@@ -1106,7 +1105,7 @@ def marshall_file(
|
|
1106
1105
|
data_as_bytes = data.read() or b""
|
1107
1106
|
mimetype = mimetype or "application/octet-stream"
|
1108
1107
|
else:
|
1109
|
-
raise
|
1108
|
+
raise StreamlitAPIException("Invalid binary data format: %s" % type(data))
|
1110
1109
|
|
1111
1110
|
if runtime.exists():
|
1112
1111
|
file_url = runtime.get_instance().media_file_mgr.add(
|
@@ -82,10 +82,6 @@ class NumberInputSerde:
|
|
82
82
|
|
83
83
|
|
84
84
|
class NumberInputMixin:
|
85
|
-
# For easier readability, all the arguments with un-changing types across these overload signatures have been
|
86
|
-
# collapsed onto a single line.
|
87
|
-
|
88
|
-
# fmt: off
|
89
85
|
# If "min_value: int" is given and all other numerical inputs are
|
90
86
|
# "int"s or not provided (value optionally being "min"), return "int"
|
91
87
|
# If "min_value: int, value: None" is given and all other numerical inputs
|
@@ -98,9 +94,19 @@ class NumberInputMixin:
|
|
98
94
|
max_value: int | None = None,
|
99
95
|
value: IntOrNone | Literal["min"] = "min",
|
100
96
|
step: int | None = None,
|
101
|
-
format: str | None = None,
|
102
|
-
|
103
|
-
|
97
|
+
format: str | None = None,
|
98
|
+
key: Key | None = None,
|
99
|
+
help: str | None = None,
|
100
|
+
on_change: WidgetCallback | None = None,
|
101
|
+
args: WidgetArgs | None = None,
|
102
|
+
kwargs: WidgetKwargs | None = None,
|
103
|
+
*,
|
104
|
+
placeholder: str | None = None,
|
105
|
+
disabled: bool = False,
|
106
|
+
label_visibility: LabelVisibility = "visible",
|
107
|
+
icon: str | None = None,
|
108
|
+
width: WidthWithoutContent = "stretch",
|
109
|
+
) -> int | IntOrNone: ...
|
104
110
|
|
105
111
|
# If "max_value: int" is given and all other numerical inputs are
|
106
112
|
# "int"s or not provided (value optionally being "min"), return "int"
|
@@ -115,9 +121,18 @@ class NumberInputMixin:
|
|
115
121
|
max_value: int,
|
116
122
|
value: IntOrNone | Literal["min"] = "min",
|
117
123
|
step: int | None = None,
|
118
|
-
format: str | None = None,
|
119
|
-
|
120
|
-
|
124
|
+
format: str | None = None,
|
125
|
+
key: Key | None = None,
|
126
|
+
help: str | None = None,
|
127
|
+
on_change: WidgetCallback | None = None,
|
128
|
+
args: WidgetArgs | None = None,
|
129
|
+
kwargs: WidgetKwargs | None = None,
|
130
|
+
placeholder: str | None = None,
|
131
|
+
disabled: bool = False,
|
132
|
+
label_visibility: LabelVisibility = "visible",
|
133
|
+
icon: str | None = None,
|
134
|
+
width: WidthWithoutContent = "stretch",
|
135
|
+
) -> int | IntOrNone: ...
|
121
136
|
|
122
137
|
# If "value=int" is given and all other numerical inputs are "int"s
|
123
138
|
# or not provided, return "int"
|
@@ -130,9 +145,18 @@ class NumberInputMixin:
|
|
130
145
|
*,
|
131
146
|
value: int,
|
132
147
|
step: int | None = None,
|
133
|
-
format: str | None = None,
|
134
|
-
|
135
|
-
|
148
|
+
format: str | None = None,
|
149
|
+
key: Key | None = None,
|
150
|
+
help: str | None = None,
|
151
|
+
on_change: WidgetCallback | None = None,
|
152
|
+
args: WidgetArgs | None = None,
|
153
|
+
kwargs: WidgetKwargs | None = None,
|
154
|
+
placeholder: str | None = None,
|
155
|
+
disabled: bool = False,
|
156
|
+
label_visibility: LabelVisibility = "visible",
|
157
|
+
icon: str | None = None,
|
158
|
+
width: WidthWithoutContent = "stretch",
|
159
|
+
) -> int: ...
|
136
160
|
|
137
161
|
# If "step=int" is given and all other numerical inputs are "int"s
|
138
162
|
# or not provided (value optionally being "min"), return "int"
|
@@ -147,9 +171,18 @@ class NumberInputMixin:
|
|
147
171
|
value: IntOrNone | Literal["min"] = "min",
|
148
172
|
*,
|
149
173
|
step: int,
|
150
|
-
format: str | None = None,
|
151
|
-
|
152
|
-
|
174
|
+
format: str | None = None,
|
175
|
+
key: Key | None = None,
|
176
|
+
help: str | None = None,
|
177
|
+
on_change: WidgetCallback | None = None,
|
178
|
+
args: WidgetArgs | None = None,
|
179
|
+
kwargs: WidgetKwargs | None = None,
|
180
|
+
placeholder: str | None = None,
|
181
|
+
disabled: bool = False,
|
182
|
+
label_visibility: LabelVisibility = "visible",
|
183
|
+
icon: str | None = None,
|
184
|
+
width: WidthWithoutContent = "stretch",
|
185
|
+
) -> int | IntOrNone: ...
|
153
186
|
|
154
187
|
# If all numerical inputs are floats (with value optionally being "min")
|
155
188
|
# or are not provided, return "float"
|
@@ -163,10 +196,19 @@ class NumberInputMixin:
|
|
163
196
|
max_value: float | None = None,
|
164
197
|
value: FloatOrNone | Literal["min"] = "min",
|
165
198
|
step: float | None = None,
|
166
|
-
format: str | None = None,
|
167
|
-
|
168
|
-
|
169
|
-
|
199
|
+
format: str | None = None,
|
200
|
+
key: Key | None = None,
|
201
|
+
help: str | None = None,
|
202
|
+
on_change: WidgetCallback | None = None,
|
203
|
+
args: WidgetArgs | None = None,
|
204
|
+
kwargs: WidgetKwargs | None = None,
|
205
|
+
*,
|
206
|
+
placeholder: str | None = None,
|
207
|
+
disabled: bool = False,
|
208
|
+
label_visibility: LabelVisibility = "visible",
|
209
|
+
icon: str | None = None,
|
210
|
+
width: WidthWithoutContent = "stretch",
|
211
|
+
) -> float | FloatOrNone: ...
|
170
212
|
|
171
213
|
@gather_metrics("number_input")
|
172
214
|
def number_input(
|
@@ -426,7 +468,9 @@ class NumberInputMixin:
|
|
426
468
|
)
|
427
469
|
|
428
470
|
if not all_int_args and not all_float_args:
|
429
|
-
raise StreamlitMixedNumericTypesError(
|
471
|
+
raise StreamlitMixedNumericTypesError(
|
472
|
+
value=value, min_value=min_value, max_value=max_value, step=step
|
473
|
+
)
|
430
474
|
|
431
475
|
session_state = get_session_state().filtered_state
|
432
476
|
if key is not None and key in session_state and session_state[key] is None:
|
@@ -480,7 +524,6 @@ class NumberInputMixin:
|
|
480
524
|
except (TypeError, ValueError):
|
481
525
|
raise StreamlitInvalidNumberFormatError(number_format)
|
482
526
|
|
483
|
-
|
484
527
|
# Ensure that the value matches arguments' types.
|
485
528
|
all_ints = int_value and all_int_args
|
486
529
|
|
@@ -579,17 +622,27 @@ class NumberInputMixin:
|
|
579
622
|
deserializer=serde.deserialize,
|
580
623
|
serializer=serde.serialize,
|
581
624
|
ctx=ctx,
|
582
|
-
value_type="double_value"
|
625
|
+
value_type="double_value",
|
583
626
|
)
|
584
627
|
|
585
628
|
if widget_state.value_changed:
|
586
629
|
if widget_state.value is not None:
|
587
630
|
# Min/Max bounds checks when the value is updated.
|
588
|
-
if
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
raise
|
631
|
+
if (
|
632
|
+
number_input_proto.has_min
|
633
|
+
and widget_state.value < number_input_proto.min
|
634
|
+
):
|
635
|
+
raise StreamlitValueBelowMinError(
|
636
|
+
value=widget_state.value, min_value=number_input_proto.min
|
637
|
+
)
|
638
|
+
|
639
|
+
if (
|
640
|
+
number_input_proto.has_max
|
641
|
+
and widget_state.value > number_input_proto.max
|
642
|
+
):
|
643
|
+
raise StreamlitValueAboveMaxError(
|
644
|
+
value=widget_state.value, max_value=number_input_proto.max
|
645
|
+
)
|
593
646
|
|
594
647
|
number_input_proto.value = widget_state.value
|
595
648
|
number_input_proto.set_value = True
|