streamlit-nightly 1.35.1.dev20240612__py2.py3-none-any.whl → 1.35.1.dev20240614__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/__init__.py +1 -1
- streamlit/commands/navigation.py +84 -18
- streamlit/components/v1/component_registry.py +24 -9
- streamlit/config.py +0 -3
- streamlit/elements/arrow.py +17 -6
- streamlit/elements/deck_gl_json_chart.py +1 -1
- streamlit/elements/dialog_decorator.py +5 -3
- streamlit/elements/html.py +1 -9
- streamlit/elements/iframe.py +53 -10
- streamlit/elements/layouts.py +66 -5
- streamlit/elements/lib/built_in_chart_utils.py +38 -10
- streamlit/elements/lib/column_types.py +1 -1
- streamlit/elements/lib/mutable_status_container.py +4 -4
- streamlit/elements/map.py +1 -1
- streamlit/elements/markdown.py +18 -14
- streamlit/elements/plotly_chart.py +5 -2
- streamlit/elements/toast.py +1 -1
- streamlit/elements/vega_charts.py +101 -39
- streamlit/elements/widgets/button.py +6 -3
- streamlit/elements/widgets/data_editor.py +1 -1
- streamlit/elements/widgets/file_uploader.py +1 -1
- streamlit/elements/write.py +11 -10
- streamlit/hello/Mapping_Demo.py +1 -1
- streamlit/navigation/page.py +107 -19
- streamlit/runtime/caching/cache_data_api.py +5 -4
- streamlit/runtime/caching/cache_errors.py +1 -1
- streamlit/runtime/caching/cache_resource_api.py +5 -4
- streamlit/runtime/caching/legacy_cache_api.py +13 -12
- streamlit/runtime/fragment.py +57 -27
- streamlit/runtime/runtime_util.py +1 -1
- streamlit/runtime/scriptrunner/script_run_context.py +1 -1
- streamlit/runtime/secrets.py +2 -2
- streamlit/runtime/state/session_state.py +1 -1
- streamlit/runtime/state/session_state_proxy.py +1 -1
- streamlit/static/asset-manifest.json +5 -5
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{4335.b492cdb7.chunk.js → 4335.f27a4b4a.chunk.js} +1 -1
- streamlit/static/static/js/{8427.59805a7f.chunk.js → 8427.5192ee0c.chunk.js} +1 -1
- streamlit/static/static/js/8536.f7b26b02.chunk.js +1 -0
- streamlit/static/static/js/main.7994a814.js +2 -0
- streamlit/testing/v1/app_test.py +4 -3
- streamlit/testing/v1/element_tree.py +2 -2
- streamlit/user_info.py +2 -4
- {streamlit_nightly-1.35.1.dev20240612.dist-info → streamlit_nightly-1.35.1.dev20240614.dist-info}/METADATA +9 -9
- {streamlit_nightly-1.35.1.dev20240612.dist-info → streamlit_nightly-1.35.1.dev20240614.dist-info}/RECORD +50 -50
- streamlit/static/static/js/8536.f8de3d9a.chunk.js +0 -1
- streamlit/static/static/js/main.0ebf040e.js +0 -2
- /streamlit/static/static/js/{main.0ebf040e.js.LICENSE.txt → main.7994a814.js.LICENSE.txt} +0 -0
- {streamlit_nightly-1.35.1.dev20240612.data → streamlit_nightly-1.35.1.dev20240614.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.35.1.dev20240612.dist-info → streamlit_nightly-1.35.1.dev20240614.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.35.1.dev20240612.dist-info → streamlit_nightly-1.35.1.dev20240614.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.35.1.dev20240612.dist-info → streamlit_nightly-1.35.1.dev20240614.dist-info}/top_level.txt +0 -0
streamlit/__init__.py
CHANGED
@@ -244,7 +244,7 @@ experimental_singleton = _experimental_singleton
|
|
244
244
|
experimental_user = _UserInfoProxy()
|
245
245
|
|
246
246
|
|
247
|
-
_EXPERIMENTAL_QUERY_PARAMS_DEPRECATE_MSG = "Refer to our [docs page](https://docs.streamlit.io/
|
247
|
+
_EXPERIMENTAL_QUERY_PARAMS_DEPRECATE_MSG = "Refer to our [docs page](https://docs.streamlit.io/develop/api-reference/caching-and-state/st.query_params) for more information."
|
248
248
|
|
249
249
|
experimental_get_query_params = _deprecate_func_name(
|
250
250
|
_get_query_params,
|
streamlit/commands/navigation.py
CHANGED
@@ -61,37 +61,103 @@ def navigation(
|
|
61
61
|
"""
|
62
62
|
Configure the available pages in a multipage app.
|
63
63
|
|
64
|
-
Call
|
65
|
-
|
66
|
-
using
|
64
|
+
Call ``st.navigation`` in your entrypoint file with one or more pages
|
65
|
+
defined by ``st.Page``. ``st.navigation`` returns the current page, which
|
66
|
+
can be executed using ``.run()`` method.
|
67
67
|
|
68
|
-
When using
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
When using ``st.navigation``, your entrypoint file (the file passed to
|
69
|
+
``streamlit run``) acts like a router or frame of common elements around
|
70
|
+
each of your pages. Streamlit executes the entrypoint file with every app
|
71
|
+
rerun. To execute the current page, you must call the ``.run()`` method on
|
72
|
+
the page object returned by ``st.navigation``.
|
72
73
|
|
73
|
-
|
74
|
-
navigation.
|
75
|
-
|
74
|
+
The set of available pages can be updated with each rerun for dynamic
|
75
|
+
navigation. By default, ``st.navigation`` draws the available pages in the
|
76
|
+
side navigation if there is more than one page. This behavior can be
|
77
|
+
changed using the ``position`` keyword argument.
|
78
|
+
|
79
|
+
As soon as any session of your app executes the ``st.navigation`` command,
|
80
|
+
your app will ignore the ``pages/`` directory (across all sessions).
|
76
81
|
|
77
82
|
Parameters
|
78
83
|
----------
|
79
|
-
pages: list[
|
80
|
-
|
81
|
-
|
84
|
+
pages: list[StreamlitPage] or dict[str, list[StreamlitPage]]
|
85
|
+
The available pages for the app.
|
86
|
+
|
87
|
+
To create labeled sections or page groupings within the navigation
|
88
|
+
menu, ``pages`` must be a dictionary. Each key is the label of a
|
89
|
+
section and each value is the list of ``StreamlitPage`` objects for
|
90
|
+
that section.
|
91
|
+
|
92
|
+
To create a navigation menu with no sections or page groupings,
|
93
|
+
``pages`` must be a list of ``StreamlitPage`` objects.
|
94
|
+
|
95
|
+
Use ``st.Page`` to create ``StreamlitPage`` objects.
|
82
96
|
|
83
97
|
position: "sidebar" or "hidden"
|
84
|
-
The position of the navigation menu.
|
98
|
+
The position of the navigation menu. If ``position`` is ``"sidebar"``
|
99
|
+
(default), the navigation widget appears at the top of the sidebar. If
|
100
|
+
``position`` is ``"hidden"``, the navigation widget is not displayed.
|
101
|
+
|
102
|
+
If there is only one page in ``pages``, the navigation will be hidden
|
103
|
+
for any value of ``position``.
|
85
104
|
|
86
|
-
|
105
|
+
Returns
|
87
106
|
-------
|
107
|
+
StreamlitPage
|
108
|
+
The current page selected by the user.
|
109
|
+
|
110
|
+
Examples
|
111
|
+
--------
|
112
|
+
The following examples show possible entrypoint files, which is the file
|
113
|
+
you pass to ``streamlit run``. Your entrypoint file manages your app's
|
114
|
+
navigation and serves as a router between pages.
|
115
|
+
|
116
|
+
You can declare pages from callables or file paths.
|
117
|
+
|
118
|
+
>>> import streamlit as st
|
119
|
+
>>> from page_functions import page1
|
120
|
+
>>>
|
121
|
+
>>> pg = st.navigation([st.Page(page1), st.Page("page2.py")])
|
122
|
+
>>> pg.run()
|
123
|
+
|
124
|
+
Use a dictionary to create sections within your navigation menu.
|
125
|
+
|
88
126
|
>>> import streamlit as st
|
89
|
-
>>> from pages import page1, page2
|
90
127
|
>>>
|
91
|
-
>>>
|
128
|
+
>>> pages = {
|
129
|
+
... "Your account" : [
|
130
|
+
... st.Page("create_account.py", title="Create your account"),
|
131
|
+
... st.Page("manage_account.py", title="Manage your account")
|
132
|
+
... ],
|
133
|
+
... "Resources" : [
|
134
|
+
... st.Page("learn.py", title="Learn about us"),
|
135
|
+
... st.Page("trial.py", title="Try it out")
|
136
|
+
... ]
|
137
|
+
... }
|
92
138
|
>>>
|
93
|
-
>>>
|
139
|
+
>>> pg = st.navigation(pages)
|
94
140
|
>>> pg.run()
|
141
|
+
|
142
|
+
Call widget functions in your entrypoint file when you want a widget to be
|
143
|
+
stateful across pages. Assign keys to your common widgets and access their
|
144
|
+
values through Session State within your pages.
|
145
|
+
|
146
|
+
>>> import streamlit as st
|
147
|
+
>>>
|
148
|
+
>>> def page1():
|
149
|
+
>>> st.write(st.session_state.foo)
|
150
|
+
>>>
|
151
|
+
>>> def page2():
|
152
|
+
>>> st.write(st.session_state.bar)
|
153
|
+
>>>
|
154
|
+
>>> # Widgets shared by all the pages
|
155
|
+
>>> st.sidebar.selectbox("Foo", ["A", "B", "C"], key="foo")
|
156
|
+
>>> st.sidebar.checkbox("Bar", key="bar")
|
157
|
+
>>>
|
158
|
+
>>> pg = st.navigation(st.Page(page1), st.Page(page2))
|
159
|
+
>>> pg.run()
|
160
|
+
|
95
161
|
"""
|
96
162
|
nav_sections = {"": pages} if isinstance(pages, list) else pages
|
97
163
|
page_list = pages_from_nav_sections(nav_sections)
|
@@ -52,25 +52,40 @@ def declare_component(
|
|
52
52
|
path: str | None = None,
|
53
53
|
url: str | None = None,
|
54
54
|
) -> CustomComponent:
|
55
|
-
"""Create a custom component and register it if there is a
|
55
|
+
"""Create a custom component and register it if there is a ``ScriptRunContext``.
|
56
56
|
|
57
|
-
The component is not registered when there is no
|
57
|
+
The component is not registered when there is no ``ScriptRunContext``.
|
58
|
+
This can happen when a ``CustomComponent`` is executed as standalone
|
59
|
+
command (e.g. for testing).
|
60
|
+
|
61
|
+
To use this function, import it from the ``streamlit.components.v1``
|
62
|
+
module.
|
63
|
+
|
64
|
+
.. warning::
|
65
|
+
Using ``st.components.v1.declare_component`` directly (instead of
|
66
|
+
importing its module) is deprecated and will be disallowd in a later
|
67
|
+
version.
|
58
68
|
|
59
69
|
Parameters
|
60
70
|
----------
|
61
|
-
name: str
|
62
|
-
A short, descriptive name for the component
|
71
|
+
name : str
|
72
|
+
A short, descriptive name for the component, like "slider".
|
73
|
+
|
63
74
|
path: str or None
|
64
|
-
The path to serve the component's frontend files from.
|
65
|
-
|
75
|
+
The path to serve the component's frontend files from. If ``path`` is
|
76
|
+
``None`` (default), Streamlit will server the component from the
|
77
|
+
location in ``url``. Either ``path`` or ``url`` must be specified, but
|
78
|
+
not both.
|
79
|
+
|
66
80
|
url: str or None
|
67
|
-
The URL that the component is served from.
|
68
|
-
|
81
|
+
The URL that the component is served from. If ``url`` is ``None``
|
82
|
+
(default), Streamlit will server the component from the location in
|
83
|
+
``path``. Either ``path`` or ``url`` must be specified, but not both.
|
69
84
|
|
70
85
|
Returns
|
71
86
|
-------
|
72
87
|
CustomComponent
|
73
|
-
A CustomComponent that can be called like a function.
|
88
|
+
A ``CustomComponent`` that can be called like a function.
|
74
89
|
Calling the component will create a new instance of the component
|
75
90
|
in the Streamlit app.
|
76
91
|
|
streamlit/config.py
CHANGED
@@ -465,9 +465,6 @@ _create_option(
|
|
465
465
|
visibility="hidden",
|
466
466
|
type_=bool,
|
467
467
|
scriptable=True,
|
468
|
-
deprecated=True,
|
469
|
-
deprecation_text="logger.enableRich has been deprecated and will be removed in a future version. Exception formatting via rich will be automatically used if rich is enable.",
|
470
|
-
expiration_date="2024-09-10",
|
471
468
|
)
|
472
469
|
|
473
470
|
# Config Section: Client #
|
streamlit/elements/arrow.py
CHANGED
@@ -95,12 +95,19 @@ class DataframeSelectionState(TypedDict, total=False):
|
|
95
95
|
key and attribute notation. Selection states cannot be programmatically
|
96
96
|
changed or set through Session State.
|
97
97
|
|
98
|
+
.. warning::
|
99
|
+
If a user sorts a dataframe, row selections will be reset. If your
|
100
|
+
users need to sort and filter the dataframe to make selections, direct
|
101
|
+
them to use the search function in the dataframe toolbar instead.
|
102
|
+
|
98
103
|
Attributes
|
99
104
|
----------
|
100
105
|
rows : list[int]
|
101
|
-
The selected rows, identified by their
|
102
|
-
|
103
|
-
dataframe in their browser.
|
106
|
+
The selected rows, identified by their integer position. The integer
|
107
|
+
positions match the original dataframe, even if the user sorts the
|
108
|
+
dataframe in their browser. For a ``pandas.DataFrame``, you can
|
109
|
+
retrieve data from its interger position using methods like ``.iloc[]``
|
110
|
+
or ``.iat[]``.
|
104
111
|
columns : list[str]
|
105
112
|
The selected columns, identified by their names.
|
106
113
|
|
@@ -150,8 +157,12 @@ class DataframeState(TypedDict, total=False):
|
|
150
157
|
|
151
158
|
Attributes
|
152
159
|
----------
|
153
|
-
selection :
|
154
|
-
The state of the ``on_select`` event.
|
160
|
+
selection : dict
|
161
|
+
The state of the ``on_select`` event. This attribure returns a
|
162
|
+
dictionary-like object that supports both key and attribute notation.
|
163
|
+
The attributes are described by the ``DataframeSelectionState``
|
164
|
+
dictionary schema.
|
165
|
+
|
155
166
|
|
156
167
|
"""
|
157
168
|
|
@@ -346,7 +357,7 @@ class ArrowMixin:
|
|
346
357
|
to change the displayed name of the column to "Dollar values"
|
347
358
|
and add a "$" prefix in each cell. For more info on the
|
348
359
|
available column types and config options, see
|
349
|
-
`Column configuration <https://docs.streamlit.io/
|
360
|
+
`Column configuration <https://docs.streamlit.io/develop/api-reference/data/st.column_config>`_.
|
350
361
|
|
351
362
|
To configure the index column(s), use ``_index`` as the column name.
|
352
363
|
|
@@ -66,7 +66,7 @@ class PydeckMixin:
|
|
66
66
|
|
67
67
|
To get a token for yourself, create an account at https://mapbox.com.
|
68
68
|
For more info on how to set config options, see
|
69
|
-
https://docs.streamlit.io/
|
69
|
+
https://docs.streamlit.io/develop/api-reference/configuration/config.toml.
|
70
70
|
|
71
71
|
Parameters
|
72
72
|
----------
|
@@ -127,9 +127,11 @@ def dialog_decorator(
|
|
127
127
|
handling any side effects of that behavior.
|
128
128
|
|
129
129
|
.. warning::
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
Only one dialog function may be called in a script run, which means
|
131
|
+
that only one dialog can be open at any given time. Since a dialog is
|
132
|
+
also a fragment, all fragment limitations apply. Dialogs can't contain
|
133
|
+
fragments, and fragments can't contain dialogs. Using dialogs in widget
|
134
|
+
callback functions is not supported.
|
133
135
|
|
134
136
|
.. |st.experimental_fragment| replace:: ``st.experimental_fragment``
|
135
137
|
.. _st.experimental_fragment: https://docs.streamlit.io/develop/api-reference/execution-flow/st.fragment
|
streamlit/elements/html.py
CHANGED
@@ -57,15 +57,7 @@ class HtmlMixin:
|
|
57
57
|
-------
|
58
58
|
>>> import streamlit as st
|
59
59
|
>>>
|
60
|
-
>>>
|
61
|
-
... <style>
|
62
|
-
... p {
|
63
|
-
... color: red;
|
64
|
-
... }
|
65
|
-
... </style>
|
66
|
-
... \"""
|
67
|
-
>>> st.html(code)
|
68
|
-
>>> st.markdown("Lorem ipsum")
|
60
|
+
>>> st.html("<p><span style='text-decoration: line-through double red;'>Oops</span>!</p>")
|
69
61
|
|
70
62
|
.. output::
|
71
63
|
https://doc-html.streamlit.app/
|
streamlit/elements/iframe.py
CHANGED
@@ -34,18 +34,37 @@ class IframeMixin:
|
|
34
34
|
) -> DeltaGenerator:
|
35
35
|
"""Load a remote URL in an iframe.
|
36
36
|
|
37
|
+
To use this function, import it from the ``streamlit.components.v1``
|
38
|
+
module.
|
39
|
+
|
40
|
+
.. warning::
|
41
|
+
Using ``st.components.v1.iframe`` directly (instead of importing
|
42
|
+
its module) is deprecated and will be disallowd in a later version.
|
43
|
+
|
37
44
|
Parameters
|
38
45
|
----------
|
39
46
|
src : str
|
40
47
|
The URL of the page to embed.
|
48
|
+
|
41
49
|
width : int
|
42
|
-
The width of the
|
43
|
-
default element width.
|
50
|
+
The width of the iframe in CSS pixels. By default, this is the
|
51
|
+
app's default element width.
|
52
|
+
|
44
53
|
height : int
|
45
|
-
The height of the frame in CSS pixels.
|
54
|
+
The height of the frame in CSS pixels. By default, this is ``150``.
|
55
|
+
|
46
56
|
scrolling : bool
|
47
|
-
|
48
|
-
|
57
|
+
Whether to allow scrolling in the iframe. If this ``False``
|
58
|
+
(default), Streamlit crops any content larger than the iframe and
|
59
|
+
does not show a scrollbar. If this is ``True``, Streamlit shows a
|
60
|
+
scrollbar when the content is larger than the iframe.
|
61
|
+
|
62
|
+
Example
|
63
|
+
-------
|
64
|
+
|
65
|
+
>>> import streamlit.components.v1 as components
|
66
|
+
>>>
|
67
|
+
>>> components.iframe("https://example.com", height=500)
|
49
68
|
|
50
69
|
"""
|
51
70
|
iframe_proto = IFrameProto()
|
@@ -68,18 +87,42 @@ class IframeMixin:
|
|
68
87
|
) -> DeltaGenerator:
|
69
88
|
"""Display an HTML string in an iframe.
|
70
89
|
|
90
|
+
To use this function, import it from the ``streamlit.components.v1``
|
91
|
+
module.
|
92
|
+
|
93
|
+
If you want to insert HTML text into your app without an iframe, try
|
94
|
+
``st.html`` instead.
|
95
|
+
|
96
|
+
.. warning::
|
97
|
+
Using ``st.components.v1.html`` directly (instead of importing
|
98
|
+
its module) is deprecated and will be disallowd in a later version.
|
99
|
+
|
71
100
|
Parameters
|
72
101
|
----------
|
73
102
|
html : str
|
74
103
|
The HTML string to embed in the iframe.
|
104
|
+
|
75
105
|
width : int
|
76
|
-
The width of the
|
77
|
-
default element width.
|
106
|
+
The width of the iframe in CSS pixels. By default, this is the
|
107
|
+
app's default element width.
|
108
|
+
|
78
109
|
height : int
|
79
|
-
The height of the frame in CSS pixels.
|
110
|
+
The height of the frame in CSS pixels. By default, this is ``150``.
|
111
|
+
|
80
112
|
scrolling : bool
|
81
|
-
|
82
|
-
|
113
|
+
Whether to allow scrolling in the iframe. If this ``False``
|
114
|
+
(default), Streamlit crops any content larger than the iframe and
|
115
|
+
does not show a scrollbar. If this is ``True``, Streamlit shows a
|
116
|
+
scrollbar when the content is larger than the iframe.
|
117
|
+
|
118
|
+
Example
|
119
|
+
-------
|
120
|
+
|
121
|
+
>>> import streamlit.components.v1 as components
|
122
|
+
>>>
|
123
|
+
>>> components.html(
|
124
|
+
>>> "<p><span style='text-decoration: line-through double red;'>Oops</span>!</p>"
|
125
|
+
>>> )
|
83
126
|
|
84
127
|
"""
|
85
128
|
iframe_proto = IFrameProto()
|
streamlit/elements/layouts.py
CHANGED
@@ -21,6 +21,7 @@ from typing_extensions import TypeAlias
|
|
21
21
|
from streamlit.errors import StreamlitAPIException
|
22
22
|
from streamlit.proto.Block_pb2 import Block as BlockProto
|
23
23
|
from streamlit.runtime.metrics_util import gather_metrics
|
24
|
+
from streamlit.string_util import validate_icon_or_emoji
|
24
25
|
|
25
26
|
if TYPE_CHECKING:
|
26
27
|
from streamlit.delta_generator import DeltaGenerator
|
@@ -163,7 +164,8 @@ class LayoutsMixin:
|
|
163
164
|
Columns can only be placed inside other columns up to one level of nesting.
|
164
165
|
|
165
166
|
.. warning::
|
166
|
-
Columns cannot be placed inside other columns in the sidebar. This
|
167
|
+
Columns cannot be placed inside other columns in the sidebar. This
|
168
|
+
is only possible in the main area of the app.
|
167
169
|
|
168
170
|
Parameters
|
169
171
|
----------
|
@@ -179,10 +181,11 @@ class LayoutsMixin:
|
|
179
181
|
the width of the first one, and the third one is three times that width.
|
180
182
|
|
181
183
|
gap : "small", "medium", or "large"
|
182
|
-
The size of the gap between the columns.
|
184
|
+
The size of the gap between the columns. The default is ``"small"``.
|
183
185
|
|
184
186
|
vertical_alignment : "top", "center", or "bottom"
|
185
|
-
The vertical alignment of the content inside the columns.
|
187
|
+
The vertical alignment of the content inside the columns. The
|
188
|
+
default is ``"top"``.
|
186
189
|
|
187
190
|
Returns
|
188
191
|
-------
|
@@ -231,6 +234,38 @@ class LayoutsMixin:
|
|
231
234
|
https://doc-columns2.streamlit.app/
|
232
235
|
height: 550px
|
233
236
|
|
237
|
+
Use ``vertical_alignment="bottom"`` to align widgets.
|
238
|
+
|
239
|
+
>>> import streamlit as st
|
240
|
+
>>>
|
241
|
+
>>> left, middle, right = st.columns(3, vertical_alignment="bottom")
|
242
|
+
>>>
|
243
|
+
>>> left.text_input("Write something")
|
244
|
+
>>> middle.button("Click me", use_container_width=True)
|
245
|
+
>>> right.checkbox("Check me")
|
246
|
+
|
247
|
+
.. output ::
|
248
|
+
https://doc-columns-bottom-widgets.streamlit.app/
|
249
|
+
height: 200px
|
250
|
+
|
251
|
+
Adjust vertical alignment to customize your grid layouts.
|
252
|
+
|
253
|
+
>>> import streamlit as st
|
254
|
+
>>> import numpy as np
|
255
|
+
>>>
|
256
|
+
>>> vertical_alignment = st.selectbox(
|
257
|
+
>>> "Vertical alignment", ["top", "center", "bottom"], index=2
|
258
|
+
>>> )
|
259
|
+
>>>
|
260
|
+
>>> left, middle, right = st.columns(3, vertical_alignment=vertical_alignment)
|
261
|
+
>>> left.image("https://static.streamlit.io/examples/cat.jpg")
|
262
|
+
>>> middle.image("https://static.streamlit.io/examples/dog.jpg")
|
263
|
+
>>> right.image("https://static.streamlit.io/examples/owl.jpg")
|
264
|
+
|
265
|
+
.. output ::
|
266
|
+
https://doc-columns-vertical-alignment.streamlit.app/
|
267
|
+
height: 600px
|
268
|
+
|
234
269
|
"""
|
235
270
|
weights = spec
|
236
271
|
if isinstance(weights, int):
|
@@ -243,7 +278,7 @@ class LayoutsMixin:
|
|
243
278
|
raise StreamlitAPIException(
|
244
279
|
"The input argument to st.columns must be either a "
|
245
280
|
"positive integer or a list of positive numeric weights. "
|
246
|
-
"See [documentation](https://docs.streamlit.io/
|
281
|
+
"See [documentation](https://docs.streamlit.io/develop/api-reference/layout/st.columns) "
|
247
282
|
"for more information."
|
248
283
|
)
|
249
284
|
|
@@ -408,7 +443,13 @@ class LayoutsMixin:
|
|
408
443
|
return tuple(tab_container._block(tab_proto(tab_label)) for tab_label in tabs)
|
409
444
|
|
410
445
|
@gather_metrics("expander")
|
411
|
-
def expander(
|
446
|
+
def expander(
|
447
|
+
self,
|
448
|
+
label: str,
|
449
|
+
expanded: bool = False,
|
450
|
+
*,
|
451
|
+
icon: str | None = None,
|
452
|
+
) -> DeltaGenerator:
|
412
453
|
r"""Insert a multi-element container that can be expanded/collapsed.
|
413
454
|
|
414
455
|
Inserts a container into your app that can be used to hold multiple elements
|
@@ -449,10 +490,28 @@ class LayoutsMixin:
|
|
449
490
|
Unsupported elements are unwrapped so only their children (text contents) render.
|
450
491
|
Display unsupported elements as literal characters by
|
451
492
|
backslash-escaping them. E.g. ``1\. Not an ordered list``.
|
493
|
+
|
452
494
|
expanded : bool
|
453
495
|
If True, initializes the expander in "expanded" state. Defaults to
|
454
496
|
False (collapsed).
|
455
497
|
|
498
|
+
icon : str, None
|
499
|
+
An optional emoji or icon to display next to the expander label. If ``icon``
|
500
|
+
is ``None`` (default), no icon is displayed. If ``icon`` is a
|
501
|
+
string, the following options are valid:
|
502
|
+
|
503
|
+
* A single-character emoji. For example, you can set ``icon="🚨"``
|
504
|
+
or ``icon="🔥"``. Emoji short codes are not supported.
|
505
|
+
|
506
|
+
* An icon from the Material Symbols library (outlined style) in the
|
507
|
+
format ``":material/icon_name:"`` where "icon_name" is the name
|
508
|
+
of the icon in snake case.
|
509
|
+
|
510
|
+
For example, ``icon=":material/thumb_up:"`` will display the
|
511
|
+
Thumb Up icon. Find additional icons in the `Material Symbols \
|
512
|
+
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Outlined>`_
|
513
|
+
font library.
|
514
|
+
|
456
515
|
Examples
|
457
516
|
--------
|
458
517
|
You can use the ``with`` notation to insert any element into an expander
|
@@ -498,6 +557,8 @@ class LayoutsMixin:
|
|
498
557
|
expandable_proto = BlockProto.Expandable()
|
499
558
|
expandable_proto.expanded = expanded
|
500
559
|
expandable_proto.label = label
|
560
|
+
if icon is not None:
|
561
|
+
expandable_proto.icon = validate_icon_or_emoji(icon)
|
501
562
|
|
502
563
|
block_proto = BlockProto()
|
503
564
|
block_proto.allow_empty = False
|
@@ -71,7 +71,8 @@ class AddRowsMetadata:
|
|
71
71
|
|
72
72
|
class ChartType(Enum):
|
73
73
|
AREA = {"mark_type": "area", "command": "area_chart"}
|
74
|
-
|
74
|
+
VERTICAL_BAR = {"mark_type": "bar", "command": "bar_chart", "horizontal": False}
|
75
|
+
HORIZONTAL_BAR = {"mark_type": "bar", "command": "bar_chart", "horizontal": True}
|
75
76
|
LINE = {"mark_type": "line", "command": "line_chart"}
|
76
77
|
SCATTER = {"mark_type": "circle", "command": "scatter_chart"}
|
77
78
|
|
@@ -165,6 +166,22 @@ def generate_chart(
|
|
165
166
|
|
166
167
|
# At this point, x_column is only None if user did not provide one AND df is empty.
|
167
168
|
|
169
|
+
if chart_type == ChartType.HORIZONTAL_BAR:
|
170
|
+
# Handle horizontal bar chart - switches x and y data:
|
171
|
+
x_encoding = _get_x_encoding(
|
172
|
+
df, y_column, y_from_user, x_axis_label, chart_type
|
173
|
+
)
|
174
|
+
y_encoding = _get_y_encoding(
|
175
|
+
df, x_column, x_from_user, y_axis_label, chart_type
|
176
|
+
)
|
177
|
+
else:
|
178
|
+
x_encoding = _get_x_encoding(
|
179
|
+
df, x_column, x_from_user, x_axis_label, chart_type
|
180
|
+
)
|
181
|
+
y_encoding = _get_y_encoding(
|
182
|
+
df, y_column, y_from_user, y_axis_label, chart_type
|
183
|
+
)
|
184
|
+
|
168
185
|
# Create a Chart with x and y encodings.
|
169
186
|
chart = alt.Chart(
|
170
187
|
data=df,
|
@@ -172,8 +189,8 @@ def generate_chart(
|
|
172
189
|
width=width or 0,
|
173
190
|
height=height or 0,
|
174
191
|
).encode(
|
175
|
-
x=
|
176
|
-
y=
|
192
|
+
x=x_encoding,
|
193
|
+
y=y_encoding,
|
177
194
|
)
|
178
195
|
|
179
196
|
# Set up opacity encoding.
|
@@ -620,7 +637,7 @@ def _maybe_melt(
|
|
620
637
|
def _get_x_encoding(
|
621
638
|
df: pd.DataFrame,
|
622
639
|
x_column: str | None,
|
623
|
-
x_from_user: str | None,
|
640
|
+
x_from_user: str | Sequence[str] | None,
|
624
641
|
x_axis_label: str | None,
|
625
642
|
chart_type: ChartType,
|
626
643
|
) -> alt.X:
|
@@ -653,12 +670,15 @@ def _get_x_encoding(
|
|
653
670
|
if x_axis_label is not None:
|
654
671
|
x_title = x_axis_label
|
655
672
|
|
673
|
+
# grid lines on x axis for horizontal bar charts only
|
674
|
+
grid = True if chart_type == ChartType.HORIZONTAL_BAR else False
|
675
|
+
|
656
676
|
return alt.X(
|
657
677
|
x_field,
|
658
678
|
title=x_title,
|
659
679
|
type=_get_x_encoding_type(df, chart_type, x_column),
|
660
680
|
scale=alt.Scale(),
|
661
|
-
axis=_get_axis_config(df, x_column, grid=
|
681
|
+
axis=_get_axis_config(df, x_column, grid=grid),
|
662
682
|
)
|
663
683
|
|
664
684
|
|
@@ -667,6 +687,7 @@ def _get_y_encoding(
|
|
667
687
|
y_column: str | None,
|
668
688
|
y_from_user: str | Sequence[str] | None,
|
669
689
|
y_axis_label: str | None,
|
690
|
+
chart_type: ChartType,
|
670
691
|
) -> alt.Y:
|
671
692
|
import altair as alt
|
672
693
|
|
@@ -697,12 +718,15 @@ def _get_y_encoding(
|
|
697
718
|
if y_axis_label is not None:
|
698
719
|
y_title = y_axis_label
|
699
720
|
|
721
|
+
# grid lines on y axis for all charts except horizontal bar charts
|
722
|
+
grid = False if chart_type == ChartType.HORIZONTAL_BAR else True
|
723
|
+
|
700
724
|
return alt.Y(
|
701
725
|
field=y_field,
|
702
726
|
title=y_title,
|
703
|
-
type=_get_y_encoding_type(df, y_column),
|
727
|
+
type=_get_y_encoding_type(df, chart_type, y_column),
|
704
728
|
scale=alt.Scale(),
|
705
|
-
axis=_get_axis_config(df, y_column, grid=
|
729
|
+
axis=_get_axis_config(df, y_column, grid=grid),
|
706
730
|
)
|
707
731
|
|
708
732
|
|
@@ -877,17 +901,21 @@ def _get_x_encoding_type(
|
|
877
901
|
if x_column is None:
|
878
902
|
return "quantitative" # Anything. If None, Vega-Lite may hide the axis.
|
879
903
|
|
880
|
-
#
|
904
|
+
# Vertical bar charts should have a discrete (ordinal) x-axis, UNLESS type is date/time
|
881
905
|
# https://github.com/streamlit/streamlit/pull/2097#issuecomment-714802475
|
882
|
-
if chart_type == ChartType.
|
906
|
+
if chart_type == ChartType.VERTICAL_BAR and not _is_date_column(df, x_column):
|
883
907
|
return "ordinal"
|
884
908
|
|
885
909
|
return type_util.infer_vegalite_type(df[x_column])
|
886
910
|
|
887
911
|
|
888
912
|
def _get_y_encoding_type(
|
889
|
-
df: pd.DataFrame, y_column: str | None
|
913
|
+
df: pd.DataFrame, chart_type: ChartType, y_column: str | None
|
890
914
|
) -> type_util.VegaLiteType:
|
915
|
+
# Horizontal bar charts should have a discrete (ordinal) y-axis, UNLESS type is date/time
|
916
|
+
if chart_type == ChartType.HORIZONTAL_BAR and not _is_date_column(df, y_column):
|
917
|
+
return "ordinal"
|
918
|
+
|
891
919
|
if y_column:
|
892
920
|
return type_util.infer_vegalite_type(df[y_column])
|
893
921
|
|
@@ -1038,7 +1038,7 @@ def ImageColumn(
|
|
1038
1038
|
The cell values need to be one of:
|
1039
1039
|
|
1040
1040
|
* A URL to fetch the image from. This can also be a relative URL of an image
|
1041
|
-
deployed via `static file serving <https://docs.streamlit.io/
|
1041
|
+
deployed via `static file serving <https://docs.streamlit.io/develop/concepts/configuration/serving-static-files>`_.
|
1042
1042
|
Note that you can NOT use an arbitrary local image if it is not available through
|
1043
1043
|
a public URL.
|
1044
1044
|
* A data URL containing an SVG XML like ``data:image/svg+xml;utf8,<svg xmlns=...</svg>``.
|
@@ -47,9 +47,9 @@ class StatusContainer(DeltaGenerator):
|
|
47
47
|
if state == "running":
|
48
48
|
expandable_proto.icon = "spinner"
|
49
49
|
elif state == "complete":
|
50
|
-
expandable_proto.icon = "check"
|
50
|
+
expandable_proto.icon = ":material/check:"
|
51
51
|
elif state == "error":
|
52
|
-
expandable_proto.icon = "error"
|
52
|
+
expandable_proto.icon = ":material/error:"
|
53
53
|
else:
|
54
54
|
raise StreamlitAPIException(
|
55
55
|
f"Unknown state ({state}). Must be one of 'running', 'complete', or 'error'."
|
@@ -140,9 +140,9 @@ class StatusContainer(DeltaGenerator):
|
|
140
140
|
if state == "running":
|
141
141
|
msg.delta.add_block.expandable.icon = "spinner"
|
142
142
|
elif state == "complete":
|
143
|
-
msg.delta.add_block.expandable.icon = "check"
|
143
|
+
msg.delta.add_block.expandable.icon = ":material/check:"
|
144
144
|
elif state == "error":
|
145
|
-
msg.delta.add_block.expandable.icon = "error"
|
145
|
+
msg.delta.add_block.expandable.icon = ":material/error:"
|
146
146
|
else:
|
147
147
|
raise StreamlitAPIException(
|
148
148
|
f"Unknown state ({state}). Must be one of 'running', 'complete', or 'error'."
|