streamlit-nightly 1.37.1.dev20240731__py2.py3-none-any.whl → 1.37.1.dev20240802__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/commands/execution_control.py +2 -4
- streamlit/config.py +15 -0
- streamlit/proto/ClientState_pb2.py +2 -2
- streamlit/proto/ClientState_pb2.pyi +4 -1
- streamlit/runtime/app_session.py +1 -0
- streamlit/runtime/fragment.py +1 -1
- streamlit/runtime/metrics_util.py +1 -3
- streamlit/runtime/scriptrunner/exec_code.py +20 -3
- streamlit/runtime/scriptrunner/script_requests.py +2 -7
- streamlit/runtime/scriptrunner/script_run_context.py +3 -1
- streamlit/runtime/scriptrunner/script_runner.py +15 -5
- streamlit/runtime/secrets.py +249 -75
- streamlit/runtime/state/session_state.py +4 -8
- streamlit/static/asset-manifest.json +3 -3
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{1168.6baadc46.chunk.js → 1168.aa1401dd.chunk.js} +1 -1
- streamlit/static/static/js/main.66b15329.js +2 -0
- streamlit/testing/v1/app_test.py +1 -1
- {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240802.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240802.dist-info}/RECORD +25 -25
- streamlit/static/static/js/main.02598bc8.js +0 -2
- /streamlit/static/static/js/{main.02598bc8.js.LICENSE.txt → main.66b15329.js.LICENSE.txt} +0 -0
- {streamlit_nightly-1.37.1.dev20240731.data → streamlit_nightly-1.37.1.dev20240802.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240802.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240802.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240802.dist-info}/top_level.txt +0 -0
@@ -67,9 +67,7 @@ def _new_fragment_id_queue(
|
|
67
67
|
return []
|
68
68
|
|
69
69
|
else: # scope == "fragment"
|
70
|
-
curr_queue =
|
71
|
-
ctx.script_requests.fragment_id_queue if ctx.script_requests else []
|
72
|
-
)
|
70
|
+
curr_queue = ctx.fragment_ids_this_run
|
73
71
|
|
74
72
|
# If st.rerun(scope="fragment") is called during a full script run, we raise an
|
75
73
|
# exception. This occurs, of course, if st.rerun(scope="fragment") is called
|
@@ -143,7 +141,7 @@ def rerun( # type: ignore[misc]
|
|
143
141
|
query_string=query_string,
|
144
142
|
page_script_hash=page_script_hash,
|
145
143
|
fragment_id_queue=_new_fragment_id_queue(ctx, scope),
|
146
|
-
is_fragment_scoped_rerun=
|
144
|
+
is_fragment_scoped_rerun=scope == "fragment",
|
147
145
|
)
|
148
146
|
)
|
149
147
|
# Force a yield point so the runner can do the rerun
|
streamlit/config.py
CHANGED
@@ -927,6 +927,21 @@ _create_option(
|
|
927
927
|
""",
|
928
928
|
)
|
929
929
|
|
930
|
+
# Config Section: Secrets #
|
931
|
+
|
932
|
+
_create_section("secrets", "Secrets configuration.")
|
933
|
+
|
934
|
+
_create_option(
|
935
|
+
"secrets.files",
|
936
|
+
description="""List of locations where secrets are searched. Entries can be a path to toml file or directory path where Kubernetes style secrets will be scanned. Order is important, import is first to last, so secrets in later files will take precedence over earlier ones.""",
|
937
|
+
default_val=[
|
938
|
+
# NOTE: The order here is important! Project-level secrets should overwrite global
|
939
|
+
# secrets.
|
940
|
+
file_util.get_streamlit_file_path("secrets.toml"),
|
941
|
+
file_util.get_project_streamlit_file_path("secrets.toml"),
|
942
|
+
],
|
943
|
+
)
|
944
|
+
|
930
945
|
|
931
946
|
def get_where_defined(key: str) -> str:
|
932
947
|
"""Indicate where (e.g. in which file) this option was defined.
|
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
|
|
15
15
|
from streamlit.proto import WidgetStates_pb2 as streamlit_dot_proto_dot_WidgetStates__pb2
|
16
16
|
|
17
17
|
|
18
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!streamlit/proto/ClientState.proto\x1a\"streamlit/proto/WidgetStates.proto\"\
|
18
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!streamlit/proto/ClientState.proto\x1a\"streamlit/proto/WidgetStates.proto\"\xa2\x01\n\x0b\x43lientState\x12\x14\n\x0cquery_string\x18\x01 \x01(\t\x12$\n\rwidget_states\x18\x02 \x01(\x0b\x32\r.WidgetStates\x12\x18\n\x10page_script_hash\x18\x03 \x01(\t\x12\x11\n\tpage_name\x18\x04 \x01(\t\x12\x13\n\x0b\x66ragment_id\x18\x05 \x01(\t\x12\x15\n\ris_auto_rerun\x18\x06 \x01(\x08\x42\x30\n\x1c\x63om.snowflake.apps.streamlitB\x10\x43lientStateProtob\x06proto3')
|
19
19
|
|
20
20
|
_globals = globals()
|
21
21
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
@@ -24,5 +24,5 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
24
24
|
_globals['DESCRIPTOR']._loaded_options = None
|
25
25
|
_globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\020ClientStateProto'
|
26
26
|
_globals['_CLIENTSTATE']._serialized_start=74
|
27
|
-
_globals['_CLIENTSTATE']._serialized_end=
|
27
|
+
_globals['_CLIENTSTATE']._serialized_end=236
|
28
28
|
# @@protoc_insertion_point(module_scope)
|
@@ -34,10 +34,12 @@ class ClientState(google.protobuf.message.Message):
|
|
34
34
|
PAGE_SCRIPT_HASH_FIELD_NUMBER: builtins.int
|
35
35
|
PAGE_NAME_FIELD_NUMBER: builtins.int
|
36
36
|
FRAGMENT_ID_FIELD_NUMBER: builtins.int
|
37
|
+
IS_AUTO_RERUN_FIELD_NUMBER: builtins.int
|
37
38
|
query_string: builtins.str
|
38
39
|
page_script_hash: builtins.str
|
39
40
|
page_name: builtins.str
|
40
41
|
fragment_id: builtins.str
|
42
|
+
is_auto_rerun: builtins.bool
|
41
43
|
@property
|
42
44
|
def widget_states(self) -> streamlit.proto.WidgetStates_pb2.WidgetStates: ...
|
43
45
|
def __init__(
|
@@ -48,8 +50,9 @@ class ClientState(google.protobuf.message.Message):
|
|
48
50
|
page_script_hash: builtins.str = ...,
|
49
51
|
page_name: builtins.str = ...,
|
50
52
|
fragment_id: builtins.str = ...,
|
53
|
+
is_auto_rerun: builtins.bool = ...,
|
51
54
|
) -> None: ...
|
52
55
|
def HasField(self, field_name: typing.Literal["widget_states", b"widget_states"]) -> builtins.bool: ...
|
53
|
-
def ClearField(self, field_name: typing.Literal["fragment_id", b"fragment_id", "page_name", b"page_name", "page_script_hash", b"page_script_hash", "query_string", b"query_string", "widget_states", b"widget_states"]) -> None: ...
|
56
|
+
def ClearField(self, field_name: typing.Literal["fragment_id", b"fragment_id", "is_auto_rerun", b"is_auto_rerun", "page_name", b"page_name", "page_script_hash", b"page_script_hash", "query_string", b"query_string", "widget_states", b"widget_states"]) -> None: ...
|
54
57
|
|
55
58
|
global___ClientState = ClientState
|
streamlit/runtime/app_session.py
CHANGED
streamlit/runtime/fragment.py
CHANGED
@@ -193,7 +193,7 @@ def _fragment(
|
|
193
193
|
ctx = get_script_run_ctx(suppress_warning=True)
|
194
194
|
assert ctx is not None
|
195
195
|
|
196
|
-
if ctx.
|
196
|
+
if ctx.fragment_ids_this_run:
|
197
197
|
# This script run is a run of one or more fragments. We restore the
|
198
198
|
# state of ctx.cursors and dg_stack to the snapshots we took when this
|
199
199
|
# fragment was declared.
|
@@ -482,8 +482,6 @@ def create_page_profile_message(
|
|
482
482
|
page_profile.uncaught_exception = uncaught_exception
|
483
483
|
|
484
484
|
if ctx := get_script_run_ctx():
|
485
|
-
page_profile.is_fragment_run = bool(
|
486
|
-
ctx.script_requests and ctx.script_requests.fragment_id_queue
|
487
|
-
)
|
485
|
+
page_profile.is_fragment_run = bool(ctx.fragment_ids_this_run)
|
488
486
|
|
489
487
|
return msg
|
@@ -27,7 +27,13 @@ if TYPE_CHECKING:
|
|
27
27
|
|
28
28
|
def exec_func_with_error_handling(
|
29
29
|
func: Callable[[], None], ctx: ScriptRunContext
|
30
|
-
) -> tuple[
|
30
|
+
) -> tuple[
|
31
|
+
Any | None,
|
32
|
+
bool,
|
33
|
+
RerunData | None,
|
34
|
+
bool,
|
35
|
+
Exception | None,
|
36
|
+
]:
|
31
37
|
"""Execute the passed function wrapped in a try/except block.
|
32
38
|
|
33
39
|
This function is called by the script runner to execute the user's script or
|
@@ -53,6 +59,7 @@ def exec_func_with_error_handling(
|
|
53
59
|
interrupted by a RerunException.
|
54
60
|
- A boolean indicating whether the script was stopped prematurely (False for
|
55
61
|
RerunExceptions, True for all other exceptions).
|
62
|
+
- The uncaught exception if one occurred, None otherwise
|
56
63
|
"""
|
57
64
|
|
58
65
|
# Avoid circular imports
|
@@ -71,6 +78,9 @@ def exec_func_with_error_handling(
|
|
71
78
|
# The result of the passed function
|
72
79
|
result: Any | None = None
|
73
80
|
|
81
|
+
# The uncaught exception if one occurred, None otherwise
|
82
|
+
uncaught_exception: Exception | None = None
|
83
|
+
|
74
84
|
try:
|
75
85
|
result = func()
|
76
86
|
except RerunException as e:
|
@@ -102,5 +112,12 @@ def exec_func_with_error_handling(
|
|
102
112
|
run_without_errors = False
|
103
113
|
premature_stop = True
|
104
114
|
handle_uncaught_app_exception(ex)
|
105
|
-
|
106
|
-
|
115
|
+
uncaught_exception = ex
|
116
|
+
|
117
|
+
return (
|
118
|
+
result,
|
119
|
+
run_without_errors,
|
120
|
+
rerun_exception_data,
|
121
|
+
premature_stop,
|
122
|
+
uncaught_exception,
|
123
|
+
)
|
@@ -54,6 +54,7 @@ class RerunData:
|
|
54
54
|
# The queue of fragment_ids waiting to be run.
|
55
55
|
fragment_id_queue: list[str] = field(default_factory=list)
|
56
56
|
is_fragment_scoped_rerun: bool = False
|
57
|
+
is_auto_rerun: bool = False
|
57
58
|
|
58
59
|
def __repr__(self) -> str:
|
59
60
|
return util.repr_(self)
|
@@ -102,13 +103,6 @@ class ScriptRequests:
|
|
102
103
|
self._state = ScriptRequestType.CONTINUE
|
103
104
|
self._rerun_data = RerunData()
|
104
105
|
|
105
|
-
@property
|
106
|
-
def fragment_id_queue(self) -> list[str]:
|
107
|
-
if not self._rerun_data:
|
108
|
-
return []
|
109
|
-
|
110
|
-
return self._rerun_data.fragment_id_queue
|
111
|
-
|
112
106
|
def request_stop(self) -> None:
|
113
107
|
"""Request that the ScriptRunner stop running. A stopped ScriptRunner
|
114
108
|
can't be used anymore. STOP requests succeed unconditionally.
|
@@ -180,6 +174,7 @@ class ScriptRequests:
|
|
180
174
|
page_name=new_data.page_name,
|
181
175
|
fragment_id_queue=fragment_id_queue,
|
182
176
|
is_fragment_scoped_rerun=new_data.is_fragment_scoped_rerun,
|
177
|
+
is_auto_rerun=new_data.is_auto_rerun,
|
183
178
|
)
|
184
179
|
|
185
180
|
return True
|
@@ -77,6 +77,7 @@ class ScriptRunContext:
|
|
77
77
|
cursors: dict[int, RunningCursor] = field(default_factory=dict)
|
78
78
|
script_requests: ScriptRequests | None = None
|
79
79
|
current_fragment_id: str | None = None
|
80
|
+
fragment_ids_this_run: list[str] | None = None
|
80
81
|
new_fragment_ids: set[str] = field(default_factory=set)
|
81
82
|
# we allow only one dialog to be open at the same time
|
82
83
|
has_dialog_opened: bool = False
|
@@ -100,6 +101,7 @@ class ScriptRunContext:
|
|
100
101
|
self,
|
101
102
|
query_string: str = "",
|
102
103
|
page_script_hash: str = "",
|
104
|
+
fragment_ids_this_run: list[str] | None = None,
|
103
105
|
) -> None:
|
104
106
|
self.cursors = {}
|
105
107
|
self.widget_ids_this_run = set()
|
@@ -115,7 +117,7 @@ class ScriptRunContext:
|
|
115
117
|
self.tracked_commands_counter = collections.Counter()
|
116
118
|
self.current_fragment_id = None
|
117
119
|
self.current_fragment_delta_path: list[int] = []
|
118
|
-
self.fragment_ids_this_run =
|
120
|
+
self.fragment_ids_this_run = fragment_ids_this_run
|
119
121
|
self.new_fragment_ids = set()
|
120
122
|
self.has_dialog_opened = False
|
121
123
|
self.disallow_cached_widget_usage = False
|
@@ -425,7 +425,6 @@ class ScriptRunner:
|
|
425
425
|
rerun_data.page_script_hash, rerun_data.page_name
|
426
426
|
)
|
427
427
|
main_page_info = self._pages_manager.get_main_page()
|
428
|
-
uncaught_exception = None
|
429
428
|
|
430
429
|
page_script_hash = (
|
431
430
|
active_script["page_script_hash"]
|
@@ -433,6 +432,8 @@ class ScriptRunner:
|
|
433
432
|
else main_page_info["page_script_hash"]
|
434
433
|
)
|
435
434
|
|
435
|
+
fragment_ids_this_run = list(rerun_data.fragment_id_queue)
|
436
|
+
|
436
437
|
ctx = self._get_script_run_ctx()
|
437
438
|
# Clear widget state on page change. This normally happens implicitly
|
438
439
|
# in the script run cleanup steps, but doing it explicitly ensures
|
@@ -457,6 +458,7 @@ class ScriptRunner:
|
|
457
458
|
ctx.reset(
|
458
459
|
query_string=rerun_data.query_string,
|
459
460
|
page_script_hash=page_script_hash,
|
461
|
+
fragment_ids_this_run=fragment_ids_this_run,
|
460
462
|
)
|
461
463
|
self._pages_manager.reset_active_script_hash()
|
462
464
|
|
@@ -555,9 +557,16 @@ class ScriptRunner:
|
|
555
557
|
wrapped_fragment()
|
556
558
|
|
557
559
|
except FragmentStorageKeyError:
|
558
|
-
raise
|
559
|
-
|
560
|
-
|
560
|
+
# Only raise an error if the fragment is not an
|
561
|
+
# auto_rerun. If it is an auto_rerun, we might have a
|
562
|
+
# race condition where the fragment_id is removed
|
563
|
+
# but the webapp sends a rerun request before the
|
564
|
+
# removal information has reached the web app
|
565
|
+
# (see https://github.com/streamlit/streamlit/issues/9080).
|
566
|
+
if not rerun_data.is_auto_rerun:
|
567
|
+
raise RuntimeError(
|
568
|
+
f"Could not find fragment with id {fragment_id}"
|
569
|
+
)
|
561
570
|
except (RerunException, StopException) as e:
|
562
571
|
# The wrapped_fragment function is executed
|
563
572
|
# inside of a exec_func_with_error_handling call, so
|
@@ -586,6 +595,7 @@ class ScriptRunner:
|
|
586
595
|
run_without_errors,
|
587
596
|
rerun_exception_data,
|
588
597
|
premature_stop,
|
598
|
+
uncaught_exception,
|
589
599
|
) = exec_func_with_error_handling(code_to_exec, ctx)
|
590
600
|
# setting the session state here triggers a yield-callback call
|
591
601
|
# which reads self._requests and checks for rerun data
|
@@ -611,7 +621,7 @@ class ScriptRunner:
|
|
611
621
|
# Create and send page profile information
|
612
622
|
ctx.enqueue(
|
613
623
|
create_page_profile_message(
|
614
|
-
ctx.tracked_commands,
|
624
|
+
commands=ctx.tracked_commands,
|
615
625
|
exec_time=to_microseconds(timer() - start_time),
|
616
626
|
prep_time=to_microseconds(prep_time),
|
617
627
|
uncaught_exception=(
|