streamlit-nightly 1.31.2.dev20240212__py2.py3-none-any.whl → 1.31.2.dev20240214__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/case_converters.py +9 -4
- streamlit/cli_util.py +2 -0
- streamlit/code_util.py +5 -2
- streamlit/color_util.py +2 -0
- streamlit/column_config.py +2 -0
- streamlit/commands/execution_control.py +4 -2
- streamlit/commands/experimental_query_params.py +7 -4
- streamlit/commands/page_config.py +11 -9
- streamlit/components/v1/components.py +23 -16
- streamlit/config.py +3 -5
- streamlit/config_option.py +12 -11
- streamlit/connections/base_connection.py +4 -2
- streamlit/connections/snowflake_connection.py +4 -4
- streamlit/connections/snowpark_connection.py +3 -3
- streamlit/connections/sql_connection.py +6 -6
- streamlit/connections/util.py +8 -5
- streamlit/constants.py +2 -0
- streamlit/cursor.py +16 -14
- streamlit/delta_generator.py +10 -13
- streamlit/deprecation_util.py +4 -3
- streamlit/echo.py +5 -3
- streamlit/elements/alert.py +16 -14
- streamlit/elements/altair_utils.py +8 -6
- streamlit/elements/arrow.py +4 -4
- streamlit/elements/arrow_altair.py +24 -34
- streamlit/elements/arrow_vega_lite.py +9 -14
- streamlit/elements/balloons.py +4 -2
- streamlit/elements/bokeh_chart.py +7 -7
- streamlit/elements/code.py +6 -4
- streamlit/elements/deck_gl_json_chart.py +8 -8
- streamlit/elements/doc_string.py +5 -9
- streamlit/elements/empty.py +4 -2
- streamlit/elements/exception.py +10 -10
- streamlit/elements/form.py +1 -3
- streamlit/elements/graphviz_chart.py +5 -6
- streamlit/elements/heading.py +16 -14
- streamlit/elements/iframe.py +14 -12
- streamlit/elements/image.py +8 -8
- streamlit/elements/json.py +6 -4
- streamlit/elements/layouts.py +12 -10
- streamlit/elements/lib/column_config_utils.py +2 -2
- streamlit/elements/lib/column_types.py +23 -23
- streamlit/elements/lib/dicttools.py +10 -6
- streamlit/elements/lib/mutable_status_container.py +7 -7
- streamlit/elements/lib/pandas_styler_utils.py +6 -6
- streamlit/elements/lib/streamlit_plotly_theme.py +2 -0
- streamlit/elements/map.py +11 -22
- streamlit/elements/markdown.py +16 -14
- streamlit/elements/media.py +16 -16
- streamlit/elements/metric.py +9 -7
- streamlit/elements/plotly_chart.py +5 -5
- streamlit/elements/progress.py +6 -6
- streamlit/elements/pyplot.py +10 -13
- streamlit/elements/snow.py +4 -2
- streamlit/elements/spinner.py +2 -0
- streamlit/elements/text.py +7 -5
- streamlit/elements/toast.py +6 -4
- streamlit/elements/utils.py +15 -28
- streamlit/elements/widgets/button.py +39 -39
- streamlit/elements/widgets/camera_input.py +21 -17
- streamlit/elements/widgets/chat.py +6 -7
- streamlit/elements/widgets/checkbox.py +21 -19
- streamlit/elements/widgets/color_picker.py +18 -16
- streamlit/elements/widgets/data_editor.py +7 -7
- streamlit/elements/widgets/file_uploader.py +59 -55
- streamlit/elements/widgets/multiselect.py +33 -42
- streamlit/elements/widgets/number_input.py +10 -5
- streamlit/elements/widgets/radio.py +1 -1
- streamlit/elements/widgets/select_slider.py +25 -34
- streamlit/elements/widgets/selectbox.py +1 -1
- streamlit/elements/widgets/slider.py +28 -36
- streamlit/elements/widgets/text_widgets.py +6 -6
- streamlit/elements/widgets/time_widgets.py +13 -13
- streamlit/elements/write.py +21 -29
- streamlit/env_util.py +5 -3
- streamlit/error_util.py +7 -3
- streamlit/errors.py +3 -1
- streamlit/external/langchain/streamlit_callback_handler.py +26 -24
- streamlit/file_util.py +18 -14
- streamlit/folder_black_list.py +3 -1
- streamlit/git_util.py +5 -3
- streamlit/js_number.py +10 -13
- streamlit/logger.py +5 -5
- streamlit/net_util.py +14 -11
- streamlit/platform.py +2 -0
- streamlit/runtime/__init__.py +2 -0
- streamlit/runtime/app_session.py +42 -42
- streamlit/runtime/caching/__init__.py +4 -4
- streamlit/runtime/caching/cache_data_api.py +3 -3
- streamlit/runtime/caching/cache_errors.py +5 -3
- streamlit/runtime/caching/cache_type.py +2 -0
- streamlit/runtime/caching/cache_utils.py +2 -4
- streamlit/runtime/caching/cached_message_replay.py +12 -5
- streamlit/runtime/caching/hashing.py +29 -21
- streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -2
- streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -5
- streamlit/runtime/connection_factory.py +8 -8
- streamlit/runtime/forward_msg_cache.py +20 -18
- streamlit/runtime/forward_msg_queue.py +8 -9
- streamlit/runtime/legacy_caching/caching.py +32 -42
- streamlit/runtime/legacy_caching/hashing.py +29 -25
- streamlit/runtime/media_file_manager.py +16 -14
- streamlit/runtime/media_file_storage.py +8 -8
- streamlit/runtime/memory_media_file_storage.py +12 -14
- streamlit/runtime/memory_session_storage.py +4 -3
- streamlit/runtime/memory_uploaded_file_manager.py +9 -10
- streamlit/runtime/metrics_util.py +20 -20
- streamlit/runtime/runtime.py +25 -27
- streamlit/runtime/runtime_util.py +5 -3
- streamlit/runtime/script_data.py +2 -0
- streamlit/runtime/scriptrunner/magic.py +17 -11
- streamlit/runtime/scriptrunner/magic_funcs.py +2 -0
- streamlit/runtime/scriptrunner/script_requests.py +6 -4
- streamlit/runtime/scriptrunner/script_run_context.py +17 -17
- streamlit/runtime/scriptrunner/script_runner.py +7 -5
- streamlit/runtime/secrets.py +4 -6
- streamlit/runtime/session_manager.py +14 -14
- streamlit/runtime/state/common.py +5 -4
- streamlit/runtime/state/query_params.py +8 -6
- streamlit/runtime/state/query_params_proxy.py +7 -5
- streamlit/runtime/state/safe_session_state.py +7 -5
- streamlit/runtime/state/session_state.py +3 -4
- streamlit/runtime/state/session_state_proxy.py +5 -5
- streamlit/runtime/state/widgets.py +20 -18
- streamlit/runtime/stats.py +13 -15
- streamlit/runtime/uploaded_file_manager.py +6 -5
- streamlit/runtime/websocket_session_manager.py +14 -14
- streamlit/source_util.py +13 -11
- streamlit/static/asset-manifest.json +13 -13
- streamlit/static/index.html +1 -1
- streamlit/static/static/css/2411.8b8f33d6.chunk.css +1 -0
- streamlit/static/static/css/43.e3b876c5.chunk.css +1 -0
- streamlit/static/static/css/6692.65519639.chunk.css +1 -0
- streamlit/static/static/js/{3075.76725a14.chunk.js → 2411.714d213e.chunk.js} +2 -2
- streamlit/static/static/js/4185.21ca0590.chunk.js +1 -0
- streamlit/static/static/js/43.36939bb1.chunk.js +1 -0
- streamlit/static/static/js/{5117.6a701db1.chunk.js → 5117.04bfe5d3.chunk.js} +1 -1
- streamlit/static/static/js/{5791.30b01ee8.chunk.js → 5791.c5138157.chunk.js} +1 -1
- streamlit/static/static/js/656.8c998bc8.chunk.js +2 -0
- streamlit/static/static/js/{6692.6ac4ea6f.chunk.js → 6692.6496cbc2.chunk.js} +1 -1
- streamlit/static/static/js/7142.400eefdd.chunk.js +1 -0
- streamlit/static/static/js/main.2737c0f9.js +2 -0
- streamlit/static/static/js/{main.043d802e.js.LICENSE.txt → main.2737c0f9.js.LICENSE.txt} +23 -25
- streamlit/string_util.py +13 -9
- streamlit/temporary_directory.py +3 -1
- streamlit/testing/v1/element_tree.py +1 -2
- streamlit/testing/v1/util.py +7 -3
- streamlit/type_util.py +30 -25
- streamlit/url_util.py +6 -4
- streamlit/user_info.py +8 -6
- streamlit/util.py +23 -37
- streamlit/version.py +16 -9
- streamlit/watcher/event_based_path_watcher.py +10 -10
- streamlit/watcher/local_sources_watcher.py +15 -13
- streamlit/watcher/path_watcher.py +0 -3
- streamlit/watcher/polling_path_watcher.py +9 -8
- streamlit/watcher/util.py +3 -2
- streamlit/web/cache_storage_manager_config.py +2 -0
- streamlit/web/server/app_static_file_handler.py +6 -5
- streamlit/web/server/browser_websocket_handler.py +10 -8
- streamlit/web/server/component_request_handler.py +7 -4
- streamlit/web/server/media_file_handler.py +5 -4
- streamlit/web/server/routes.py +6 -3
- streamlit/web/server/server.py +41 -34
- streamlit/web/server/server_util.py +8 -3
- streamlit/web/server/stats_request_handler.py +14 -5
- streamlit/web/server/upload_file_request_handler.py +7 -8
- streamlit/web/server/websocket_headers.py +2 -2
- {streamlit_nightly-1.31.2.dev20240212.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.31.2.dev20240212.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/RECORD +176 -176
- streamlit/static/static/css/3075.81b3d18f.chunk.css +0 -1
- streamlit/static/static/css/43.c24b25fa.chunk.css +0 -1
- streamlit/static/static/css/6692.bb444a79.chunk.css +0 -1
- streamlit/static/static/js/1215.baf3721f.chunk.js +0 -2
- streamlit/static/static/js/4185.90e929dc.chunk.js +0 -1
- streamlit/static/static/js/43.8ca4bc8a.chunk.js +0 -1
- streamlit/static/static/js/7142.a359ed63.chunk.js +0 -1
- streamlit/static/static/js/main.043d802e.js +0 -2
- /streamlit/static/static/js/{3075.76725a14.chunk.js.LICENSE.txt → 2411.714d213e.chunk.js.LICENSE.txt} +0 -0
- /streamlit/static/static/js/{1215.baf3721f.chunk.js.LICENSE.txt → 656.8c998bc8.chunk.js.LICENSE.txt} +0 -0
- {streamlit_nightly-1.31.2.dev20240212.data → streamlit_nightly-1.31.2.dev20240214.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.31.2.dev20240212.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.31.2.dev20240212.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.31.2.dev20240212.dist-info → streamlit_nightly-1.31.2.dev20240214.dist-info}/top_level.txt +0 -0
@@ -12,20 +12,11 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
15
17
|
from dataclasses import dataclass
|
16
18
|
from textwrap import dedent
|
17
|
-
from typing import
|
18
|
-
TYPE_CHECKING,
|
19
|
-
Any,
|
20
|
-
Callable,
|
21
|
-
Generic,
|
22
|
-
List,
|
23
|
-
Optional,
|
24
|
-
Sequence,
|
25
|
-
Tuple,
|
26
|
-
Union,
|
27
|
-
cast,
|
28
|
-
)
|
19
|
+
from typing import TYPE_CHECKING, Any, Callable, Generic, Sequence, Tuple, cast
|
29
20
|
|
30
21
|
from typing_extensions import TypeGuard
|
31
22
|
|
@@ -64,30 +55,30 @@ if TYPE_CHECKING:
|
|
64
55
|
from streamlit.delta_generator import DeltaGenerator
|
65
56
|
|
66
57
|
|
67
|
-
def _is_range_value(value:
|
58
|
+
def _is_range_value(value: T | Sequence[T]) -> TypeGuard[Sequence[T]]:
|
68
59
|
return isinstance(value, (list, tuple))
|
69
60
|
|
70
61
|
|
71
62
|
@dataclass
|
72
63
|
class SelectSliderSerde(Generic[T]):
|
73
64
|
options: Sequence[T]
|
74
|
-
value:
|
65
|
+
value: list[int]
|
75
66
|
is_range_value: bool
|
76
67
|
|
77
|
-
def serialize(self, v: object) ->
|
68
|
+
def serialize(self, v: object) -> list[int]:
|
78
69
|
return self._as_index_list(v)
|
79
70
|
|
80
71
|
def deserialize(
|
81
72
|
self,
|
82
|
-
ui_value:
|
73
|
+
ui_value: list[int] | None,
|
83
74
|
widget_id: str = "",
|
84
|
-
) ->
|
75
|
+
) -> T | tuple[T, T]:
|
85
76
|
if not ui_value:
|
86
77
|
# Widget has not been used; fallback to the original value,
|
87
78
|
ui_value = self.value
|
88
79
|
|
89
80
|
# The widget always returns floats, so convert to ints before indexing
|
90
|
-
return_value:
|
81
|
+
return_value: tuple[T, T] = cast(
|
91
82
|
Tuple[T, T],
|
92
83
|
tuple(map(lambda x: self.options[int(x)], ui_value)),
|
93
84
|
)
|
@@ -95,7 +86,7 @@ class SelectSliderSerde(Generic[T]):
|
|
95
86
|
# If the original value was a list/tuple, so will be the output (and vice versa)
|
96
87
|
return return_value if self.is_range_value else return_value[0]
|
97
88
|
|
98
|
-
def _as_index_list(self, v: object) ->
|
89
|
+
def _as_index_list(self, v: object) -> list[int]:
|
99
90
|
if _is_range_value(v):
|
100
91
|
slider_value = [index_(self.options, val) for val in v]
|
101
92
|
start, end = slider_value
|
@@ -114,15 +105,15 @@ class SelectSliderMixin:
|
|
114
105
|
options: OptionSequence[T] = (),
|
115
106
|
value: object = None,
|
116
107
|
format_func: Callable[[Any], Any] = str,
|
117
|
-
key:
|
118
|
-
help:
|
119
|
-
on_change:
|
120
|
-
args:
|
121
|
-
kwargs:
|
108
|
+
key: Key | None = None,
|
109
|
+
help: str | None = None,
|
110
|
+
on_change: WidgetCallback | None = None,
|
111
|
+
args: WidgetArgs | None = None,
|
112
|
+
kwargs: WidgetKwargs | None = None,
|
122
113
|
*, # keyword-only arguments:
|
123
114
|
disabled: bool = False,
|
124
115
|
label_visibility: LabelVisibility = "visible",
|
125
|
-
) ->
|
116
|
+
) -> T | tuple[T, T]:
|
126
117
|
r"""
|
127
118
|
Display a slider widget to select items from a list.
|
128
119
|
|
@@ -251,15 +242,15 @@ class SelectSliderMixin:
|
|
251
242
|
options: OptionSequence[T] = (),
|
252
243
|
value: object = None,
|
253
244
|
format_func: Callable[[Any], Any] = str,
|
254
|
-
key:
|
255
|
-
help:
|
256
|
-
on_change:
|
257
|
-
args:
|
258
|
-
kwargs:
|
245
|
+
key: Key | None = None,
|
246
|
+
help: str | None = None,
|
247
|
+
on_change: WidgetCallback | None = None,
|
248
|
+
args: WidgetArgs | None = None,
|
249
|
+
kwargs: WidgetKwargs | None = None,
|
259
250
|
disabled: bool = False,
|
260
251
|
label_visibility: LabelVisibility = "visible",
|
261
|
-
ctx:
|
262
|
-
) ->
|
252
|
+
ctx: ScriptRunContext | None = None,
|
253
|
+
) -> T | tuple[T, T]:
|
263
254
|
key = to_key(key)
|
264
255
|
check_callback_rules(self.dg, on_change)
|
265
256
|
check_session_state_rules(default_value=value, key=key)
|
@@ -270,7 +261,7 @@ class SelectSliderMixin:
|
|
270
261
|
if len(opt) == 0:
|
271
262
|
raise StreamlitAPIException("The `options` argument needs to be non-empty")
|
272
263
|
|
273
|
-
def as_index_list(v: object) ->
|
264
|
+
def as_index_list(v: object) -> list[int]:
|
274
265
|
if _is_range_value(v):
|
275
266
|
slider_value = [index_(opt, val) for val in v]
|
276
267
|
start, end = slider_value
|
@@ -349,6 +340,6 @@ class SelectSliderMixin:
|
|
349
340
|
return widget_state.value
|
350
341
|
|
351
342
|
@property
|
352
|
-
def dg(self) ->
|
343
|
+
def dg(self) -> DeltaGenerator:
|
353
344
|
"""Get our DeltaGenerator."""
|
354
345
|
return cast("DeltaGenerator", self)
|
@@ -12,23 +12,15 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
15
17
|
from dataclasses import dataclass
|
16
18
|
from datetime import date, datetime, time, timedelta, timezone, tzinfo
|
17
19
|
from numbers import Integral, Real
|
18
20
|
from textwrap import dedent
|
19
|
-
from typing import
|
20
|
-
TYPE_CHECKING,
|
21
|
-
Any,
|
22
|
-
List,
|
23
|
-
Optional,
|
24
|
-
Sequence,
|
25
|
-
Tuple,
|
26
|
-
TypeVar,
|
27
|
-
Union,
|
28
|
-
cast,
|
29
|
-
)
|
21
|
+
from typing import TYPE_CHECKING, Any, Final, Sequence, Tuple, TypeVar, Union, cast
|
30
22
|
|
31
|
-
from typing_extensions import
|
23
|
+
from typing_extensions import TypeAlias
|
32
24
|
|
33
25
|
from streamlit.elements.form import current_form_id
|
34
26
|
from streamlit.elements.utils import (
|
@@ -119,7 +111,7 @@ def _datetime_to_micros(dt: datetime) -> int:
|
|
119
111
|
return _delta_to_micros(utc_dt - UTC_EPOCH)
|
120
112
|
|
121
113
|
|
122
|
-
def _micros_to_datetime(micros: int, orig_tz:
|
114
|
+
def _micros_to_datetime(micros: int, orig_tz: tzinfo | None) -> datetime:
|
123
115
|
"""Restore times/datetimes to original timezone (dates are always naive)"""
|
124
116
|
utc_dt = UTC_EPOCH + timedelta(microseconds=micros)
|
125
117
|
# Add the original timezone. No conversion is required here,
|
@@ -129,12 +121,12 @@ def _micros_to_datetime(micros: int, orig_tz: Optional[tzinfo]) -> datetime:
|
|
129
121
|
|
130
122
|
@dataclass
|
131
123
|
class SliderSerde:
|
132
|
-
value:
|
124
|
+
value: list[float]
|
133
125
|
data_type: int
|
134
126
|
single_value: bool
|
135
|
-
orig_tz:
|
127
|
+
orig_tz: tzinfo | None
|
136
128
|
|
137
|
-
def deserialize(self, ui_value:
|
129
|
+
def deserialize(self, ui_value: list[float] | None, widget_id: str = ""):
|
138
130
|
if ui_value is not None:
|
139
131
|
val: Any = ui_value
|
140
132
|
else:
|
@@ -157,7 +149,7 @@ class SliderSerde:
|
|
157
149
|
]
|
158
150
|
return val[0] if self.single_value else tuple(val)
|
159
151
|
|
160
|
-
def serialize(self, v: Any) ->
|
152
|
+
def serialize(self, v: Any) -> list[Any]:
|
161
153
|
range_value = isinstance(v, (list, tuple))
|
162
154
|
value = list(v) if range_value else [v]
|
163
155
|
if self.data_type == SliderProto.DATE:
|
@@ -174,16 +166,16 @@ class SliderMixin:
|
|
174
166
|
def slider(
|
175
167
|
self,
|
176
168
|
label: str,
|
177
|
-
min_value:
|
178
|
-
max_value:
|
179
|
-
value:
|
180
|
-
step:
|
181
|
-
format:
|
182
|
-
key:
|
183
|
-
help:
|
184
|
-
on_change:
|
185
|
-
args:
|
186
|
-
kwargs:
|
169
|
+
min_value: SliderScalar | None = None,
|
170
|
+
max_value: SliderScalar | None = None,
|
171
|
+
value: SliderValue | None = None,
|
172
|
+
step: Step | None = None,
|
173
|
+
format: str | None = None,
|
174
|
+
key: Key | None = None,
|
175
|
+
help: str | None = None,
|
176
|
+
on_change: WidgetCallback | None = None,
|
177
|
+
args: WidgetArgs | None = None,
|
178
|
+
kwargs: WidgetKwargs | None = None,
|
187
179
|
*, # keyword-only arguments:
|
188
180
|
disabled: bool = False,
|
189
181
|
label_visibility: LabelVisibility = "visible",
|
@@ -359,17 +351,17 @@ class SliderMixin:
|
|
359
351
|
min_value=None,
|
360
352
|
max_value=None,
|
361
353
|
value=None,
|
362
|
-
step:
|
363
|
-
format:
|
364
|
-
key:
|
365
|
-
help:
|
366
|
-
on_change:
|
367
|
-
args:
|
368
|
-
kwargs:
|
354
|
+
step: Step | None = None,
|
355
|
+
format: str | None = None,
|
356
|
+
key: Key | None = None,
|
357
|
+
help: str | None = None,
|
358
|
+
on_change: WidgetCallback | None = None,
|
359
|
+
args: WidgetArgs | None = None,
|
360
|
+
kwargs: WidgetKwargs | None = None,
|
369
361
|
*, # keyword-only arguments:
|
370
362
|
disabled: bool = False,
|
371
363
|
label_visibility: LabelVisibility = "visible",
|
372
|
-
ctx:
|
364
|
+
ctx: ScriptRunContext | None = None,
|
373
365
|
) -> SliderReturn:
|
374
366
|
key = to_key(key)
|
375
367
|
check_callback_rules(self.dg, on_change)
|
@@ -673,6 +665,6 @@ class SliderMixin:
|
|
673
665
|
return cast(SliderReturn, widget_state.value)
|
674
666
|
|
675
667
|
@property
|
676
|
-
def dg(self) ->
|
668
|
+
def dg(self) -> DeltaGenerator:
|
677
669
|
"""Get our DeltaGenerator."""
|
678
670
|
return cast("DeltaGenerator", self)
|
@@ -16,11 +16,8 @@ from __future__ import annotations
|
|
16
16
|
|
17
17
|
from dataclasses import dataclass
|
18
18
|
from textwrap import dedent
|
19
|
-
from typing import cast, overload
|
19
|
+
from typing import TYPE_CHECKING, Literal, cast, overload
|
20
20
|
|
21
|
-
from typing_extensions import Literal
|
22
|
-
|
23
|
-
import streamlit
|
24
21
|
from streamlit.elements.form import current_form_id
|
25
22
|
from streamlit.elements.utils import (
|
26
23
|
check_callback_rules,
|
@@ -47,6 +44,9 @@ from streamlit.type_util import (
|
|
47
44
|
to_key,
|
48
45
|
)
|
49
46
|
|
47
|
+
if TYPE_CHECKING:
|
48
|
+
from streamlit.delta_generator import DeltaGenerator
|
49
|
+
|
50
50
|
|
51
51
|
@dataclass
|
52
52
|
class TextInputSerde:
|
@@ -581,6 +581,6 @@ class TextWidgetsMixin:
|
|
581
581
|
return widget_state.value
|
582
582
|
|
583
583
|
@property
|
584
|
-
def dg(self) ->
|
584
|
+
def dg(self) -> DeltaGenerator:
|
585
585
|
"""Get our DeltaGenerator."""
|
586
|
-
return cast("
|
586
|
+
return cast("DeltaGenerator", self)
|
@@ -20,7 +20,7 @@ from textwrap import dedent
|
|
20
20
|
from typing import (
|
21
21
|
TYPE_CHECKING,
|
22
22
|
Any,
|
23
|
-
|
23
|
+
Final,
|
24
24
|
Literal,
|
25
25
|
Sequence,
|
26
26
|
Tuple,
|
@@ -61,8 +61,8 @@ DateWidgetReturn: TypeAlias = Union[
|
|
61
61
|
date, Tuple[()], Tuple[date], Tuple[date, date], None
|
62
62
|
]
|
63
63
|
|
64
|
-
DEFAULT_STEP_MINUTES = 15
|
65
|
-
ALLOWED_DATE_FORMATS = re.compile(
|
64
|
+
DEFAULT_STEP_MINUTES: Final = 15
|
65
|
+
ALLOWED_DATE_FORMATS: Final = re.compile(
|
66
66
|
r"^(YYYY[/.\-]MM[/.\-]DD|DD[/.\-]MM[/.\-]YYYY|MM[/.\-]DD[/.\-]YYYY)$"
|
67
67
|
)
|
68
68
|
|
@@ -86,8 +86,8 @@ def _adjust_years(input_date: date, years: int) -> date:
|
|
86
86
|
|
87
87
|
def _parse_date_value(
|
88
88
|
value: DateValue | Literal["today"] | Literal["default_value_today"],
|
89
|
-
) ->
|
90
|
-
parsed_dates:
|
89
|
+
) -> tuple[list[date] | None, bool]:
|
90
|
+
parsed_dates: list[date]
|
91
91
|
range_value: bool = False
|
92
92
|
if value is None:
|
93
93
|
return None, range_value
|
@@ -172,7 +172,7 @@ class _DateInputValues:
|
|
172
172
|
value: DateValue | Literal["today"] | Literal["default_value_today"],
|
173
173
|
min_value: SingleDateValue,
|
174
174
|
max_value: SingleDateValue,
|
175
|
-
) ->
|
175
|
+
) -> _DateInputValues:
|
176
176
|
parsed_value, is_range = _parse_date_value(value=value)
|
177
177
|
return cls(
|
178
178
|
value=parsed_value,
|
@@ -249,7 +249,7 @@ class DateInputSerde:
|
|
249
249
|
return return_value[0]
|
250
250
|
return cast(DateWidgetReturn, tuple(return_value))
|
251
251
|
|
252
|
-
def serialize(self, v: DateWidgetReturn) ->
|
252
|
+
def serialize(self, v: DateWidgetReturn) -> list[str]:
|
253
253
|
if v is None:
|
254
254
|
return []
|
255
255
|
|
@@ -271,7 +271,7 @@ class TimeWidgetsMixin:
|
|
271
271
|
*, # keyword-only arguments:
|
272
272
|
disabled: bool = False,
|
273
273
|
label_visibility: LabelVisibility = "visible",
|
274
|
-
step:
|
274
|
+
step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
|
275
275
|
) -> time:
|
276
276
|
pass
|
277
277
|
|
@@ -288,7 +288,7 @@ class TimeWidgetsMixin:
|
|
288
288
|
*, # keyword-only arguments:
|
289
289
|
disabled: bool = False,
|
290
290
|
label_visibility: LabelVisibility = "visible",
|
291
|
-
step:
|
291
|
+
step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
|
292
292
|
) -> time | None:
|
293
293
|
pass
|
294
294
|
|
@@ -305,7 +305,7 @@ class TimeWidgetsMixin:
|
|
305
305
|
*, # keyword-only arguments:
|
306
306
|
disabled: bool = False,
|
307
307
|
label_visibility: LabelVisibility = "visible",
|
308
|
-
step:
|
308
|
+
step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
|
309
309
|
) -> time | None:
|
310
310
|
r"""Display a time input widget.
|
311
311
|
|
@@ -425,7 +425,7 @@ class TimeWidgetsMixin:
|
|
425
425
|
*, # keyword-only arguments:
|
426
426
|
disabled: bool = False,
|
427
427
|
label_visibility: LabelVisibility = "visible",
|
428
|
-
step:
|
428
|
+
step: int | timedelta = timedelta(minutes=DEFAULT_STEP_MINUTES),
|
429
429
|
ctx: ScriptRunContext | None = None,
|
430
430
|
) -> time | None:
|
431
431
|
key = to_key(key)
|
@@ -703,7 +703,7 @@ class TimeWidgetsMixin:
|
|
703
703
|
parsed_min_date = parse_date_deterministic(min_value)
|
704
704
|
parsed_max_date = parse_date_deterministic(max_value)
|
705
705
|
|
706
|
-
parsed: str | None |
|
706
|
+
parsed: str | None | list[str | None]
|
707
707
|
if value == "today" or value == "default_value_today" or value is None:
|
708
708
|
parsed = None
|
709
709
|
elif isinstance(value, (datetime, date)):
|
@@ -804,6 +804,6 @@ class TimeWidgetsMixin:
|
|
804
804
|
return widget_state.value
|
805
805
|
|
806
806
|
@property
|
807
|
-
def dg(self) ->
|
807
|
+
def dg(self) -> DeltaGenerator:
|
808
808
|
"""Get our DeltaGenerator."""
|
809
809
|
return cast("DeltaGenerator", self)
|
streamlit/elements/write.py
CHANGED
@@ -19,18 +19,7 @@ import inspect
|
|
19
19
|
import json
|
20
20
|
import types
|
21
21
|
from io import StringIO
|
22
|
-
from typing import
|
23
|
-
TYPE_CHECKING,
|
24
|
-
Any,
|
25
|
-
Callable,
|
26
|
-
Final,
|
27
|
-
Generator,
|
28
|
-
Iterable,
|
29
|
-
List,
|
30
|
-
Tuple,
|
31
|
-
Type,
|
32
|
-
cast,
|
33
|
-
)
|
22
|
+
from typing import TYPE_CHECKING, Any, Callable, Final, Generator, Iterable, List, cast
|
34
23
|
|
35
24
|
from streamlit import type_util
|
36
25
|
from streamlit.errors import StreamlitAPIException
|
@@ -45,7 +34,7 @@ if TYPE_CHECKING:
|
|
45
34
|
|
46
35
|
|
47
36
|
# Special methods:
|
48
|
-
HELP_TYPES: Final[
|
37
|
+
HELP_TYPES: Final[tuple[type[Any], ...]] = (
|
49
38
|
types.BuiltinFunctionType,
|
50
39
|
types.BuiltinMethodType,
|
51
40
|
types.FunctionType,
|
@@ -53,9 +42,9 @@ HELP_TYPES: Final[Tuple[Type[Any], ...]] = (
|
|
53
42
|
types.ModuleType,
|
54
43
|
)
|
55
44
|
|
56
|
-
_LOGGER = get_logger(__name__)
|
45
|
+
_LOGGER: Final = get_logger(__name__)
|
57
46
|
|
58
|
-
_TEXT_CURSOR = "▕"
|
47
|
+
_TEXT_CURSOR: Final = "▕"
|
59
48
|
|
60
49
|
|
61
50
|
class StreamingOutput(List[Any]):
|
@@ -66,7 +55,7 @@ class WriteMixin:
|
|
66
55
|
@gather_metrics("write_stream")
|
67
56
|
def write_stream(
|
68
57
|
self, stream: Callable[..., Any] | Generator[Any, Any, Any] | Iterable[Any]
|
69
|
-
) ->
|
58
|
+
) -> list[Any] | str:
|
70
59
|
"""Stream a generator, iterable, or stream-like sequence to the app.
|
71
60
|
|
72
61
|
``st.write_stream`` iterates through the given sequences and writes all
|
@@ -99,14 +88,14 @@ class WriteMixin:
|
|
99
88
|
>>> import streamlit as st
|
100
89
|
>>>
|
101
90
|
>>> _LOREM_IPSUM = \"\"\"
|
102
|
-
>>> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
|
91
|
+
>>> Lorem ipsum dolor sit amet, **consectetur adipiscing** elit, sed do eiusmod tempor
|
103
92
|
>>> incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
|
104
93
|
>>> nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
105
94
|
>>> \"\"\"
|
106
95
|
>>>
|
107
96
|
>>>
|
108
97
|
>>> def stream_data():
|
109
|
-
>>> for word in _LOREM_IPSUM.split():
|
98
|
+
>>> for word in _LOREM_IPSUM.split(" "):
|
110
99
|
>>> yield word + " "
|
111
100
|
>>> time.sleep(0.02)
|
112
101
|
>>>
|
@@ -115,7 +104,7 @@ class WriteMixin:
|
|
115
104
|
>>> columns=["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"],
|
116
105
|
>>> )
|
117
106
|
>>>
|
118
|
-
>>> for word in _LOREM_IPSUM.split():
|
107
|
+
>>> for word in _LOREM_IPSUM.split(" "):
|
119
108
|
>>> yield word + " "
|
120
109
|
>>> time.sleep(0.02)
|
121
110
|
>>>
|
@@ -133,14 +122,14 @@ class WriteMixin:
|
|
133
122
|
# not be passed in here.
|
134
123
|
if isinstance(stream, str) or type_util.is_dataframe_like(stream):
|
135
124
|
raise StreamlitAPIException(
|
136
|
-
"`st.
|
125
|
+
"`st.write_stream` expects a generator or stream-like object as input "
|
137
126
|
f"not {type(stream)}. Please use `st.write` instead for "
|
138
127
|
"this data type."
|
139
128
|
)
|
140
129
|
|
141
130
|
stream_container: DeltaGenerator | None = None
|
142
131
|
streamed_response: str = ""
|
143
|
-
written_content:
|
132
|
+
written_content: list[Any] = StreamingOutput()
|
144
133
|
|
145
134
|
def flush_stream_response():
|
146
135
|
"""Write the full response to the app."""
|
@@ -149,7 +138,7 @@ class WriteMixin:
|
|
149
138
|
|
150
139
|
if streamed_response and stream_container:
|
151
140
|
# Replace the stream_container element the full response
|
152
|
-
stream_container.
|
141
|
+
stream_container.markdown(streamed_response)
|
153
142
|
written_content.append(streamed_response)
|
154
143
|
stream_container = None
|
155
144
|
streamed_response = ""
|
@@ -168,12 +157,15 @@ class WriteMixin:
|
|
168
157
|
# Iterate through the generator and write each chunk to the app
|
169
158
|
# with a type writer effect.
|
170
159
|
for chunk in stream: # type: ignore
|
171
|
-
if type_util.
|
172
|
-
chunk, "openai.types.chat.chat_completion_chunk.ChatCompletionChunk"
|
173
|
-
):
|
160
|
+
if type_util.is_openai_chunk(chunk):
|
174
161
|
# Try to convert OpenAI chat completion chunk to a string:
|
175
162
|
try:
|
176
|
-
|
163
|
+
if len(chunk.choices) == 0:
|
164
|
+
# The choices list can be empty. E.g. when using the
|
165
|
+
# AzureOpenAI client, the first chunk will always be empty.
|
166
|
+
chunk = ""
|
167
|
+
else:
|
168
|
+
chunk = chunk.choices[0].delta.content or ""
|
177
169
|
except AttributeError as err:
|
178
170
|
raise StreamlitAPIException(
|
179
171
|
"Failed to parse the OpenAI ChatCompletionChunk. "
|
@@ -203,7 +195,7 @@ class WriteMixin:
|
|
203
195
|
first_text = True
|
204
196
|
streamed_response += chunk
|
205
197
|
# Only add the streaming symbol on the second text chunk
|
206
|
-
stream_container.
|
198
|
+
stream_container.markdown(
|
207
199
|
streamed_response + ("" if first_text else _TEXT_CURSOR),
|
208
200
|
)
|
209
201
|
elif callable(chunk):
|
@@ -346,7 +338,7 @@ class WriteMixin:
|
|
346
338
|
kwargs,
|
347
339
|
)
|
348
340
|
|
349
|
-
string_buffer:
|
341
|
+
string_buffer: list[str] = []
|
350
342
|
|
351
343
|
# This bans some valid cases like: e = st.empty(); e.write("a", "b").
|
352
344
|
# BUT: 1) such cases are rare, 2) this rule is easy to understand,
|
@@ -476,6 +468,6 @@ class WriteMixin:
|
|
476
468
|
flush_buffer()
|
477
469
|
|
478
470
|
@property
|
479
|
-
def dg(self) ->
|
471
|
+
def dg(self) -> DeltaGenerator:
|
480
472
|
"""Get our DeltaGenerator."""
|
481
473
|
return cast("DeltaGenerator", self)
|
streamlit/env_util.py
CHANGED
@@ -12,6 +12,8 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
15
17
|
import os
|
16
18
|
import platform
|
17
19
|
import re
|
@@ -23,7 +25,7 @@ IS_DARWIN = _system == "Darwin"
|
|
23
25
|
IS_LINUX_OR_BSD = (_system == "Linux") or ("BSD" in _system)
|
24
26
|
|
25
27
|
|
26
|
-
def is_pex():
|
28
|
+
def is_pex() -> bool:
|
27
29
|
"""Return if streamlit running in pex.
|
28
30
|
|
29
31
|
Pex modifies sys.path so the pex file is the first path and that's
|
@@ -34,7 +36,7 @@ def is_pex():
|
|
34
36
|
return False
|
35
37
|
|
36
38
|
|
37
|
-
def is_repl():
|
39
|
+
def is_repl() -> bool:
|
38
40
|
"""Return True if running in the Python REPL."""
|
39
41
|
import inspect
|
40
42
|
|
@@ -52,7 +54,7 @@ def is_repl():
|
|
52
54
|
return False
|
53
55
|
|
54
56
|
|
55
|
-
def is_executable_in_path(name):
|
57
|
+
def is_executable_in_path(name: str) -> bool:
|
56
58
|
"""Check if executable is in OS path."""
|
57
59
|
from shutil import which
|
58
60
|
|
streamlit/error_util.py
CHANGED
@@ -12,15 +12,19 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
from typing import Final
|
18
|
+
|
15
19
|
import streamlit as st
|
16
20
|
from streamlit import config
|
17
21
|
from streamlit.errors import UncaughtAppException
|
18
22
|
from streamlit.logger import get_logger
|
19
23
|
|
20
|
-
_LOGGER = get_logger(__name__)
|
24
|
+
_LOGGER: Final = get_logger(__name__)
|
21
25
|
|
22
26
|
|
23
|
-
def _print_rich_exception(e: BaseException):
|
27
|
+
def _print_rich_exception(e: BaseException) -> None:
|
24
28
|
from rich import box, panel
|
25
29
|
|
26
30
|
# Monkey patch the panel to use our custom box style
|
@@ -31,7 +35,7 @@ def _print_rich_exception(e: BaseException):
|
|
31
35
|
box=box.Box("────\n \n────\n \n────\n────\n \n────\n"),
|
32
36
|
**kwargs,
|
33
37
|
):
|
34
|
-
super(
|
38
|
+
super().__init__(renderable, box, **kwargs)
|
35
39
|
|
36
40
|
from rich import traceback as rich_traceback
|
37
41
|
|
streamlit/errors.py
CHANGED
@@ -12,6 +12,8 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
15
17
|
from streamlit import util
|
16
18
|
|
17
19
|
|
@@ -89,7 +91,7 @@ class StreamlitAPIWarning(StreamlitAPIException, Warning):
|
|
89
91
|
"""
|
90
92
|
|
91
93
|
def __init__(self, *args):
|
92
|
-
super(
|
94
|
+
super().__init__(*args)
|
93
95
|
import inspect
|
94
96
|
import traceback
|
95
97
|
|