streamlit-nightly 1.40.3.dev20241201__py2.py3-none-any.whl → 1.40.3.dev20241202__py2.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/elements/exception.py +83 -43
- streamlit/navigation/page.py +1 -1
- streamlit/runtime/pages_manager.py +6 -3
- streamlit/runtime/scriptrunner_utils/script_run_context.py +6 -0
- {streamlit_nightly-1.40.3.dev20241201.dist-info → streamlit_nightly-1.40.3.dev20241202.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.40.3.dev20241201.dist-info → streamlit_nightly-1.40.3.dev20241202.dist-info}/RECORD +10 -10
- {streamlit_nightly-1.40.3.dev20241201.data → streamlit_nightly-1.40.3.dev20241202.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.40.3.dev20241201.dist-info → streamlit_nightly-1.40.3.dev20241202.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.40.3.dev20241201.dist-info → streamlit_nightly-1.40.3.dev20241202.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.40.3.dev20241201.dist-info → streamlit_nightly-1.40.3.dev20241202.dist-info}/top_level.txt +0 -0
streamlit/elements/exception.py
CHANGED
@@ -16,18 +16,17 @@ from __future__ import annotations
|
|
16
16
|
|
17
17
|
import os
|
18
18
|
import traceback
|
19
|
-
from typing import TYPE_CHECKING, Final, cast
|
19
|
+
from typing import TYPE_CHECKING, Callable, Final, TypeVar, cast
|
20
20
|
|
21
|
-
import streamlit
|
22
21
|
from streamlit.errors import (
|
23
22
|
MarkdownFormattedException,
|
24
|
-
StreamlitAPIException,
|
25
23
|
StreamlitAPIWarning,
|
26
24
|
UncaughtAppException,
|
27
25
|
)
|
28
26
|
from streamlit.logger import get_logger
|
29
27
|
from streamlit.proto.Exception_pb2 import Exception as ExceptionProto
|
30
28
|
from streamlit.runtime.metrics_util import gather_metrics
|
29
|
+
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
31
30
|
|
32
31
|
if TYPE_CHECKING:
|
33
32
|
from streamlit.delta_generator import DeltaGenerator
|
@@ -38,12 +37,6 @@ _LOGGER: Final = get_logger(__name__)
|
|
38
37
|
# frontend when we encounter an uncaught app exception.
|
39
38
|
_GENERIC_UNCAUGHT_EXCEPTION_TEXT: Final = "This app has encountered an error. The original error message is redacted to prevent data leaks. Full error details have been recorded in the logs (if you're on Streamlit Cloud, click on 'Manage app' in the lower right of your app)."
|
40
39
|
|
41
|
-
# Extract the streamlit package path. Make it absolute, resolve aliases, and
|
42
|
-
# ensure there's a trailing path separator
|
43
|
-
_STREAMLIT_DIR: Final = os.path.join(
|
44
|
-
os.path.realpath(os.path.dirname(streamlit.__file__)), ""
|
45
|
-
)
|
46
|
-
|
47
40
|
|
48
41
|
class ExceptionMixin:
|
49
42
|
@gather_metrics("exception")
|
@@ -84,16 +77,9 @@ def marshall(exception_proto: ExceptionProto, exception: BaseException) -> None:
|
|
84
77
|
exception : BaseException
|
85
78
|
The exception whose data we're extracting
|
86
79
|
"""
|
87
|
-
# If this is a StreamlitAPIException, we prune all Streamlit entries
|
88
|
-
# from the exception's stack trace.
|
89
|
-
is_api_exception = isinstance(exception, StreamlitAPIException)
|
90
80
|
is_markdown_exception = isinstance(exception, MarkdownFormattedException)
|
91
81
|
is_uncaught_app_exception = isinstance(exception, UncaughtAppException)
|
92
82
|
|
93
|
-
stack_trace = _get_stack_trace_str_list(
|
94
|
-
exception, strip_streamlit_stack_entries=is_api_exception
|
95
|
-
)
|
96
|
-
|
97
83
|
# Some exceptions (like UserHashError) have an alternate_name attribute so
|
98
84
|
# we can pretend to the user that the exception is called something else.
|
99
85
|
if getattr(exception, "alternate_name", None) is not None:
|
@@ -101,6 +87,8 @@ def marshall(exception_proto: ExceptionProto, exception: BaseException) -> None:
|
|
101
87
|
else:
|
102
88
|
exception_proto.type = type(exception).__name__
|
103
89
|
|
90
|
+
stack_trace = _get_stack_trace_str_list(exception)
|
91
|
+
|
104
92
|
exception_proto.stack_trace.extend(stack_trace)
|
105
93
|
exception_proto.is_warning = isinstance(exception, Warning)
|
106
94
|
|
@@ -185,9 +173,7 @@ def _format_syntax_error_message(exception: SyntaxError) -> str:
|
|
185
173
|
return str(exception)
|
186
174
|
|
187
175
|
|
188
|
-
def _get_stack_trace_str_list(
|
189
|
-
exception: BaseException, strip_streamlit_stack_entries: bool = False
|
190
|
-
) -> list[str]:
|
176
|
+
def _get_stack_trace_str_list(exception: BaseException) -> list[str]:
|
191
177
|
"""Get the stack trace for the given exception.
|
192
178
|
|
193
179
|
Parameters
|
@@ -195,16 +181,13 @@ def _get_stack_trace_str_list(
|
|
195
181
|
exception : BaseException
|
196
182
|
The exception to extract the traceback from
|
197
183
|
|
198
|
-
strip_streamlit_stack_entries : bool
|
199
|
-
If True, all traceback entries that are in the Streamlit package
|
200
|
-
will be removed from the list. We do this for exceptions that result
|
201
|
-
from incorrect usage of Streamlit APIs, so that the user doesn't see
|
202
|
-
a bunch of noise about ScriptRunner, DeltaGenerator, etc.
|
203
|
-
|
204
184
|
Returns
|
205
185
|
-------
|
206
|
-
|
207
|
-
The exception traceback as
|
186
|
+
tuple of two string lists
|
187
|
+
The exception traceback as two lists of strings. The first represents the part
|
188
|
+
of the stack trace the users don't typically want to see, containing internal
|
189
|
+
Streamlit code. The second is whatever comes after the Streamlit stack trace,
|
190
|
+
which is usually what the user wants.
|
208
191
|
|
209
192
|
"""
|
210
193
|
extracted_traceback: traceback.StackSummary | None = None
|
@@ -218,36 +201,93 @@ def _get_stack_trace_str_list(
|
|
218
201
|
|
219
202
|
# Format the extracted traceback and add it to the protobuf element.
|
220
203
|
if extracted_traceback is None:
|
221
|
-
|
204
|
+
trace_str_list = [
|
222
205
|
"Cannot extract the stack trace for this exception. "
|
223
206
|
"Try calling exception() within the `catch` block."
|
224
207
|
]
|
225
208
|
else:
|
226
|
-
|
227
|
-
|
228
|
-
|
209
|
+
internal_frames, external_frames = _split_internal_streamlit_frames(
|
210
|
+
extracted_traceback
|
211
|
+
)
|
212
|
+
|
213
|
+
if external_frames:
|
214
|
+
trace_str_list = traceback.format_list(external_frames)
|
229
215
|
else:
|
230
|
-
|
216
|
+
trace_str_list = traceback.format_list(internal_frames)
|
231
217
|
|
232
|
-
|
218
|
+
trace_str_list = [item.strip() for item in trace_str_list]
|
233
219
|
|
234
|
-
return
|
220
|
+
return trace_str_list
|
235
221
|
|
236
222
|
|
237
|
-
def
|
238
|
-
"""True if the given file is part of
|
223
|
+
def _is_in_package(file: str, package_path: str) -> bool:
|
224
|
+
"""True if the given file is part of package_path."""
|
239
225
|
try:
|
240
|
-
common_prefix = os.path.commonprefix([os.path.realpath(file),
|
226
|
+
common_prefix = os.path.commonprefix([os.path.realpath(file), package_path])
|
241
227
|
except ValueError:
|
242
228
|
# Raised if paths are on different drives.
|
243
229
|
return False
|
244
230
|
|
245
|
-
return common_prefix ==
|
231
|
+
return common_prefix == package_path
|
246
232
|
|
247
233
|
|
248
|
-
def
|
234
|
+
def _split_internal_streamlit_frames(
|
249
235
|
extracted_tb: traceback.StackSummary,
|
250
|
-
) -> list[traceback.FrameSummary]:
|
251
|
-
|
252
|
-
|
253
|
-
|
236
|
+
) -> tuple[list[traceback.FrameSummary], list[traceback.FrameSummary]]:
|
237
|
+
"""Split the traceback into a Streamlit-internal part and an external part.
|
238
|
+
|
239
|
+
The internal part is everything up to (but excluding) the first frame belonging to
|
240
|
+
the user's code. The external part is everything else.
|
241
|
+
|
242
|
+
So if the stack looks like this:
|
243
|
+
|
244
|
+
1. Streamlit frame
|
245
|
+
2. Pandas frame
|
246
|
+
3. Altair frame
|
247
|
+
4. Streamlit frame
|
248
|
+
5. User frame
|
249
|
+
6. User frame
|
250
|
+
7. Streamlit frame
|
251
|
+
8. Matplotlib frame
|
252
|
+
|
253
|
+
...then this should return 1-4 as the internal traceback and 5-8 as the external.
|
254
|
+
|
255
|
+
(Note that something like the example above is extremely unlikely to happen since
|
256
|
+
it's not like Altair is calling Streamlit code, but you get the idea.)
|
257
|
+
"""
|
258
|
+
|
259
|
+
ctx = get_script_run_ctx()
|
260
|
+
|
261
|
+
if not ctx:
|
262
|
+
return [], list(extracted_tb)
|
263
|
+
|
264
|
+
package_path = os.path.join(os.path.realpath(str(ctx.main_script_parent)), "")
|
265
|
+
|
266
|
+
return _split_list(
|
267
|
+
extracted_tb,
|
268
|
+
split_point=lambda tb: _is_in_package(tb.filename, package_path),
|
269
|
+
)
|
270
|
+
|
271
|
+
|
272
|
+
T = TypeVar("T")
|
273
|
+
|
274
|
+
|
275
|
+
def _split_list(
|
276
|
+
orig_list: list[T], split_point: Callable[[T], bool]
|
277
|
+
) -> tuple[list[T], list[T]]:
|
278
|
+
before: list[T] = []
|
279
|
+
after: list[T] = []
|
280
|
+
|
281
|
+
saw_split_point = False
|
282
|
+
|
283
|
+
for item in orig_list:
|
284
|
+
if not saw_split_point:
|
285
|
+
if split_point(item):
|
286
|
+
saw_split_point = True
|
287
|
+
|
288
|
+
if saw_split_point:
|
289
|
+
after.append(item)
|
290
|
+
else:
|
291
|
+
before.append(item)
|
292
|
+
|
293
|
+
return before, after
|
streamlit/navigation/page.py
CHANGED
@@ -57,8 +57,7 @@ class PagesStrategyV1:
|
|
57
57
|
def _handle_page_changed(_path: str) -> None:
|
58
58
|
source_util.invalidate_pages_cache()
|
59
59
|
|
60
|
-
|
61
|
-
pages_dir = main_script_path.parent / "pages"
|
60
|
+
pages_dir = pages_manager.main_script_parent / "pages"
|
62
61
|
watch_dir(
|
63
62
|
str(pages_dir),
|
64
63
|
_handle_page_changed,
|
@@ -243,6 +242,10 @@ class PagesManager:
|
|
243
242
|
def main_script_path(self) -> ScriptPath:
|
244
243
|
return self._main_script_path
|
245
244
|
|
245
|
+
@property
|
246
|
+
def main_script_parent(self) -> Path:
|
247
|
+
return Path(self._main_script_path).parent
|
248
|
+
|
246
249
|
@property
|
247
250
|
def main_script_hash(self) -> PageHash:
|
248
251
|
return self._main_script_hash
|
@@ -295,7 +298,7 @@ class PagesManager:
|
|
295
298
|
def set_pages(self, pages: dict[PageHash, PageInfo]) -> None:
|
296
299
|
# Manually setting the pages indicates we are using MPA v2.
|
297
300
|
if isinstance(self.pages_strategy, PagesStrategyV1):
|
298
|
-
if os.path.exists(
|
301
|
+
if os.path.exists(self.main_script_parent / "pages"):
|
299
302
|
_LOGGER.warning(
|
300
303
|
"st.navigation was called in an app with a pages/ directory. This may cause unusual app behavior. You may want to rename the pages/ directory."
|
301
304
|
)
|
@@ -39,6 +39,8 @@ from streamlit.errors import (
|
|
39
39
|
from streamlit.logger import get_logger
|
40
40
|
|
41
41
|
if TYPE_CHECKING:
|
42
|
+
from pathlib import Path
|
43
|
+
|
42
44
|
from streamlit.cursor import RunningCursor
|
43
45
|
from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
|
44
46
|
from streamlit.proto.PageProfile_pb2 import Command
|
@@ -114,6 +116,10 @@ class ScriptRunContext:
|
|
114
116
|
def active_script_hash(self):
|
115
117
|
return self._active_script_hash
|
116
118
|
|
119
|
+
@property
|
120
|
+
def main_script_parent(self) -> Path:
|
121
|
+
return self.pages_manager.main_script_parent
|
122
|
+
|
117
123
|
@contextlib.contextmanager
|
118
124
|
def run_with_active_hash(self, page_hash: str):
|
119
125
|
original_page_hash = self._active_script_hash
|
@@ -65,7 +65,7 @@ streamlit/elements/deck_gl_json_chart.py,sha256=3j8oZjtMK4IxiVW_ISlXPfu56X3UfEQh
|
|
65
65
|
streamlit/elements/dialog_decorator.py,sha256=12lIbNyinnfk_VvSWB8xauAMCT8PPfdn157aIMtudbg,10052
|
66
66
|
streamlit/elements/doc_string.py,sha256=IuCqpXX0GqKIjCMcaOOHr-fmOixFlCdvCT8d8EIYEAE,16024
|
67
67
|
streamlit/elements/empty.py,sha256=O0UGJsTsij2ZFk1bNP877vxdDkViXM04Q-lp9HMhs0U,4615
|
68
|
-
streamlit/elements/exception.py,sha256=
|
68
|
+
streamlit/elements/exception.py,sha256=WESsjo9PbIGpDvCLc3AEcdCeRMQhsviKgf34aOkrDO8,9841
|
69
69
|
streamlit/elements/form.py,sha256=Nm2DfsypnBB5uFZ2aC_frEPcRCSjhlrxxkcA6_TbfNw,12681
|
70
70
|
streamlit/elements/graphviz_chart.py,sha256=x2CwyP1lqDmIGObs3-Auk-6izCsdctuznKmdcUQqyoY,4937
|
71
71
|
streamlit/elements/heading.py,sha256=xzsf5QFUhlNW1VXjxmsyUHsHDCDzvo4Q6bgVoEBkMec,9893
|
@@ -135,7 +135,7 @@ streamlit/hello/plotting_demo.py,sha256=VNTbJtjujCEW5_fz2LoElwmz7vGaOKTjlOF_E94P
|
|
135
135
|
streamlit/hello/streamlit_app.py,sha256=CeLTbfeel07VDxckb4CYVi2U3C1bS-Q8sRU9VycobQA,1683
|
136
136
|
streamlit/hello/utils.py,sha256=IZMM6MZ4tcrLuSN9RWmMEYlzTbbzA3trpq6Pa82NeRw,992
|
137
137
|
streamlit/navigation/__init__.py,sha256=Vrf1yVMOcTyhUPnYvsfyeL96Vpd5z8KoSV5ZzTcTQgU,616
|
138
|
-
streamlit/navigation/page.py,sha256=
|
138
|
+
streamlit/navigation/page.py,sha256=PVdP1NJQ7jVABgawVkzd-ijAofVhUvq5cPJkTMIm8Nk,11732
|
139
139
|
streamlit/proto/Alert_pb2.py,sha256=rGlkoiE7c-gmZbYpuhRdFmRkYLcR3AmdHH3lHw8q1-E,1565
|
140
140
|
streamlit/proto/Alert_pb2.pyi,sha256=sf1JHN92JSQs2_15clCjEfBGPByTTG-FSSZ-qGjWLXk,3106
|
141
141
|
streamlit/proto/AppPage_pb2.py,sha256=zc06HvAElRirQavLwn0TzwJFhB3kvYRxSRdCS1P9ozE,1443
|
@@ -309,7 +309,7 @@ streamlit/runtime/memory_media_file_storage.py,sha256=9jzWImu9qCUGbJ61c4UhkxRSAP
|
|
309
309
|
streamlit/runtime/memory_session_storage.py,sha256=mTPuVAapuuUl0h4xZOZqviBHho9v9mDxY-XXSkqrgyQ,2936
|
310
310
|
streamlit/runtime/memory_uploaded_file_manager.py,sha256=rCLvdZv2nPlWeCiHnwV8phcVV43mUCgW7BaWkmEXgpM,4422
|
311
311
|
streamlit/runtime/metrics_util.py,sha256=khmoXNXtpRp7IIpbSVqrmTPB_sT8Oo4hyI9V6P1qthk,15001
|
312
|
-
streamlit/runtime/pages_manager.py,sha256=
|
312
|
+
streamlit/runtime/pages_manager.py,sha256=wuqKcS9qX-h_XXw0EyiggUZ0WH9L7s5FmLiElZ_3oU8,12939
|
313
313
|
streamlit/runtime/runtime.py,sha256=ek-bSvOSzwLaY06Sej44wPC5n7WDCMdx0VqYgUz2xWE,29337
|
314
314
|
streamlit/runtime/runtime_util.py,sha256=pPgc524cnmjVffZp_QuH3Yql8TFxuSs23gjnv7gIhqk,4021
|
315
315
|
streamlit/runtime/script_data.py,sha256=-sBITUF0U7DIDL5LE_nFpXAvjnEfiJ9J3HAnnqML9ds,1749
|
@@ -341,7 +341,7 @@ streamlit/runtime/scriptrunner/script_runner.py,sha256=rNhGoicfv_cg0yyHEFbcTdMYG
|
|
341
341
|
streamlit/runtime/scriptrunner_utils/__init__.py,sha256=3ecJDi5VtnxRDoaDEdgQIJ-UeNg5VWPZiycE3l6nhf0,840
|
342
342
|
streamlit/runtime/scriptrunner_utils/exceptions.py,sha256=FM09ZMEkAGqdNUPSp3SyFxp0O7g77fZtL_6JcqxNMB8,1554
|
343
343
|
streamlit/runtime/scriptrunner_utils/script_requests.py,sha256=_CeahHuCUJL8CL2oEWkKLOPDAw5HssYgTzg9tdtdUWE,12078
|
344
|
-
streamlit/runtime/scriptrunner_utils/script_run_context.py,sha256=
|
344
|
+
streamlit/runtime/scriptrunner_utils/script_run_context.py,sha256=TSio56JoWKRCr4AngaWHCrjZjhjB5fmf7TslFdL9wKo,10435
|
345
345
|
streamlit/runtime/state/__init__.py,sha256=rPkmN09FxLMWUDDBbs7Ig2d5MwAKu0GlXQwZSgBHbrY,1433
|
346
346
|
streamlit/runtime/state/common.py,sha256=yYZc4NiFQp0lqMRYSS_Lin_WC3FJj-2irXcPvpjfBOc,6407
|
347
347
|
streamlit/runtime/state/query_params.py,sha256=kCNQI99ctEGY7B2q49D9RM1vGGlZn9b4IqTxtMM9BJs,7507
|
@@ -617,9 +617,9 @@ streamlit/web/server/server_util.py,sha256=ioIHkXNlA_ujj2Q3isziM8r5glKxgK2JZRoCD
|
|
617
617
|
streamlit/web/server/stats_request_handler.py,sha256=e144zIhzLTB1PN4CwTCxElCoWMuo9IsBEPex2exHCQ0,3641
|
618
618
|
streamlit/web/server/upload_file_request_handler.py,sha256=ftyKpARrUjOpRcFETIXuoTyOG_mo-ToOw5NI0y_W4lE,5003
|
619
619
|
streamlit/web/server/websocket_headers.py,sha256=uUxypj04ondEC4ocBiYCndX_N06Zwe1Mt690Vupe08Y,2232
|
620
|
-
streamlit_nightly-1.40.3.
|
621
|
-
streamlit_nightly-1.40.3.
|
622
|
-
streamlit_nightly-1.40.3.
|
623
|
-
streamlit_nightly-1.40.3.
|
624
|
-
streamlit_nightly-1.40.3.
|
625
|
-
streamlit_nightly-1.40.3.
|
620
|
+
streamlit_nightly-1.40.3.dev20241202.data/scripts/streamlit.cmd,sha256=ZEYM3vBJSp-k7vwSJ3ba5NzEk9-qHdSeLvGYAAe1mMw,676
|
621
|
+
streamlit_nightly-1.40.3.dev20241202.dist-info/METADATA,sha256=DXIeFUyhn9gZfSCvPUPm3-0JfBEMnER8zGzUkz0z4uI,8513
|
622
|
+
streamlit_nightly-1.40.3.dev20241202.dist-info/WHEEL,sha256=pxeNX5JdtCe58PUSYP9upmc7jdRPgvT0Gm9kb1SHlVw,109
|
623
|
+
streamlit_nightly-1.40.3.dev20241202.dist-info/entry_points.txt,sha256=uNJ4DwGNXEhOK0USwSNanjkYyR-Bk7eYQbJFDrWyOgY,53
|
624
|
+
streamlit_nightly-1.40.3.dev20241202.dist-info/top_level.txt,sha256=V3FhKbm7G2LnR0s4SytavrjIPNIhvcsAGXfYHAwtQzw,10
|
625
|
+
streamlit_nightly-1.40.3.dev20241202.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|