streamlit-nightly 1.37.1.dev20240731__py2.py3-none-any.whl → 1.37.1.dev20240801__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.
Files changed (26) hide show
  1. streamlit/commands/execution_control.py +2 -4
  2. streamlit/config.py +15 -0
  3. streamlit/proto/ClientState_pb2.py +2 -2
  4. streamlit/proto/ClientState_pb2.pyi +4 -1
  5. streamlit/runtime/app_session.py +1 -0
  6. streamlit/runtime/fragment.py +1 -1
  7. streamlit/runtime/metrics_util.py +1 -3
  8. streamlit/runtime/scriptrunner/exec_code.py +20 -3
  9. streamlit/runtime/scriptrunner/script_requests.py +2 -7
  10. streamlit/runtime/scriptrunner/script_run_context.py +3 -1
  11. streamlit/runtime/scriptrunner/script_runner.py +15 -5
  12. streamlit/runtime/secrets.py +249 -75
  13. streamlit/runtime/state/session_state.py +4 -8
  14. streamlit/static/asset-manifest.json +3 -3
  15. streamlit/static/index.html +1 -1
  16. streamlit/static/static/js/{1168.6baadc46.chunk.js → 1168.aa1401dd.chunk.js} +1 -1
  17. streamlit/static/static/js/main.66b15329.js +2 -0
  18. streamlit/testing/v1/app_test.py +1 -1
  19. {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240801.dist-info}/METADATA +1 -1
  20. {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240801.dist-info}/RECORD +25 -25
  21. streamlit/static/static/js/main.02598bc8.js +0 -2
  22. /streamlit/static/static/js/{main.02598bc8.js.LICENSE.txt → main.66b15329.js.LICENSE.txt} +0 -0
  23. {streamlit_nightly-1.37.1.dev20240731.data → streamlit_nightly-1.37.1.dev20240801.data}/scripts/streamlit.cmd +0 -0
  24. {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240801.dist-info}/WHEEL +0 -0
  25. {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240801.dist-info}/entry_points.txt +0 -0
  26. {streamlit_nightly-1.37.1.dev20240731.dist-info → streamlit_nightly-1.37.1.dev20240801.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=True,
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\"\x8b\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(\tB0\n\x1c\x63om.snowflake.apps.streamlitB\x10\x43lientStateProtob\x06proto3')
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=213
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
@@ -363,6 +363,7 @@ class AppSession:
363
363
  client_state.page_script_hash,
364
364
  client_state.page_name,
365
365
  fragment_id=fragment_id if fragment_id else None,
366
+ is_auto_rerun=client_state.is_auto_rerun,
366
367
  )
367
368
  else:
368
369
  rerun_data = RerunData()
@@ -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.script_requests and ctx.script_requests.fragment_id_queue:
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[Any | None, bool, RerunData | None, bool]:
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
- return result, run_without_errors, rerun_exception_data, premature_stop
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 = None
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 RuntimeError(
559
- f"Could not find fragment with id {fragment_id}"
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=(