streamlit-nightly 1.45.2.dev20250522__py3-none-any.whl → 1.45.2.dev20250526__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/commands/echo.py +1 -1
- streamlit/config.py +2 -1
- streamlit/config_option.py +1 -1
- streamlit/config_util.py +4 -5
- streamlit/delta_generator.py +21 -0
- streamlit/elements/arrow.py +19 -0
- streamlit/elements/code.py +11 -10
- streamlit/elements/exception.py +4 -12
- streamlit/elements/graphviz_chart.py +1 -1
- streamlit/elements/heading.py +3 -4
- streamlit/elements/lib/built_in_chart_utils.py +19 -0
- streamlit/elements/lib/image_utils.py +2 -3
- streamlit/elements/lib/layout_utils.py +41 -1
- streamlit/elements/markdown.py +1 -1
- streamlit/elements/media.py +1 -1
- streamlit/elements/progress.py +3 -3
- streamlit/elements/vega_charts.py +5 -0
- streamlit/elements/widgets/button.py +1 -1
- streamlit/elements/widgets/color_picker.py +8 -14
- streamlit/elements/widgets/radio.py +1 -1
- streamlit/elements/widgets/selectbox.py +1 -1
- streamlit/elements/widgets/slider.py +10 -18
- streamlit/elements/widgets/text_widgets.py +1 -2
- streamlit/errors.py +15 -0
- streamlit/hello/animation_demo.py +1 -1
- streamlit/hello/mapping_demo.py +3 -4
- streamlit/logger.py +1 -1
- streamlit/proto/Block_pb2.py +32 -32
- streamlit/proto/Block_pb2.pyi +22 -10
- streamlit/proto/Code_pb2.py +5 -3
- streamlit/proto/Code_pb2.pyi +2 -9
- streamlit/proto/Element_pb2.py +5 -3
- streamlit/proto/Element_pb2.pyi +20 -3
- streamlit/runtime/caching/hashing.py +8 -9
- streamlit/runtime/credentials.py +8 -21
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.CudC4cnG.js → ErrorOutline.esm.CtshIbC5.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.qn_AyTtU.js → FileDownload.esm.A0XrMp_A.js} +1 -1
- streamlit/static/static/js/{FileHelper.BWuvkxif.js → FileHelper.BkYmOfR4.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.CHYZBZGR.js → FormClearHelper.DvUrjO5s.js} +1 -1
- streamlit/static/static/js/{Hooks.aQtyO1Es.js → Hooks.Dw0PPeMp.js} +1 -1
- streamlit/static/static/js/{InputInstructions.u4jPRzPB.js → InputInstructions.BwkpOG-3.js} +1 -1
- streamlit/static/static/js/{ProgressBar.CG44OwiE.js → ProgressBar.Po8toa5U.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.VXXdANh0.js → RenderInPortalIfExists.DG7izwhP.js} +1 -1
- streamlit/static/static/js/{Toolbar.e8AKFI20.js → Toolbar.zoRxypF9.js} +1 -1
- streamlit/static/static/js/{base-input.D7ucWcOg.js → base-input.3hmq5vR4.js} +1 -1
- streamlit/static/static/js/{checkbox.B9R-wnB7.js → checkbox.DHVebTBP.js} +1 -1
- streamlit/static/static/js/{createSuper.C1ofFeAG.js → createSuper.CCzF882j.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.DtdlN29o.js → data-grid-overlay-editor.CRIS0V5u.js} +1 -1
- streamlit/static/static/js/{downloader.amlkJvLF.js → downloader.DOuJ7F43.js} +1 -1
- streamlit/static/static/js/{es6.Bx1hXnS0.js → es6.BojNhy97.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.DgHMAYbI.js → iframeResizer.contentWindow.CmN7IDO7.js} +1 -1
- streamlit/static/static/js/{index.7CBT51EL.js → index.3HscCA0Q.js} +1 -1
- streamlit/static/static/js/{index.N0sZYfFM.js → index.B0GUCtHl.js} +1 -1
- streamlit/static/static/js/{index.DlKdkJEq.js → index.B3Y99Usz.js} +1 -1
- streamlit/static/static/js/{index.CQRM5-Cg.js → index.B6guKn0h.js} +1 -1
- streamlit/static/static/js/{index.DZf_kpi0.js → index.BEfxU01i.js} +1 -1
- streamlit/static/static/js/{index.Yu7J_Dze.js → index.BMWx_YQD.js} +1 -1
- streamlit/static/static/js/{index.DQ5EXoB_.js → index.BV-8GugV.js} +1 -1
- streamlit/static/static/js/{index.BqEJFCLf.js → index.BXfm7UZe.js} +1 -1
- streamlit/static/static/js/{index.DE1gGOzc.js → index.BfcdLS9y.js} +1 -1
- streamlit/static/static/js/{index.D5GJYvYX.js → index.BgmEuudT.js} +1 -1
- streamlit/static/static/js/{index.BdDyuQmj.js → index.BsiojTxz.js} +1 -1
- streamlit/static/static/js/{index.Bn5K9Bd_.js → index.BvWDoWjf.js} +1 -1
- streamlit/static/static/js/{index.1mfAtb9U.js → index.CLFnBokZ.js} +1 -1
- streamlit/static/static/js/{index.C3vs9CpH.js → index.CPiByGGr.js} +1 -1
- streamlit/static/static/js/{index.DUennCN8.js → index.CTVSiPCo.js} +1 -1
- streamlit/static/static/js/{index.BmoykTHR.js → index.CVxkW_lc.js} +1 -1
- streamlit/static/static/js/{index.C0T_M4GD.js → index.CWweAMBx.js} +1 -1
- streamlit/static/static/js/{index.VzRep4kY.js → index.CZ6f-p0K.js} +1 -1
- streamlit/static/static/js/{index.BtNqOUEO.js → index.CdgLDqMc.js} +1 -1
- streamlit/static/static/js/{index.D08mj5Od.js → index.Cpz3pp0B.js} +1 -1
- streamlit/static/static/js/{index.DN4Mx7FE.js → index.CzMgwzgb.js} +1 -1
- streamlit/static/static/js/{index.CYHkBSAi.js → index.DH2YAEv6.js} +1 -1
- streamlit/static/static/js/{index.BD_oIhGF.js → index.DNlMgaSP.js} +1 -1
- streamlit/static/static/js/{index.DiBs3xkT.js → index.DP7RHJHC.js} +1 -1
- streamlit/static/static/js/{index.CMLTPeKt.js → index.DcLQo3NB.js} +5 -5
- streamlit/static/static/js/{index.BWuE2_HE.js → index.DkNaEiLi.js} +1 -1
- streamlit/static/static/js/{index.Bdy3ZPdq.js → index.DtpZrdsz.js} +1 -1
- streamlit/static/static/js/{index.B8eTe00V.js → index.HdiDLe37.js} +1 -1
- streamlit/static/static/js/{index.CNh3_B-b.js → index.Ih0EXMso.js} +1 -1
- streamlit/static/static/js/{index.BaaFPBjg.js → index.R5J-UXhx.js} +1 -1
- streamlit/static/static/js/{index.Bna1CU8i.js → index.VVmp3qV7.js} +1 -1
- streamlit/static/static/js/{index.D97xl78q.js → index.YePOPnW6.js} +11 -11
- streamlit/static/static/js/{index.BgTPKzvI.js → index.YtwVjbe-.js} +1 -1
- streamlit/static/static/js/{index.Bon8EwWL.js → index.kWUcv9pK.js} +1 -1
- streamlit/static/static/js/{index.DNwNuLWE.js → index.muQ-sA7D.js} +1 -1
- streamlit/static/static/js/{index.DxHtKYyS.js → index.p5qVS5RU.js} +1 -1
- streamlit/static/static/js/{index.Or4BfcX_.js → index.whcmqOYZ.js} +1 -1
- streamlit/static/static/js/{input.CRcaB9oP.js → input.C95vVzrH.js} +1 -1
- streamlit/static/static/js/{memory.F9D6Oyjj.js → memory.lfILky3m.js} +1 -1
- streamlit/static/static/js/{mergeWith.BYtZfcmi.js → mergeWith.CdpKbzWl.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.ClWmQbhW.js → number-overlay-editor.D2TjUrKf.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.BHxvTsgt.js → possibleConstructorReturn.DQV58bYB.js} +1 -1
- streamlit/static/static/js/{sandbox.9HJbznr2.js → sandbox.R1dhBCnm.js} +1 -1
- streamlit/static/static/js/{textarea.MC6GQYce.js → textarea.t5D4QCw3.js} +1 -1
- streamlit/static/static/js/{timepicker.BJLSDuQc.js → timepicker.BI9iPIxz.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.BxOYujrG.js → toConsumableArray.COyXrPhy.js} +1 -1
- streamlit/static/static/js/{uniqueId.nweXvThW.js → uniqueId.CaWObuU_.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.ByOGmtKn.js → useBasicWidgetState.Wd2TSACf.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.oE3yUL9n.js → useOnInputChange.CUFXty-S.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.Cg-VqiDm.js → withFullScreenWrapper.wgkD5MeK.js} +1 -1
- streamlit/watcher/path_watcher.py +2 -3
- streamlit/web/bootstrap.py +1 -1
- streamlit/web/server/server.py +1 -1
- {streamlit_nightly-1.45.2.dev20250522.dist-info → streamlit_nightly-1.45.2.dev20250526.dist-info}/METADATA +3 -3
- {streamlit_nightly-1.45.2.dev20250522.dist-info → streamlit_nightly-1.45.2.dev20250526.dist-info}/RECORD +111 -111
- {streamlit_nightly-1.45.2.dev20250522.dist-info → streamlit_nightly-1.45.2.dev20250526.dist-info}/WHEEL +1 -1
- {streamlit_nightly-1.45.2.dev20250522.data → streamlit_nightly-1.45.2.dev20250526.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.2.dev20250522.dist-info → streamlit_nightly-1.45.2.dev20250526.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.2.dev20250522.dist-info → streamlit_nightly-1.45.2.dev20250526.dist-info}/top_level.txt +0 -0
streamlit/commands/echo.py
CHANGED
@@ -101,7 +101,7 @@ def echo(
|
|
101
101
|
show_code(code_string, "python")
|
102
102
|
|
103
103
|
except FileNotFoundError as err:
|
104
|
-
show_warning("Unable to display code.
|
104
|
+
show_warning(f"Unable to display code. {err}")
|
105
105
|
|
106
106
|
|
107
107
|
def _get_initial_indent(lines: Iterable[str]) -> int:
|
streamlit/config.py
CHANGED
@@ -1301,7 +1301,8 @@ def get_where_defined(key: str) -> str:
|
|
1301
1301
|
config_options = get_config_options()
|
1302
1302
|
|
1303
1303
|
if key not in config_options:
|
1304
|
-
|
1304
|
+
msg = f'Config key "{key}" not defined.'
|
1305
|
+
raise RuntimeError(msg)
|
1305
1306
|
return config_options[key].where_defined
|
1306
1307
|
|
1307
1308
|
|
streamlit/config_option.py
CHANGED
@@ -189,7 +189,7 @@ class ConfigOption:
|
|
189
189
|
if self.replaced_by:
|
190
190
|
self.deprecated = True
|
191
191
|
if deprecation_text is None:
|
192
|
-
deprecation_text = "Replaced by
|
192
|
+
deprecation_text = f"Replaced by {self.replaced_by}."
|
193
193
|
|
194
194
|
if self.deprecated:
|
195
195
|
if not expiration_date:
|
streamlit/config_util.py
CHANGED
@@ -84,7 +84,7 @@ def show_config(
|
|
84
84
|
continue
|
85
85
|
|
86
86
|
out.append("")
|
87
|
-
append_section("[
|
87
|
+
append_section(f"[{section}]")
|
88
88
|
out.append("")
|
89
89
|
|
90
90
|
for option in section_options.values():
|
@@ -125,8 +125,7 @@ def show_config(
|
|
125
125
|
append_comment(line)
|
126
126
|
append_comment("")
|
127
127
|
append_comment(
|
128
|
-
"This option will be removed on or after
|
129
|
-
% option.expiration_date
|
128
|
+
f"This option will be removed on or after {option.expiration_date}."
|
130
129
|
)
|
131
130
|
|
132
131
|
import toml
|
@@ -138,7 +137,7 @@ def show_config(
|
|
138
137
|
# Ensure a line break before appending "Default" comment, if not already there
|
139
138
|
if out[-1] != "#":
|
140
139
|
append_comment("")
|
141
|
-
append_comment("Default:
|
140
|
+
append_comment(f"Default: {toml_default}")
|
142
141
|
else:
|
143
142
|
# Don't say "Default: (unset)" here because this branch applies
|
144
143
|
# to complex config settings too.
|
@@ -151,7 +150,7 @@ def show_config(
|
|
151
150
|
if option_is_manually_set:
|
152
151
|
if out[-1] != "# ":
|
153
152
|
append_comment("")
|
154
|
-
append_comment("The value below was set in
|
153
|
+
append_comment(f"The value below was set in {option.where_defined}")
|
155
154
|
|
156
155
|
toml_setting = toml.dumps({key: option.value})
|
157
156
|
|
streamlit/delta_generator.py
CHANGED
@@ -106,6 +106,7 @@ if TYPE_CHECKING:
|
|
106
106
|
|
107
107
|
from streamlit.cursor import Cursor
|
108
108
|
from streamlit.elements.lib.built_in_chart_utils import AddRowsMetadata
|
109
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig
|
109
110
|
|
110
111
|
MAX_DELTA_BYTES: Final[int] = 14 * 1024 * 1024 # 14MB
|
111
112
|
|
@@ -437,6 +438,7 @@ class DeltaGenerator(
|
|
437
438
|
delta_type: str,
|
438
439
|
element_proto: Message,
|
439
440
|
add_rows_metadata: AddRowsMetadata | None = None,
|
441
|
+
layout_config: LayoutConfig | None = None,
|
440
442
|
) -> DeltaGenerator:
|
441
443
|
"""Create NewElement delta, fill it, and enqueue it.
|
442
444
|
|
@@ -476,6 +478,25 @@ class DeltaGenerator(
|
|
476
478
|
msg_el_proto = getattr(msg.delta.new_element, delta_type)
|
477
479
|
msg_el_proto.CopyFrom(element_proto)
|
478
480
|
|
481
|
+
if layout_config:
|
482
|
+
if layout_config.height:
|
483
|
+
if isinstance(layout_config.height, int):
|
484
|
+
msg.delta.new_element.height_config.pixel_height = (
|
485
|
+
layout_config.height
|
486
|
+
)
|
487
|
+
elif layout_config.height == "content":
|
488
|
+
msg.delta.new_element.height_config.use_content = True
|
489
|
+
else:
|
490
|
+
msg.delta.new_element.height_config.use_stretch = True
|
491
|
+
|
492
|
+
if layout_config.width:
|
493
|
+
if isinstance(layout_config.width, int):
|
494
|
+
msg.delta.new_element.width_config.pixel_width = layout_config.width
|
495
|
+
elif layout_config.width == "content":
|
496
|
+
msg.delta.new_element.width_config.use_content = True
|
497
|
+
else:
|
498
|
+
msg.delta.new_element.width_config.use_stretch = True
|
499
|
+
|
479
500
|
# Only enqueue message and fill in metadata if there's a container.
|
480
501
|
msg_was_enqueued = False
|
481
502
|
if dg._root_container is not None and dg._cursor is not None:
|
streamlit/elements/arrow.py
CHANGED
@@ -908,6 +908,25 @@ def _arrow_add_rows(
|
|
908
908
|
and dg._cursor.props["add_rows_metadata"].last_index is None
|
909
909
|
):
|
910
910
|
st_method = getattr(dg, dg._cursor.props["add_rows_metadata"].chart_command)
|
911
|
+
metadata = dg._cursor.props["add_rows_metadata"]
|
912
|
+
|
913
|
+
# Pass the styling properties stored in add_rows_metadata
|
914
|
+
# to the new element call.
|
915
|
+
kwargs = {}
|
916
|
+
if metadata.color is not None:
|
917
|
+
kwargs["color"] = metadata.color
|
918
|
+
if metadata.width is not None:
|
919
|
+
kwargs["width"] = metadata.width
|
920
|
+
if metadata.height is not None:
|
921
|
+
kwargs["height"] = metadata.height
|
922
|
+
if metadata.stack is not None:
|
923
|
+
kwargs["stack"] = metadata.stack
|
924
|
+
|
925
|
+
if metadata.chart_command == "bar_chart":
|
926
|
+
kwargs["horizontal"] = metadata.horizontal
|
927
|
+
|
928
|
+
kwargs["use_container_width"] = metadata.use_container_width
|
929
|
+
|
911
930
|
st_method(data, **kwargs)
|
912
931
|
return None
|
913
932
|
|
streamlit/elements/code.py
CHANGED
@@ -16,7 +16,13 @@ from __future__ import annotations
|
|
16
16
|
|
17
17
|
from typing import TYPE_CHECKING, cast
|
18
18
|
|
19
|
-
from streamlit.elements.lib.layout_utils import
|
19
|
+
from streamlit.elements.lib.layout_utils import (
|
20
|
+
Height,
|
21
|
+
LayoutConfig,
|
22
|
+
WidthWithoutContent,
|
23
|
+
validate_height,
|
24
|
+
validate_width,
|
25
|
+
)
|
20
26
|
from streamlit.proto.Code_pb2 import Code as CodeProto
|
21
27
|
from streamlit.runtime.metrics_util import gather_metrics
|
22
28
|
from streamlit.string_util import clean_text
|
@@ -35,7 +41,7 @@ class CodeMixin:
|
|
35
41
|
*,
|
36
42
|
line_numbers: bool = False,
|
37
43
|
wrap_lines: bool = False,
|
38
|
-
height:
|
44
|
+
height: Height = "content",
|
39
45
|
width: WidthWithoutContent = "stretch",
|
40
46
|
) -> DeltaGenerator:
|
41
47
|
"""Display a code block with optional syntax highlighting.
|
@@ -111,17 +117,12 @@ class CodeMixin:
|
|
111
117
|
code_proto.language = language or "plaintext"
|
112
118
|
code_proto.show_line_numbers = line_numbers
|
113
119
|
code_proto.wrap_lines = wrap_lines
|
114
|
-
if height:
|
115
|
-
code_proto.height = height
|
116
120
|
|
117
|
-
|
121
|
+
validate_height(height, allow_content=True)
|
118
122
|
validate_width(width)
|
119
|
-
|
120
|
-
code_proto.width_config.pixel_width = width
|
121
|
-
else:
|
122
|
-
code_proto.width_config.use_stretch = True
|
123
|
+
layout_config = LayoutConfig(height=height, width=width)
|
123
124
|
|
124
|
-
return self.dg._enqueue("code", code_proto)
|
125
|
+
return self.dg._enqueue("code", code_proto, layout_config=layout_config)
|
125
126
|
|
126
127
|
@property
|
127
128
|
def dg(self) -> DeltaGenerator:
|
streamlit/elements/exception.py
CHANGED
@@ -237,18 +237,10 @@ def _format_syntax_error_message(exception: SyntaxError) -> str:
|
|
237
237
|
)
|
238
238
|
|
239
239
|
return (
|
240
|
-
'File "
|
241
|
-
"
|
242
|
-
"
|
243
|
-
"
|
244
|
-
% {
|
245
|
-
"filename": exception.filename,
|
246
|
-
"lineno": exception.lineno,
|
247
|
-
"text": exception.text.rstrip(),
|
248
|
-
"caret_indent": caret_indent,
|
249
|
-
"errname": type(exception).__name__,
|
250
|
-
"msg": exception.msg,
|
251
|
-
}
|
240
|
+
f'File "{exception.filename}", line {exception.lineno}\n'
|
241
|
+
f" {exception.text.rstrip()}\n"
|
242
|
+
f" {caret_indent}^\n"
|
243
|
+
f"{type(exception).__name__}: {exception.msg}"
|
252
244
|
)
|
253
245
|
# If a few edge cases, SyntaxErrors don't have all these nice fields. So we
|
254
246
|
# have a fall back here.
|
streamlit/elements/heading.py
CHANGED
@@ -286,14 +286,13 @@ class HeadingMixin:
|
|
286
286
|
proto.anchor = anchor
|
287
287
|
elif anchor is True: # type: ignore
|
288
288
|
raise StreamlitAPIException(
|
289
|
-
"Anchor parameter has invalid value:
|
290
|
-
"Supported values: None, any string or False"
|
289
|
+
f"Anchor parameter has invalid value: {anchor}. "
|
290
|
+
"Supported values: None, any string or False"
|
291
291
|
)
|
292
292
|
else:
|
293
293
|
raise StreamlitAPIException(
|
294
|
-
"Anchor parameter has invalid type:
|
294
|
+
f"Anchor parameter has invalid type: {type(anchor).__name__}. "
|
295
295
|
"Supported values: None, any string or False"
|
296
|
-
% type(anchor).__name__
|
297
296
|
)
|
298
297
|
|
299
298
|
if help:
|
@@ -71,6 +71,15 @@ class AddRowsMetadata:
|
|
71
71
|
chart_command: str
|
72
72
|
last_index: Hashable | None
|
73
73
|
columns: PrepDataColumns
|
74
|
+
# Chart styling properties
|
75
|
+
color: str | Color | list[Color] | None = None
|
76
|
+
width: int | None = None
|
77
|
+
height: int | None = None
|
78
|
+
use_container_width: bool = True
|
79
|
+
# Only applicable for bar & area charts
|
80
|
+
stack: bool | ChartStackType | None = None
|
81
|
+
# Only applicable for bar charts
|
82
|
+
horizontal: bool = False
|
74
83
|
|
75
84
|
|
76
85
|
class ChartType(Enum):
|
@@ -147,8 +156,11 @@ def generate_chart(
|
|
147
156
|
size_from_user: str | float | None = None,
|
148
157
|
width: int | None = None,
|
149
158
|
height: int | None = None,
|
159
|
+
use_container_width: bool = True,
|
150
160
|
# Bar & Area charts only:
|
151
161
|
stack: bool | ChartStackType | None = None,
|
162
|
+
# Bar charts only:
|
163
|
+
horizontal: bool = False,
|
152
164
|
) -> tuple[alt.Chart | alt.LayerChart, AddRowsMetadata]:
|
153
165
|
"""Function to use the chart's type, data columns and indices to figure out the
|
154
166
|
chart's spec.
|
@@ -186,6 +198,13 @@ def generate_chart(
|
|
186
198
|
"color_column": color_column,
|
187
199
|
"size_column": size_column,
|
188
200
|
},
|
201
|
+
# Chart styling properties
|
202
|
+
color=color_from_user,
|
203
|
+
width=width,
|
204
|
+
height=height,
|
205
|
+
use_container_width=use_container_width,
|
206
|
+
stack=stack,
|
207
|
+
horizontal=horizontal,
|
189
208
|
)
|
190
209
|
|
191
210
|
# At this point, all foo_column variables are either None/empty or contain actual
|
@@ -160,8 +160,7 @@ def _verify_np_shape(array: npt.NDArray[Any]) -> npt.NDArray[Any]:
|
|
160
160
|
raise StreamlitAPIException("Numpy shape has to be of length 2 or 3.")
|
161
161
|
if len(shape) == 3 and shape[-1] not in (1, 3, 4):
|
162
162
|
raise StreamlitAPIException(
|
163
|
-
"Channel can only be 1, 3, or 4 got
|
164
|
-
% (shape[-1], str(shape))
|
163
|
+
f"Channel can only be 1, 3, or 4 got {shape[-1]}. Shape is {shape}"
|
165
164
|
)
|
166
165
|
|
167
166
|
# If there's only one channel, convert is to x, y
|
@@ -437,7 +436,7 @@ def marshall_images(
|
|
437
436
|
|
438
437
|
# We use the index of the image in the input image list to identify this image inside
|
439
438
|
# MediaFileManager. For this, we just add the index to the image's "coordinates".
|
440
|
-
image_id = "
|
439
|
+
image_id = f"{coordinates}-{coord_suffix}"
|
441
440
|
|
442
441
|
proto_img.url = image_to_url(
|
443
442
|
single_image, width, clamp, channels, output_format, image_id
|
@@ -11,15 +11,25 @@
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
|
+
from __future__ import annotations
|
14
15
|
|
16
|
+
from dataclasses import dataclass
|
15
17
|
from typing import Literal, Union
|
16
18
|
|
17
19
|
from typing_extensions import TypeAlias
|
18
20
|
|
19
|
-
from streamlit.errors import StreamlitInvalidWidthError
|
21
|
+
from streamlit.errors import StreamlitInvalidHeightError, StreamlitInvalidWidthError
|
20
22
|
|
21
23
|
WidthWithoutContent: TypeAlias = Union[int, Literal["stretch"]]
|
22
24
|
Width: TypeAlias = Union[int, Literal["stretch", "content"]]
|
25
|
+
HeightWithoutContent: TypeAlias = Union[int, Literal["stretch"]]
|
26
|
+
Height: TypeAlias = Union[int, Literal["stretch", "content"]]
|
27
|
+
|
28
|
+
|
29
|
+
@dataclass
|
30
|
+
class LayoutConfig:
|
31
|
+
width: Width | None = None
|
32
|
+
height: Height | None = None
|
23
33
|
|
24
34
|
|
25
35
|
def validate_width(width: Width, allow_content: bool = False) -> None:
|
@@ -49,3 +59,33 @@ def validate_width(width: Width, allow_content: bool = False) -> None:
|
|
49
59
|
raise StreamlitInvalidWidthError(width, allow_content)
|
50
60
|
elif width <= 0:
|
51
61
|
raise StreamlitInvalidWidthError(width, allow_content)
|
62
|
+
|
63
|
+
|
64
|
+
def validate_height(height: Height, allow_content: bool = False) -> None:
|
65
|
+
"""Validate the height parameter.
|
66
|
+
|
67
|
+
Parameters
|
68
|
+
----------
|
69
|
+
height : Any
|
70
|
+
The height value to validate.
|
71
|
+
allow_content : bool
|
72
|
+
Whether to allow "content" as a valid height value.
|
73
|
+
|
74
|
+
Raises
|
75
|
+
------
|
76
|
+
StreamlitInvalidHeightError
|
77
|
+
If the height value is invalid.
|
78
|
+
"""
|
79
|
+
if not isinstance(height, (int, str)):
|
80
|
+
raise StreamlitInvalidHeightError(height, allow_content)
|
81
|
+
|
82
|
+
if isinstance(height, str):
|
83
|
+
valid_strings = ["stretch"]
|
84
|
+
if allow_content:
|
85
|
+
valid_strings.append("content")
|
86
|
+
|
87
|
+
if height not in valid_strings:
|
88
|
+
raise StreamlitInvalidHeightError(height, allow_content)
|
89
|
+
|
90
|
+
elif height <= 0:
|
91
|
+
raise StreamlitInvalidHeightError(height, allow_content)
|
streamlit/elements/markdown.py
CHANGED
@@ -252,7 +252,7 @@ class MarkdownMixin:
|
|
252
252
|
body = sympy.latex(body)
|
253
253
|
|
254
254
|
latex_proto = MarkdownProto()
|
255
|
-
latex_proto.body = "$$\n
|
255
|
+
latex_proto.body = f"$$\n{clean_text(body)}\n$$"
|
256
256
|
latex_proto.element_type = MarkdownProto.Type.LATEX
|
257
257
|
if help:
|
258
258
|
latex_proto.help = help
|
streamlit/elements/media.py
CHANGED
@@ -478,7 +478,7 @@ def _marshall_av_media(
|
|
478
478
|
elif type_util.is_type(data, "numpy.ndarray"):
|
479
479
|
data_or_filename = cast("npt.NDArray[Any]", data).tobytes()
|
480
480
|
else:
|
481
|
-
raise RuntimeError("Invalid binary data format:
|
481
|
+
raise RuntimeError(f"Invalid binary data format: {type(data)}")
|
482
482
|
|
483
483
|
if runtime.exists():
|
484
484
|
file_url = runtime.get_instance().media_file_mgr.add(
|
streamlit/elements/progress.py
CHANGED
@@ -66,17 +66,17 @@ def _get_value(value: FloatOrInt) -> int:
|
|
66
66
|
if 0 <= value <= 100:
|
67
67
|
return value
|
68
68
|
raise StreamlitAPIException(
|
69
|
-
"Progress Value has invalid value [0, 100]:
|
69
|
+
f"Progress Value has invalid value [0, 100]: {value}"
|
70
70
|
)
|
71
71
|
|
72
72
|
if isinstance(value, float):
|
73
73
|
if _check_float_between(value, low=0.0, high=1.0):
|
74
74
|
return int(value * 100)
|
75
75
|
raise StreamlitAPIException(
|
76
|
-
"Progress Value has invalid value [0.0, 1.0]:
|
76
|
+
f"Progress Value has invalid value [0.0, 1.0]: {value}"
|
77
77
|
)
|
78
78
|
raise StreamlitAPIException(
|
79
|
-
"Progress Value has invalid type:
|
79
|
+
f"Progress Value has invalid type: {type(value).__name__}"
|
80
80
|
)
|
81
81
|
|
82
82
|
|
@@ -742,6 +742,7 @@ class VegaChartsMixin:
|
|
742
742
|
size_from_user=None,
|
743
743
|
width=width,
|
744
744
|
height=height,
|
745
|
+
use_container_width=use_container_width,
|
745
746
|
)
|
746
747
|
return cast(
|
747
748
|
"DeltaGenerator",
|
@@ -983,6 +984,7 @@ class VegaChartsMixin:
|
|
983
984
|
width=width,
|
984
985
|
height=height,
|
985
986
|
stack=stack,
|
987
|
+
use_container_width=use_container_width,
|
986
988
|
)
|
987
989
|
return cast(
|
988
990
|
"DeltaGenerator",
|
@@ -1248,7 +1250,9 @@ class VegaChartsMixin:
|
|
1248
1250
|
size_from_user=None,
|
1249
1251
|
width=width,
|
1250
1252
|
height=height,
|
1253
|
+
use_container_width=use_container_width,
|
1251
1254
|
stack=stack,
|
1255
|
+
horizontal=horizontal,
|
1252
1256
|
)
|
1253
1257
|
return cast(
|
1254
1258
|
"DeltaGenerator",
|
@@ -1459,6 +1463,7 @@ class VegaChartsMixin:
|
|
1459
1463
|
size_from_user=size,
|
1460
1464
|
width=width,
|
1461
1465
|
height=height,
|
1466
|
+
use_container_width=use_container_width,
|
1462
1467
|
)
|
1463
1468
|
return cast(
|
1464
1469
|
"DeltaGenerator",
|
@@ -1105,7 +1105,7 @@ def marshall_file(
|
|
1105
1105
|
data_as_bytes = data.read() or b""
|
1106
1106
|
mimetype = mimetype or "application/octet-stream"
|
1107
1107
|
else:
|
1108
|
-
raise StreamlitAPIException("Invalid binary data format:
|
1108
|
+
raise StreamlitAPIException(f"Invalid binary data format: {type(data)}")
|
1109
1109
|
|
1110
1110
|
if runtime.exists():
|
1111
1111
|
file_url = runtime.get_instance().media_file_mgr.add(
|
@@ -206,25 +206,19 @@ class ColorPickerMixin:
|
|
206
206
|
|
207
207
|
# make sure the value is a string
|
208
208
|
if not isinstance(value, str):
|
209
|
-
raise StreamlitAPIException(
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
"""
|
214
|
-
% type(value).__name__
|
215
|
-
)
|
209
|
+
raise StreamlitAPIException(f"""
|
210
|
+
Color Picker Value has invalid type: {type(value).__name__}. Expects a hex string
|
211
|
+
like '#00FFAA' or '#000'.
|
212
|
+
""")
|
216
213
|
|
217
214
|
# validate the value and expects a hex string
|
218
215
|
match = re.match(r"^#(?:[0-9a-fA-F]{3}){1,2}$", value)
|
219
216
|
|
220
217
|
if not match:
|
221
|
-
raise StreamlitAPIException(
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
"""
|
226
|
-
% value
|
227
|
-
)
|
218
|
+
raise StreamlitAPIException(f"""
|
219
|
+
'{value}' is not a valid hex code for colors. Valid ones are like
|
220
|
+
'#00FFAA' or '#000'.
|
221
|
+
""")
|
228
222
|
|
229
223
|
color_picker_proto = ColorPickerProto()
|
230
224
|
color_picker_proto.id = element_id
|
@@ -351,7 +351,7 @@ class RadioMixin:
|
|
351
351
|
|
352
352
|
if not isinstance(index, int) and index is not None:
|
353
353
|
raise StreamlitAPIException(
|
354
|
-
"Radio Value has invalid type:
|
354
|
+
f"Radio Value has invalid type: {type(index).__name__}"
|
355
355
|
)
|
356
356
|
|
357
357
|
if index is not None and len(opt) > 0 and not 0 <= index < len(opt):
|
@@ -495,7 +495,7 @@ class SelectboxMixin:
|
|
495
495
|
|
496
496
|
if not isinstance(index, int) and index is not None:
|
497
497
|
raise StreamlitAPIException(
|
498
|
-
"Selectbox Value has invalid type:
|
498
|
+
f"Selectbox Value has invalid type: {type(index).__name__}"
|
499
499
|
)
|
500
500
|
|
501
501
|
if index is not None and len(opt) > 0 and not 0 <= index < len(opt):
|
@@ -813,17 +813,13 @@ class SliderMixin:
|
|
813
813
|
)
|
814
814
|
|
815
815
|
if not int_args and not float_args and not timelike_args:
|
816
|
-
|
816
|
+
msg = (
|
817
817
|
"Slider value arguments must be of matching types."
|
818
|
-
"\n`min_value` has
|
819
|
-
"\n`max_value` has
|
820
|
-
"\n`step` has
|
821
|
-
% {
|
822
|
-
"min_type": type(min_value).__name__,
|
823
|
-
"max_type": type(max_value).__name__,
|
824
|
-
"step": type(step).__name__,
|
825
|
-
}
|
818
|
+
f"\n`min_value` has {type(min_value).__name__} type."
|
819
|
+
f"\n`max_value` has {type(max_value).__name__} type."
|
820
|
+
f"\n`step` has {type(step).__name__} type."
|
826
821
|
)
|
822
|
+
raise StreamlitAPIException(msg)
|
827
823
|
|
828
824
|
# Ensure that the value matches arguments' types.
|
829
825
|
all_ints = data_type == SliderProto.INT and int_args
|
@@ -831,17 +827,13 @@ class SliderMixin:
|
|
831
827
|
all_timelikes = data_type in TIMELIKE_TYPES and timelike_args
|
832
828
|
|
833
829
|
if not all_ints and not all_floats and not all_timelikes:
|
834
|
-
|
830
|
+
msg = (
|
835
831
|
"Both value and arguments must be of the same type."
|
836
|
-
"\n`value` has
|
837
|
-
"\n`min_value` has
|
838
|
-
"\n`max_value` has
|
839
|
-
% {
|
840
|
-
"value_type": type(value).__name__,
|
841
|
-
"min_type": type(min_value).__name__,
|
842
|
-
"max_type": type(max_value).__name__,
|
843
|
-
}
|
832
|
+
f"\n`value` has {type(value).__name__} type."
|
833
|
+
f"\n`min_value` has {type(min_value).__name__} type."
|
834
|
+
f"\n`max_value` has {type(max_value).__name__} type."
|
844
835
|
)
|
836
|
+
raise StreamlitAPIException(msg)
|
845
837
|
|
846
838
|
# Ensure that min <= value(s) <= max, adjusting the bounds as necessary.
|
847
839
|
min_value = min(min_value, max_value)
|
@@ -369,8 +369,7 @@ class TextWidgetsMixin:
|
|
369
369
|
text_input_proto.type = TextInputProto.PASSWORD
|
370
370
|
else:
|
371
371
|
raise StreamlitAPIException(
|
372
|
-
"'
|
373
|
-
% type
|
372
|
+
f"'{type}' is not a valid text_input type. Valid types are 'default' and 'password'."
|
374
373
|
)
|
375
374
|
|
376
375
|
# Marshall the autocomplete param. If unspecified, this will be
|
streamlit/errors.py
CHANGED
@@ -480,3 +480,18 @@ class StreamlitInvalidWidthError(LocalizableStreamlitException):
|
|
480
480
|
width=repr(width),
|
481
481
|
valid_values=valid_values,
|
482
482
|
)
|
483
|
+
|
484
|
+
|
485
|
+
class StreamlitInvalidHeightError(LocalizableStreamlitException):
|
486
|
+
"""Exception raised when an invalid height value is provided."""
|
487
|
+
|
488
|
+
def __init__(self, height: Any, allow_content: bool = False) -> None:
|
489
|
+
valid_values = "an integer (pixels) or 'stretch'"
|
490
|
+
if allow_content:
|
491
|
+
valid_values = "an integer (pixels), 'stretch', or 'content'"
|
492
|
+
|
493
|
+
super().__init__(
|
494
|
+
"Invalid height value: {height}. Height must be either {valid_values}.",
|
495
|
+
height=repr(height),
|
496
|
+
valid_values=valid_values,
|
497
|
+
)
|
@@ -42,7 +42,7 @@ def animation_demo() -> None:
|
|
42
42
|
for frame_num, a in enumerate(np.linspace(0.0, 4 * np.pi, 100)):
|
43
43
|
# Here were setting value for these two elements.
|
44
44
|
progress_bar.progress(frame_num)
|
45
|
-
frame_text.text("Frame
|
45
|
+
frame_text.text(f"Frame {frame_num + 1}/100")
|
46
46
|
|
47
47
|
# Performing some fractal wizardry.
|
48
48
|
c = separation * np.exp(1j * a)
|
streamlit/hello/mapping_demo.py
CHANGED
@@ -26,7 +26,7 @@ def mapping_demo() -> None:
|
|
26
26
|
def from_data_file(filename: str) -> pd.DataFrame:
|
27
27
|
url = (
|
28
28
|
"https://raw.githubusercontent.com/streamlit/"
|
29
|
-
"example-data/master/hello/v1
|
29
|
+
f"example-data/master/hello/v1/{filename}"
|
30
30
|
)
|
31
31
|
return pd.read_json(url)
|
32
32
|
|
@@ -95,11 +95,10 @@ def mapping_demo() -> None:
|
|
95
95
|
st.error("Please choose at least one layer above.")
|
96
96
|
except URLError as e:
|
97
97
|
st.error(
|
98
|
-
"""
|
98
|
+
f"""
|
99
99
|
**This demo requires internet access.**
|
100
|
-
Connection error:
|
100
|
+
Connection error: {e.reason}
|
101
101
|
"""
|
102
|
-
% e.reason
|
103
102
|
)
|
104
103
|
|
105
104
|
|
streamlit/logger.py
CHANGED