streamlit-nightly 1.20.1.dev20230329__py2.py3-none-any.whl → 1.20.1.dev20230330__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/elements/doc_string.py +14 -2
- streamlit/runtime/websocket_session_manager.py +9 -4
- streamlit/testing/element_tree.py +132 -0
- streamlit/testing/script_interactions.py +6 -1
- {streamlit_nightly-1.20.1.dev20230329.dist-info → streamlit_nightly-1.20.1.dev20230330.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.20.1.dev20230329.dist-info → streamlit_nightly-1.20.1.dev20230330.dist-info}/RECORD +10 -10
- {streamlit_nightly-1.20.1.dev20230329.data → streamlit_nightly-1.20.1.dev20230330.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.20.1.dev20230329.dist-info → streamlit_nightly-1.20.1.dev20230330.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.20.1.dev20230329.dist-info → streamlit_nightly-1.20.1.dev20230330.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.20.1.dev20230329.dist-info → streamlit_nightly-1.20.1.dev20230330.dist-info}/top_level.txt +0 -0
streamlit/elements/doc_string.py
CHANGED
@@ -70,6 +70,10 @@ class HelpMixin:
|
|
70
70
|
>>>
|
71
71
|
>>> st.help(pandas.DataFrame)
|
72
72
|
|
73
|
+
.. output::
|
74
|
+
https://doc-string.streamlit.app/
|
75
|
+
height: 700px
|
76
|
+
|
73
77
|
Want to quickly check what data type is output by a certain function?
|
74
78
|
Try:
|
75
79
|
|
@@ -95,17 +99,25 @@ class HelpMixin:
|
|
95
99
|
>>>
|
96
100
|
>>> st.help(fido)
|
97
101
|
|
102
|
+
.. output::
|
103
|
+
https://doc-string1.streamlit.app/
|
104
|
+
height: 300px
|
105
|
+
|
98
106
|
And if you're using Magic, you can get help for functions, classes,
|
99
107
|
and modules without even typing ``st.help``:
|
100
108
|
|
101
109
|
>>> import streamlit as st
|
102
110
|
>>> import pandas
|
103
111
|
>>>
|
104
|
-
>>> # Get help for Pandas
|
105
|
-
>>> pandas.
|
112
|
+
>>> # Get help for Pandas read_csv:
|
113
|
+
>>> pandas.read_csv
|
106
114
|
>>>
|
107
115
|
>>> # Get help for Streamlit itself:
|
108
116
|
>>> st
|
117
|
+
|
118
|
+
.. output::
|
119
|
+
https://doc-string2.streamlit.app/
|
120
|
+
height: 700px
|
109
121
|
"""
|
110
122
|
doc_string_proto = DocStringProto()
|
111
123
|
_marshall(doc_string_proto, obj)
|
@@ -62,13 +62,18 @@ class WebsocketSessionManager(SessionManager):
|
|
62
62
|
user_info: Dict[str, Optional[str]],
|
63
63
|
existing_session_id: Optional[str] = None,
|
64
64
|
) -> str:
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
if existing_session_id in self._active_session_info_by_id:
|
66
|
+
LOGGER.warning(
|
67
|
+
"Session with id %s is already connected! Connecting to a new session.",
|
68
|
+
existing_session_id,
|
69
|
+
)
|
68
70
|
|
69
|
-
session_info =
|
71
|
+
session_info = (
|
70
72
|
existing_session_id
|
73
|
+
and existing_session_id not in self._active_session_info_by_id
|
74
|
+
and self._session_storage.get(existing_session_id)
|
71
75
|
)
|
76
|
+
|
72
77
|
if session_info:
|
73
78
|
existing_session = session_info.session
|
74
79
|
existing_session.register_file_watchers()
|
@@ -37,6 +37,8 @@ from streamlit.proto.Radio_pb2 import Radio as RadioProto
|
|
37
37
|
from streamlit.proto.Selectbox_pb2 import Selectbox as SelectboxProto
|
38
38
|
from streamlit.proto.Slider_pb2 import Slider as SliderProto
|
39
39
|
from streamlit.proto.Text_pb2 import Text as TextProto
|
40
|
+
from streamlit.proto.TextArea_pb2 import TextArea as TextAreaProto
|
41
|
+
from streamlit.proto.TextInput_pb2 import TextInput as TextInputProto
|
40
42
|
from streamlit.proto.WidgetStates_pb2 import WidgetState, WidgetStates
|
41
43
|
from streamlit.runtime.state.common import user_key_from_widget_id
|
42
44
|
from streamlit.runtime.state.session_state import SessionState
|
@@ -711,6 +713,124 @@ class SelectSlider(Element, Widget, Generic[T]):
|
|
711
713
|
return self.set_value([lower, upper])
|
712
714
|
|
713
715
|
|
716
|
+
@dataclass(repr=False)
|
717
|
+
class TextInput(Element):
|
718
|
+
_value: str | None
|
719
|
+
proto: TextInputProto
|
720
|
+
type: str
|
721
|
+
id: str
|
722
|
+
label: str
|
723
|
+
max_chars: int
|
724
|
+
help: str
|
725
|
+
form_id: str
|
726
|
+
autocomplete: str
|
727
|
+
placeholder: str
|
728
|
+
disabled: bool
|
729
|
+
key: str | None
|
730
|
+
|
731
|
+
root: ElementTree = field(repr=False)
|
732
|
+
|
733
|
+
def __init__(self, proto: TextInputProto, root: ElementTree):
|
734
|
+
self.proto = proto
|
735
|
+
self.root = root
|
736
|
+
self._value = None
|
737
|
+
|
738
|
+
self.type = "text_input"
|
739
|
+
self.id = proto.id
|
740
|
+
self.label = proto.label
|
741
|
+
self.max_chars = proto.max_chars
|
742
|
+
self.help = proto.help
|
743
|
+
self.form_id = proto.form_id
|
744
|
+
self.autocomplete = proto.autocomplete
|
745
|
+
self.placeholder = proto.placeholder
|
746
|
+
self.disabled = proto.disabled
|
747
|
+
self.key = user_key_from_widget_id(self.id)
|
748
|
+
|
749
|
+
def set_value(self, v: str) -> TextInput:
|
750
|
+
self._value = v
|
751
|
+
return self
|
752
|
+
|
753
|
+
def widget_state(self) -> WidgetState:
|
754
|
+
ws = WidgetState()
|
755
|
+
ws.id = self.id
|
756
|
+
ws.string_value = self.value
|
757
|
+
return ws
|
758
|
+
|
759
|
+
@property
|
760
|
+
def value(self) -> str:
|
761
|
+
if self._value is not None:
|
762
|
+
return self._value
|
763
|
+
else:
|
764
|
+
state = self.root.session_state
|
765
|
+
assert state
|
766
|
+
# Awkward to do this with `cast`
|
767
|
+
return state[self.id] # type: ignore
|
768
|
+
|
769
|
+
def input(self, v: str) -> TextInput:
|
770
|
+
# TODO should input be setting or appending?
|
771
|
+
if self.max_chars and len(v) > self.max_chars:
|
772
|
+
return self
|
773
|
+
return self.set_value(v)
|
774
|
+
|
775
|
+
|
776
|
+
@dataclass(repr=False)
|
777
|
+
class TextArea(Element):
|
778
|
+
_value: str | None
|
779
|
+
proto: TextAreaProto
|
780
|
+
type: str
|
781
|
+
id: str
|
782
|
+
label: str
|
783
|
+
max_chars: int
|
784
|
+
help: str
|
785
|
+
form_id: str
|
786
|
+
placeholder: str
|
787
|
+
disabled: bool
|
788
|
+
key: str | None
|
789
|
+
|
790
|
+
root: ElementTree = field(repr=False)
|
791
|
+
|
792
|
+
def __init__(self, proto: TextAreaProto, root: ElementTree):
|
793
|
+
self.proto = proto
|
794
|
+
self.root = root
|
795
|
+
self._value = None
|
796
|
+
|
797
|
+
self.type = "text_area"
|
798
|
+
self.id = proto.id
|
799
|
+
self.label = proto.label
|
800
|
+
self.max_chars = proto.max_chars
|
801
|
+
self.help = proto.help
|
802
|
+
self.form_id = proto.form_id
|
803
|
+
self.placeholder = proto.placeholder
|
804
|
+
self.disabled = proto.disabled
|
805
|
+
self.key = user_key_from_widget_id(self.id)
|
806
|
+
|
807
|
+
def set_value(self, v: str) -> TextArea:
|
808
|
+
self._value = v
|
809
|
+
return self
|
810
|
+
|
811
|
+
def widget_state(self) -> WidgetState:
|
812
|
+
ws = WidgetState()
|
813
|
+
ws.id = self.id
|
814
|
+
ws.string_value = self.value
|
815
|
+
return ws
|
816
|
+
|
817
|
+
@property
|
818
|
+
def value(self) -> str:
|
819
|
+
if self._value is not None:
|
820
|
+
return self._value
|
821
|
+
else:
|
822
|
+
state = self.root.session_state
|
823
|
+
assert state
|
824
|
+
# Awkward to do this with `cast`
|
825
|
+
return state[self.id] # type: ignore
|
826
|
+
|
827
|
+
def input(self, v: str) -> TextArea:
|
828
|
+
# TODO should input be setting or appending?
|
829
|
+
if self.max_chars and len(v) > self.max_chars:
|
830
|
+
return self
|
831
|
+
return self.set_value(v)
|
832
|
+
|
833
|
+
|
714
834
|
@dataclass(init=False, repr=False)
|
715
835
|
class Block:
|
716
836
|
type: str
|
@@ -823,6 +943,14 @@ class Block:
|
|
823
943
|
def get(self, element_type: Literal["button"]) -> Sequence[Button]:
|
824
944
|
...
|
825
945
|
|
946
|
+
@overload
|
947
|
+
def get(self, element_type: Literal["text_input"]) -> Sequence[TextInput]:
|
948
|
+
...
|
949
|
+
|
950
|
+
@overload
|
951
|
+
def get(self, element_type: Literal["text_area"]) -> Sequence[TextArea]:
|
952
|
+
...
|
953
|
+
|
826
954
|
def get(self, element_type: str) -> Sequence[Node]:
|
827
955
|
return [e for e in self if e.type == element_type]
|
828
956
|
|
@@ -972,6 +1100,10 @@ def parse_tree_from_messages(messages: list[ForwardMsg]) -> ElementTree:
|
|
972
1100
|
raise ValueError(f"Slider with unknown type {elt.slider}")
|
973
1101
|
elif elt.WhichOneof("type") == "button":
|
974
1102
|
new_node = Button(elt.button, root=root)
|
1103
|
+
elif elt.WhichOneof("type") == "text_input":
|
1104
|
+
new_node = TextInput(elt.text_input, root=root)
|
1105
|
+
elif elt.WhichOneof("type") == "text_area":
|
1106
|
+
new_node = TextArea(elt.text_area, root=root)
|
975
1107
|
elif elt.WhichOneof("type") == "code":
|
976
1108
|
new_node = Code(elt.code, root=root)
|
977
1109
|
else:
|
@@ -20,7 +20,7 @@ import textwrap
|
|
20
20
|
import unittest
|
21
21
|
from unittest.mock import MagicMock
|
22
22
|
|
23
|
-
from streamlit import source_util
|
23
|
+
from streamlit import config, source_util
|
24
24
|
from streamlit.runtime import Runtime
|
25
25
|
from streamlit.runtime.caching.storage.dummy_cache_storage import (
|
26
26
|
MemoryCacheStorageManager,
|
@@ -54,6 +54,11 @@ class InteractiveScriptTests(unittest.TestCase):
|
|
54
54
|
source_util._cached_pages = self.saved_cached_pages
|
55
55
|
Runtime._instance = None
|
56
56
|
|
57
|
+
@classmethod
|
58
|
+
def setUpClass(cls) -> None:
|
59
|
+
# set unconditionally for whole process, since we are just running tests
|
60
|
+
config.set_option("runner.postScriptGC", False)
|
61
|
+
|
57
62
|
def script_from_string(self, script_name: str, script: str) -> LocalScriptRunner:
|
58
63
|
"""Create a runner for a script with the contents from a string.
|
59
64
|
|
@@ -52,7 +52,7 @@ streamlit/elements/color_picker.py,sha256=SWPuKExaQAZ3qTjGuGZE9STadyTeoXbKtsSl6z
|
|
52
52
|
streamlit/elements/data_editor.py,sha256=vyy4a9YkGV4__SFA70LUoMS5BqInWVJqP3VI3kBuGN4,22373
|
53
53
|
streamlit/elements/dataframe_selector.py,sha256=BJ9PxtQSTJmxLufKYig5BOTllUoMlFIrClAXOEJceYw,23378
|
54
54
|
streamlit/elements/deck_gl_json_chart.py,sha256=ew_NJlW0r7zWwwNjW5Fgi_WzKtfWkGEpMLeQStX26f4,5900
|
55
|
-
streamlit/elements/doc_string.py,sha256=
|
55
|
+
streamlit/elements/doc_string.py,sha256=4FicKk0nkE1QaqZtharJDQpn5-ErQLh9LFFbjZySjRo,16515
|
56
56
|
streamlit/elements/empty.py,sha256=Uq8i2Lr_PPa2As97dQFaHvmsp4sFQnkxl940rHY9pDo,2598
|
57
57
|
streamlit/elements/exception.py,sha256=mODDi3pLy3_gMzruyL5mbCR15QSOlC67SGIZj0SsYhA,9131
|
58
58
|
streamlit/elements/file_uploader.py,sha256=dBP_LXyYBa_FCmNfHSANkZ79bfDpoJWUl7cwgnfC3hY,17023
|
@@ -181,7 +181,7 @@ streamlit/runtime/secrets.py,sha256=IyLvm-wIEZDbf-5s5nDmbUGUIlBzumRwUfQ_bl6e88M,
|
|
181
181
|
streamlit/runtime/session_manager.py,sha256=YidIoIjyefSkIcLxXwIA9eEajnUYI2ZIudEXiGp_WPA,12404
|
182
182
|
streamlit/runtime/stats.py,sha256=rW5Qn0cOGBoXPujn-m5uXWrP7ynZaGblFBTqNXL35UA,3044
|
183
183
|
streamlit/runtime/uploaded_file_manager.py,sha256=33VuJwFUDHDXnKn3Kuk5rXmY7lfOAiaeOe2FtUpwoIw,11423
|
184
|
-
streamlit/runtime/websocket_session_manager.py,sha256=
|
184
|
+
streamlit/runtime/websocket_session_manager.py,sha256=xQycGDSZznKFl-6HIx6t80IFfUH3Y7rDtuy3T3CK9II,6005
|
185
185
|
streamlit/runtime/caching/__init__.py,sha256=-ZIG57eSh_xIvxdK9ABJgIPc5kqRRRe0-q97kc-M3CQ,4700
|
186
186
|
streamlit/runtime/caching/cache_data_api.py,sha256=UAv_GKEsDc2iyZdMOSiFGFxTzuFMRS2X9sJhNshgxKs,23793
|
187
187
|
streamlit/runtime/caching/cache_errors.py,sha256=sURFQo_rSFwLYV1uXIZtQux8OMa-eI0n8nPg8jjT-VQ,5992
|
@@ -374,9 +374,9 @@ streamlit/static/vendor/bokeh/bokeh-widgets-2.4.3.min.js,sha256=u3UguW5_pdn4Ko_8
|
|
374
374
|
streamlit/static/vendor/viz/viz-1.8.0.min.js,sha256=IxSkZJCwrWQu3WdNuTL79gZuPydKJj5GKWUQklAG3tw,7055772
|
375
375
|
streamlit/static/vendor/viz/viz.js-LICENSE.txt,sha256=uaCz_LNbK2dfOhmcMesZ7dHew6oIaHvk-w0xfoZeNc0,1063
|
376
376
|
streamlit/testing/__init__.py,sha256=LTDGDB-ahkVmBP0P6YP2tyR5e1QTnVTSb1f3yZWi7go,611
|
377
|
-
streamlit/testing/element_tree.py,sha256=
|
377
|
+
streamlit/testing/element_tree.py,sha256=odnFU55-drxZpSTa9NIzr4PZCw6mUeQo1M90WIKsWlE,33586
|
378
378
|
streamlit/testing/local_script_runner.py,sha256=RmNx09snXsykAW8cj3pPaf2LVd9QHUGMKbY_SLy530Y,5300
|
379
|
-
streamlit/testing/script_interactions.py,sha256=
|
379
|
+
streamlit/testing/script_interactions.py,sha256=oEcw2ExaM39iFyvxF2Y28rwkOTO7RstE6wDOgHDLzlg,3048
|
380
380
|
streamlit/vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
381
381
|
streamlit/vendor/ipython/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
382
382
|
streamlit/vendor/ipython/modified_sys_path.py,sha256=ZqgBdpdyc_pWkieJUhKDdmW9sIQDUIZCz4ZXv3lp28s,2746
|
@@ -401,9 +401,9 @@ streamlit/web/server/server_util.py,sha256=XJ9ngvipySXQqncV30nAn_QVnjYXvvl9j5aMq
|
|
401
401
|
streamlit/web/server/stats_request_handler.py,sha256=rJelIrHJAz4EGctKLnixEbEVetrXcsDVYp7la033tGE,3405
|
402
402
|
streamlit/web/server/upload_file_request_handler.py,sha256=jyfvPcGSr_IELU3DE75z7GpHYyix0w1ONu3aAoP5BWI,5964
|
403
403
|
streamlit/web/server/websocket_headers.py,sha256=oTieGEZ16m1cmZMuus_fwgTIWF9LUFvCtmls2_GivgA,1867
|
404
|
-
streamlit_nightly-1.20.1.
|
405
|
-
streamlit_nightly-1.20.1.
|
406
|
-
streamlit_nightly-1.20.1.
|
407
|
-
streamlit_nightly-1.20.1.
|
408
|
-
streamlit_nightly-1.20.1.
|
409
|
-
streamlit_nightly-1.20.1.
|
404
|
+
streamlit_nightly-1.20.1.dev20230330.data/scripts/streamlit.cmd,sha256=bIvl64RLCLmXTMo-YWqncINDWHlgQx_RgPvL41gYGh4,671
|
405
|
+
streamlit_nightly-1.20.1.dev20230330.dist-info/METADATA,sha256=zXihma-97b2Brh3LvSqrE0qw-Ddfoim16gNtcqtZNX4,7322
|
406
|
+
streamlit_nightly-1.20.1.dev20230330.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
|
407
|
+
streamlit_nightly-1.20.1.dev20230330.dist-info/entry_points.txt,sha256=uNJ4DwGNXEhOK0USwSNanjkYyR-Bk7eYQbJFDrWyOgY,53
|
408
|
+
streamlit_nightly-1.20.1.dev20230330.dist-info/top_level.txt,sha256=V3FhKbm7G2LnR0s4SytavrjIPNIhvcsAGXfYHAwtQzw,10
|
409
|
+
streamlit_nightly-1.20.1.dev20230330.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|