streamlit-nightly 1.45.2.dev20250519__py3-none-any.whl → 1.45.2.dev20250520__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/commands/execution_control.py +4 -3
- streamlit/components/v1/component_registry.py +7 -3
- streamlit/config.py +27 -24
- streamlit/config_option.py +10 -6
- streamlit/elements/arrow.py +4 -3
- streamlit/elements/lib/dialog.py +5 -2
- streamlit/elements/lib/image_utils.py +9 -7
- streamlit/elements/lib/mutable_status_container.py +4 -2
- streamlit/elements/map.py +5 -7
- streamlit/external/langchain/streamlit_callback_handler.py +4 -3
- streamlit/runtime/app_session.py +22 -15
- streamlit/runtime/fragment.py +2 -1
- streamlit/runtime/runtime.py +5 -3
- streamlit/runtime/scriptrunner/script_runner.py +20 -5
- streamlit/runtime/scriptrunner_utils/script_requests.py +4 -1
- streamlit/runtime/session_manager.py +2 -1
- streamlit/runtime/state/session_state.py +8 -2
- streamlit/runtime/websocket_session_manager.py +10 -6
- streamlit/source_util.py +5 -2
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.B2DOu8EH.js → ErrorOutline.esm.CYnuXr-f.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.DstlwNHu.js → FileDownload.esm.CjkhjFuL.js} +1 -1
- streamlit/static/static/js/{FileHelper.BWWQqMOU.js → FileHelper.CvjfDg2R.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.BGe2ueaE.js → FormClearHelper.DieF97Af.js} +1 -1
- streamlit/static/static/js/{Hooks.tQYB--C2.js → Hooks.B1Hx6FYs.js} +1 -1
- streamlit/static/static/js/{InputInstructions.Clv91g7p.js → InputInstructions.B8AIK0e4.js} +1 -1
- streamlit/static/static/js/{ProgressBar.BmywC1Dh.js → ProgressBar.BVxh16au.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.CRlfBS_A.js → RenderInPortalIfExists.DRyuwMyI.js} +1 -1
- streamlit/static/static/js/{Toolbar.CxDjZGYY.js → Toolbar.3K8i84rX.js} +1 -1
- streamlit/static/static/js/{base-input.TLM9rFnB.js → base-input.C1EhHiwL.js} +1 -1
- streamlit/static/static/js/{checkbox.BvTs7ir2.js → checkbox.DQdrfkU_.js} +1 -1
- streamlit/static/static/js/{createSuper.CryPxxcx.js → createSuper.DTmFPsVr.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.BYX_RT_W.js → data-grid-overlay-editor.CPiIqh8K.js} +1 -1
- streamlit/static/static/js/{downloader.C2cF4iLz.js → downloader.C4KaNzxK.js} +1 -1
- streamlit/static/static/js/{es6.BPpXtadL.js → es6.2nWKWyMO.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.CAGxfaad.js → iframeResizer.contentWindow.DOVaChyF.js} +1 -1
- streamlit/static/static/js/{index.BJIk3rkJ.js → index.23pPuDjr.js} +1 -1
- streamlit/static/static/js/{index.D2rbVI1R.js → index.B-40SN8a.js} +1 -1
- streamlit/static/static/js/{index.D8v5LzMW.js → index.B0p5dBNu.js} +1 -1
- streamlit/static/static/js/{index.C8O0fRRc.js → index.BNYIeVmg.js} +1 -1
- streamlit/static/static/js/{index.DmD0Hg8e.js → index.BPnbqXpq.js} +1 -1
- streamlit/static/static/js/{index.tHSVhX7i.js → index.BT_313OI.js} +1 -1
- streamlit/static/static/js/{index.PsMi6f1B.js → index.BUb9IRAO.js} +1 -1
- streamlit/static/static/js/{index.BqP6-bem.js → index.BZrvTwVD.js} +1 -1
- streamlit/static/static/js/{index.CP9EMY2-.js → index.Bcm9abjs.js} +1 -1
- streamlit/static/static/js/{index.CfsV_XcR.js → index.Bh-zaqn6.js} +1 -1
- streamlit/static/static/js/{index.CnTzmxFX.js → index.Bu_wWseL.js} +1 -1
- streamlit/static/static/js/{index.VZh85EDG.js → index.BzBFnPX6.js} +1 -1
- streamlit/static/static/js/{index.PICOQqdk.js → index.C5QL_Xc_.js} +3 -3
- streamlit/static/static/js/{index.Cr1bZQOj.js → index.C6IpjREC.js} +10 -10
- streamlit/static/static/js/{index.D2U4aasb.js → index.C9oHDNvg.js} +1 -1
- streamlit/static/static/js/{index.CVDkaxGw.js → index.C9p4my_G.js} +1 -1
- streamlit/static/static/js/{index.1-29DVqv.js → index.CO8q3_vh.js} +1 -1
- streamlit/static/static/js/{index.B0YdZDVI.js → index.CR5G6E_h.js} +1 -1
- streamlit/static/static/js/{index.B5yAxnmX.js → index.CoUTSHXm.js} +1 -1
- streamlit/static/static/js/{index.BmU9sqeT.js → index.Csqhk1Jf.js} +1 -1
- streamlit/static/static/js/{index.CTXQmjSk.js → index.CxAOY3A6.js} +1 -1
- streamlit/static/static/js/{index.D5URUwlK.js → index.Cz7YuCRg.js} +1 -1
- streamlit/static/static/js/{index.CCWf3Q8a.js → index.Cz8OuaJg.js} +1 -1
- streamlit/static/static/js/{index.CJ1Mm4_5.js → index.D-7j7tdp.js} +1 -1
- streamlit/static/static/js/{index.CUpMOfPT.js → index.DBp4KGpt.js} +1 -1
- streamlit/static/static/js/{index.Q8LT3Yc8.js → index.DSTk15fA.js} +1 -1
- streamlit/static/static/js/{index.DprxqaP6.js → index.DSqmiAEF.js} +1 -1
- streamlit/static/static/js/{index.Cru7LoUn.js → index.DZ1uB38i.js} +1 -1
- streamlit/static/static/js/{index.BaIyE8V2.js → index.DerK8bdM.js} +1 -1
- streamlit/static/static/js/{index.ByFQchx0.js → index.Dh4ndZnq.js} +1 -1
- streamlit/static/static/js/{index.DQzP17_a.js → index.DucZyI7j.js} +1 -1
- streamlit/static/static/js/{index.Dh4NdvDT.js → index.DxkI2mS0.js} +1 -1
- streamlit/static/static/js/{index.TjQrtUrg.js → index.InQfrcIt.js} +1 -1
- streamlit/static/static/js/{index.BSmqXjy0.js → index.VSUuNjWj.js} +1 -1
- streamlit/static/static/js/{index.DFRfj6Kd.js → index.jOftLS0z.js} +1 -1
- streamlit/static/static/js/{index.BXj3r4Gs.js → index.mFs4Hj36.js} +1 -1
- streamlit/static/static/js/{index.DhlrCCaI.js → index.tW6ORFdt.js} +1 -1
- streamlit/static/static/js/{input.9JARw5iy.js → input.ut_XFtNH.js} +1 -1
- streamlit/static/static/js/{memory.k3bLbeHC.js → memory.DSoAMmQE.js} +1 -1
- streamlit/static/static/js/{mergeWith.DcuUmnJ3.js → mergeWith.BY-TWxsL.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.DEI0ot7m.js → number-overlay-editor.D5sSj_3j.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.BkddCCrr.js → possibleConstructorReturn.BNBjNW5N.js} +1 -1
- streamlit/static/static/js/{sandbox.ZLSXrkQF.js → sandbox.BXmhoUqL.js} +1 -1
- streamlit/static/static/js/{textarea.DEIgwup5.js → textarea.qz8i3H9z.js} +1 -1
- streamlit/static/static/js/{timepicker.2xpM3pZh.js → timepicker.CZROecqL.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.D9L2gAvg.js → toConsumableArray.BoolbIbO.js} +1 -1
- streamlit/static/static/js/{uniqueId.C0bkQJ2c.js → uniqueId.DFKK3fms.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.BWUuKz-P.js → useBasicWidgetState.QKx5EFIj.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.B_sYOzmC.js → useOnInputChange.CpgAX3wz.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.1A2DRT-e.js → withFullScreenWrapper.DrAgwq5e.js} +1 -1
- streamlit/testing/v1/element_tree.py +4 -0
- streamlit/testing/v1/local_script_runner.py +4 -4
- streamlit/web/cli.py +7 -5
- streamlit/web/server/oidc_mixin.py +0 -2
- {streamlit_nightly-1.45.2.dev20250519.dist-info → streamlit_nightly-1.45.2.dev20250520.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.45.2.dev20250519.dist-info → streamlit_nightly-1.45.2.dev20250520.dist-info}/RECORD +96 -96
- {streamlit_nightly-1.45.2.dev20250519.dist-info → streamlit_nightly-1.45.2.dev20250520.dist-info}/WHEEL +1 -1
- {streamlit_nightly-1.45.2.dev20250519.data → streamlit_nightly-1.45.2.dev20250520.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.2.dev20250519.dist-info → streamlit_nightly-1.45.2.dev20250520.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.2.dev20250519.dist-info → streamlit_nightly-1.45.2.dev20250520.dist-info}/top_level.txt +0 -0
@@ -91,9 +91,10 @@ def _new_fragment_id_queue(
|
|
91
91
|
)
|
92
92
|
|
93
93
|
new_queue = list(dropwhile(lambda x: x != ctx.current_fragment_id, curr_queue))
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
if not new_queue:
|
95
|
+
raise RuntimeError(
|
96
|
+
"Could not find current_fragment_id in fragment_id_queue. This should never happen."
|
97
|
+
)
|
97
98
|
|
98
99
|
return new_queue
|
99
100
|
|
@@ -33,7 +33,8 @@ def _get_module_name(caller_frame: FrameType) -> str:
|
|
33
33
|
# Get the caller's module name. `__name__` gives us the module's
|
34
34
|
# fully-qualified name, which includes its package.
|
35
35
|
module = inspect.getmodule(caller_frame)
|
36
|
-
|
36
|
+
if module is None:
|
37
|
+
raise RuntimeError("module is None. This should never happen.")
|
37
38
|
module_name = module.__name__
|
38
39
|
|
39
40
|
# If the caller was the main module that was executed (that is, if the
|
@@ -96,10 +97,13 @@ def declare_component(
|
|
96
97
|
|
97
98
|
# Get our stack frame.
|
98
99
|
current_frame: FrameType | None = inspect.currentframe()
|
99
|
-
|
100
|
+
if current_frame is None:
|
101
|
+
raise RuntimeError("current_frame is None. This should never happen.")
|
100
102
|
# Get the stack frame of our calling function.
|
101
103
|
caller_frame = current_frame.f_back
|
102
|
-
|
104
|
+
if caller_frame is None:
|
105
|
+
raise RuntimeError("caller_frame is None. This should never happen.")
|
106
|
+
|
103
107
|
module_name = _get_module_name(caller_frame)
|
104
108
|
|
105
109
|
# Build the component name.
|
streamlit/config.py
CHANGED
@@ -226,9 +226,8 @@ def get_options_for_section(section: str) -> dict[str, Any]:
|
|
226
226
|
|
227
227
|
def _create_section(section: str, description: str) -> None:
|
228
228
|
"""Create a config section and store it globally in this module."""
|
229
|
-
|
230
|
-
f'Cannot define section "{section}" twice.'
|
231
|
-
)
|
229
|
+
if section in _section_descriptions:
|
230
|
+
raise RuntimeError(f'Cannot define section "{section}" twice.')
|
232
231
|
_section_descriptions[section] = description
|
233
232
|
|
234
233
|
|
@@ -293,13 +292,12 @@ def _create_option(
|
|
293
292
|
type_=type_,
|
294
293
|
sensitive=sensitive,
|
295
294
|
)
|
296
|
-
|
297
|
-
|
298
|
-
option.section,
|
299
|
-
", ".join(_section_descriptions.keys()),
|
295
|
+
if option.section not in _section_descriptions:
|
296
|
+
raise RuntimeError(
|
297
|
+
f'Section "{option.section}" must be one of {", ".join(_section_descriptions.keys())}.'
|
300
298
|
)
|
301
|
-
|
302
|
-
|
299
|
+
if key in _config_options_template:
|
300
|
+
raise RuntimeError(f'Cannot define option "{key}" twice.')
|
303
301
|
_config_options_template[key] = option
|
304
302
|
return option
|
305
303
|
|
@@ -342,11 +340,13 @@ def _delete_option(key: str) -> None:
|
|
342
340
|
|
343
341
|
Only for use in testing.
|
344
342
|
"""
|
343
|
+
if _config_options is None:
|
344
|
+
raise RuntimeError(
|
345
|
+
"_config_options should always be populated here. This should never happen."
|
346
|
+
)
|
347
|
+
|
345
348
|
try:
|
346
349
|
del _config_options_template[key]
|
347
|
-
assert _config_options is not None, (
|
348
|
-
"_config_options should always be populated here."
|
349
|
-
)
|
350
350
|
del _config_options[key]
|
351
351
|
except Exception: # noqa: S110
|
352
352
|
# We don't care if the option already doesn't exist.
|
@@ -1334,9 +1334,10 @@ def is_manually_set(option_name: str) -> bool:
|
|
1334
1334
|
def show_config() -> None:
|
1335
1335
|
"""Print all config options to the terminal."""
|
1336
1336
|
with _config_lock:
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1337
|
+
if _config_options is None:
|
1338
|
+
raise RuntimeError(
|
1339
|
+
"_config_options should always be populated here. This should never happen."
|
1340
|
+
)
|
1340
1341
|
config_util.show_config(_section_descriptions, _config_options)
|
1341
1342
|
|
1342
1343
|
|
@@ -1359,9 +1360,9 @@ def _set_option(key: str, value: Any, where_defined: str) -> None:
|
|
1359
1360
|
Tells the config system where this was set.
|
1360
1361
|
|
1361
1362
|
"""
|
1362
|
-
|
1363
|
-
"_config_options should always be populated here."
|
1364
|
-
|
1363
|
+
if _config_options is None:
|
1364
|
+
raise RuntimeError("_config_options should always be populated here.")
|
1365
|
+
|
1365
1366
|
if key not in _config_options:
|
1366
1367
|
# Import logger locally to prevent circular references
|
1367
1368
|
from streamlit.logger import get_logger
|
@@ -1617,13 +1618,15 @@ def _check_conflicts() -> None:
|
|
1617
1618
|
LOGGER = get_logger(__name__)
|
1618
1619
|
|
1619
1620
|
if get_option("global.developmentMode"):
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1621
|
+
if not _is_unset("server.port"):
|
1622
|
+
raise RuntimeError(
|
1623
|
+
"server.port does not work when global.developmentMode is true."
|
1624
|
+
)
|
1623
1625
|
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1626
|
+
if not _is_unset("browser.serverPort"):
|
1627
|
+
raise RuntimeError(
|
1628
|
+
"browser.serverPort does not work when global.developmentMode is true."
|
1629
|
+
)
|
1627
1630
|
|
1628
1631
|
# XSRF conflicts
|
1629
1632
|
if get_option("server.enableXsrfProtection") and (
|
streamlit/config_option.py
CHANGED
@@ -167,7 +167,8 @@ class ConfigOption:
|
|
167
167
|
r")$"
|
168
168
|
)
|
169
169
|
match = re.match(key_format, self.key)
|
170
|
-
|
170
|
+
if match is None:
|
171
|
+
raise ValueError(f'Key "{self.key}" has invalid format.')
|
171
172
|
self.section, self.name = match.group("section"), match.group("name")
|
172
173
|
|
173
174
|
self.description = description
|
@@ -191,8 +192,10 @@ class ConfigOption:
|
|
191
192
|
deprecation_text = "Replaced by %s." % self.replaced_by
|
192
193
|
|
193
194
|
if self.deprecated:
|
194
|
-
|
195
|
-
|
195
|
+
if not expiration_date:
|
196
|
+
raise ValueError("expiration_date is required for deprecated items.")
|
197
|
+
if not deprecation_text:
|
198
|
+
raise ValueError("deprecation_text is required for deprecated items.")
|
196
199
|
self.expiration_date = expiration_date
|
197
200
|
self.deprecation_text = textwrap.dedent(deprecation_text)
|
198
201
|
|
@@ -218,9 +221,10 @@ class ConfigOption:
|
|
218
221
|
Returns self, which makes testing easier. See config_test.py.
|
219
222
|
|
220
223
|
"""
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
+
if get_val_func.__doc__ is None:
|
225
|
+
raise RuntimeError(
|
226
|
+
"Complex config options require doc strings for their description."
|
227
|
+
)
|
224
228
|
self.description = get_val_func.__doc__
|
225
229
|
self._get_val_func = get_val_func
|
226
230
|
return self
|
streamlit/elements/arrow.py
CHANGED
@@ -952,9 +952,10 @@ def marshall(proto: ArrowProto, data: Data, default_uuid: str | None = None) ->
|
|
952
952
|
if dataframe_util.is_pandas_styler(data):
|
953
953
|
# default_uuid is a string only if the data is a `Styler`,
|
954
954
|
# and `None` otherwise.
|
955
|
-
|
956
|
-
|
957
|
-
|
955
|
+
if not isinstance(default_uuid, str):
|
956
|
+
raise StreamlitAPIException(
|
957
|
+
"Default UUID must be a string for Styler data."
|
958
|
+
)
|
958
959
|
marshall_styler(proto, data, default_uuid)
|
959
960
|
|
960
961
|
proto.data = dataframe_util.convert_anything_to_arrow_bytes(data)
|
streamlit/elements/lib/dialog.py
CHANGED
@@ -115,8 +115,11 @@ class Dialog(DeltaGenerator):
|
|
115
115
|
def _update(self, should_open: bool) -> None:
|
116
116
|
"""Send an updated proto message to indicate the open-status for the dialog."""
|
117
117
|
|
118
|
-
|
119
|
-
|
118
|
+
if self._current_proto is None or self._delta_path is None:
|
119
|
+
raise RuntimeError(
|
120
|
+
"Dialog not correctly initialized. This should never happen."
|
121
|
+
)
|
122
|
+
|
120
123
|
_assert_first_dialog_to_be_opened(should_open)
|
121
124
|
msg = ForwardMsg()
|
122
125
|
msg.metadata.delta_path[:] = self._delta_path
|
@@ -416,13 +416,15 @@ def marshall_images(
|
|
416
416
|
else:
|
417
417
|
captions = [str(caption)]
|
418
418
|
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
419
|
+
if not isinstance(captions, list):
|
420
|
+
raise StreamlitAPIException(
|
421
|
+
"If image is a list then caption should be a list as well."
|
422
|
+
)
|
423
|
+
|
424
|
+
if len(captions) != len(images):
|
425
|
+
raise StreamlitAPIException(
|
426
|
+
f"Cannot pair {len(captions)} captions with {len(images)} images."
|
427
|
+
)
|
426
428
|
|
427
429
|
proto_imgs.width = int(width)
|
428
430
|
# Each image in an image list needs to be kept track of at its own coordinates.
|
@@ -122,8 +122,10 @@ class StatusContainer(DeltaGenerator):
|
|
122
122
|
The new state of the status container. This mainly changes the
|
123
123
|
icon. If None, the state is not changed.
|
124
124
|
"""
|
125
|
-
|
126
|
-
|
125
|
+
if self._current_proto is None or self._delta_path is None:
|
126
|
+
raise RuntimeError(
|
127
|
+
"StatusContainer is not correctly initialized. This should never happen."
|
128
|
+
)
|
127
129
|
|
128
130
|
msg = ForwardMsg()
|
129
131
|
msg.metadata.delta_path[:] = self._delta_path
|
streamlit/elements/map.py
CHANGED
@@ -296,7 +296,7 @@ def to_deckgl_json(
|
|
296
296
|
)
|
297
297
|
df = df[used_columns]
|
298
298
|
|
299
|
-
|
299
|
+
converted_color_arg = _convert_color_arg_or_column(df, color_arg, color_col_name)
|
300
300
|
|
301
301
|
zoom, center_lat, center_lon = _get_viewport_details(
|
302
302
|
df, lat_col_name, lon_col_name, zoom
|
@@ -313,7 +313,7 @@ def to_deckgl_json(
|
|
313
313
|
"getRadius": size_arg,
|
314
314
|
"radiusMinPixels": 3,
|
315
315
|
"radiusUnits": "meters",
|
316
|
-
"getFillColor":
|
316
|
+
"getFillColor": converted_color_arg,
|
317
317
|
"data": df.to_dict("records"),
|
318
318
|
}
|
319
319
|
]
|
@@ -378,7 +378,7 @@ def _get_value_and_col_name(
|
|
378
378
|
data: DataFrame,
|
379
379
|
value_or_name: Any,
|
380
380
|
default_value: Any,
|
381
|
-
) -> tuple[
|
381
|
+
) -> tuple[str, str | None]:
|
382
382
|
"""Take a value_or_name passed in by the Streamlit developer and return a PyDeck
|
383
383
|
argument and column name for that property.
|
384
384
|
|
@@ -390,7 +390,7 @@ def _get_value_and_col_name(
|
|
390
390
|
- If the user passes size="my_col_123", this returns "@@=my_col_123" and "my_col_123".
|
391
391
|
"""
|
392
392
|
|
393
|
-
pydeck_arg: str
|
393
|
+
pydeck_arg: str
|
394
394
|
|
395
395
|
if isinstance(value_or_name, str) and value_or_name in data.columns:
|
396
396
|
col_name = value_or_name
|
@@ -405,7 +405,7 @@ def _get_value_and_col_name(
|
|
405
405
|
|
406
406
|
def _convert_color_arg_or_column(
|
407
407
|
data: DataFrame,
|
408
|
-
color_arg: str
|
408
|
+
color_arg: str,
|
409
409
|
color_col_name: str | None,
|
410
410
|
) -> None | str | IntColorTuple:
|
411
411
|
"""Converts color to a format accepted by PyDeck.
|
@@ -434,8 +434,6 @@ def _convert_color_arg_or_column(
|
|
434
434
|
f'Column "{color_col_name}" does not appear to contain valid colors.'
|
435
435
|
)
|
436
436
|
|
437
|
-
# This is guaranteed to be a str because of _get_value_and_col_name
|
438
|
-
assert isinstance(color_arg, str)
|
439
437
|
color_arg_out = color_arg
|
440
438
|
|
441
439
|
elif color_arg is not None:
|
@@ -250,9 +250,10 @@ class LLMThought:
|
|
250
250
|
def complete(self, final_label: str | None = None) -> None:
|
251
251
|
"""Finish the thought."""
|
252
252
|
if final_label is None and self._state == LLMThoughtState.RUNNING_TOOL:
|
253
|
-
|
254
|
-
|
255
|
-
|
253
|
+
if self._last_tool is None:
|
254
|
+
raise RuntimeError(
|
255
|
+
"_last_tool should never be null when _state == RUNNING_TOOL"
|
256
|
+
)
|
256
257
|
final_label = self._labeler.get_tool_label(
|
257
258
|
self._last_tool, is_complete=True
|
258
259
|
)
|
streamlit/runtime/app_session.py
CHANGED
@@ -578,9 +578,11 @@ class AppSession:
|
|
578
578
|
browser. Set only for the SCRIPT_STARTED event.
|
579
579
|
"""
|
580
580
|
|
581
|
-
|
582
|
-
|
583
|
-
|
581
|
+
if self._event_loop != asyncio.get_running_loop():
|
582
|
+
raise RuntimeError(
|
583
|
+
"This function must only be called on the eventloop thread the AppSession was created on. "
|
584
|
+
"This should never happen."
|
585
|
+
)
|
584
586
|
|
585
587
|
if sender is not self._scriptrunner:
|
586
588
|
# This event was sent by a non-current ScriptRunner; ignore it.
|
@@ -596,9 +598,10 @@ class AppSession:
|
|
596
598
|
if event == ScriptRunnerEvent.SCRIPT_STARTED:
|
597
599
|
if self._state != AppSessionState.SHUTDOWN_REQUESTED:
|
598
600
|
self._state = AppSessionState.APP_IS_RUNNING
|
599
|
-
|
600
|
-
|
601
|
-
|
601
|
+
if page_script_hash is None:
|
602
|
+
raise RuntimeError(
|
603
|
+
"page_script_hash must be set for the SCRIPT_STARTED event. This should never happen."
|
604
|
+
)
|
602
605
|
|
603
606
|
# Update the client state with the new page_script_hash if
|
604
607
|
# necessary. This handles an edge case where a script is never
|
@@ -646,9 +649,11 @@ class AppSession:
|
|
646
649
|
else:
|
647
650
|
# The script didn't complete successfully: send the exception
|
648
651
|
# to the frontend.
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
+
if exception is None:
|
653
|
+
raise RuntimeError(
|
654
|
+
"exception must be set for the SCRIPT_STOPPED_WITH_COMPILE_ERROR event. "
|
655
|
+
"This should never happen."
|
656
|
+
)
|
652
657
|
msg = ForwardMsg()
|
653
658
|
exception_utils.marshall(
|
654
659
|
msg.session_event.script_compilation_exception, exception
|
@@ -666,9 +671,10 @@ class AppSession:
|
|
666
671
|
self._local_sources_watcher.update_watched_modules()
|
667
672
|
|
668
673
|
elif event == ScriptRunnerEvent.SHUTDOWN:
|
669
|
-
|
670
|
-
|
671
|
-
|
674
|
+
if client_state is None:
|
675
|
+
raise RuntimeError(
|
676
|
+
"client_state must be set for the SHUTDOWN event. This should never happen."
|
677
|
+
)
|
672
678
|
|
673
679
|
if self._state == AppSessionState.SHUTDOWN_REQUESTED:
|
674
680
|
# Only clear media files if the script is done running AND the
|
@@ -679,9 +685,10 @@ class AppSession:
|
|
679
685
|
self._scriptrunner = None
|
680
686
|
|
681
687
|
elif event == ScriptRunnerEvent.ENQUEUE_FORWARD_MSG:
|
682
|
-
|
683
|
-
|
684
|
-
|
688
|
+
if forward_msg is None:
|
689
|
+
raise RuntimeError(
|
690
|
+
"null forward_msg in ENQUEUE_FORWARD_MSG event. This should never happen."
|
691
|
+
)
|
685
692
|
self._enqueue_forward_msg(forward_msg)
|
686
693
|
|
687
694
|
# Send a message if our run state changed
|
streamlit/runtime/fragment.py
CHANGED
@@ -192,7 +192,8 @@ def _fragment(
|
|
192
192
|
# fragment runs will generally run in a new script run, thus we'll have a
|
193
193
|
# new ctx.
|
194
194
|
ctx = get_script_run_ctx(suppress_warning=True)
|
195
|
-
|
195
|
+
if ctx is None:
|
196
|
+
raise RuntimeError("ctx is None. This should never happen.")
|
196
197
|
|
197
198
|
if ctx.fragment_ids_this_run:
|
198
199
|
# This script run is a run of one or more fragments. We restore the
|
streamlit/runtime/runtime.py
CHANGED
@@ -374,9 +374,11 @@ class Runtime:
|
|
374
374
|
-----
|
375
375
|
Threading: UNSAFE. Must be called on the eventloop thread.
|
376
376
|
"""
|
377
|
-
|
378
|
-
|
379
|
-
|
377
|
+
if existing_session_id and session_id_override:
|
378
|
+
raise RuntimeError(
|
379
|
+
"Only one of existing_session_id and session_id_override should be set. "
|
380
|
+
"This should never happen."
|
381
|
+
)
|
380
382
|
|
381
383
|
if self._state in (RuntimeState.STOPPING, RuntimeState.STOPPED):
|
382
384
|
raise RuntimeStoppedError(f"Can't connect_session (state={self._state})")
|
@@ -322,7 +322,10 @@ class ScriptRunner:
|
|
322
322
|
If there is no ScriptRunContext for the current thread.
|
323
323
|
|
324
324
|
"""
|
325
|
-
|
325
|
+
if not self._is_in_script_thread():
|
326
|
+
raise RuntimeError(
|
327
|
+
"ScriptRunner._get_script_run_ctx must be called from the script thread."
|
328
|
+
)
|
326
329
|
|
327
330
|
ctx = get_script_run_ctx()
|
328
331
|
if ctx is None:
|
@@ -342,7 +345,10 @@ class ScriptRunner:
|
|
342
345
|
When the ScriptRequestQueue is empty, or when a SHUTDOWN request is
|
343
346
|
dequeued, this function will exit and its thread will terminate.
|
344
347
|
"""
|
345
|
-
|
348
|
+
if not self._is_in_script_thread():
|
349
|
+
raise RuntimeError(
|
350
|
+
"ScriptRunner._run_script_thread must be called from the script thread."
|
351
|
+
)
|
346
352
|
|
347
353
|
_LOGGER.debug("Beginning script thread")
|
348
354
|
|
@@ -372,7 +378,10 @@ class ScriptRunner:
|
|
372
378
|
self._run_script(request.rerun_data)
|
373
379
|
request = self._requests.on_scriptrunner_ready()
|
374
380
|
|
375
|
-
|
381
|
+
if request.type != ScriptRequestType.STOP:
|
382
|
+
raise RuntimeError(
|
383
|
+
f"Unrecognized ScriptRequestType: {request.type}. This should never happen."
|
384
|
+
)
|
376
385
|
|
377
386
|
# Send a SHUTDOWN event before exiting, so some state can be saved
|
378
387
|
# for use in a future script run when not triggered by the client.
|
@@ -434,7 +443,10 @@ class ScriptRunner:
|
|
434
443
|
if request.type == ScriptRequestType.RERUN:
|
435
444
|
raise RerunException(request.rerun_data)
|
436
445
|
|
437
|
-
|
446
|
+
if request.type != ScriptRequestType.STOP:
|
447
|
+
raise RuntimeError(
|
448
|
+
f"Unrecognized ScriptRequestType: {request.type}. This should never happen."
|
449
|
+
)
|
438
450
|
raise StopException()
|
439
451
|
|
440
452
|
@contextmanager
|
@@ -462,7 +474,10 @@ class ScriptRunner:
|
|
462
474
|
|
463
475
|
"""
|
464
476
|
|
465
|
-
|
477
|
+
if not self._is_in_script_thread():
|
478
|
+
raise RuntimeError(
|
479
|
+
"ScriptRunner._run_script must be called from the script thread."
|
480
|
+
)
|
466
481
|
|
467
482
|
# An explicit loop instead of recursion to avoid stack overflows
|
468
483
|
while True:
|
@@ -284,7 +284,10 @@ class ScriptRequests:
|
|
284
284
|
self._state = ScriptRequestType.CONTINUE
|
285
285
|
return ScriptRequest(ScriptRequestType.RERUN, self._rerun_data)
|
286
286
|
|
287
|
-
|
287
|
+
if self._state != ScriptRequestType.STOP:
|
288
|
+
raise RuntimeError(
|
289
|
+
f"Unrecognized ScriptRunnerState: {self._state}. This should never happen."
|
290
|
+
)
|
288
291
|
return ScriptRequest(ScriptRequestType.STOP)
|
289
292
|
|
290
293
|
def on_scriptrunner_ready(self) -> ScriptRequest:
|
@@ -72,7 +72,8 @@ class SessionInfo:
|
|
72
72
|
return self.client is not None
|
73
73
|
|
74
74
|
def to_active(self) -> ActiveSessionInfo:
|
75
|
-
|
75
|
+
if not self.is_active():
|
76
|
+
raise RuntimeError("A SessionInfo with no client cannot be active!")
|
76
77
|
|
77
78
|
# NOTE: The cast here (rather than copying this SessionInfo's fields into a new
|
78
79
|
# ActiveSessionInfo) is important as the Runtime expects to be able to mutate
|
@@ -261,7 +261,10 @@ class WStates(MutableMapping[str, Any]):
|
|
261
261
|
If the widget doesn't exist, raise an Exception.
|
262
262
|
"""
|
263
263
|
metadata = self.widget_metadata.get(widget_id)
|
264
|
-
|
264
|
+
|
265
|
+
if metadata is None:
|
266
|
+
raise RuntimeError(f"Widget {widget_id} not found.")
|
267
|
+
|
265
268
|
callback = metadata.callback
|
266
269
|
if callback is None:
|
267
270
|
return
|
@@ -468,7 +471,10 @@ class SessionState:
|
|
468
471
|
|
469
472
|
At least one of the arguments must have a value.
|
470
473
|
"""
|
471
|
-
|
474
|
+
if user_key is None and widget_id is None:
|
475
|
+
raise ValueError(
|
476
|
+
"user_key and widget_id cannot both be None. This should never happen."
|
477
|
+
)
|
472
478
|
|
473
479
|
if user_key is not None:
|
474
480
|
try:
|
@@ -67,9 +67,11 @@ class WebsocketSessionManager(SessionManager):
|
|
67
67
|
existing_session_id: str | None = None,
|
68
68
|
session_id_override: str | None = None,
|
69
69
|
) -> str:
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
if existing_session_id and session_id_override:
|
71
|
+
raise RuntimeError(
|
72
|
+
"Only one of existing_session_id and session_id_override should be truthy. "
|
73
|
+
"This should never happen."
|
74
|
+
)
|
73
75
|
|
74
76
|
if existing_session_id in self._active_session_info_by_id:
|
75
77
|
_LOGGER.warning(
|
@@ -109,9 +111,11 @@ class WebsocketSessionManager(SessionManager):
|
|
109
111
|
"Created new session for client %s. Session ID: %s", id(client), session.id
|
110
112
|
)
|
111
113
|
|
112
|
-
|
113
|
-
|
114
|
-
|
114
|
+
if session.id in self._active_session_info_by_id:
|
115
|
+
raise RuntimeError(
|
116
|
+
f"session.id '{session.id}' registered multiple times. "
|
117
|
+
"This should never happen."
|
118
|
+
)
|
115
119
|
|
116
120
|
self._active_session_info_by_id[session.id] = ActiveSessionInfo(client, session)
|
117
121
|
return session.id
|
streamlit/source_util.py
CHANGED
@@ -61,9 +61,12 @@ PAGE_FILENAME_REGEX = re.compile(r"([0-9]*)[_ -]*(.*)\.py")
|
|
61
61
|
def page_sort_key(script_path: Path) -> tuple[float, str]:
|
62
62
|
matches = re.findall(PAGE_FILENAME_REGEX, script_path.name)
|
63
63
|
|
64
|
-
# Failing this
|
64
|
+
# Failing this should only be possible if script_path isn't a Python
|
65
65
|
# file, which should never happen.
|
66
|
-
|
66
|
+
if len(matches) == 0:
|
67
|
+
raise ValueError(
|
68
|
+
f"{script_path} is not a Python file. This should never happen."
|
69
|
+
)
|
67
70
|
|
68
71
|
[(number, label)] = matches
|
69
72
|
label = label.lower()
|
streamlit/static/index.html
CHANGED
@@ -51,7 +51,7 @@
|
|
51
51
|
<script>
|
52
52
|
window.prerenderReady = false
|
53
53
|
</script>
|
54
|
-
<script type="module" crossorigin src="./static/js/index.
|
54
|
+
<script type="module" crossorigin src="./static/js/index.C5QL_Xc_.js"></script>
|
55
55
|
<link rel="stylesheet" crossorigin href="./static/css/index.C6rq3aMZ.css">
|
56
56
|
</head>
|
57
57
|
<body>
|
@@ -1 +1 @@
|
|
1
|
-
import{r,E as a,_ as n}from"./index.
|
1
|
+
import{r,E as a,_ as n}from"./index.C5QL_Xc_.js";var i=r.forwardRef(function(e,t){var o={fill:"currentColor",xmlns:"http://www.w3.org/2000/svg"};return r.createElement(a,n({iconAttrs:o,iconVerticalAlign:"middle",iconViewBox:"0 0 24 24"},e,{ref:t}),r.createElement("path",{d:"M11 15h2v2h-2v-2zm0-8h2v6h-2V7zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"}))});i.displayName="ErrorOutline";export{i as E};
|
@@ -1 +1 @@
|
|
1
|
-
import{r as e,E as n,_ as a}from"./index.
|
1
|
+
import{r as e,E as n,_ as a}from"./index.C5QL_Xc_.js";var o=e.forwardRef(function(t,r){var l={fill:"currentColor",xmlns:"http://www.w3.org/2000/svg"};return e.createElement(n,a({iconAttrs:l,iconVerticalAlign:"middle",iconViewBox:"0 0 24 24"},t,{ref:r}),e.createElement("path",{fill:"none",d:"M0 0h24v24H0V0z"}),e.createElement("path",{d:"M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z"}))});o.displayName="Delete";var i=e.forwardRef(function(t,r){var l={fill:"currentColor",xmlns:"http://www.w3.org/2000/svg"};return e.createElement(n,a({iconAttrs:l,iconVerticalAlign:"middle",iconViewBox:"0 0 24 24"},t,{ref:r}),e.createElement("rect",{width:24,height:24,fill:"none"}),e.createElement("path",{d:"M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zm-1-4l-1.41-1.41L13 12.17V4h-2v8.17L8.41 9.59 7 11l5 5 5-5z"}))});i.displayName="FileDownload";export{o as D,i as F};
|