streamlit-nightly 1.32.3.dev20240325__py2.py3-none-any.whl → 1.32.3.dev20240328__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 (85) hide show
  1. streamlit/__init__.py +4 -2
  2. streamlit/components/v1/__init__.py +3 -17
  3. streamlit/components/v1/{custom_component.py → components.py} +159 -11
  4. streamlit/delta_generator.py +3 -0
  5. streamlit/elements/media.py +52 -4
  6. streamlit/elements/widgets/time_widgets.py +5 -21
  7. streamlit/errors.py +0 -6
  8. streamlit/proto/AutoRerun_pb2.py +25 -0
  9. streamlit/proto/AutoRerun_pb2.pyi +48 -0
  10. streamlit/proto/ClientState_pb2.py +3 -3
  11. streamlit/proto/ClientState_pb2.pyi +4 -1
  12. streamlit/proto/Delta_pb2.py +2 -2
  13. streamlit/proto/Delta_pb2.pyi +4 -1
  14. streamlit/proto/ForwardMsg_pb2.py +10 -9
  15. streamlit/proto/ForwardMsg_pb2.pyi +12 -3
  16. streamlit/proto/NewSession_pb2.py +24 -24
  17. streamlit/proto/NewSession_pb2.pyi +8 -1
  18. streamlit/proto/PageProfile_pb2.py +6 -6
  19. streamlit/proto/PageProfile_pb2.pyi +4 -1
  20. streamlit/runtime/app_session.py +67 -24
  21. streamlit/runtime/caching/cache_data_api.py +3 -3
  22. streamlit/runtime/caching/cache_errors.py +0 -11
  23. streamlit/runtime/caching/cache_resource_api.py +2 -2
  24. streamlit/runtime/caching/cache_utils.py +1 -43
  25. streamlit/runtime/fragment.py +239 -0
  26. streamlit/runtime/metrics_util.py +17 -9
  27. streamlit/runtime/runtime.py +6 -12
  28. streamlit/runtime/runtime_util.py +54 -2
  29. streamlit/runtime/scriptrunner/script_requests.py +53 -37
  30. streamlit/runtime/scriptrunner/script_run_context.py +15 -2
  31. streamlit/runtime/scriptrunner/script_runner.py +63 -14
  32. streamlit/runtime/state/common.py +2 -0
  33. streamlit/runtime/state/session_state.py +51 -7
  34. streamlit/runtime/state/widgets.py +10 -2
  35. streamlit/static/asset-manifest.json +19 -19
  36. streamlit/static/index.html +1 -1
  37. streamlit/static/static/js/1074.73973756.chunk.js +1 -0
  38. streamlit/static/static/js/1451.3b0a3e31.chunk.js +1 -0
  39. streamlit/static/static/js/1792.b8efa879.chunk.js +1 -0
  40. streamlit/static/static/js/{3092.3d4df25e.chunk.js → 3092.ad569cc8.chunk.js} +1 -1
  41. streamlit/static/static/js/3513.e3e7300a.chunk.js +1 -0
  42. streamlit/static/static/js/4177.69f9f18d.chunk.js +1 -0
  43. streamlit/static/static/js/4319.a6745434.chunk.js +1 -0
  44. streamlit/static/static/js/{4477.2555c11a.chunk.js → 4477.e10e4373.chunk.js} +1 -1
  45. streamlit/static/static/js/{4666.99f3abc3.chunk.js → 4666.b694c5a9.chunk.js} +1 -1
  46. streamlit/static/static/js/5106.44f0ff51.chunk.js +1 -0
  47. streamlit/static/static/js/5379.6571574f.chunk.js +1 -0
  48. streamlit/static/static/js/6013.8e80e091.chunk.js +1 -0
  49. streamlit/static/static/js/6718.802da17e.chunk.js +1 -0
  50. streamlit/static/static/js/7175.be4076bc.chunk.js +1 -0
  51. streamlit/static/static/js/{7602.f0420392.chunk.js → 7602.6175e969.chunk.js} +1 -1
  52. streamlit/static/static/js/{8492.e6dab83f.chunk.js → 8492.f56c9d4c.chunk.js} +1 -1
  53. streamlit/static/static/js/8691.9ccf7f89.chunk.js +1 -0
  54. streamlit/static/static/js/main.722453f0.js +2 -0
  55. streamlit/testing/v1/local_script_runner.py +2 -0
  56. streamlit/time_util.py +88 -0
  57. streamlit/watcher/local_sources_watcher.py +2 -1
  58. streamlit/web/server/component_request_handler.py +2 -2
  59. streamlit/web/server/server.py +2 -1
  60. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/METADATA +1 -1
  61. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/RECORD +66 -68
  62. streamlit/components/lib/__init__.py +0 -13
  63. streamlit/components/lib/local_component_registry.py +0 -82
  64. streamlit/components/types/__init__.py +0 -13
  65. streamlit/components/types/base_component_registry.py +0 -98
  66. streamlit/components/types/base_custom_component.py +0 -137
  67. streamlit/components/v1/component_registry.py +0 -103
  68. streamlit/static/static/js/1074.71719df6.chunk.js +0 -1
  69. streamlit/static/static/js/1451.e3be1711.chunk.js +0 -1
  70. streamlit/static/static/js/1792.16c16498.chunk.js +0 -1
  71. streamlit/static/static/js/3513.57cff89c.chunk.js +0 -1
  72. streamlit/static/static/js/4177.ab9a7aa1.chunk.js +0 -1
  73. streamlit/static/static/js/4319.213fc321.chunk.js +0 -1
  74. streamlit/static/static/js/5106.22187bfc.chunk.js +0 -1
  75. streamlit/static/static/js/5379.e466522d.chunk.js +0 -1
  76. streamlit/static/static/js/6013.75c92264.chunk.js +0 -1
  77. streamlit/static/static/js/6718.97945fc6.chunk.js +0 -1
  78. streamlit/static/static/js/7175.8c1b4d38.chunk.js +0 -1
  79. streamlit/static/static/js/8691.24a5792f.chunk.js +0 -1
  80. streamlit/static/static/js/main.7fde7092.js +0 -2
  81. /streamlit/static/static/js/{main.7fde7092.js.LICENSE.txt → main.722453f0.js.LICENSE.txt} +0 -0
  82. {streamlit_nightly-1.32.3.dev20240325.data → streamlit_nightly-1.32.3.dev20240328.data}/scripts/streamlit.cmd +0 -0
  83. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/WHEEL +0 -0
  84. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/entry_points.txt +0 -0
  85. {streamlit_nightly-1.32.3.dev20240325.dist-info → streamlit_nightly-1.32.3.dev20240328.dist-info}/top_level.txt +0 -0
