streamlit-nightly 1.38.1.dev20240902__py2.py3-none-any.whl → 1.38.1.dev20240904__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 (44) hide show
  1. streamlit/components/v1/custom_component.py +3 -5
  2. streamlit/delta_generator.py +5 -0
  3. streamlit/elements/arrow.py +2 -4
  4. streamlit/elements/layouts.py +19 -1
  5. streamlit/elements/lib/dialog.py +3 -10
  6. streamlit/elements/lib/utils.py +120 -2
  7. streamlit/elements/media.py +3 -3
  8. streamlit/elements/plotly_chart.py +13 -9
  9. streamlit/elements/vega_charts.py +2 -4
  10. streamlit/elements/widgets/button.py +6 -6
  11. streamlit/elements/widgets/button_group.py +2 -3
  12. streamlit/elements/widgets/camera_input.py +2 -3
  13. streamlit/elements/widgets/chat.py +5 -4
  14. streamlit/elements/widgets/checkbox.py +2 -3
  15. streamlit/elements/widgets/color_picker.py +2 -3
  16. streamlit/elements/widgets/data_editor.py +2 -4
  17. streamlit/elements/widgets/file_uploader.py +2 -3
  18. streamlit/elements/widgets/multiselect.py +5 -3
  19. streamlit/elements/widgets/number_input.py +2 -3
  20. streamlit/elements/widgets/radio.py +5 -3
  21. streamlit/elements/widgets/select_slider.py +2 -3
  22. streamlit/elements/widgets/selectbox.py +5 -3
  23. streamlit/elements/widgets/slider.py +2 -3
  24. streamlit/elements/widgets/text_widgets.py +3 -5
  25. streamlit/elements/widgets/time_widgets.py +3 -5
  26. streamlit/errors.py +25 -0
  27. streamlit/navigation/page.py +6 -0
  28. streamlit/proto/Block_pb2.py +28 -28
  29. streamlit/proto/Block_pb2.pyi +8 -2
  30. streamlit/runtime/app_session.py +2 -1
  31. streamlit/runtime/runtime.py +1 -1
  32. streamlit/runtime/state/common.py +3 -51
  33. streamlit/runtime/state/widgets.py +1 -68
  34. streamlit/static/asset-manifest.json +2 -2
  35. streamlit/static/index.html +1 -1
  36. streamlit/static/static/js/main.31d1a42d.js +28 -0
  37. {streamlit_nightly-1.38.1.dev20240902.dist-info → streamlit_nightly-1.38.1.dev20240904.dist-info}/METADATA +1 -1
  38. {streamlit_nightly-1.38.1.dev20240902.dist-info → streamlit_nightly-1.38.1.dev20240904.dist-info}/RECORD +43 -43
  39. {streamlit_nightly-1.38.1.dev20240902.dist-info → streamlit_nightly-1.38.1.dev20240904.dist-info}/WHEEL +1 -1
  40. streamlit/static/static/js/main.3454bbd6.js +0 -28
  41. /streamlit/static/static/js/{main.3454bbd6.js.LICENSE.txt → main.31d1a42d.js.LICENSE.txt} +0 -0
  42. {streamlit_nightly-1.38.1.dev20240902.data → streamlit_nightly-1.38.1.dev20240904.data}/scripts/streamlit.cmd +0 -0
  43. {streamlit_nightly-1.38.1.dev20240902.dist-info → streamlit_nightly-1.38.1.dev20240904.dist-info}/entry_points.txt +0 -0
  44. {streamlit_nightly-1.38.1.dev20240902.dist-info → streamlit_nightly-1.38.1.dev20240904.dist-info}/top_level.txt +0 -0
@@ -27,6 +27,7 @@ from streamlit.elements.lib.policies import (
27
27
  from streamlit.elements.lib.utils import (
28
28
  Key,
29
29
  LabelVisibility,
30
+ compute_and_register_element_id,
30
31
  get_label_visibility_proto_value,
31
32
  to_key,
32
33
  )
@@ -40,7 +41,6 @@ from streamlit.runtime.state import (
40
41
  WidgetKwargs,
41
42
  register_widget,
42
43
  )
43
- from streamlit.runtime.state.common import compute_element_id
44
44
 
45
45
  if TYPE_CHECKING:
46
46
  from streamlit.delta_generator import DeltaGenerator
@@ -186,7 +186,7 @@ class ColorPickerMixin:
186
186
  )
187
187
  maybe_raise_label_warnings(label, label_visibility)
188
188
 
