streamlit-nightly 1.45.1.dev20250504__py3-none-any.whl → 1.45.1.dev20250506__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 +11 -9
- streamlit/commands/execution_control.py +5 -6
- streamlit/commands/logo.py +7 -2
- streamlit/components/v1/components.py +1 -1
- streamlit/connections/__init__.py +2 -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 +17 -37
- streamlit/elements/alert.py +1 -1
- streamlit/elements/arrow.py +3 -3
- streamlit/elements/deck_gl_json_chart.py +1 -1
- streamlit/elements/exception.py +5 -1
- streamlit/elements/json.py +1 -1
- streamlit/elements/layouts.py +3 -9
- streamlit/elements/lib/built_in_chart_utils.py +14 -6
- streamlit/elements/lib/column_config_utils.py +1 -3
- streamlit/elements/lib/column_types.py +2 -2
- streamlit/elements/lib/dialog.py +2 -1
- streamlit/elements/lib/file_uploader_utils.py +7 -2
- streamlit/elements/lib/js_number.py +4 -4
- streamlit/elements/lib/options_selector_utils.py +9 -6
- streamlit/elements/media.py +8 -7
- streamlit/elements/metric.py +4 -4
- streamlit/elements/progress.py +1 -1
- 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/elements/widgets/time_widgets.py +43 -0
- streamlit/errors.py +9 -6
- streamlit/proto/DateInput_pb2.py +4 -3
- streamlit/proto/DateInput_pb2.pyi +8 -2
- streamlit/proto/TimeInput_pb2.py +4 -3
- streamlit/proto/TimeInput_pb2.pyi +9 -2
- streamlit/runtime/__init__.py +1 -1
- streamlit/runtime/caching/__init__.py +6 -6
- streamlit/runtime/caching/cache_data_api.py +7 -9
- streamlit/runtime/caching/hashing.py +1 -1
- streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
- streamlit/runtime/connection_factory.py +1 -1
- streamlit/runtime/credentials.py +4 -4
- 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/__init__.py +4 -4
- streamlit/runtime/scriptrunner/script_runner.py +6 -9
- streamlit/runtime/scriptrunner_utils/script_run_context.py +1 -0
- streamlit/runtime/secrets.py +15 -8
- streamlit/runtime/state/__init__.py +5 -5
- streamlit/runtime/state/query_params.py +8 -8
- streamlit/runtime/state/session_state.py +8 -1
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.Bp4VdNOc.js → ErrorOutline.esm.BgsGCsV4.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.hVzDDDNS.js → FileDownload.esm.CCKezPn5.js} +1 -1
- streamlit/static/static/js/{FileHelper.BGcyDQ_S.js → FileHelper.CprSF_kT.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.a0IiSXcn.js → FormClearHelper.DiwQ0EtT.js} +1 -1
- streamlit/static/static/js/{Hooks.C2dZkryw.js → Hooks.DDqhyZ1_.js} +1 -1
- streamlit/static/static/js/{InputInstructions.Cn0WICoN.js → InputInstructions.BCEZxme4.js} +1 -1
- streamlit/static/static/js/{ProgressBar.VRmRPHtW.js → ProgressBar.CGdY94g_.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.CZa97lrw.js → RenderInPortalIfExists.uGJp_Q0v.js} +1 -1
- streamlit/static/static/js/{Toolbar.DJZBBDvl.js → Toolbar.hTlw0-K1.js} +1 -1
- streamlit/static/static/js/{base-input.CzerGAEH.js → base-input.mGTY3-qU.js} +1 -1
- streamlit/static/static/js/{checkbox.C6Sj4eVw.js → checkbox.Cg-5cKAh.js} +1 -1
- streamlit/static/static/js/{createSuper.C7yhRETi.js → createSuper.-HPb1oYT.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.DAgcbVks.js → data-grid-overlay-editor.BpNYxiTp.js} +1 -1
- streamlit/static/static/js/{downloader.B8HL-u_1.js → downloader.DS9891pS.js} +1 -1
- streamlit/static/static/js/{es6.BxAW_jrO.js → es6.CU1PEL2w.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.CS8fz-W7.js → iframeResizer.contentWindow.CgJE2bJN.js} +1 -1
- streamlit/static/static/js/{index.BwnckS8e.js → index.B209tswL.js} +1 -1
- streamlit/static/static/js/{index.C7t1-CQQ.js → index.BC0ueJ8H.js} +1 -1
- streamlit/static/static/js/{index.DWb5kgxt.js → index.BHVQ94t4.js} +1 -1
- streamlit/static/static/js/{index.DgOrPDFa.js → index.BT0p7gAu.js} +1 -1
- streamlit/static/static/js/{index.uOOdkOMl.js → index.BTTj6ld4.js} +1 -1
- streamlit/static/static/js/{index.CG2pASlR.js → index.BVjgrQ4R.js} +1 -1
- streamlit/static/static/js/{index.6jptdEp6.js → index.BXYstdPh.js} +1 -1
- streamlit/static/static/js/{index.Dt0FtS-M.js → index.BZ9mqzEJ.js} +1 -1
- streamlit/static/static/js/{index.CSAdYIt3.js → index.Bb-Ukg41.js} +1 -1
- streamlit/static/static/js/{index.B2tTSlE1.js → index.BhTok8vt.js} +1 -1
- streamlit/static/static/js/{index.DIZcktIN.js → index.Bph6ZoI5.js} +1 -1
- streamlit/static/static/js/{index.B7UKH_JX.js → index.CJPcdxPe.js} +1 -1
- streamlit/static/static/js/{index.D6KElXAI.js → index.CMOA-8Q2.js} +1 -1
- streamlit/static/static/js/{index.Cxp7siQJ.js → index.CN91oQMB.js} +5 -5
- streamlit/static/static/js/{index.Cr1JUXmf.js → index.CtoDsUtq.js} +1 -1
- streamlit/static/static/js/{index.C4KrRG3c.js → index.CvFsF3FD.js} +1 -1
- streamlit/static/static/js/{index.DDCep3pE.js → index.CyGuL4If.js} +1 -1
- streamlit/static/static/js/{index.ChOkUAuD.js → index.CzGUd4IN.js} +1 -1
- streamlit/static/static/js/{index.A_t8lw--.js → index.DAxf3_iz.js} +1 -1
- streamlit/static/static/js/{index.DG9Swsby.js → index.DJHUlWgy.js} +1 -1
- streamlit/static/static/js/{index.CHL4u91M.js → index.DLTqo4pp.js} +1 -1
- streamlit/static/static/js/{index.o12m2E2P.js → index.DPJBu2uZ.js} +1 -1
- streamlit/static/static/js/{index.CLFopaXS.js → index.DVpzZJNg.js} +1 -1
- streamlit/static/static/js/{index.vdE-PayY.js → index.DWV80Vyw.js} +1 -1
- streamlit/static/static/js/{index.DR2lTx8N.js → index.DZ6oX-v9.js} +5 -5
- streamlit/static/static/js/{index.DtY8dAVN.js → index.Dh4RKl-F.js} +1 -1
- streamlit/static/static/js/{index.BRtyx04t.js → index.Dn76KVNf.js} +1 -1
- streamlit/static/static/js/{index.qMnAjj-G.js → index.DtqvdV-p.js} +1 -1
- streamlit/static/static/js/{index.BwlA1Cf_.js → index.ErkF0SoX.js} +1 -1
- streamlit/static/static/js/{index.QdRaJV_a.js → index.GSYBrzVp.js} +1 -1
- streamlit/static/static/js/{index.CSPC2m_c.js → index.OngWTN39.js} +1 -1
- streamlit/static/static/js/{index.CGzwdjEF.js → index.PSwG8ayC.js} +1 -1
- streamlit/static/static/js/{index.D_0HKLRm.js → index.UTlCdasa.js} +1 -1
- streamlit/static/static/js/{index.aBgCjIEX.js → index.eR_vQpeg.js} +1 -1
- streamlit/static/static/js/{index.BBClg-gm.js → index.fLsU9uCJ.js} +1 -1
- streamlit/static/static/js/{index.BDzCUpOG.js → index.hPjr68pz.js} +1 -1
- streamlit/static/static/js/{index.CgzjjllY.js → index.kXOZCC_6.js} +1 -1
- streamlit/static/static/js/{input.qNZgmgfK.js → input.DY17i94N.js} +1 -1
- streamlit/static/static/js/{memory.DifcSUze.js → memory.DsIIcbSd.js} +1 -1
- streamlit/static/static/js/{mergeWith.Bykfc0n-.js → mergeWith.cRgGdgvI.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.D_L9PQiU.js → number-overlay-editor.B8Xi2dYq.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.Cyeph4pU.js → possibleConstructorReturn.BgDi5nUm.js} +1 -1
- streamlit/static/static/js/{sandbox.DT6zcSKI.js → sandbox.BH9emp13.js} +1 -1
- streamlit/static/static/js/{textarea.C46FrViu.js → textarea.DAyShsGG.js} +1 -1
- streamlit/static/static/js/{timepicker.N6lFakQJ.js → timepicker.CCH2R2Y0.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.DwaNiLbv.js → toConsumableArray.CNffSDCu.js} +1 -1
- streamlit/static/static/js/{uniqueId.bNZuA9Mz.js → uniqueId.B49CstkV.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.qUuCVRZV.js → useBasicWidgetState.CkThOkF9.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.CylEhpc7.js → useOnInputChange.BqEq0xFZ.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.BQay_j7X.js → withFullScreenWrapper.UsvF_Jwr.js} +1 -1
- streamlit/string_util.py +8 -5
- streamlit/web/bootstrap.py +5 -4
- streamlit/web/cli.py +2 -1
- streamlit/web/server/__init__.py +2 -2
- 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.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250506.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250506.dist-info}/RECORD +139 -139
- {streamlit_nightly-1.45.1.dev20250504.data → streamlit_nightly-1.45.1.dev20250506.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250506.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250506.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.1.dev20250504.dist-info → streamlit_nightly-1.45.1.dev20250506.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,27 +12,29 @@
|
|
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
|
|
19
21
|
__all__ = [
|
20
22
|
"AreaChartColumn",
|
21
|
-
"Column",
|
22
|
-
"TextColumn",
|
23
|
-
"NumberColumn",
|
24
23
|
"BarChartColumn",
|
25
24
|
"CheckboxColumn",
|
25
|
+
"Column",
|
26
|
+
"DateColumn",
|
26
27
|
"DatetimeColumn",
|
27
28
|
"ImageColumn",
|
28
|
-
"
|
29
|
-
"ProgressColumn",
|
30
|
-
"LinkColumn",
|
29
|
+
"JsonColumn",
|
31
30
|
"LineChartColumn",
|
31
|
+
"LinkColumn",
|
32
32
|
"ListColumn",
|
33
|
-
"
|
33
|
+
"NumberColumn",
|
34
|
+
"ProgressColumn",
|
35
|
+
"SelectboxColumn",
|
36
|
+
"TextColumn",
|
34
37
|
"TimeColumn",
|
35
|
-
"JsonColumn",
|
36
38
|
]
|
37
39
|
|
38
40
|
|
@@ -90,11 +90,8 @@ def _new_fragment_id_queue(
|
|
90
90
|
"functions during fragment reruns."
|
91
91
|
)
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
dropwhile(lambda x: x != ctx.current_fragment_id, curr_queue)
|
96
|
-
)
|
97
|
-
), (
|
93
|
+
new_queue = list(dropwhile(lambda x: x != ctx.current_fragment_id, curr_queue))
|
94
|
+
assert new_queue, (
|
98
95
|
"Could not find current_fragment_id in fragment_id_queue. This should never happen."
|
99
96
|
)
|
100
97
|
|
@@ -222,7 +219,9 @@ def switch_page(page: str | Path | StreamlitPage) -> NoReturn: # type: ignore[m
|
|
222
219
|
|
223
220
|
if len(matched_pages) == 0:
|
224
221
|
raise StreamlitAPIException(
|
225
|
-
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."
|
226
225
|
)
|
227
226
|
|
228
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,
|
@@ -284,7 +297,7 @@ class DeltaGenerator(
|
|
284
297
|
|
285
298
|
def __enter__(self) -> None:
|
286
299
|
# with block started
|
287
|
-
context_dg_stack.set(context_dg_stack.get()
|
300
|
+
context_dg_stack.set((*context_dg_stack.get(), self))
|
288
301
|
|
289
302
|
def __exit__(
|
290
303
|
self,
|
@@ -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
|
@@ -530,7 +542,7 @@ class DeltaGenerator(
|
|
530
542
|
# a brand new cursor for this new block we're creating.
|
531
543
|
block_cursor = cursor.RunningCursor(
|
532
544
|
root_container=dg._root_container,
|
533
|
-
parent_path=dg._cursor.parent_path
|
545
|
+
parent_path=(*dg._cursor.parent_path, dg._cursor.index),
|
534
546
|
)
|
535
547
|
|
536
548
|
# `dg_type` param added for st.status container. It allows us to
|
@@ -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/alert.py
CHANGED
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/json.py
CHANGED
@@ -134,7 +134,7 @@ class JsonMixin:
|
|
134
134
|
json_proto.max_expand_depth = expanded
|
135
135
|
else:
|
136
136
|
raise TypeError(
|
137
|
-
f"The type {
|
137
|
+
f"The type {type(expanded)} of `expanded` is not supported"
|
138
138
|
", must be bool or int."
|
139
139
|
)
|
140
140
|
|
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
|
----------
|
@@ -74,11 +74,19 @@ class AddRowsMetadata:
|
|
74
74
|
|
75
75
|
|
76
76
|
class ChartType(Enum):
|
77
|
-
AREA = {"mark_type": "area", "command": "area_chart"}
|
78
|
-
VERTICAL_BAR = {
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
AREA: Final = {"mark_type": "area", "command": "area_chart"}
|
78
|
+
VERTICAL_BAR: Final = {
|
79
|
+
"mark_type": "bar",
|
80
|
+
"command": "bar_chart",
|
81
|
+
"horizontal": False,
|
82
|
+
}
|
83
|
+
HORIZONTAL_BAR: Final = {
|
84
|
+
"mark_type": "bar",
|
85
|
+
"command": "bar_chart",
|
86
|
+
"horizontal": True,
|
87
|
+
}
|
88
|
+
LINE: Final = {"mark_type": "line", "command": "line_chart"}
|
89
|
+
SCATTER: Final = {"mark_type": "circle", "command": "scatter_chart"}
|
82
90
|
|
83
91
|
|
84
92
|
# Color and size legends need different title paddings in order for them
|
@@ -1035,7 +1043,7 @@ def _get_size_encoding(
|
|
1035
1043
|
return alt.SizeValue(100)
|
1036
1044
|
else:
|
1037
1045
|
raise StreamlitAPIException(
|
1038
|
-
f"This does not look like a valid size: {
|
1046
|
+
f"This does not look like a valid size: {size_value!r}"
|
1039
1047
|
)
|
1040
1048
|
|
1041
1049
|
elif size_column is not None or size_value is not None:
|
@@ -509,9 +509,7 @@ def _convert_column_config_to_json(column_config_mapping: ColumnConfigMapping) -
|
|
509
509
|
# Ignore all None values and prefix columns specified by numerical index:
|
510
510
|
return json.dumps(
|
511
511
|
{
|
512
|
-
(
|
513
|
-
f"{_NUMERICAL_POSITION_PREFIX}{str(k)}" if isinstance(k, int) else k
|
514
|
-
): v
|
512
|
+
(f"{_NUMERICAL_POSITION_PREFIX}{k!s}" if isinstance(k, int) else k): v
|
515
513
|
for (k, v) in remove_none_values(column_config_mapping).items()
|
516
514
|
},
|
517
515
|
allow_nan=False,
|
@@ -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
|
|
@@ -59,9 +59,14 @@ def enforce_filename_restriction(filename: str, allowed_types: Sequence[str]) ->
|
|
59
59
|
enforce file type check by extension on the frontend, but we check it on backend
|
60
60
|
before returning file to the user to protect ourselves.
|
61
61
|
"""
|
62
|
-
|
62
|
+
normalized_filename = filename.lower()
|
63
|
+
base_name, extension = os.path.splitext(normalized_filename)
|
64
|
+
normalized_allowed_types = [allowed_type.lower() for allowed_type in allowed_types]
|
63
65
|
|
64
|
-
if not any(
|
66
|
+
if not any(
|
67
|
+
normalized_filename.endswith(allowed_type)
|
68
|
+
for allowed_type in normalized_allowed_types
|
69
|
+
):
|
65
70
|
raise StreamlitAPIException(
|
66
71
|
f"Invalid file extension: `{extension}`. Allowed: {allowed_types}"
|
67
72
|
)
|
@@ -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,10 +54,13 @@ 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
|
-
|
60
|
-
|
57
|
+
if (
|
58
|
+
isinstance(value, float)
|
59
|
+
and isinstance(x, float)
|
60
|
+
and abs(x - value) < _FLOAT_EQUALITY_EPSILON
|
61
|
+
):
|
62
|
+
return i
|
63
|
+
raise ValueError(f"{x} is not in iterable")
|
61
64
|
|
62
65
|
|
63
66
|
def check_and_convert_to_indices(
|
@@ -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(
|
streamlit/elements/metric.py
CHANGED
@@ -214,7 +214,7 @@ class MetricMixin:
|
|
214
214
|
def _parse_label(label: str) -> str:
|
215
215
|
if not isinstance(label, str):
|
216
216
|
raise TypeError(
|
217
|
-
f"'{
|
217
|
+
f"'{label}' is of type {type(label)}, which is not an accepted type."
|
218
218
|
" label only accepts: str. Please convert the label to an accepted type."
|
219
219
|
)
|
220
220
|
return label
|
@@ -236,7 +236,7 @@ def _parse_value(value: Value) -> str:
|
|
236
236
|
pass
|
237
237
|
|
238
238
|
raise TypeError(
|
239
|
-
f"'{
|
239
|
+
f"'{value}' is of type {type(value)}, which is not an accepted type."
|
240
240
|
" value only accepts: int, float, str, or None."
|
241
241
|
" Please convert the value to an accepted type."
|
242
242
|
)
|
@@ -251,7 +251,7 @@ def _parse_delta(delta: Delta) -> str:
|
|
251
251
|
return str(delta)
|
252
252
|
else:
|
253
253
|
raise TypeError(
|
254
|
-
f"'{
|
254
|
+
f"'{delta}' is of type {type(delta)}, which is not an accepted type."
|
255
255
|
" delta only accepts: int, float, str, or None."
|
256
256
|
" Please convert the value to an accepted type."
|
257
257
|
)
|
@@ -263,7 +263,7 @@ def _determine_delta_color_and_direction(
|
|
263
263
|
) -> MetricColorAndDirection:
|
264
264
|
if delta_color not in {"normal", "inverse", "off"}:
|
265
265
|
raise StreamlitAPIException(
|
266
|
-
f"'{
|
266
|
+
f"'{delta_color}' is not an accepted value. delta_color only accepts: "
|
267
267
|
"'normal', 'inverse', or 'off'"
|
268
268
|
)
|
269
269
|
|
streamlit/elements/progress.py
CHANGED
@@ -89,7 +89,7 @@ def _get_text(text: str | None) -> str | None:
|
|
89
89
|
if isinstance(text, str):
|
90
90
|
return clean_text(text)
|
91
91
|
raise StreamlitAPIException(
|
92
|
-
f"Progress Text is of type {
|
92
|
+
f"Progress Text is of type {type(text)}, which is not an accepted type."
|
93
93
|
"Text only accepts: str. Please convert the text to an accepted type."
|
94
94
|
)
|
95
95
|
|
@@ -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
|
|