streamlit/__init__.py CHANGED
@@ -81,6 +81,7 @@ from streamlit.runtime.caching import (
81
81
  from streamlit.runtime.connection_factory import (
82
82
  connection_factory as _connection,
83
83
  )
84
+ from streamlit.runtime.fragment import fragment as _fragment
84
85
  from streamlit.runtime.metrics_util import gather_metrics as _gather_metrics
85
86
  from streamlit.runtime.secrets import secrets_singleton as _secrets_singleton
86
87
  from streamlit.runtime.state import (
@@ -230,9 +231,10 @@ column_config = _column_config
230
231
  connection = _connection
231
232
 
232
233
  # Experimental APIs
233
- experimental_user = _UserInfoProxy()
234
- experimental_singleton = _experimental_singleton
234
+ experimental_fragment = _fragment
235
235
  experimental_memo = _experimental_memo
236
+ experimental_singleton = _experimental_singleton
237
+ experimental_user = _UserInfoProxy()
236
238
 
237
239
  _EXPERIMENTAL_QUERY_PARAMS_DEPRECATE_MSG = "Refer to our [docs page](https://docs.streamlit.io/library/api-reference/utilities/st.query_params) for more information."
238
240
 
@@ -12,29 +12,15 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """
16
- This directory contains the files and modules for the exposed API.
17
- """
18
-
19
- import streamlit
20
-
21
- # The `custom_component as components` import exists as existing custom components have started
22
- # to rely on internals of the components package. For example, streamlit-option-menu accesses
23
- # [register_widget](https://github.com/victoryhb/streamlit-option-menu/blob/master/streamlit_option_menu/streamlit_callback.py#L28),
24
- # which is only a transitive import through `streamlit.components.v1.custom_component`.
25
- # Since we do not know what other internals are used out in the wild, let's try to
26
- # model the old behavior and not to break things. Ideally, custom component implementors
27
- # use officially exposed APIs only or do direct imports instead of indirect imports.
28
- from streamlit.components.v1 import custom_component as components
29
- from streamlit.components.v1.component_registry import declare_component
30
-
31
15
  # `html` and `iframe` are part of Custom Components, so they appear in this
32
16
  # `streamlit.components.v1` namespace.
17
+ import streamlit
18
+ from streamlit.components.v1.components import declare_component
19
+
33
20
  html = streamlit._main._html
34
21
  iframe = streamlit._main._iframe
35
22
 
36
23
  __all__ = [
37
- "components",
38
24
  "declare_component",
39
25
  "html",
40
26
  "iframe",
@@ -14,13 +14,17 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ import inspect
17
18
  import json
18
- from typing import TYPE_CHECKING, Any
19
+ import os
20
+ import threading
21
+ from typing import TYPE_CHECKING, Any, Final
19
22
 
20
- from streamlit import _main, type_util
21
- from streamlit.components.types.base_custom_component import BaseCustomComponent
23
+ import streamlit
24
+ from streamlit import type_util, util
22
25
  from streamlit.elements.form import current_form_id
23
26
  from streamlit.errors import StreamlitAPIException
27
+ from streamlit.logger import get_logger
24
28
  from streamlit.proto.Components_pb2 import ArrowTable as ArrowTableProto
25
29
  from streamlit.proto.Components_pb2 import SpecialArg
26
30
  from streamlit.proto.Element_pb2 import Element
@@ -33,6 +37,8 @@ from streamlit.type_util import to_bytes
33
37
  if TYPE_CHECKING:
34
38
  from streamlit.delta_generator import DeltaGenerator
35
39
 
40
+ _LOGGER: Final = get_logger(__name__)
41
+
36
42
 
37
43
  class MarshallComponentException(StreamlitAPIException):
38
44
  """Class for exceptions generated during custom component marshalling."""
@@ -40,9 +46,34 @@ class MarshallComponentException(StreamlitAPIException):
40
46
  pass
41
47
 
42
48
 
43
- class CustomComponent(BaseCustomComponent):
49
+ class CustomComponent:
44
50
  """A Custom Component declaration."""
45
51
 
52
+ def __init__(
53
+ self,
54
+ name: str,
55
+ path: str | None = None,
56
+ url: str | None = None,
57
+ ):
58
+ if (path is None and url is None) or (path is not None and url is not None):
59
+ raise StreamlitAPIException(
60
+ "Either 'path' or 'url' must be set, but not both."
61
+ )
62
+
63
+ self.name = name
64
+ self.path = path
65
+ self.url = url
66
+
67
+ def __repr__(self) -> str:
68
+ return util.repr_(self)
69
+
70
+ @property
71
+ def abspath(self) -> str | None:
72
+ """The absolute path that the component is served from."""
73
+ if self.path is None:
74
+ return None
75
+ return os.path.abspath(self.path)
76
+
46
77
  def __call__(
47
78
  self,
48
79
  *args,
@@ -158,7 +189,7 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
158
189
 
159
190
  if key is None:
160
191
  marshall_element_args()
161
- computed_id = compute_widget_id(
192
+ id = compute_widget_id(
162
193
  "component_instance",
163
194
  user_key=key,
164
195
  name=self.name,
@@ -170,7 +201,7 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
170
201
  page=ctx.page_script_hash if ctx else None,
171
202
  )
172
203
  else:
173
- computed_id = compute_widget_id(
204
+ id = compute_widget_id(
174
205
  "component_instance",
175
206
  user_key=key,
176
207
  name=self.name,
@@ -179,7 +210,7 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
179
210
  key=key,
180
211
  page=ctx.page_script_hash if ctx else None,
181
212
  )
182
- element.component_instance.id = computed_id
213
+ element.component_instance.id = id
183
214
 
184
215
  def deserialize_component(ui_value, widget_id=""):
185
216
  # ui_value is an object from json, an ArrowTable proto, or a bytearray
@@ -211,7 +242,7 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
211
242
 
212
243
  # We currently only support writing to st._main, but this will change
213
244
  # when we settle on an improved API in a post-layout world.
214
- dg = _main
245
+ dg = streamlit._main
215
246
 
216
247
  element = Element()
217
248
  return_value = marshall_component(dg, element)
@@ -228,14 +259,131 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
228
259
  and self.name == other.name
229
260
  and self.path == other.path
230
261
  and self.url == other.url
231
- and self.module_name == other.module_name
232
262
  )
233
263
 
234
264
  def __ne__(self, other) -> bool:
235
265
  """Inequality operator."""
236
-
237
- # we have to use "not X == Y"" here because if we use "X != Y" we call __ne__ again and end up in recursion
238
266
  return not self == other
239
267
 
240
268
  def __str__(self) -> str:
241
269
  return f"'{self.name}': {self.path if self.path is not None else self.url}"
270
+
271
+
272
+ def declare_component(
273
+ name: str,
274
+ path: str | None = None,
275
+ url: str | None = None,
276
+ ) -> CustomComponent:
277
+ """Create and register a custom component.
278
+
279
+ Parameters
280
+ ----------
281
+ name: str
282
+ A short, descriptive name for the component. Like, "slider".
283
+ path: str or None
284
+ The path to serve the component's frontend files from. Either
285
+ `path` or `url` must be specified, but not both.
286
+ url: str or None
287
+ The URL that the component is served from. Either `path` or `url`
288
+ must be specified, but not both.
289
+
290
+ Returns
291
+ -------
292
+ CustomComponent
293
+ A CustomComponent that can be called like a function.
294
+ Calling the component will create a new instance of the component
295
+ in the Streamlit app.
296
+
297
+ """
298
+
299
+ # Get our stack frame.
300
+ current_frame = inspect.currentframe()
301
+ assert current_frame is not None
302
+
303
+ # Get the stack frame of our calling function.
304
+ caller_frame = current_frame.f_back
305
+ assert caller_frame is not None
306
+
307
+ # Get the caller's module name. `__name__` gives us the module's
308
+ # fully-qualified name, which includes its package.
309
+ module = inspect.getmodule(caller_frame)
310
+ assert module is not None
311
+ module_name = module.__name__
312
+
313
+ # If the caller was the main module that was executed (that is, if the
314
+ # user executed `python my_component.py`), then this name will be
315
+ # "__main__" instead of the actual package name. In this case, we use
316
+ # the main module's filename, sans `.py` extension, as the component name.
317
+ if module_name == "__main__":
318
+ file_path = inspect.getfile(caller_frame)
319
+ filename = os.path.basename(file_path)
320
+ module_name, _ = os.path.splitext(filename)
321
+
322
+ # Build the component name.
323
+ component_name = f"{module_name}.{name}"
324
+
325
+ # Create our component object, and register it.
326
+ component = CustomComponent(name=component_name, path=path, url=url)
327
+ ComponentRegistry.instance().register_component(component)
328
+
329
+ return component
330
+
331
+
332
+ class ComponentRegistry:
333
+ _instance_lock: threading.Lock = threading.Lock()
334
+ _instance: ComponentRegistry | None = None
335
+
336
+ @classmethod
337
+ def instance(cls) -> ComponentRegistry:
338
+ """Returns the singleton ComponentRegistry"""
339
+ # We use a double-checked locking optimization to avoid the overhead
340
+ # of acquiring the lock in the common case:
341
+ # https://en.wikipedia.org/wiki/Double-checked_locking
342
+ if cls._instance is None:
343
+ with cls._instance_lock:
344
+ if cls._instance is None:
345
+ cls._instance = ComponentRegistry()
346
+ return cls._instance
347
+
348
+ def __init__(self):
349
+ self._components: dict[str, CustomComponent] = {}
350
+ self._lock = threading.Lock()
351
+
352
+ def __repr__(self) -> str:
353
+ return util.repr_(self)
354
+
355
+ def register_component(self, component: CustomComponent) -> None:
356
+ """Register a CustomComponent.
357
+
358
+ Parameters
359
+ ----------
360
+ component : CustomComponent
361
+ The component to register.
362
+ """
363
+
364
+ # Validate the component's path
365
+ abspath = component.abspath
366
+ if abspath is not None and not os.path.isdir(abspath):
367
+ raise StreamlitAPIException(f"No such component directory: '{abspath}'")
368
+
369
+ with self._lock:
370
+ existing = self._components.get(component.name)
371
+ self._components[component.name] = component
372
+
373
+ if existing is not None and component != existing:
374
+ _LOGGER.warning(
375
+ "%s overriding previously-registered %s",
376
+ component,
377
+ existing,
378
+ )
379
+
380
+ _LOGGER.debug("Registered component %s", component)
381
+
382
+ def get_component_path(self, name: str) -> str | None:
383
+ """Return the filesystem path for the component with the given name.
384
+
385
+ If no such component is registered, or if the component exists but is
386
+ being served from a URL, return None instead.
387
+ """
388
+ component = self._components.get(name, None)
389
+ return component.abspath if component is not None else None
@@ -897,4 +897,7 @@ def _enqueue_message(msg: ForwardMsg_pb2.ForwardMsg) -> None:
897
897
  if ctx is None:
898
898
  raise NoSessionContext()
899
899
 
900
+ if ctx.current_fragment_id and msg.WhichOneof("type") == "delta":
901
+ msg.delta.fragment_id = ctx.current_fragment_id
902
+
900
903
  ctx.enqueue(msg)
@@ -16,6 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import io
18
18
  import re
19
+ from datetime import timedelta
19
20
  from pathlib import Path
20
21
  from typing import TYPE_CHECKING, Dict, Final, Union, cast
21
22
 
@@ -29,6 +30,7 @@ from streamlit.proto.Audio_pb2 import Audio as AudioProto
29
30
  from streamlit.proto.Video_pb2 import Video as VideoProto
30
31
  from streamlit.runtime import caching
31
32
  from streamlit.runtime.metrics_util import gather_metrics
33
+ from streamlit.runtime.runtime_util import duration_to_seconds
32
34
 
33
35
  if TYPE_CHECKING:
34
36
  from typing import Any
@@ -45,6 +47,16 @@ SubtitleData: TypeAlias = Union[
45
47
  str, Path, bytes, io.BytesIO, Dict[str, Union[str, Path, bytes, io.BytesIO]], None
46
48
  ]
47
49
 
50
+ MediaTime: TypeAlias = Union[int, float, timedelta, str]
51
+
52
+ TIMEDELTA_PARSE_ERROR_MESSAGE: Final = (
53
+ "Failed to convert '{param_name}' to a timedelta. "
54
+ "Please use a string in a format supported by "
55
+ "[Pandas Timedelta constructor]"
56
+ "(https://pandas.pydata.org/docs/reference/api/pandas.Timedelta.html), "
57
+ 'e.g. `"10s"`, `"15 seconds"`, or `"1h23s"`. Got: {param_value}'
58
+ )
59
+
48
60
 
49
61
  class MediaMixin:
50
62
  @gather_metrics("audio")
@@ -52,10 +64,10 @@ class MediaMixin:
52
64
  self,
53
65
  data: MediaData,
54
66
  format: str = "audio/wav",
55
- start_time: int = 0,
67
+ start_time: MediaTime = 0,
56
68
  *,
57
69
  sample_rate: int | None = None,
58
- end_time: int | None = None,
70
+ end_time: MediaTime | None = None,
59
71
  loop: bool = False,
60
72
  ) -> DeltaGenerator:
61
73
  """Display an audio player.
@@ -111,6 +123,8 @@ class MediaMixin:
111
123
  height: 865px
112
124
 
113
125
  """
126
+ start_time, end_time = _parse_start_time_end_time(start_time, end_time)
127
+
114
128
  audio_proto = AudioProto()
115
129
  coordinates = self.dg._get_delta_path_str()
116
130
 
@@ -143,10 +157,10 @@ class MediaMixin:
143
157
  self,
144
158
  data: MediaData,
145
159
  format: str = "video/mp4",
146
- start_time: int = 0,
160
+ start_time: MediaTime = 0,
147
161
  *, # keyword-only arguments:
148
162
  subtitles: SubtitleData = None,
149
- end_time: int | None = None,
163
+ end_time: MediaTime | None = None,
150
164
  loop: bool = False,
151
165
  ) -> DeltaGenerator:
152
166
  """Display a video player.
@@ -246,6 +260,9 @@ class MediaMixin:
246
260
  for more information.
247
261
 
248
262
  """
263
+
264
+ start_time, end_time = _parse_start_time_end_time(start_time, end_time)
265
+
249
266
  video_proto = VideoProto()
250
267
  coordinates = self.dg._get_delta_path_str()
251
268
  marshall_video(
@@ -461,6 +478,37 @@ def marshall_video(
461
478
  ) from original_err
462
479
 
463
480
 
481
+ def _parse_start_time_end_time(
482
+ start_time: MediaTime, end_time: MediaTime | None
483
+ ) -> tuple[int, int | None]:
484
+ """Parse start_time and end_time and return them as int."""
485
+
486
+ try:
487
+ maybe_start_time = duration_to_seconds(start_time, coerce_none_to_inf=False)
488
+ if maybe_start_time is None:
489
+ raise ValueError
490
+ start_time = int(maybe_start_time)
491
+ except (StreamlitAPIException, ValueError):
492
+ error_msg = TIMEDELTA_PARSE_ERROR_MESSAGE.format(
493
+ param_name="start_time", param_value=start_time
494
+ )
495
+ raise StreamlitAPIException(error_msg) from None
496
+
497
+ try:
498
+ # TODO[kajarenc]: Replace `duration_to_seconds` with `time_to_seconds`
499
+ # when PR #8343 is merged.
500
+ end_time = duration_to_seconds(end_time, coerce_none_to_inf=False)
501
+ if end_time is not None:
502
+ end_time = int(end_time)
503
+ except StreamlitAPIException:
504
+ error_msg = TIMEDELTA_PARSE_ERROR_MESSAGE.format(
505
+ param_name="end_time", param_value=end_time
506
+ )
507
+ raise StreamlitAPIException(error_msg) from None
508
+
509
+ return start_time, end_time
510
+
511
+
464
512
  def _validate_and_normalize(data: npt.NDArray[Any]) -> tuple[bytes, int]:
465
513
  """Validates and normalizes numpy array data.
466
514
  We validate numpy array shape (should be 1d or 2d)
@@ -50,6 +50,7 @@ from streamlit.runtime.state import (
50
50
  register_widget,
51
51
  )
52
52
  from streamlit.runtime.state.common import compute_widget_id
53
+ from streamlit.time_util import adjust_years
53
54
  from streamlit.type_util import Key, LabelVisibility, maybe_raise_label_warnings, to_key
54
55
 
55
56
  if TYPE_CHECKING:
@@ -67,23 +68,6 @@ ALLOWED_DATE_FORMATS: Final = re.compile(
67
68
  )
68
69
 
69
70
 
70
- def _adjust_years(input_date: date, years: int) -> date:
71
- """Add or subtract years from a date."""
72
- try:
73
- # Attempt to directly add/subtract years
74
- return input_date.replace(year=input_date.year + years)
75
- except ValueError as err:
76
- # Handle case for leap year date (February 29) that doesn't exist in the target year
77
- # by moving the date to February 28
78
- if input_date.month == 2 and input_date.day == 29:
79
- return input_date.replace(year=input_date.year + years, month=2, day=28)
80
-
81
- raise StreamlitAPIException(
82
- f"Date {input_date} does not exist in the target year {input_date.year + years}. "
83
- "This should never happen. Please report this bug."
84
- ) from err
85
-
86
-
87
71
  def _parse_date_value(
88
72
  value: DateValue | Literal["today"] | Literal["default_value_today"],
89
73
  ) -> tuple[list[date] | None, bool]:
@@ -128,9 +112,9 @@ def _parse_min_date(
128
112
  parsed_min_date = min_value
129
113
  elif min_value is None:
130
114
  if parsed_dates:
131
- parsed_min_date = _adjust_years(parsed_dates[0], years=-10)
115
+ parsed_min_date = adjust_years(parsed_dates[0], years=-10)
132
116
  else:
133
- parsed_min_date = _adjust_years(date.today(), years=-10)
117
+ parsed_min_date = adjust_years(date.today(), years=-10)
134
118
  else:
135
119
  raise StreamlitAPIException(
136
120
  "DateInput min should either be a date/datetime or None"
@@ -149,9 +133,9 @@ def _parse_max_date(
149
133
  parsed_max_date = max_value
150
134
  elif max_value is None:
151
135
  if parsed_dates:
152
- parsed_max_date = _adjust_years(parsed_dates[-1], years=10)
136
+ parsed_max_date = adjust_years(parsed_dates[-1], years=10)
153
137
  else:
154
- parsed_max_date = _adjust_years(date.today(), years=10)
138
+ parsed_max_date = adjust_years(date.today(), years=10)
155
139
  else:
156
140
  raise StreamlitAPIException(
157
141
  "DateInput max should either be a date/datetime or None"
streamlit/errors.py CHANGED
@@ -28,12 +28,6 @@ class Error(Exception):
28
28
  pass
29
29
 
30
30
 
31
- class CustomComponentError(Error):
32
- """Exceptions thrown in the custom components code path."""
33
-
34
- pass
35
-
36
-
37
31
  class DeprecationError(Error):
38
32
  pass
39
33
 
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: streamlit/proto/AutoRerun.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+
15
+
16
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fstreamlit/proto/AutoRerun.proto\"2\n\tAutoRerun\x12\x10\n\x08interval\x18\x01 \x01(\x02\x12\x13\n\x0b\x66ragment_id\x18\x02 \x01(\tb\x06proto3')
17
+
18
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
19
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'streamlit.proto.AutoRerun_pb2', globals())
20
+ if _descriptor._USE_C_DESCRIPTORS == False:
21
+
22
+ DESCRIPTOR._options = None
23
+ _AUTORERUN._serialized_start=35
24
+ _AUTORERUN._serialized_end=85
25
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,48 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ *!
5
+ Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2024)
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+ """
19
+ import builtins
20
+ import google.protobuf.descriptor
21
+ import google.protobuf.message
22
+ import sys
23
+
24
+ if sys.version_info >= (3, 8):
25
+ import typing as typing_extensions
26
+ else:
27
+ import typing_extensions
28
+
29
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
30
+
31
+ class AutoRerun(google.protobuf.message.Message):
32
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
33
+
34
+ INTERVAL_FIELD_NUMBER: builtins.int
35
+ FRAGMENT_ID_FIELD_NUMBER: builtins.int
36
+ interval: builtins.float
37
+ """The interval of reruns in seconds"""
38
+ fragment_id: builtins.str
39
+ """The fragment ID to rerun"""
40
+ def __init__(
41
+ self,
42
+ *,
43
+ interval: builtins.float = ...,
44
+ fragment_id: builtins.str = ...,
45
+ ) -> None: ...
46
+ def ClearField(self, field_name: typing_extensions.Literal["fragment_id", b"fragment_id", "interval", b"interval"]) -> None: ...
47
+
48
+ global___AutoRerun = AutoRerun
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
14
14
  from streamlit.proto import WidgetStates_pb2 as streamlit_dot_proto_dot_WidgetStates__pb2
15
15
 
16
16
 
17
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!streamlit/proto/ClientState.proto\x1a\"streamlit/proto/WidgetStates.proto\"v\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(\tB0\n\x1c\x63om.snowflake.apps.streamlitB\x10\x43lientStateProtob\x06proto3')
17
+ 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
18
 
19
19
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
20
20
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'streamlit.proto.ClientState_pb2', globals())
@@ -22,6 +22,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
22
22
 
23
23
  DESCRIPTOR._options = None
24
24
  DESCRIPTOR._serialized_options = b'\n\034com.snowflake.apps.streamlitB\020ClientStateProto'
25
- _CLIENTSTATE._serialized_start=73
26
- _CLIENTSTATE._serialized_end=191
25
+ _CLIENTSTATE._serialized_start=74
26
+ _CLIENTSTATE._serialized_end=213
27
27
  # @@protoc_insertion_point(module_scope)
@@ -36,11 +36,13 @@ class ClientState(google.protobuf.message.Message):
36
36
  WIDGET_STATES_FIELD_NUMBER: builtins.int
37
37
  PAGE_SCRIPT_HASH_FIELD_NUMBER: builtins.int
38
38
  PAGE_NAME_FIELD_NUMBER: builtins.int
39
+ FRAGMENT_ID_FIELD_NUMBER: builtins.int
39
40
  query_string: builtins.str
40
41
  @property
41
42
  def widget_states(self) -> streamlit.proto.WidgetStates_pb2.WidgetStates: ...
42
43
  page_script_hash: builtins.str
43
44
  page_name: builtins.str
45
+ fragment_id: builtins.str
44
46
  def __init__(
45
47
  self,
46
48
  *,
@@ -48,8 +50,9 @@ class ClientState(google.protobuf.message.Message):
48
50
  widget_states: streamlit.proto.WidgetStates_pb2.WidgetStates | None = ...,
49
51
  page_script_hash: builtins.str = ...,
50
52
  page_name: builtins.str = ...,
53
+ fragment_id: builtins.str = ...,
51
54
  ) -> None: ...
52
55
  def HasField(self, field_name: typing_extensions.Literal["widget_states", b"widget_states"]) -> builtins.bool: ...
53
- def ClearField(self, field_name: typing_extensions.Literal["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_extensions.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: ...
54
57
 
55
58
  global___ClientState = ClientState
@@ -17,7 +17,7 @@ from streamlit.proto import NamedDataSet_pb2 as streamlit_dot_proto_dot_NamedDat
17
17
  from streamlit.proto import ArrowNamedDataSet_pb2 as streamlit_dot_proto_dot_ArrowNamedDataSet__pb2
18
18
 
19
19
 
20
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bstreamlit/proto/Delta.proto\x1a\x1bstreamlit/proto/Block.proto\x1a\x1dstreamlit/proto/Element.proto\x1a\"streamlit/proto/NamedDataSet.proto\x1a\'streamlit/proto/ArrowNamedDataSet.proto\"\x9e\x01\n\x05\x44\x65lta\x12\x1f\n\x0bnew_element\x18\x03 \x01(\x0b\x32\x08.ElementH\x00\x12\x1b\n\tadd_block\x18\x06 \x01(\x0b\x32\x06.BlockH\x00\x12!\n\x08\x61\x64\x64_rows\x18\x05 \x01(\x0b\x32\r.NamedDataSetH\x00\x12,\n\x0e\x61rrow_add_rows\x18\x07 \x01(\x0b\x32\x12.ArrowNamedDataSetH\x00\x42\x06\n\x04typeB*\n\x1c\x63om.snowflake.apps.streamlitB\nDeltaProtob\x06proto3')
20
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bstreamlit/proto/Delta.proto\x1a\x1bstreamlit/proto/Block.proto\x1a\x1dstreamlit/proto/Element.proto\x1a\"streamlit/proto/NamedDataSet.proto\x1a\'streamlit/proto/ArrowNamedDataSet.proto\"\xb3\x01\n\x05\x44\x65lta\x12\x1f\n\x0bnew_element\x18\x03 \x01(\x0b\x32\x08.ElementH\x00\x12\x1b\n\tadd_block\x18\x06 \x01(\x0b\x32\x06.BlockH\x00\x12!\n\x08\x61\x64\x64_rows\x18\x05 \x01(\x0b\x32\r.NamedDataSetH\x00\x12,\n\x0e\x61rrow_add_rows\x18\x07 \x01(\x0b\x32\x12.ArrowNamedDataSetH\x00\x12\x13\n\x0b\x66ragment_id\x18\x08 \x01(\tB\x06\n\x04typeB*\n\x1c\x63om.snowflake.apps.streamlitB\nDeltaProtob\x06proto3')
21
21
 
22
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
23
23
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'streamlit.proto.Delta_pb2', globals())
@@ -26,5 +26,5 @@ if _descriptor._USE_C_DESCRIPTORS == False:
26
26
  DESCRIPTOR._options = None
27
27
  DESCRIPTOR._serialized_options = b'\n\034com.snowflake.apps.streamlitB\nDeltaProto'
28
28
  _DELTA._serialized_start=169
29
- _DELTA._serialized_end=327
29
+ _DELTA._serialized_end=348
30
30
  # @@protoc_insertion_point(module_scope)
@@ -41,6 +41,7 @@ class Delta(google.protobuf.message.Message):
41
41
  ADD_BLOCK_FIELD_NUMBER: builtins.int
42
42
  ADD_ROWS_FIELD_NUMBER: builtins.int
43
43
  ARROW_ADD_ROWS_FIELD_NUMBER: builtins.int
44
+ FRAGMENT_ID_FIELD_NUMBER: builtins.int
44
45
  @property
45
46
  def new_element(self) -> streamlit.proto.Element_pb2.Element:
46
47
  """Append a new element to the frontend."""
@@ -56,6 +57,7 @@ class Delta(google.protobuf.message.Message):
56
57
  """
57
58
  @property
58
59
  def arrow_add_rows(self) -> streamlit.proto.ArrowNamedDataSet_pb2.ArrowNamedDataSet: ...
60
+ fragment_id: builtins.str
59
61
  def __init__(
60
62
  self,
61
63
  *,
@@ -63,9 +65,10 @@ class Delta(google.protobuf.message.Message):
63
65
  add_block: streamlit.proto.Block_pb2.Block | None = ...,
64
66
  add_rows: streamlit.proto.NamedDataSet_pb2.NamedDataSet | None = ...,
65
67
  arrow_add_rows: streamlit.proto.ArrowNamedDataSet_pb2.ArrowNamedDataSet | None = ...,
68
+ fragment_id: builtins.str = ...,
66
69
  ) -> None: ...
67
70
  def HasField(self, field_name: typing_extensions.Literal["add_block", b"add_block", "add_rows", b"add_rows", "arrow_add_rows", b"arrow_add_rows", "new_element", b"new_element", "type", b"type"]) -> builtins.bool: ...
68
- def ClearField(self, field_name: typing_extensions.Literal["add_block", b"add_block", "add_rows", b"add_rows", "arrow_add_rows", b"arrow_add_rows", "new_element", b"new_element", "type", b"type"]) -> None: ...
71
+ def ClearField(self, field_name: typing_extensions.Literal["add_block", b"add_block", "add_rows", b"add_rows", "arrow_add_rows", b"arrow_add_rows", "fragment_id", b"fragment_id", "new_element", b"new_element", "type", b"type"]) -> None: ...
69
72
  def WhichOneof(self, oneof_group: typing_extensions.Literal["type", b"type"]) -> typing_extensions.Literal["new_element", "add_block", "add_rows", "arrow_add_rows"] | None: ...
70
73
 
71
74
  global___Delta = Delta