189
- element_id = compute_element_id(
189
+ element_id = compute_and_register_element_id(
190
190
  "color_picker",
191
191
  user_key=key,
192
192
  label=label,
@@ -241,7 +241,6 @@ class ColorPickerMixin:
241
241
  widget_state = register_widget(
242
242
  "color_picker",
243
243
  color_picker_proto,
244
- user_key=key,
245
244
  on_change_handler=on_change,
246
245
  args=args,
247
246
  kwargs=kwargs,
@@ -55,7 +55,7 @@ from streamlit.elements.lib.column_config_utils import (
55
55
  )
56
56
  from streamlit.elements.lib.pandas_styler_utils import marshall_styler
57
57
  from streamlit.elements.lib.policies import check_widget_policies
58
- from streamlit.elements.lib.utils import Key, to_key
58
+ from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
59
59
  from streamlit.errors import StreamlitAPIException
60
60
  from streamlit.proto.Arrow_pb2 import Arrow as ArrowProto
61
61
  from streamlit.runtime.metrics_util import gather_metrics
@@ -66,7 +66,6 @@ from streamlit.runtime.state import (
66
66
  WidgetKwargs,
67
67
  register_widget,
68
68
  )
69
- from streamlit.runtime.state.common import compute_element_id
70
69
  from streamlit.type_util import is_type
71
70
  from streamlit.util import calc_md5
72
71
 
@@ -885,7 +884,7 @@ class DataEditorMixin:
885
884
  # format that will hash consistently, so we do it late here to have it
886
885
  # as close as possible to how it used to be.
887
886
  ctx = get_script_run_ctx()
888
- element_id = compute_element_id(
887
+ element_id = compute_and_register_element_id(
889
888
  "data_editor",
890
889
  user_key=key,
891
890
  data=arrow_bytes,
@@ -948,7 +947,6 @@ class DataEditorMixin:
948
947
  widget_state = register_widget(
949
948
  "data_editor",
950
949
  proto,
951
- user_key=key,
952
950
  on_change_handler=on_change,
953
951
  args=args,
954
952
  kwargs=kwargs,
@@ -29,6 +29,7 @@ from streamlit.elements.lib.policies import (
29
29
  from streamlit.elements.lib.utils import (
30
30
  Key,
31
31
  LabelVisibility,
32
+ compute_and_register_element_id,
32
33
  get_label_visibility_proto_value,
33
34
  to_key,
34
35
  )
@@ -43,7 +44,6 @@ from streamlit.runtime.state import (
43
44
  WidgetKwargs,
44
45
  register_widget,
45
46
  )
46
- from streamlit.runtime.state.common import compute_element_id
47
47
  from streamlit.runtime.uploaded_file_manager import DeletedFile, UploadedFile
48
48
 
49
49
  if TYPE_CHECKING:
@@ -405,7 +405,7 @@ class FileUploaderMixin:
405
405
  )
406
406
  maybe_raise_label_warnings(label, label_visibility)
407
407
 
408
- element_id = compute_element_id(
408
+ element_id = compute_and_register_element_id(
409
409
  "file_uploader",
410
410
  user_key=key,
411
411
  label=label,
@@ -461,7 +461,6 @@ class FileUploaderMixin:
461
461
  widget_state = register_widget(
462
462
  "file_uploader",
463
463
  file_uploader_proto,
464
- user_key=key,
465
464
  on_change_handler=on_change,
466
465
  args=args,
467
466
  kwargs=kwargs,
@@ -32,6 +32,7 @@ from streamlit.elements.lib.policies import (
32
32
  from streamlit.elements.lib.utils import (
33
33
  Key,
34
34
  LabelVisibility,
35
+ compute_and_register_element_id,
35
36
  get_label_visibility_proto_value,
36
37
  maybe_coerce_enum_sequence,
37
38
  to_key,
@@ -41,7 +42,9 @@ from streamlit.proto.MultiSelect_pb2 import MultiSelect as MultiSelectProto
41
42
  from streamlit.runtime.metrics_util import gather_metrics
42
43
  from streamlit.runtime.scriptrunner import ScriptRunContext, get_script_run_ctx
43
44
  from streamlit.runtime.state import register_widget
44
- from streamlit.runtime.state.common import compute_element_id, save_for_app_testing
45
+ from streamlit.runtime.state.common import (
46
+ save_for_app_testing,
47
+ )
45
48
  from streamlit.type_util import (
46
49
  T,
47
50
  is_iterable,
@@ -280,7 +283,7 @@ class MultiSelectMixin:
280
283
  default_values = get_default_indices(indexable_options, default)
281
284
 
282
285
  form_id = current_form_id(self.dg)
283
- element_id = compute_element_id(
286
+ element_id = compute_and_register_element_id(
284
287
  widget_name,
285
288
  user_key=key,
286
289
  label=label,
@@ -313,7 +316,6 @@ class MultiSelectMixin:
313
316
  widget_state = register_widget(
314
317
  "multiselect",
315
318
  proto,
316
- user_key=key,
317
319
  on_change_handler=on_change,
318
320
  args=args,
319
321
  kwargs=kwargs,
@@ -29,6 +29,7 @@ from streamlit.elements.lib.policies import (
29
29
  from streamlit.elements.lib.utils import (
30
30
  Key,
31
31
  LabelVisibility,
32
+ compute_and_register_element_id,
32
33
  get_label_visibility_proto_value,
33
34
  to_key,
34
35
  )
@@ -44,7 +45,6 @@ from streamlit.runtime.state import (
44
45
  get_session_state,
45
46
  register_widget,
46
47
  )
47
- from streamlit.runtime.state.common import compute_element_id
48
48
 
49
49
  if TYPE_CHECKING:
50
50
  from streamlit.delta_generator import DeltaGenerator
@@ -350,7 +350,7 @@ class NumberInputMixin:
350
350
  )
351
351
  maybe_raise_label_warnings(label, label_visibility)
352
352
 
353
- element_id = compute_element_id(
353
+ element_id = compute_and_register_element_id(
354
354
  "number_input",
355
355
  user_key=key,
356
356
  label=label,
@@ -515,7 +515,6 @@ class NumberInputMixin:
515
515
  widget_state = register_widget(
516
516
  "number_input",
517
517
  number_input_proto,
518
- user_key=key,
519
518
  on_change_handler=on_change,
520
519
  args=args,
521
520
  kwargs=kwargs,
@@ -27,6 +27,7 @@ from streamlit.elements.lib.policies import (
27
27
  from streamlit.elements.lib.utils import (
28
28
  Key,
29
29
  LabelVisibility,
30
+ compute_and_register_element_id,
30
31
  get_label_visibility_proto_value,
31
32
  maybe_coerce_enum,
32
33
  to_key,
@@ -42,7 +43,9 @@ from streamlit.runtime.state import (
42
43
  get_session_state,
43
44
  register_widget,
44
45
  )
45
- from streamlit.runtime.state.common import compute_element_id, save_for_app_testing
46
+ from streamlit.runtime.state.common import (
47
+ save_for_app_testing,
48
+ )
46
49
  from streamlit.type_util import (
47
50
  T,
48
51
  check_python_comparable,
@@ -312,7 +315,7 @@ class RadioMixin:
312
315
  opt = convert_anything_to_list(options)
313
316
  check_python_comparable(opt)
314
317
 
315
- element_id = compute_element_id(
318
+ element_id = compute_and_register_element_id(
316
319
  "radio",
317
320
  user_key=key,
318
321
  label=label,
@@ -374,7 +377,6 @@ class RadioMixin:
374
377
  widget_state = register_widget(
375
378
  "radio",
376
379
  radio_proto,
377
- user_key=key,
378
380
  on_change_handler=on_change,
379
381
  args=args,
380
382
  kwargs=kwargs,
@@ -38,6 +38,7 @@ from streamlit.elements.lib.policies import (
38
38
  from streamlit.elements.lib.utils import (
39
39
  Key,
40
40
  LabelVisibility,
41
+ compute_and_register_element_id,
41
42
  get_label_visibility_proto_value,
42
43
  maybe_coerce_enum,
43
44
  maybe_coerce_enum_sequence,
@@ -55,7 +56,6 @@ from streamlit.runtime.state import (
55
56
  )
56
57
  from streamlit.runtime.state.common import (
57
58
  RegisterWidgetResult,
58
- compute_element_id,
59
59
  save_for_app_testing,
60
60
  )
61
61
  from streamlit.type_util import T, check_python_comparable
@@ -365,7 +365,7 @@ class SelectSliderMixin:
365
365
  # Convert element to index of the elements
366
366
  slider_value = as_index_list(value)
367
367
 
368
- element_id = compute_element_id(
368
+ element_id = compute_and_register_element_id(
369
369
  "select_slider",
370
370
  user_key=key,
371
371
  label=label,
@@ -401,7 +401,6 @@ class SelectSliderMixin:
401
401
  widget_state = register_widget(
402
402
  "slider",
403
403
  slider_proto,
404
- user_key=key,
405
404
  on_change_handler=on_change,
406
405
  args=args,
407
406
  kwargs=kwargs,
@@ -26,6 +26,7 @@ from streamlit.elements.lib.policies import (
26
26
  from streamlit.elements.lib.utils import (
27
27
  Key,
28
28
  LabelVisibility,
29
+ compute_and_register_element_id,
29
30
  get_label_visibility_proto_value,
30
31
  maybe_coerce_enum,
31
32
  to_key,
@@ -41,7 +42,9 @@ from streamlit.runtime.state import (
41
42
  get_session_state,
42
43
  register_widget,
43
44
  )
44
- from streamlit.runtime.state.common import compute_element_id, save_for_app_testing
45
+ from streamlit.runtime.state.common import (
46
+ save_for_app_testing,
47
+ )
45
48
  from streamlit.type_util import (
46
49
  T,
47
50
  check_python_comparable,
@@ -284,7 +287,7 @@ class SelectboxMixin:
284
287
  opt = convert_anything_to_list(options)
285
288
  check_python_comparable(opt)
286
289
 
287
- element_id = compute_element_id(
290
+ element_id = compute_and_register_element_id(
288
291
  "selectbox",
289
292
  user_key=key,
290
293
  label=label,
@@ -332,7 +335,6 @@ class SelectboxMixin:
332
335
  widget_state = register_widget(
333
336
  "selectbox",
334
337
  selectbox_proto,
335
- user_key=key,
336
338
  on_change_handler=on_change,
337
339
  args=args,
338
340
  kwargs=kwargs,
@@ -41,6 +41,7 @@ from streamlit.elements.lib.policies import (
41
41
  from streamlit.elements.lib.utils import (
42
42
  Key,
43
43
  LabelVisibility,
44
+ compute_and_register_element_id,
44
45
  get_label_visibility_proto_value,
45
46
  to_key,
46
47
  )
@@ -56,7 +57,6 @@ from streamlit.runtime.state import (
56
57
  get_session_state,
57
58
  register_widget,
58
59
  )
59
- from streamlit.runtime.state.common import compute_element_id
60
60
 
61
61
  if TYPE_CHECKING:
62
62
  from streamlit.delta_generator import DeltaGenerator
@@ -542,7 +542,7 @@ class SliderMixin:
542
542
  )
543
543
  maybe_raise_label_warnings(label, label_visibility)
544
544
 
545
- element_id = compute_element_id(
545
+ element_id = compute_and_register_element_id(
546
546
  "slider",
547
547
  user_key=key,
548
548
  label=label,
@@ -826,7 +826,6 @@ class SliderMixin:
826
826
  widget_state = register_widget(
827
827
  "slider",
828
828
  slider_proto,
829
- user_key=key,
830
829
  on_change_handler=on_change,
831
830
  args=args,
832
831
  kwargs=kwargs,
@@ -26,6 +26,7 @@ from streamlit.elements.lib.policies import (
26
26
  from streamlit.elements.lib.utils import (
27
27
  Key,
28
28
  LabelVisibility,
29
+ compute_and_register_element_id,
29
30
  get_label_visibility_proto_value,
30
31
  to_key,
31
32
  )
@@ -41,7 +42,6 @@ from streamlit.runtime.state import (
41
42
  get_session_state,
42
43
  register_widget,
43
44
  )
44
- from streamlit.runtime.state.common import compute_element_id
45
45
  from streamlit.type_util import (
46
46
  SupportsStr,
47
47
  )
@@ -275,7 +275,7 @@ class TextWidgetsMixin:
275
275
  # Make sure value is always string or None:
276
276
  value = str(value) if value is not None else None
277
277
 
278
- element_id = compute_element_id(
278
+ element_id = compute_and_register_element_id(
279
279
  "text_input",
280
280
  user_key=key,
281
281
  label=label,
@@ -335,7 +335,6 @@ class TextWidgetsMixin:
335
335
  widget_state = register_widget(
336
336
  "text_input",
337
337
  text_input_proto,
338
- user_key=key,
339
338
  on_change_handler=on_change,
340
339
  args=args,
341
340
  kwargs=kwargs,
@@ -548,7 +547,7 @@ class TextWidgetsMixin:
548
547
 
549
548
  value = str(value) if value is not None else None
550
549
 
551
- element_id = compute_element_id(
550
+ element_id = compute_and_register_element_id(
552
551
  "text_area",
553
552
  user_key=key,
554
553
  label=label,
@@ -593,7 +592,6 @@ class TextWidgetsMixin:
593
592
  widget_state = register_widget(
594
593
  "text_area",
595
594
  text_area_proto,
596
- user_key=key,
597
595
  on_change_handler=on_change,
598
596
  args=args,
599
597
  kwargs=kwargs,
@@ -40,6 +40,7 @@ from streamlit.elements.lib.policies import (
40
40
  from streamlit.elements.lib.utils import (
41
41
  Key,
42
42
  LabelVisibility,
43
+ compute_and_register_element_id,
43
44
  get_label_visibility_proto_value,
44
45
  to_key,
45
46
  )
@@ -55,7 +56,6 @@ from streamlit.runtime.state import (
55
56
  get_session_state,
56
57
  register_widget,
57
58
  )
58
- from streamlit.runtime.state.common import compute_element_id
59
59
  from streamlit.time_util import adjust_years
60
60
 
61
61
  if TYPE_CHECKING:
@@ -454,7 +454,7 @@ class TimeWidgetsMixin:
454
454
  "The type of value should be one of datetime, time or None"
455
455
  )
456
456
 
457
- element_id = compute_element_id(
457
+ element_id = compute_and_register_element_id(
458
458
  "time_input",
459
459
  user_key=key,
460
460
  label=label,
@@ -500,7 +500,6 @@ class TimeWidgetsMixin:
500
500
  widget_state = register_widget(
501
501
  "time_input",
502
502
  time_input_proto,
503
- user_key=key,
504
503
  on_change_handler=on_change,
505
504
  args=args,
506
505
  kwargs=kwargs,
@@ -730,7 +729,7 @@ class TimeWidgetsMixin:
730
729
 
731
730
  # TODO this is missing the error path, integrate with the dateinputvalues parsing
732
731
 
733
- element_id = compute_element_id(
732
+ element_id = compute_and_register_element_id(
734
733
  "date_input",
735
734
  user_key=key,
736
735
  label=label,
@@ -804,7 +803,6 @@ class TimeWidgetsMixin:
804
803
  widget_state = register_widget(
805
804
  "date_input",
806
805
  date_input_proto,
807
- user_key=key,
808
806
  on_change_handler=on_change,
809
807
  args=args,
810
808
  kwargs=kwargs,
streamlit/errors.py CHANGED
@@ -100,6 +100,31 @@ class DuplicateWidgetID(StreamlitAPIException):
100
100
  pass
101
101
 
102
102
 
103
+ class StreamlitDuplicateElementId(DuplicateWidgetID):
104
+ """An exception raised when the auto-generated ID of an element is not unique."""
105
+
106
+ def __init__(self, element_type: str):
107
+ super().__init__(
108
+ f"There are multiple `{element_type}` elements with the same "
109
+ "auto-generated ID. When this element is created, it is assigned an "
110
+ "internal ID based on the element type and provided parameters. Multiple "
111
+ "elements with the same type and parameters will cause this error.\n\n"
112
+ "To fix this error, please pass a unique `key` argument to the "
113
+ f"`{element_type}` element."
114
+ )
115
+
116
+
117
+ class StreamlitDuplicateElementKey(DuplicateWidgetID):
118
+ """An exception raised when the key of an element is not unique."""
119
+
120
+ def __init__(self, user_key: str):
121
+ super().__init__(
122
+ f"There are multiple elements with the same `key='{user_key}'`. "
123
+ "To fix this, please make sure that the `key` argument is unique for "
124
+ "each element you create."
125
+ )
126
+
127
+
103
128
  class UnserializableSessionStateError(StreamlitAPIException):
104
129
  pass
105
130
 
@@ -206,6 +206,12 @@ class StreamlitPage:
206
206
  self._page: Path | Callable[[], None] = page
207
207
  self._title: str = title or inferred_name.replace("_", " ")
208
208
  self._icon: str = icon or inferred_icon
209
+
210
+ if self._title.strip() == "":
211
+ raise StreamlitAPIException(
212
+ "The title of the page cannot be empty or consist of underscores/spaces only"
213
+ )
214
+
209
215
  if url_path is not None and url_path.strip() == "" and not default:
210
216
  raise StreamlitAPIException(
211
217
  "The URL path cannot be an empty string unless the page is the default page."
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
14
14
 
15
15
 
16
16
 
17
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bstreamlit/proto/Block.proto\"\xc0\t\n\x05\x42lock\x12#\n\x08vertical\x18\x01 \x01(\x0b\x32\x0f.Block.VerticalH\x00\x12\'\n\nhorizontal\x18\x02 \x01(\x0b\x32\x11.Block.HorizontalH\x00\x12\x1f\n\x06\x63olumn\x18\x03 \x01(\x0b\x32\r.Block.ColumnH\x00\x12\'\n\nexpandable\x18\x04 \x01(\x0b\x32\x11.Block.ExpandableH\x00\x12\x1b\n\x04\x66orm\x18\x05 \x01(\x0b\x32\x0b.Block.FormH\x00\x12,\n\rtab_container\x18\x06 \x01(\x0b\x32\x13.Block.TabContainerH\x00\x12\x19\n\x03tab\x18\x07 \x01(\x0b\x32\n.Block.TabH\x00\x12*\n\x0c\x63hat_message\x18\t \x01(\x0b\x32\x12.Block.ChatMessageH\x00\x12!\n\x07popover\x18\n \x01(\x0b\x32\x0e.Block.PopoverH\x00\x12\x1f\n\x06\x64ialog\x18\x0b \x01(\x0b\x32\r.Block.DialogH\x00\x12\x13\n\x0b\x61llow_empty\x18\x08 \x01(\x08\x1a*\n\x08Vertical\x12\x0e\n\x06\x62order\x18\x01 \x01(\x08\x12\x0e\n\x06height\x18\x02 \x01(\r\x1a\x19\n\nHorizontal\x12\x0b\n\x03gap\x18\x01 \x01(\t\x1a\x98\x01\n\x06\x43olumn\x12\x0e\n\x06weight\x18\x01 \x01(\x01\x12\x0b\n\x03gap\x18\x02 \x01(\t\x12;\n\x12vertical_alignment\x18\x03 \x01(\x0e\x32\x1f.Block.Column.VerticalAlignment\"4\n\x11VerticalAlignment\x12\x07\n\x03TOP\x10\x00\x12\n\n\x06\x43\x45NTER\x10\x01\x12\n\n\x06\x42OTTOM\x10\x02\x1aM\n\nExpandable\x12\r\n\x05label\x18\x01 \x01(\t\x12\x15\n\x08\x65xpanded\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x0c\n\x04icon\x18\x03 \x01(\tB\x0b\n\t_expanded\x1a\x9d\x01\n\x06\x44ialog\x12\r\n\x05title\x18\x01 \x01(\t\x12\x13\n\x0b\x64ismissible\x18\x02 \x01(\x08\x12(\n\x05width\x18\x03 \x01(\x0e\x32\x19.Block.Dialog.DialogWidth\x12\x14\n\x07is_open\x18\x04 \x01(\x08H\x00\x88\x01\x01\"#\n\x0b\x44ialogWidth\x12\t\n\x05SMALL\x10\x00\x12\t\n\x05LARGE\x10\x01\x42\n\n\x08_is_open\x1a@\n\x04\x46orm\x12\x0f\n\x07\x66orm_id\x18\x01 \x01(\t\x12\x17\n\x0f\x63lear_on_submit\x18\x02 \x01(\x08\x12\x0e\n\x06\x62order\x18\x03 \x01(\x08\x1a\x0e\n\x0cTabContainer\x1a\x14\n\x03Tab\x12\r\n\x05label\x18\x01 \x01(\t\x1a\x63\n\x07Popover\x12\r\n\x05label\x18\x01 \x01(\t\x12\x1b\n\x13use_container_width\x18\x02 \x01(\x08\x12\x0c\n\x04help\x18\x03 \x01(\t\x12\x10\n\x08\x64isabled\x18\x04 \x01(\x08\x12\x0c\n\x04icon\x18\x05 \x01(\t\x1a\x8d\x01\n\x0b\x43hatMessage\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x61vatar\x18\x02 \x01(\t\x12\x32\n\x0b\x61vatar_type\x18\x03 \x01(\x0e\x32\x1d.Block.ChatMessage.AvatarType\",\n\nAvatarType\x12\t\n\x05IMAGE\x10\x00\x12\t\n\x05\x45MOJI\x10\x01\x12\x08\n\x04ICON\x10\x02\x42\x06\n\x04typeB*\n\x1c\x63om.snowflake.apps.streamlitB\nBlockProtob\x06proto3')
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bstreamlit/proto/Block.proto\"\xd8\t\n\x05\x42lock\x12#\n\x08vertical\x18\x01 \x01(\x0b\x32\x0f.Block.VerticalH\x00\x12\'\n\nhorizontal\x18\x02 \x01(\x0b\x32\x11.Block.HorizontalH\x00\x12\x1f\n\x06\x63olumn\x18\x03 \x01(\x0b\x32\r.Block.ColumnH\x00\x12\'\n\nexpandable\x18\x04 \x01(\x0b\x32\x11.Block.ExpandableH\x00\x12\x1b\n\x04\x66orm\x18\x05 \x01(\x0b\x32\x0b.Block.FormH\x00\x12,\n\rtab_container\x18\x06 \x01(\x0b\x32\x13.Block.TabContainerH\x00\x12\x19\n\x03tab\x18\x07 \x01(\x0b\x32\n.Block.TabH\x00\x12*\n\x0c\x63hat_message\x18\t \x01(\x0b\x32\x12.Block.ChatMessageH\x00\x12!\n\x07popover\x18\n \x01(\x0b\x32\x0e.Block.PopoverH\x00\x12\x1f\n\x06\x64ialog\x18\x0b \x01(\x0b\x32\r.Block.DialogH\x00\x12\x13\n\x0b\x61llow_empty\x18\x08 \x01(\x08\x12\x0f\n\x02id\x18\x0c \x01(\tH\x01\x88\x01\x01\x1a*\n\x08Vertical\x12\x0e\n\x06\x62order\x18\x01 \x01(\x08\x12\x0e\n\x06height\x18\x02 \x01(\r\x1a\x19\n\nHorizontal\x12\x0b\n\x03gap\x18\x01 \x01(\t\x1a\x98\x01\n\x06\x43olumn\x12\x0e\n\x06weight\x18\x01 \x01(\x01\x12\x0b\n\x03gap\x18\x02 \x01(\t\x12;\n\x12vertical_alignment\x18\x03 \x01(\x0e\x32\x1f.Block.Column.VerticalAlignment\"4\n\x11VerticalAlignment\x12\x07\n\x03TOP\x10\x00\x12\n\n\x06\x43\x45NTER\x10\x01\x12\n\n\x06\x42OTTOM\x10\x02\x1aM\n\nExpandable\x12\r\n\x05label\x18\x01 \x01(\t\x12\x15\n\x08\x65xpanded\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x0c\n\x04icon\x18\x03 \x01(\tB\x0b\n\t_expanded\x1a\x9d\x01\n\x06\x44ialog\x12\r\n\x05title\x18\x01 \x01(\t\x12\x13\n\x0b\x64ismissible\x18\x02 \x01(\x08\x12(\n\x05width\x18\x03 \x01(\x0e\x32\x19.Block.Dialog.DialogWidth\x12\x14\n\x07is_open\x18\x04 \x01(\x08H\x00\x88\x01\x01\"#\n\x0b\x44ialogWidth\x12\t\n\x05SMALL\x10\x00\x12\t\n\x05LARGE\x10\x01\x42\n\n\x08_is_open\x1a@\n\x04\x46orm\x12\x0f\n\x07\x66orm_id\x18\x01 \x01(\t\x12\x17\n\x0f\x63lear_on_submit\x18\x02 \x01(\x08\x12\x0e\n\x06\x62order\x18\x03 \x01(\x08\x1a\x0e\n\x0cTabContainer\x1a\x14\n\x03Tab\x12\r\n\x05label\x18\x01 \x01(\t\x1a\x63\n\x07Popover\x12\r\n\x05label\x18\x01 \x01(\t\x12\x1b\n\x13use_container_width\x18\x02 \x01(\x08\x12\x0c\n\x04help\x18\x03 \x01(\t\x12\x10\n\x08\x64isabled\x18\x04 \x01(\x08\x12\x0c\n\x04icon\x18\x05 \x01(\t\x1a\x8d\x01\n\x0b\x43hatMessage\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x61vatar\x18\x02 \x01(\t\x12\x32\n\x0b\x61vatar_type\x18\x03 \x01(\x0e\x32\x1d.Block.ChatMessage.AvatarType\",\n\nAvatarType\x12\t\n\x05IMAGE\x10\x00\x12\t\n\x05\x45MOJI\x10\x01\x12\x08\n\x04ICON\x10\x02\x42\x06\n\x04typeB\x05\n\x03_idB*\n\x1c\x63om.snowflake.apps.streamlitB\nBlockProtob\x06proto3')
18
18
 
19
19
  _globals = globals()
20
20
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -23,31 +23,31 @@ if not _descriptor._USE_C_DESCRIPTORS:
23
23
  _globals['DESCRIPTOR']._loaded_options = None
24
24
  _globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\nBlockProto'
25
25
  _globals['_BLOCK']._serialized_start=32
26
- _globals['_BLOCK']._serialized_end=1248
27
- _globals['_BLOCK_VERTICAL']._serialized_start=428
28
- _globals['_BLOCK_VERTICAL']._serialized_end=470
29
- _globals['_BLOCK_HORIZONTAL']._serialized_start=472
30
- _globals['_BLOCK_HORIZONTAL']._serialized_end=497
31
- _globals['_BLOCK_COLUMN']._serialized_start=500
32
- _globals['_BLOCK_COLUMN']._serialized_end=652
33
- _globals['_BLOCK_COLUMN_VERTICALALIGNMENT']._serialized_start=600
34
- _globals['_BLOCK_COLUMN_VERTICALALIGNMENT']._serialized_end=652
35
- _globals['_BLOCK_EXPANDABLE']._serialized_start=654
36
- _globals['_BLOCK_EXPANDABLE']._serialized_end=731
37
- _globals['_BLOCK_DIALOG']._serialized_start=734
38
- _globals['_BLOCK_DIALOG']._serialized_end=891
39
- _globals['_BLOCK_DIALOG_DIALOGWIDTH']._serialized_start=844
40
- _globals['_BLOCK_DIALOG_DIALOGWIDTH']._serialized_end=879
41
- _globals['_BLOCK_FORM']._serialized_start=893
42
- _globals['_BLOCK_FORM']._serialized_end=957
43
- _globals['_BLOCK_TABCONTAINER']._serialized_start=959
44
- _globals['_BLOCK_TABCONTAINER']._serialized_end=973
45
- _globals['_BLOCK_TAB']._serialized_start=975
46
- _globals['_BLOCK_TAB']._serialized_end=995
47
- _globals['_BLOCK_POPOVER']._serialized_start=997
48
- _globals['_BLOCK_POPOVER']._serialized_end=1096
49
- _globals['_BLOCK_CHATMESSAGE']._serialized_start=1099
50
- _globals['_BLOCK_CHATMESSAGE']._serialized_end=1240
51
- _globals['_BLOCK_CHATMESSAGE_AVATARTYPE']._serialized_start=1196
52
- _globals['_BLOCK_CHATMESSAGE_AVATARTYPE']._serialized_end=1240
26
+ _globals['_BLOCK']._serialized_end=1272
27
+ _globals['_BLOCK_VERTICAL']._serialized_start=445
28
+ _globals['_BLOCK_VERTICAL']._serialized_end=487
29
+ _globals['_BLOCK_HORIZONTAL']._serialized_start=489
30
+ _globals['_BLOCK_HORIZONTAL']._serialized_end=514
31
+ _globals['_BLOCK_COLUMN']._serialized_start=517
32
+ _globals['_BLOCK_COLUMN']._serialized_end=669
33
+ _globals['_BLOCK_COLUMN_VERTICALALIGNMENT']._serialized_start=617
34
+ _globals['_BLOCK_COLUMN_VERTICALALIGNMENT']._serialized_end=669
35
+ _globals['_BLOCK_EXPANDABLE']._serialized_start=671
36
+ _globals['_BLOCK_EXPANDABLE']._serialized_end=748
37
+ _globals['_BLOCK_DIALOG']._serialized_start=751
38
+ _globals['_BLOCK_DIALOG']._serialized_end=908
39
+ _globals['_BLOCK_DIALOG_DIALOGWIDTH']._serialized_start=861
40
+ _globals['_BLOCK_DIALOG_DIALOGWIDTH']._serialized_end=896
41
+ _globals['_BLOCK_FORM']._serialized_start=910
42
+ _globals['_BLOCK_FORM']._serialized_end=974
43
+ _globals['_BLOCK_TABCONTAINER']._serialized_start=976
44
+ _globals['_BLOCK_TABCONTAINER']._serialized_end=990
45
+ _globals['_BLOCK_TAB']._serialized_start=992
46
+ _globals['_BLOCK_TAB']._serialized_end=1012
47
+ _globals['_BLOCK_POPOVER']._serialized_start=1014
48
+ _globals['_BLOCK_POPOVER']._serialized_end=1113
49
+ _globals['_BLOCK_CHATMESSAGE']._serialized_start=1116
50
+ _globals['_BLOCK_CHATMESSAGE']._serialized_end=1257
51
+ _globals['_BLOCK_CHATMESSAGE_AVATARTYPE']._serialized_start=1213
52
+ _globals['_BLOCK_CHATMESSAGE_AVATARTYPE']._serialized_end=1257
53
53
  # @@protoc_insertion_point(module_scope)
@@ -267,7 +267,9 @@ class Block(google.protobuf.message.Message):
267
267
  POPOVER_FIELD_NUMBER: builtins.int
268
268
  DIALOG_FIELD_NUMBER: builtins.int
269
269
  ALLOW_EMPTY_FIELD_NUMBER: builtins.int
270
+ ID_FIELD_NUMBER: builtins.int
270
271
  allow_empty: builtins.bool
272
+ id: builtins.str
271
273
  @property
272
274
  def vertical(self) -> global___Block.Vertical: ...
273
275
  @property
@@ -302,9 +304,13 @@ class Block(google.protobuf.message.Message):
302
304
  popover: global___Block.Popover | None = ...,
303
305
  dialog: global___Block.Dialog | None = ...,
304
306
  allow_empty: builtins.bool = ...,
307
+ id: builtins.str | None = ...,
305
308
  ) -> None: ...
306
- def HasField(self, field_name: typing.Literal["chat_message", b"chat_message", "column", b"column", "dialog", b"dialog", "expandable", b"expandable", "form", b"form", "horizontal", b"horizontal", "popover", b"popover", "tab", b"tab", "tab_container", b"tab_container", "type", b"type", "vertical", b"vertical"]) -> builtins.bool: ...
307
- def ClearField(self, field_name: typing.Literal["allow_empty", b"allow_empty", "chat_message", b"chat_message", "column", b"column", "dialog", b"dialog", "expandable", b"expandable", "form", b"form", "horizontal", b"horizontal", "popover", b"popover", "tab", b"tab", "tab_container", b"tab_container", "type", b"type", "vertical", b"vertical"]) -> None: ...
309
+ def HasField(self, field_name: typing.Literal["_id", b"_id", "chat_message", b"chat_message", "column", b"column", "dialog", b"dialog", "expandable", b"expandable", "form", b"form", "horizontal", b"horizontal", "id", b"id", "popover", b"popover", "tab", b"tab", "tab_container", b"tab_container", "type", b"type", "vertical", b"vertical"]) -> builtins.bool: ...
310
+ def ClearField(self, field_name: typing.Literal["_id", b"_id", "allow_empty", b"allow_empty", "chat_message", b"chat_message", "column", b"column", "dialog", b"dialog", "expandable", b"expandable", "form", b"form", "horizontal", b"horizontal", "id", b"id", "popover", b"popover", "tab", b"tab", "tab_container", b"tab_container", "type", b"type", "vertical", b"vertical"]) -> None: ...
311
+ @typing.overload
312
+ def WhichOneof(self, oneof_group: typing.Literal["_id", b"_id"]) -> typing.Literal["id"] | None: ...
313
+ @typing.overload
308
314
  def WhichOneof(self, oneof_group: typing.Literal["type", b"type"]) -> typing.Literal["vertical", "horizontal", "column", "expandable", "form", "tab_container", "tab", "chat_message", "popover", "dialog"] | None: ...
309
315
 
310
316
  global___Block = Block
@@ -854,7 +854,8 @@ class AppSession:
854
854
  page_proto = msg.app_pages.add()
855
855
 
856
856
  page_proto.page_script_hash = page_script_hash
857
- page_proto.page_name = page_info["page_name"]
857
+ page_proto.page_name = page_info["page_name"].replace("_", " ")
858
+ page_proto.url_pathname = page_info["page_name"]
858
859
  page_proto.icon = page_info["icon"]
859
860
 
860
861
 
@@ -560,7 +560,7 @@ class Runtime:
560
560
  uploaded_file_manager=self._uploaded_file_mgr,
561
561
  script_cache=self._script_cache,
562
562
  message_enqueued_callback=self._enqueued_some_message,
563
- user_info={"email": "test@test.com"},
563
+ user_info={"email": "test@example.com"},
564
564
  )
565
565
 
566
566
  try:
@@ -16,9 +16,7 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- import hashlib
20
19
  from dataclasses import dataclass, field
21
- from datetime import date, datetime, time, timedelta
22
20
  from typing import (
23
21
  TYPE_CHECKING,
24
22
  Any,
@@ -26,7 +24,6 @@ from typing import (
26
24
  Dict,
27
25
  Final,
28
26
  Generic,
29
- Iterable,
30
27
  Literal,
31
28
  Tuple,
32
29
  TypeVar,
@@ -35,11 +32,12 @@ from typing import (
35
32
  get_args,
36
33
  )
37
34
 
38
- from google.protobuf.message import Message
39
35
  from typing_extensions import TypeAlias, TypeGuard
40
36
 
41
37
  from streamlit import config, util
42
- from streamlit.errors import StreamlitAPIException
38
+ from streamlit.errors import (
39
+ StreamlitAPIException,
40
+ )
43
41
  from streamlit.proto.Arrow_pb2 import Arrow
44
42
  from streamlit.proto.ArrowVegaLiteChart_pb2 import ArrowVegaLiteChart
45
43
  from streamlit.proto.Button_pb2 import Button
@@ -61,13 +59,9 @@ from streamlit.proto.Slider_pb2 import Slider
61
59
  from streamlit.proto.TextArea_pb2 import TextArea
62
60
  from streamlit.proto.TextInput_pb2 import TextInput
63
61
  from streamlit.proto.TimeInput_pb2 import TimeInput
64
- from streamlit.util import HASHLIB_KWARGS
65
62
 
66
63
  if TYPE_CHECKING:
67
- from builtins import ellipsis
68
-
69
64
  from streamlit.runtime.scriptrunner_utils.script_run_context import ScriptRunContext
70
- from streamlit.runtime.state.widgets import NoValue
71
65
 
72
66
 
73
67
  # Protobuf types for all widgets.
@@ -218,48 +212,6 @@ class RegisterWidgetResult(Generic[T_co]):
218
212
  return cls(value=deserializer(None, ""), value_changed=False)
219
213
 
220
214
 
221
- PROTO_SCALAR_VALUE = Union[float, int, bool, str, bytes]
222
- SAFE_VALUES = Union[
223
- date,
224
- time,
225
- datetime,
226
- timedelta,
227
- None,
228
- "NoValue",
229
- "ellipsis",
230
- Message,
231
- PROTO_SCALAR_VALUE,
232
- ]
233
-
234
-
235
- def compute_element_id(
236
- element_type: str,
237
- user_key: str | None = None,
238
- **kwargs: SAFE_VALUES | Iterable[SAFE_VALUES],
239
- ) -> str:
240
- """Compute the id for the given element. This id is stable: a given
241
- set of inputs to this function will always produce the same id output.
242
-
243
- Only stable, deterministic values should be used to compute element ids. Using
244
- nondeterministic values as inputs can cause the resulting element id to
245
- change between runs.
246
-
247
- The element id includes the user_key so elements with identical arguments can
248
- use it to be distinct.
249
-
250
- The element id includes an easily identified prefix, and the user_key as a
251
- suffix, to make it easy to identify it and know if a key maps to it.
252
- """
253
- h = hashlib.new("md5", **HASHLIB_KWARGS)
254
- h.update(element_type.encode("utf-8"))
255
- # This will iterate in a consistent order when the provided arguments have
256
- # consistent order; dicts are always in insertion order.
257
- for k, v in kwargs.items():
258
- h.update(str(k).encode("utf-8"))
259
- h.update(str(v).encode("utf-8"))
260
- return f"{GENERATED_ELEMENT_ID_PREFIX}-{h.hexdigest()}-{user_key}"
261
-
262
-
263
215
  def user_key_from_element_id(element_id: str) -> str | None:
264
216
  """Return the user key portion of a element id, or None if the id does not
265
217
  have a user key.