streamlit-nightly 1.52.3.dev20260113__py3-none-any.whl → 1.53.1.dev20260114__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/logo.py +2 -0
- streamlit/commands/page_config.py +16 -16
- streamlit/components/v2/__init__.py +2 -2
- streamlit/connections/base_connection.py +16 -4
- streamlit/connections/snowflake_connection.py +254 -205
- streamlit/elements/form.py +2 -2
- streamlit/elements/metric.py +49 -48
- streamlit/elements/widgets/button.py +9 -9
- streamlit/elements/widgets/chat.py +5 -9
- streamlit/elements/widgets/data_editor.py +3 -3
- streamlit/elements/widgets/file_uploader.py +10 -11
- streamlit/elements/widgets/select_slider.py +4 -0
- streamlit/runtime/caching/cache_data_api.py +25 -21
- streamlit/runtime/caching/cache_resource_api.py +69 -41
- streamlit/runtime/connection_factory.py +67 -41
- streamlit/static/index.html +1 -1
- streamlit/static/manifest.json +304 -304
- streamlit/static/static/js/{ErrorOutline.esm.BjVqd_6R.js → ErrorOutline.esm.BAZUU4id.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.DJCSsghl.js → FileDownload.esm.C6tTTniR.js} +1 -1
- streamlit/static/static/js/{FileHelper.C---TH7o.js → FileHelper.BOHlwlc9.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.C-6BC487.js → FormClearHelper.D4lty7rT.js} +1 -1
- streamlit/static/static/js/{InputInstructions.sxc3InCI.js → InputInstructions.BWw9lhud.js} +1 -1
- streamlit/static/static/js/{Particles.S8yD7iW-.js → Particles.BDi7fIn-.js} +1 -1
- streamlit/static/static/js/{ProgressBar.BiYsyZCC.js → ProgressBar.DCHh4N3P.js} +1 -1
- streamlit/static/static/js/{StreamlitSyntaxHighlighter.9jZF8jX1.js → StreamlitSyntaxHighlighter.BRydQwEj.js} +1 -1
- streamlit/static/static/js/{TableChart.esm.BdA4Q1rZ.js → TableChart.esm.7KFX5I_G.js} +1 -1
- streamlit/static/static/js/{Toolbar.B9DaaDfN.js → Toolbar.guIuiwEF.js} +1 -1
- streamlit/static/static/js/{WidgetLabelHelpIconInline.DxODTLS2.js → WidgetLabelHelpIconInline.CzodezAH.js} +1 -1
- streamlit/static/static/js/{base-input.Gf1cKuQR.js → base-input.Cg7NpsfS.js} +1 -1
- streamlit/static/static/js/{checkbox.CnoNruf3.js → checkbox.Bs20OTna.js} +1 -1
- streamlit/static/static/js/{createDownloadLinkElement.B48AepiL.js → createDownloadLinkElement.DSqCyu38.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.Cmdq9aqU.js → data-grid-overlay-editor.Ch4SqNfY.js} +1 -1
- streamlit/static/static/js/{downloader.CQLoQdMX.js → downloader.Oj5CTGJA.js} +1 -1
- streamlit/static/static/js/{embed.oKwocwU8.js → embed.CqzzUq73.js} +1 -1
- streamlit/static/static/js/{es6.BRxlY_y5.js → es6.CYrlw0Vn.js} +2 -2
- streamlit/static/static/js/{formatNumber.DaagZyZe.js → formatNumber.CT_v8e75.js} +1 -1
- streamlit/static/static/js/{iconPosition.Q3hNvmK4.js → iconPosition.DPAvXTmd.js} +1 -1
- streamlit/static/static/js/{iframeResizer.contentWindow.B6EBvI9L.js → iframeResizer.contentWindow.T4DvQsIf.js} +1 -1
- streamlit/static/static/js/{index.BoX8d5rK.js → index.AGYZDQZm.js} +1 -1
- streamlit/static/static/js/{index.KtjGDGY5.js → index.B3HdcUdo.js} +1 -1
- streamlit/static/static/js/{index.B9kZB0o1.js → index.B8ZZdPqF.js} +1 -1
- streamlit/static/static/js/{index.CFCBhOfx.js → index.B9Oowxt8.js} +1 -1
- streamlit/static/static/js/{index.CCQ5p_WC.js → index.BEzgNZOm.js} +1 -1
- streamlit/static/static/js/{index.D1pK_Vw2.js → index.BJnWg9Jq.js} +1 -1
- streamlit/static/static/js/{index.na9UBuse.js → index.BPxuKK0S.js} +1 -1
- streamlit/static/static/js/{index.QTaWooav.js → index.BTA0d5oq.js} +1 -1
- streamlit/static/static/js/{index.pU9mQeVC.js → index.BTqav7_K.js} +1 -1
- streamlit/static/static/js/{index.BXEC4cf3.js → index.BZ8xp-w9.js} +1 -1
- streamlit/static/static/js/{index.BF23fbfs.js → index.BoWBzl6h.js} +1 -1
- streamlit/static/static/js/index.Bqgt60FU.js +1 -0
- streamlit/static/static/js/{index.Dh5SAThV.js → index.BsYYrijt.js} +1 -1
- streamlit/static/static/js/{index.19_qtO6t.js → index.CGRIbGGV.js} +1 -1
- streamlit/static/static/js/{index.CSfsEKCF.js → index.CJQq5LcR.js} +1 -1
- streamlit/static/static/js/{index.Fu73QtkD.js → index.CPYB1awG.js} +1 -1
- streamlit/static/static/js/{index.BzwlrgZO.js → index.CVKk1nkB.js} +1 -1
- streamlit/static/static/js/{index.B03eQZoH.js → index.CVXiBeDI.js} +1 -1
- streamlit/static/static/js/{index.BRfGUOQ-.js → index.CXVpBAvU.js} +4 -4
- streamlit/static/static/js/{index.slgxPafU.js → index.Cfe-tCQJ.js} +1 -1
- streamlit/static/static/js/{index.D6X2coHR.js → index.ClFk8x0U.js} +1 -1
- streamlit/static/static/js/{index.WXybx2Xq.js → index.CnXxoVEM.js} +1 -1
- streamlit/static/static/js/{index.j4fnjyHo.js → index.Cw4eSvJ7.js} +1 -1
- streamlit/static/static/js/{index.KN1VmyYN.js → index.D6HCANv6.js} +1 -1
- streamlit/static/static/js/{index.CP-hoxJM.js → index.D7KbBAWb.js} +1 -1
- streamlit/static/static/js/{index.CCFwVy90.js → index.D84XHt50.js} +1 -1
- streamlit/static/static/js/{index.BkSwGJoh.js → index.DL_Ooizi.js} +1 -1
- streamlit/static/static/js/{index.QHnxuesF.js → index.DNyw7S7Z.js} +1 -1
- streamlit/static/static/js/{index.BAI9aHCq.js → index.DPlPEuq6.js} +1 -1
- streamlit/static/static/js/{index.CJ4oJe0V.js → index.DQzRwgrT.js} +1 -1
- streamlit/static/static/js/{index.CVlg41MB.js → index.DXRGd--0.js} +1 -1
- streamlit/static/static/js/{index.CIbgt5wY.js → index.DZDt5hYD.js} +1 -1
- streamlit/static/static/js/{index.BVT89mQw.js → index.DesNeXSA.js} +1 -1
- streamlit/static/static/js/{index.Boa0Egng.js → index.Dg9k4R8B.js} +1 -1
- streamlit/static/static/js/{index.43b777iP.js → index.Do9A7QCt.js} +1 -1
- streamlit/static/static/js/{index.DJ7P09eb.js → index.DrSH3pK3.js} +1 -1
- streamlit/static/static/js/{index.OpATzEaW.js → index.Dtd5z2rM.js} +1 -1
- streamlit/static/static/js/{index.BnfTPrHb.js → index.DzldU3Hy.js} +1 -1
- streamlit/static/static/js/{index.C0fSEz-3.js → index.GZi6GTJa.js} +1 -1
- streamlit/static/static/js/{index.CYE7b5Du.js → index.LOA31DFn.js} +1 -1
- streamlit/static/static/js/{index.Ca7MUNWJ.js → index.MtwRNvlS.js} +1 -1
- streamlit/static/static/js/{index.BbSFVZ3p.js → index.XHtvnZ0-.js} +1 -1
- streamlit/static/static/js/{index.CvIqsWy1.js → index.Yj6vcyFD.js} +1 -1
- streamlit/static/static/js/{index.BGBTkulf.js → index.b-MrPulo.js} +1 -1
- streamlit/static/static/js/{index.DGYHxruh.js → index.hcUYvTqs.js} +1 -1
- streamlit/static/static/js/{index.CvB9JBqS.js → index.tLZuZM89.js} +6 -6
- streamlit/static/static/js/{index.Xg-Qttib.js → index.wngeYhKj.js} +1 -1
- streamlit/static/static/js/{index.whRT3Vm3.js → index.xCV2qwtw.js} +1 -1
- streamlit/static/static/js/{input.CPzINTl-.js → input.CYXuTqoa.js} +1 -1
- streamlit/static/static/js/{main.DSPn8dUe.js → main.BE-siVKv.js} +1 -1
- streamlit/static/static/js/{memory.CfD8IGoU.js → memory.V554ztRg.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.4Ae0qegV.js → number-overlay-editor.BiUTOXIl.js} +1 -1
- streamlit/static/static/js/{pandasStylerUtils.D2EjZ7k6.js → pandasStylerUtils.Dej3Tstq.js} +1 -1
- streamlit/static/static/js/{sandbox.C6vcPIm0.js → sandbox.gpd7KGMo.js} +1 -1
- streamlit/static/static/js/{styled-components.BBmp8buj.js → styled-components.Coj4dr6D.js} +1 -1
- streamlit/static/static/js/{throttle.BPcPpy-S.js → throttle.gZUdtYp7.js} +1 -1
- streamlit/static/static/js/{timepicker.ryzkTs2C.js → timepicker.B-Y4aU15.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.Dg1nDaB_.js → toConsumableArray.CcKcKvEd.js} +1 -1
- streamlit/static/static/js/uniqueId.PRn3V1WU.js +1 -0
- streamlit/static/static/js/{useBasicWidgetState.A4U5lzAm.js → useBasicWidgetState.D-fc_aIL.js} +1 -1
- streamlit/static/static/js/{useIntlLocale.DWJgLlNz.js → useIntlLocale.CY32IeNt.js} +1 -1
- streamlit/static/static/js/{useTextInputAutoExpand.BrBonw8t.js → useTextInputAutoExpand.C0jK7TwF.js} +1 -1
- streamlit/static/static/js/{useUpdateUiValue.BkOWyNVX.js → useUpdateUiValue.CDQloDgB.js} +1 -1
- streamlit/static/static/js/{useWaveformController.CBlvXlgZ.js → useWaveformController.BLEIAIDo.js} +1 -1
- streamlit/static/static/js/{withCalculatedWidth.D4cpOyNe.js → withCalculatedWidth.B3oSlRC0.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.BMim3w94.js → withFullScreenWrapper.Cw_ebNmr.js} +1 -1
- streamlit/user_info.py +225 -166
- {streamlit_nightly-1.52.3.dev20260113.dist-info → streamlit_nightly-1.53.1.dev20260114.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.52.3.dev20260113.dist-info → streamlit_nightly-1.53.1.dev20260114.dist-info}/RECORD +111 -111
- streamlit/static/static/js/index.CrPjcPY1.js +0 -1
- streamlit/static/static/js/uniqueId.BFHzT5KQ.js +0 -1
- {streamlit_nightly-1.52.3.dev20260113.data → streamlit_nightly-1.53.1.dev20260114.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.52.3.dev20260113.dist-info → streamlit_nightly-1.53.1.dev20260114.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.52.3.dev20260113.dist-info → streamlit_nightly-1.53.1.dev20260114.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.52.3.dev20260113.dist-info → streamlit_nightly-1.53.1.dev20260114.dist-info}/top_level.txt +0 -0
streamlit/commands/logo.py
CHANGED
|
@@ -56,6 +56,8 @@ def logo(
|
|
|
56
56
|
`configuration option <https://docs.streamlit.io/develop/api-reference/configuration/config.toml>`_
|
|
57
57
|
``client.toolbarMode="minimal"``.
|
|
58
58
|
|
|
59
|
+
If a user clicks the logo, they are redirected to your app's home page.
|
|
60
|
+
|
|
59
61
|
Parameters
|
|
60
62
|
----------
|
|
61
63
|
image: Anything supported by st.image (except list)
|
|
@@ -170,28 +170,28 @@ def set_page_config(
|
|
|
170
170
|
.. _st.image: https://docs.streamlit.io/develop/api-reference/media/st.image
|
|
171
171
|
|
|
172
172
|
layout: "centered", "wide", or None
|
|
173
|
-
|
|
174
|
-
the page layout is inherited from the previous call of
|
|
175
|
-
``st.set_page_config``. If this is ``None`` and no previous call
|
|
176
|
-
exists, the page layout is ``"centered"``.
|
|
173
|
+
Layout of the page content. The following layouts are supported:
|
|
177
174
|
|
|
178
|
-
``
|
|
179
|
-
|
|
175
|
+
- ``None`` (default): The page layout is inherited from the previous
|
|
176
|
+
call of ``st.set_page_config``. If no previous call exists, the page
|
|
177
|
+
layout is ``"centered"``.
|
|
178
|
+
- ``"centered"``: Page elements are constrained to a centered column of
|
|
179
|
+
fixed width.
|
|
180
|
+
- ``"wide"``: Page elements use the entire screen width.
|
|
180
181
|
|
|
181
182
|
initial_sidebar_state: "auto", "expanded", "collapsed", int, or None
|
|
182
|
-
|
|
183
|
-
sidebar state is inherited from the previous call of
|
|
184
|
-
``st.set_page_config``. If no previous call exists, the sidebar state
|
|
185
|
-
is ``"auto"``.
|
|
186
|
-
|
|
187
|
-
The following states are supported:
|
|
183
|
+
Initial state of the sidebar. The following states are supported:
|
|
188
184
|
|
|
189
|
-
- ``
|
|
185
|
+
- ``None`` (default): The sidebar state is inherited from the previous
|
|
186
|
+
call of ``st.set_page_config``. If no previous call exists, the
|
|
187
|
+
sidebar state is ``"auto"``.
|
|
188
|
+
- ``"auto"``: The sidebar is hidden on small devices and shown
|
|
189
|
+
otherwise.
|
|
190
190
|
- ``"expanded"``: The sidebar is shown initially.
|
|
191
191
|
- ``"collapsed"``: The sidebar is hidden initially.
|
|
192
|
-
- ``int``:
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
- ``int``: The sidebar will use ``"auto"`` behavior but start with the
|
|
193
|
+
specified width in pixels. The width must be between 200 and 600
|
|
194
|
+
pixels, inclusive.
|
|
195
195
|
|
|
196
196
|
In most cases, ``"auto"`` provides the best user experience across
|
|
197
197
|
devices of different sizes.
|
|
@@ -214,8 +214,8 @@ def component(
|
|
|
214
214
|
) -> ComponentRenderer:
|
|
215
215
|
'''Register an ``st.components.v2`` component and return a callable to mount it.
|
|
216
216
|
|
|
217
|
-
Components
|
|
218
|
-
are provided, the component
|
|
217
|
+
Components can have any combination of HTML, CSS, and JavaScript. If none
|
|
218
|
+
are provided, the component renders as an empty element without raising
|
|
219
219
|
an error.
|
|
220
220
|
|
|
221
221
|
If your component is defined in an installed package, you can declare an
|
|
@@ -35,6 +35,13 @@ class BaseConnection(ABC, Generic[RawConnectionT]):
|
|
|
35
35
|
implementation of connections more convenient. See the docstrings for each of the
|
|
36
36
|
methods of this class for more information
|
|
37
37
|
|
|
38
|
+
By default, ``BaseConnection`` is a global-scoped connection. It has a class
|
|
39
|
+
method |BaseConnection.scope()|_ that returns ``"global"``. To implement a session-scoped
|
|
40
|
+
connection, override this method to return ``"session"`` in your subclass.
|
|
41
|
+
|
|
42
|
+
.. |BaseConnection.scope()| replace:: ``BaseConnection.scope()``
|
|
43
|
+
.. _BaseConnection.scope(): #baseconnectionscope
|
|
44
|
+
|
|
38
45
|
.. note::
|
|
39
46
|
While providing an implementation of ``_connect`` is technically all that's
|
|
40
47
|
required to define a valid connection, connections should also provide the user
|
|
@@ -179,14 +186,19 @@ class BaseConnection(ABC, Generic[RawConnectionT]):
|
|
|
179
186
|
def scope(cls) -> Literal["global", "session"]:
|
|
180
187
|
"""Returns the scope of this connection type.
|
|
181
188
|
|
|
182
|
-
"global" connection instances will be cached
|
|
183
|
-
once during the lifetime of an
|
|
184
|
-
|
|
189
|
+
This is a class method. ``"global"`` connection instances will be cached
|
|
190
|
+
globally and are typically created once during the lifetime of an
|
|
191
|
+
application. ``"session"`` connection instances will be cached per
|
|
192
|
+
session and are typically created once per user session.
|
|
193
|
+
|
|
194
|
+
A connection's scope can't be changed for different instances of the
|
|
195
|
+
same connection type. If you want to switch between global and
|
|
196
|
+
session-scoped connections, you should create two different connection
|
|
197
|
+
types.
|
|
185
198
|
|
|
186
199
|
Returns
|
|
187
200
|
-------
|
|
188
201
|
"global" or "session"
|
|
189
|
-
The scope of this connection type.
|
|
190
202
|
"""
|
|
191
203
|
return "global"
|
|
192
204
|
|
|
@@ -54,211 +54,12 @@ SNOWPARK_USER_TOKEN_HEADER_NAME = "Sf-Context-Current-User-Token" # noqa: S105
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
class BaseSnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
57
|
-
"""
|
|
58
|
-
|
|
59
|
-
For standard connections, create an instance of this using
|
|
60
|
-
``st.connection("snowflake")`` or
|
|
61
|
-
``st.connection("<name>", type="snowflake")``. Connection parameters for a
|
|
62
|
-
SnowflakeConnection can be specified using ``secrets.toml`` and/or
|
|
63
|
-
``**kwargs``. Connection parameters are passed to
|
|
64
|
-
|snowflake.connector.connect()|.
|
|
65
|
-
|
|
66
|
-
When an app is running in Streamlit in Snowflake,
|
|
67
|
-
``st.connection("snowflake")`` connects automatically using the app owner's
|
|
68
|
-
role without further configuration. ``**kwargs`` will be ignored in this
|
|
69
|
-
case. Use ``secrets.toml`` and ``**kwargs`` to configure your connection
|
|
70
|
-
for local development.
|
|
71
|
-
|
|
72
|
-
When an app is running in Snowpark Container Services and has caller's rights
|
|
73
|
-
enabled, ``st.connection("snowflake-callers-rights")`` connects automatically
|
|
74
|
-
using the current user's identity tokens. This will be a session-scoped connection
|
|
75
|
-
to ensure that the identity stays tied to the active user. Unlike with
|
|
76
|
-
``"snowflake"`` connections, it will use the Snowpark Container Services connection
|
|
77
|
-
settings even when other ``**kwargs`` are provided.
|
|
78
|
-
|
|
79
|
-
BaseSnowflakeConnection includes several convenience methods. For example, you
|
|
80
|
-
can directly execute a SQL query with ``.query()`` or access the underlying
|
|
81
|
-
Snowflake Connector object with ``.raw_connection``.
|
|
82
|
-
|
|
83
|
-
.. |snowflake.connector.connect()| replace:: ``snowflake.connector.connect()``
|
|
84
|
-
.. _snowflake.connector.connect(): https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#label-snowflake-connector-methods-connect
|
|
85
|
-
|
|
86
|
-
.. Important::
|
|
87
|
-
`snowflake-snowpark-python <https://pypi.org/project/snowflake-snowpark-python/>`_
|
|
88
|
-
must be installed in your environment to use this connection. You can
|
|
89
|
-
install it as an extra with Streamlit:
|
|
90
|
-
|
|
91
|
-
.. code-block:: shell
|
|
92
|
-
|
|
93
|
-
pip install streamlit[snowflake]
|
|
94
|
-
|
|
95
|
-
.. Important::
|
|
96
|
-
Account identifiers must be of the form ``<orgname>-<account_name>``
|
|
97
|
-
where ``<orgname>`` is the name of your Snowflake organization and
|
|
98
|
-
``<account_name>`` is the unique name of your account within your
|
|
99
|
-
organization. This is dash-separated, not dot-separated like when used
|
|
100
|
-
in SQL queries. For more information, see `Account identifiers
|
|
101
|
-
<https://docs.snowflake.com/en/user-guide/admin-account-identifier>`_.
|
|
102
|
-
|
|
103
|
-
.. Important::
|
|
104
|
-
Caller's rights connections rely on credentials provided when a user first
|
|
105
|
-
connects to a Streamlit app. These credentials are only valid for a short period
|
|
106
|
-
of time - so caller's rights connections must be created at the top of an app
|
|
107
|
-
or else the connection may fail.
|
|
108
|
-
|
|
109
|
-
Examples
|
|
110
|
-
--------
|
|
111
|
-
**Example 1: Configuration with Streamlit secrets**
|
|
112
|
-
|
|
113
|
-
You can configure your Snowflake connection using Streamlit's
|
|
114
|
-
`Secrets management <https://docs.streamlit.io/develop/concepts/connections/secrets-management>`_.
|
|
115
|
-
For example, if you have MFA enabled on your account, you can connect using
|
|
116
|
-
`key-pair authentication <https://docs.snowflake.com/en/user-guide/key-pair-auth>`_.
|
|
117
|
-
|
|
118
|
-
``.streamlit/secrets.toml``:
|
|
119
|
-
|
|
120
|
-
>>> [connections.snowflake]
|
|
121
|
-
>>> account = "xxx-xxx"
|
|
122
|
-
>>> user = "xxx"
|
|
123
|
-
>>> private_key_file = "/xxx/xxx/xxx.p8"
|
|
124
|
-
>>> role = "xxx"
|
|
125
|
-
>>> warehouse = "xxx"
|
|
126
|
-
>>> database = "xxx"
|
|
127
|
-
>>> schema = "xxx"
|
|
128
|
-
|
|
129
|
-
Your app code:
|
|
130
|
-
|
|
131
|
-
>>> import streamlit as st
|
|
132
|
-
>>> conn = st.connection("snowflake")
|
|
133
|
-
>>> df = conn.query("SELECT * FROM my_table")
|
|
134
|
-
|
|
135
|
-
**Example 2: Configuration with keyword arguments and external authentication**
|
|
136
|
-
|
|
137
|
-
You can configure your Snowflake connection with keyword arguments. The
|
|
138
|
-
keyword arguments are merged with (and take precedence over) the values in
|
|
139
|
-
``secrets.toml``. However, if you name your connection ``"snowflake"`` and
|
|
140
|
-
don't have a ``[connections.snowflake]`` dictionary in your
|
|
141
|
-
``secrets.toml`` file, Streamlit will ignore any keyword arguments and use
|
|
142
|
-
the default Snowflake connection as described in Example 5 and Example 6.
|
|
143
|
-
To configure your connection using only keyword arguments, declare a name
|
|
144
|
-
for the connection other than ``"snowflake"``.
|
|
145
|
-
|
|
146
|
-
For example, if your Snowflake account supports SSO, you can set up a quick
|
|
147
|
-
local connection for development using `browser-based SSO
|
|
148
|
-
<https://docs.snowflake.com/en/user-guide/admin-security-fed-auth-use#how-browser-based-sso-works>`_.
|
|
149
|
-
Because there is nothing configured in ``secrets.toml``, the name is an
|
|
150
|
-
empty string and the type is set to ``"snowflake"``. This prevents
|
|
151
|
-
Streamlit from ignoring the keyword arguments and using a default
|
|
152
|
-
Snowflake connection.
|
|
153
|
-
|
|
154
|
-
>>> import streamlit as st
|
|
155
|
-
>>> conn = st.connection(
|
|
156
|
-
... "",
|
|
157
|
-
... type="snowflake",
|
|
158
|
-
... account="xxx-xxx",
|
|
159
|
-
... user="xxx",
|
|
160
|
-
... authenticator="externalbrowser",
|
|
161
|
-
... )
|
|
162
|
-
>>> df = conn.query("SELECT * FROM my_table")
|
|
163
|
-
|
|
164
|
-
**Example 3: Named connection with Snowflake's connection configuration file**
|
|
165
|
-
|
|
166
|
-
Snowflake's Python Connector supports a `connection configuration file
|
|
167
|
-
<https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-connect#connecting-using-the-connections-toml-file>`_,
|
|
168
|
-
which is well integrated with Streamlit's ``SnowflakeConnection``. If you
|
|
169
|
-
already have one or more connections configured, all you need to do is pass
|
|
170
|
-
the name of the connection to use.
|
|
171
|
-
|
|
172
|
-
``~/.snowflake/connections.toml``:
|
|
173
|
-
|
|
174
|
-
>>> [my_connection]
|
|
175
|
-
>>> account = "xxx-xxx"
|
|
176
|
-
>>> user = "xxx"
|
|
177
|
-
>>> password = "xxx"
|
|
178
|
-
>>> warehouse = "xxx"
|
|
179
|
-
>>> database = "xxx"
|
|
180
|
-
>>> schema = "xxx"
|
|
181
|
-
|
|
182
|
-
Your app code:
|
|
183
|
-
|
|
184
|
-
>>> import streamlit as st
|
|
185
|
-
>>> conn = st.connection("my_connection", type="snowflake")
|
|
186
|
-
>>> df = conn.query("SELECT * FROM my_table")
|
|
187
|
-
|
|
188
|
-
**Example 4: Named connection with Streamlit secrets and Snowflake's connection configuration file**
|
|
189
|
-
|
|
190
|
-
If you have a Snowflake configuration file with a connection named
|
|
191
|
-
``my_connection`` as in Example 3, you can pass the connection name through
|
|
192
|
-
``secrets.toml``.
|
|
193
|
-
|
|
194
|
-
``.streamlit/secrets.toml``:
|
|
195
|
-
|
|
196
|
-
>>> [connections.snowflake]
|
|
197
|
-
>>> connection_name = "my_connection"
|
|
198
|
-
|
|
199
|
-
Your app code:
|
|
200
|
-
|
|
201
|
-
>>> import streamlit as st
|
|
202
|
-
>>> conn = st.connection("snowflake")
|
|
203
|
-
>>> df = conn.query("SELECT * FROM my_table")
|
|
204
|
-
|
|
205
|
-
**Example 5: Default connection with an environment variable**
|
|
206
|
-
|
|
207
|
-
If you don't have a ``[connections.snowflake]`` dictionary in your
|
|
208
|
-
``secrets.toml`` file and use ``st.connection("snowflake")``, Streamlit
|
|
209
|
-
will use the default connection for the `Snowflake Python Connector
|
|
210
|
-
<https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-connect#setting-a-default-connection>`_.
|
|
211
|
-
|
|
212
|
-
If you have a Snowflake configuration file with a connection named
|
|
213
|
-
``my_connection`` as in Example 3, you can set an environment variable to
|
|
214
|
-
declare it as the default Snowflake connection.
|
|
215
|
-
|
|
216
|
-
>>> SNOWFLAKE_DEFAULT_CONNECTION_NAME = "my_connection"
|
|
217
|
-
|
|
218
|
-
Your app code:
|
|
219
|
-
|
|
220
|
-
>>> import streamlit as st
|
|
221
|
-
>>> conn = st.connection("snowflake")
|
|
222
|
-
>>> df = conn.query("SELECT * FROM my_table")
|
|
223
|
-
|
|
224
|
-
**Example 6: Default connection in Snowflake's connection configuration file**
|
|
225
|
-
|
|
226
|
-
If you have a Snowflake configuration file that defines your ``default``
|
|
227
|
-
connection, Streamlit will automatically use it if no other connection is
|
|
228
|
-
declared.
|
|
229
|
-
|
|
230
|
-
``~/.snowflake/connections.toml``:
|
|
231
|
-
|
|
232
|
-
>>> [default]
|
|
233
|
-
>>> account = "xxx-xxx"
|
|
234
|
-
>>> user = "xxx"
|
|
235
|
-
>>> password = "xxx"
|
|
236
|
-
>>> warehouse = "xxx"
|
|
237
|
-
>>> database = "xxx"
|
|
238
|
-
>>> schema = "xxx"
|
|
239
|
-
|
|
240
|
-
Your app code:
|
|
241
|
-
|
|
242
|
-
>>> import streamlit as st
|
|
243
|
-
>>> conn = st.connection("snowflake")
|
|
244
|
-
>>> df = conn.query("SELECT * FROM my_table")
|
|
245
|
-
|
|
246
|
-
**Example 7: Caller's rights connection when running in Snowpark Container Services**
|
|
247
|
-
|
|
248
|
-
This connection will work for any Streamlit-in-Snowflake app using a container
|
|
249
|
-
runtime, as well as any self-managed caller's rights Service in Snowpark Container
|
|
250
|
-
Services that is hosting Streamlit.
|
|
251
|
-
|
|
252
|
-
This will use the Snowpark-provided account, host, database, and schema to connect.
|
|
253
|
-
Additionally, it will set ``client_session_keep_alive`` to ``True``. These values
|
|
254
|
-
may be overridden with ``**kwargs``.
|
|
255
|
-
|
|
256
|
-
Your app code:
|
|
257
|
-
|
|
258
|
-
>>> import streamlit as st
|
|
259
|
-
>>> conn = st.connection("snowflake-callers-rights")
|
|
260
|
-
>>> df = conn.query("SELECT * FROM my_table")
|
|
57
|
+
"""Base class for Snowflake connections.
|
|
261
58
|
|
|
59
|
+
This base class provides the common methods and properties for Snowflake
|
|
60
|
+
connections. See the docstrings for each of these methods for more
|
|
61
|
+
information. The docstring for ``SnowflakeConnection`` provides an overall
|
|
62
|
+
description of the Snowflake connection types.
|
|
262
63
|
"""
|
|
263
64
|
|
|
264
65
|
def query(
|
|
@@ -553,7 +354,255 @@ class BaseSnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
|
553
354
|
class SnowflakeConnection(BaseSnowflakeConnection):
|
|
554
355
|
"""A connection to Snowflake using the Snowflake Connector for Python.
|
|
555
356
|
|
|
556
|
-
|
|
357
|
+
For standard connections, create an instance of this using
|
|
358
|
+
``st.connection("snowflake")`` or
|
|
359
|
+
``st.connection("<name>", type="snowflake")``. Connection parameters for a
|
|
360
|
+
SnowflakeConnection can be specified using ``secrets.toml`` and/or
|
|
361
|
+
``**kwargs``. Connection parameters are passed to
|
|
362
|
+
|snowflake.connector.connect()|_.
|
|
363
|
+
|
|
364
|
+
When an app is running in Streamlit in Snowflake,
|
|
365
|
+
``st.connection("snowflake")`` connects automatically using the app owner's
|
|
366
|
+
role without further configuration. ``**kwargs`` are ignored in this
|
|
367
|
+
case. Use ``secrets.toml`` and ``**kwargs`` to configure your connection
|
|
368
|
+
for local development.
|
|
369
|
+
|
|
370
|
+
When an app is running in Snowpark Container Services and has caller's rights
|
|
371
|
+
enabled, ``st.connection("snowflake-callers-rights")`` connects automatically
|
|
372
|
+
using the current user's identity tokens. This is a session-scoped connection
|
|
373
|
+
to ensure that the identity stays tied to the active user. Unlike with
|
|
374
|
+
``"snowflake"`` connections, it will use the Snowpark Container Services
|
|
375
|
+
connection settings even when other ``**kwargs`` are provided.
|
|
376
|
+
|
|
377
|
+
The Snowflake connection includes several convenience methods. For example, you
|
|
378
|
+
can directly execute a SQL query with ``.query()`` or access the underlying
|
|
379
|
+
Snowflake Connector object with ``.raw_connection``.
|
|
380
|
+
|
|
381
|
+
.. |snowflake.connector.connect()| replace:: ``snowflake.connector.connect()``
|
|
382
|
+
.. _snowflake.connector.connect(): https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#label-snowflake-connector-methods-connect
|
|
383
|
+
|
|
384
|
+
.. Important::
|
|
385
|
+
- `snowflake-snowpark-python <https://pypi.org/project/snowflake-snowpark-python/>`_
|
|
386
|
+
must be installed in your environment to use this connection. You can
|
|
387
|
+
install it as an extra with Streamlit:
|
|
388
|
+
|
|
389
|
+
.. code-block:: shell
|
|
390
|
+
|
|
391
|
+
pip install streamlit[snowflake]
|
|
392
|
+
|
|
393
|
+
- Account identifiers must be of the form ``<orgname>-<account_name>``
|
|
394
|
+
where ``<orgname>`` is the name of your Snowflake organization and
|
|
395
|
+
``<account_name>`` is the unique name of your account within your
|
|
396
|
+
organization. This is dash-separated, not dot-separated like when used
|
|
397
|
+
in SQL queries. For more information, see `Account identifiers
|
|
398
|
+
<https://docs.snowflake.com/en/user-guide/admin-account-identifier>`_.
|
|
399
|
+
|
|
400
|
+
- Caller's rights connections rely on credentials provided when a user first
|
|
401
|
+
connects to a Streamlit app. These credentials are only valid for about
|
|
402
|
+
two minutes. Therefore, caller's rights connections must be created at
|
|
403
|
+
the top of an app or else the connection may fail.
|
|
404
|
+
|
|
405
|
+
- To develop locally with a caller's rights connection, use an
|
|
406
|
+
environment variable to logically switch between a ``"snowflake"``
|
|
407
|
+
connection locally and a ``"snowflake-callers-rights"`` connection in
|
|
408
|
+
Snowpark Container Services.
|
|
409
|
+
|
|
410
|
+
Examples
|
|
411
|
+
--------
|
|
412
|
+
**Example 1: Configuration with Streamlit secrets**
|
|
413
|
+
|
|
414
|
+
You can configure your Snowflake connection using Streamlit's
|
|
415
|
+
`Secrets management <https://docs.streamlit.io/develop/concepts/connections/secrets-management>`_.
|
|
416
|
+
For example, if you have MFA enabled on your account, you can connect using
|
|
417
|
+
`key-pair authentication <https://docs.snowflake.com/en/user-guide/key-pair-auth>`_.
|
|
418
|
+
|
|
419
|
+
.. code-block:: toml
|
|
420
|
+
:filename: ~/.snowflake/connections.toml
|
|
421
|
+
|
|
422
|
+
[connections.snowflake]
|
|
423
|
+
account = "xxx-xxx"
|
|
424
|
+
user = "xxx"
|
|
425
|
+
private_key_file = "/xxx/xxx/xxx.p8"
|
|
426
|
+
role = "xxx"
|
|
427
|
+
warehouse = "xxx"
|
|
428
|
+
database = "xxx"
|
|
429
|
+
schema = "xxx"
|
|
430
|
+
|
|
431
|
+
.. code-block:: python
|
|
432
|
+
:filename: streamlit_app.py
|
|
433
|
+
|
|
434
|
+
import streamlit as st
|
|
435
|
+
|
|
436
|
+
conn = st.connection("snowflake")
|
|
437
|
+
df = conn.query("SELECT * FROM my_table")
|
|
438
|
+
|
|
439
|
+
**Example 2: Configuration with keyword arguments and external authentication**
|
|
440
|
+
|
|
441
|
+
You can configure your Snowflake connection with keyword arguments. The
|
|
442
|
+
keyword arguments are merged with (and take precedence over) the values in
|
|
443
|
+
``secrets.toml``. However, if you name your connection ``"snowflake"`` and
|
|
444
|
+
don't have a ``[connections.snowflake]`` dictionary in your
|
|
445
|
+
``secrets.toml`` file, Streamlit will ignore any keyword arguments and use
|
|
446
|
+
the default Snowflake connection as described in Example 5 and Example 6.
|
|
447
|
+
To configure your connection using only keyword arguments, declare a name
|
|
448
|
+
for the connection other than ``"snowflake"``.
|
|
449
|
+
|
|
450
|
+
For example, if your Snowflake account supports SSO, you can set up a quick
|
|
451
|
+
local connection for development using `browser-based SSO
|
|
452
|
+
<https://docs.snowflake.com/en/user-guide/admin-security-fed-auth-use#how-browser-based-sso-works>`_.
|
|
453
|
+
Because there is nothing configured in ``secrets.toml``, the name is an
|
|
454
|
+
empty string and the type is set to ``"snowflake"``. This prevents
|
|
455
|
+
Streamlit from ignoring the keyword arguments and using a default
|
|
456
|
+
Snowflake connection.
|
|
457
|
+
|
|
458
|
+
.. code-block:: python
|
|
459
|
+
:filename: streamlit_app.py
|
|
460
|
+
|
|
461
|
+
import streamlit as st
|
|
462
|
+
|
|
463
|
+
conn = st.connection(
|
|
464
|
+
"",
|
|
465
|
+
type="snowflake",
|
|
466
|
+
account="xxx-xxx",
|
|
467
|
+
user="xxx",
|
|
468
|
+
authenticator="externalbrowser",
|
|
469
|
+
)
|
|
470
|
+
df = conn.query("SELECT * FROM my_table")
|
|
471
|
+
|
|
472
|
+
**Example 3: Named connection with Snowflake's connection configuration file**
|
|
473
|
+
|
|
474
|
+
Snowflake's Python Connector supports a `connection configuration file
|
|
475
|
+
<https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-connect#connecting-using-the-connections-toml-file>`_,
|
|
476
|
+
which is well integrated with Streamlit's ``SnowflakeConnection``. If you
|
|
477
|
+
already have one or more connections configured, all you need to do is pass
|
|
478
|
+
the name of the connection to use.
|
|
479
|
+
|
|
480
|
+
.. code-block:: toml
|
|
481
|
+
:filename: ~/.snowflake/connections.toml
|
|
482
|
+
|
|
483
|
+
[my_connection]
|
|
484
|
+
account = "xxx-xxx"
|
|
485
|
+
user = "xxx"
|
|
486
|
+
password = "xxx"
|
|
487
|
+
warehouse = "xxx"
|
|
488
|
+
database = "xxx"
|
|
489
|
+
schema = "xxx"
|
|
490
|
+
|
|
491
|
+
.. code-block:: python
|
|
492
|
+
:filename: streamlit_app.py
|
|
493
|
+
|
|
494
|
+
import streamlit as st
|
|
495
|
+
|
|
496
|
+
conn = st.connection("my_connection", type="snowflake")
|
|
497
|
+
df = conn.query("SELECT * FROM my_table")
|
|
498
|
+
|
|
499
|
+
**Example 4: Named connection with Streamlit secrets and Snowflake's connection configuration file**
|
|
500
|
+
|
|
501
|
+
If you have a Snowflake configuration file with a connection named
|
|
502
|
+
``my_connection`` as in Example 3, you can pass the connection name through
|
|
503
|
+
``secrets.toml``.
|
|
504
|
+
|
|
505
|
+
.. code-block:: toml
|
|
506
|
+
:filename: .streamlit/secrets.toml
|
|
507
|
+
|
|
508
|
+
[connections.snowflake]
|
|
509
|
+
connection_name = "my_connection"
|
|
510
|
+
|
|
511
|
+
.. code-block:: python
|
|
512
|
+
:filename: streamlit_app.py
|
|
513
|
+
|
|
514
|
+
import streamlit as st
|
|
515
|
+
|
|
516
|
+
conn = st.connection("snowflake")
|
|
517
|
+
df = conn.query("SELECT * FROM my_table")
|
|
518
|
+
|
|
519
|
+
**Example 5: Default connection with an environment variable**
|
|
520
|
+
|
|
521
|
+
If you don't have a ``[connections.snowflake]`` dictionary in your
|
|
522
|
+
``secrets.toml`` file and use ``st.connection("snowflake")``, Streamlit
|
|
523
|
+
will use the default connection for the `Snowflake Python Connector
|
|
524
|
+
<https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-connect#setting-a-default-connection>`_.
|
|
525
|
+
|
|
526
|
+
If you have a Snowflake configuration file with a connection named
|
|
527
|
+
``my_connection`` as in Example 3, you can set an environment variable to
|
|
528
|
+
declare it as the default Snowflake connection.
|
|
529
|
+
|
|
530
|
+
.. code-block:: toml
|
|
531
|
+
:filename: .streamlit/secrets.toml
|
|
532
|
+
|
|
533
|
+
SNOWFLAKE_DEFAULT_CONNECTION_NAME = "my_connection"
|
|
534
|
+
|
|
535
|
+
.. code-block:: python
|
|
536
|
+
:filename: streamlit_app.py
|
|
537
|
+
|
|
538
|
+
import streamlit as st
|
|
539
|
+
|
|
540
|
+
conn = st.connection("snowflake")
|
|
541
|
+
df = conn.query("SELECT * FROM my_table")
|
|
542
|
+
|
|
543
|
+
**Example 6: Default connection in Snowflake's connection configuration file**
|
|
544
|
+
|
|
545
|
+
If you have a Snowflake configuration file that defines your ``default``
|
|
546
|
+
connection, Streamlit will automatically use it if no other connection is
|
|
547
|
+
declared.
|
|
548
|
+
|
|
549
|
+
.. code-block:: toml
|
|
550
|
+
:filename: ~/.snowflake/connections.toml
|
|
551
|
+
|
|
552
|
+
[default]
|
|
553
|
+
account = "xxx-xxx"
|
|
554
|
+
user = "xxx"
|
|
555
|
+
password = "xxx"
|
|
556
|
+
warehouse = "xxx"
|
|
557
|
+
database = "xxx"
|
|
558
|
+
schema = "xxx"
|
|
559
|
+
|
|
560
|
+
.. code-block:: python
|
|
561
|
+
:filename: streamlit_app.py
|
|
562
|
+
|
|
563
|
+
import streamlit as st
|
|
564
|
+
|
|
565
|
+
conn = st.connection("snowflake")
|
|
566
|
+
df = conn.query("SELECT * FROM my_table")
|
|
567
|
+
|
|
568
|
+
**Example 7: Caller's rights connection when running in Snowpark Container Services**
|
|
569
|
+
|
|
570
|
+
You can use ``"snowflake-callers-rights"`` type connections in any
|
|
571
|
+
environment running on Snowpark Container Services, including Streamlit in
|
|
572
|
+
Snowflake on containers and any self-managed caller's rights Service.
|
|
573
|
+
|
|
574
|
+
This will use the Snowpark-provided account, host, database, and schema to connect.
|
|
575
|
+
Additionally, it will set ``client_session_keep_alive`` to ``True``. These values
|
|
576
|
+
may be overridden with ``**kwargs`` in ``st.connection``. For a complete list
|
|
577
|
+
of keyword arguments, see the documentation for |snowflake.connector.connect()|_.
|
|
578
|
+
|
|
579
|
+
.. |snowflake.connector.connect()| replace:: ``snowflake.connector.connect()``
|
|
580
|
+
.. _snowflake.connector.connect(): https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#label-snowflake-connector-methods-connect
|
|
581
|
+
|
|
582
|
+
.. code-block:: python
|
|
583
|
+
:filename: streamlit_app.py
|
|
584
|
+
|
|
585
|
+
import streamlit as st
|
|
586
|
+
|
|
587
|
+
conn = st.connection("snowflake-callers-rights")
|
|
588
|
+
df = conn.query("SELECT * FROM my_table")
|
|
589
|
+
|
|
590
|
+
If you want to develop locally with a caller's rights connection, use an
|
|
591
|
+
environment variable to logically switch between a ``"snowflake"``
|
|
592
|
+
connection locally and a ``"snowflake-callers-rights"`` connection in
|
|
593
|
+
Snowpark Container Services.
|
|
594
|
+
|
|
595
|
+
.. code-block:: python
|
|
596
|
+
:filename: streamlit_app.py
|
|
597
|
+
|
|
598
|
+
import streamlit as st
|
|
599
|
+
|
|
600
|
+
conn = (
|
|
601
|
+
st.connection("snowflake")
|
|
602
|
+
if "LOCAL_DEVELOPMENT" in st.secrets and st.secrets["LOCAL_DEVELOPMENT"]
|
|
603
|
+
else st.connection("snowflake-callers-rights")
|
|
604
|
+
)
|
|
605
|
+
df = conn.query("SELECT * FROM my_table")
|
|
557
606
|
"""
|
|
558
607
|
|
|
559
608
|
def _connect(self, **kwargs: Any) -> InternalSnowflakeConnection:
|
streamlit/elements/form.py
CHANGED
|
@@ -341,8 +341,8 @@ class FormMixin:
|
|
|
341
341
|
- ``"spinner"``: Displays a spinner as an icon.
|
|
342
342
|
|
|
343
343
|
icon_position : "left" or "right"
|
|
344
|
-
The position of the icon relative to the button label.
|
|
345
|
-
``"left"``.
|
|
344
|
+
The position of the icon relative to the button label. This
|
|
345
|
+
defaults to ``"left"``.
|
|
346
346
|
|
|
347
347
|
disabled : bool
|
|
348
348
|
Whether to disable the button. If this is ``False`` (default), the
|