Additional Streamlit in Snowflake features¶
This topic describes additional Streamlit in Snowflake features.
Custom UI in Streamlit in Snowflake¶
Custom UI enables customization of the look, feel, and front-end behavior of Streamlit in Snowflake apps. This feature supports the following:
Custom HTML and CSS using
unsafe_allow_html=True
in st.markdown.Iframed HTML, CSS, and JavaScript using st.components.v1.html.
Note
Custom UI has some restrictions related to the Content Security Policy (CSP). For more information, see Limitations when loading external resources in Streamlit in Snowflake.
To start customizing your Streamlit in Snowflake app, simply call st.components.v1.html
, or st.markdown
with unsafe_allow_html=True
.
The provided HTML is added to the app front end in the user’s browser.
Note
You must specify the inline HTML or load the HTML into a string. You cannot pass a URL or a file path directly to the command to run or embed.
See the following examples for customizing your Streamlit in Snowflake apps:
Customize your sidebar background color:
st.markdown(""" <style> [data-testid=stSidebar] { background-color: #94d3e6; } </style> """, unsafe_allow_html=True)
Add an app logo with
streamlit-extras
:Make sure to install the
streamlit-extras
package before running.from streamlit_extras.app_logo import add_logo add_logo("./Logo.png", height=60)
Set the sidebar width programmatically:
import streamlit.components.v1 as components components.html(""" <script> window.parent.document.querySelector('[data-testid="stSidebar"]').style.width = "300px"; </script> """, height=0)
Create an in-browser DataFrame exploratory data analysis (EDA) with
ydata-profiling
:import streamlit as st import streamlit.components.v1 as components from sklearn.datasets import load_iris from ydata_profiling import ProfileReport st.set_page_config(layout="wide") df = load_iris(as_frame=True).data html = ProfileReport(df).to_html() components.html(html, height=500, scrolling=True)
External network access in Streamlit in Snowflake¶
You can create secure access to specific network locations external to Snowflake, and you can use that access from within the Streamlit app code. You can enable access through an external access integration.
To enable a Streamlit app to use an external access integration, you can run the CREATE STREAMLIT or ALTER STREAMLIT command and set the EXTERNAL_ACCESS_INTEGRATIONS parameter to include that integration.
With an external access integration, you can use Python libraries that access external locations, such as requests
or urllib
,
and use third-party libraries which require access to a network location.
For more information, see External network access overview.
Example: Access the OpenAI API¶
The following example shows how to create an external access integration for an outbound request to the OpenAI API. This example includes setting up the security integration and granting the required privileges.
To create a network rule that represents the external network’s location and restrictions for access, use the CREATE NETWORK RULE command as shown in the following example:
CREATE OR REPLACE NETWORK RULE network_rules MODE = EGRESS TYPE = HOST_PORT VALUE_LIST = ('api.openai.com');
For more information, see Creating a network rule to represent the external network location.
To create a secret that represents credentials required to authenticate with the external network location, use the CREATE SECRET command as shown in the following example:
CREATE OR REPLACE SECRET openai_key TYPE = GENERIC_STRING SECRET_STRING = '<any_string>';
For more information, see Creating a secret to represent credentials.
To create an external access integration, run the CREATE EXTERNAL ACCESS INTEGRATION command, setting ALLOWED_NETWORK_RULES to the network rule you created and ALLOWED_AUTHENTICATION_SECRETS to the secret you created:
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION openai_access_int ALLOWED_NETWORK_RULES = (network_rules) ALLOWED_AUTHENTICATION_SECRETS = (openai_key) ENABLED = TRUE;
To grant the required privileges to use the SECRET and INTEGRATION objects for external access to the Streamlit app creator, use the GRANT <privileges> command as shown in the following example:
GRANT READ ON SECRET openai_key TO ROLE streamlit_app_creator_role; GRANT USAGE ON INTEGRATION openai_access_int TO ROLE streamlit_app_creator_role;
To enable the Streamlit app to use the integration, run the ALTER STREAMLIT command, setting the EXTERNAL_ACCESS_INTEGRATIONS property to the integration as shown in the following example:
USE ROLE streamlit_app_creator_role; ALTER STREAMLIT streamlit_db.streamlit_schema.streamlit_app SET EXTERNAL_ACCESS_INTEGRATIONS = (openai_access_int) SECRETS = ('my_openai_key' = streamlit_db.streamlit_schema.openai_key);
Note
You can also set up a new Streamlit object to use an external access integration by specifying the EXTERNAL_ACCESS_INTEGRATIONS parameter when you run the CREATE STREAMLIT command, as shown in the following example:
CREATE STREAMLIT streamlit_db.streamlit_schema.streamlit_app ROOT_LOCATION = '<stage_path_and_root_directory>' MAIN_FILE = '<path_to_main_file_in_root_directory>' EXTERNAL_ACCESS_INTEGRATIONS = (openai_access_int) SECRETS = ('my_openai_key' = streamlit_db.streamlit_schema.openai_key);
In your Streamlit app code, call the external API, as shown in the following example:
from openai import OpenAI import streamlit as st import _snowflake st.title(":speech_balloon: Simple chat app using an external LLM") st.write("This app shows how to call an external LLM to build a simple chat application.") # Use the _snowflake library to access secrets secret = _snowflake.get_generic_secret_string('my_openai_key') client = OpenAI(api_key=secret) # ... # code to use API # ...
Custom sleep timer for a Streamlit app¶
You can set a custom sleep timer for a Streamlit app to auto-suspend. To set the custom sleep timer, create
a config.toml
configuration file inside the .streamlit
folder on the path specified by
the ROOT_LOCATION
parameter of the STREAMLIT object.
For example, if you want the Streamlit app to auto-suspend after 8 minutes, add the following to the config.toml
file:
[snowflake]
[snowflake.sleep]
streamlitSleepTimeoutMinutes = 8
Upload the config.toml
file to the stage location as shown in the following example:
PUT file:///<path_to_your_root_folder>/my_app/config.toml @streamlit_db.streamlit_schema.streamlit_stage/.streamlit/ overwrite=true auto_compress=false;
For more information on working with Streamlit files, see Create and deploy Streamlit apps using SQL.
Note
You can set the streamlitSleepTimeoutMinutes
to any value between 5 to 240 minutes.
If you do not create the configuration file to specify the timer, the default auto-suspend time is 15 minutes.
Context functions and row access policies in Streamlit in Snowflake¶
To use context functions, such as CURRENT_USER, and data from tables with row access policies in a Streamlit in Snowflake app, a user with the ACCOUNTADMIN role must grant the global READ SESSION privilege to the Streamlit app owner role, as shown in the following example:
USE ROLE ACCOUNTADMIN;
GRANT READ SESSION ON ACCOUNT TO ROLE streamlit_owner_role;
Note
In a Streamlit in Snowflake app, you can’t use row access policies that use CURRENT_ROLE. Streamlit in Snowflake apps run with owner’s rights, so using CURRENT_ROLE inside a Streamlit app always returns the app owner role. For more information, see Understanding owner’s rights and Streamlit in Snowflake apps.
Example: Access data in a table with row access policy using CURRENT_USER¶
You can use a Streamlit in Snowflake app to govern access to rows in a table protected by a row access policy. Specify the CURRENT_USER function in the body of the row access policy and add the row access policy to the table.
The following example demonstrates how to govern access to a table that is protected by a row access policy in a Streamlit in Snowflake app.
Create a table and insert data:
CREATE TABLE row_access_policy_test_table ( id INT, some_data VARCHAR(100), the_owner VARCHAR(50) ); INSERT INTO row_access_policy_test_table (id, some_data, the_owner) VALUES (4, 'Some information 4', 'ALICE'), (5, 'Some information 5', 'FRANK'), (6, 'Some information 6', 'ALICE');
Create a row access policy:
CREATE OR REPLACE ROW ACCESS POLICY st_schema.row_access_policy AS (the_owner VARCHAR) RETURNS BOOLEAN -> the_owner = CURRENT_USER();
Add the row access policy to the table:
ALTER TABLE row_access_policy_test_table ADD ROW ACCESS POLICY st_schema.row_access_policy ON (the_owner);
Create a Streamlit app.
Grant the global READ SESSION privilege to the Streamlit app owner role:
GRANT READ SESSION ON ACCOUNT TO ROLE streamlit_owner_role;
Add the following code to your Streamlit app:
# Import Python packages import streamlit as st from snowflake.snowpark.context import get_active_session st.title("CURRENT_USER() + Row Access Policy in SiS Demo :balloon:") st.write( """You can access `CURRENT_USER()` and data from tables with row access policies in Streamlit in Snowflake apps """) # Get the current credentials session = get_active_session() st.header('Demo') st.subheader('Credentials') sql = "SELECT CURRENT_USER();" df = session.sql(sql).collect() st.write(df) st.subheader('Row Access on a Table') sql = "SELECT * FROM st_db.st_schema.row_access_policy_test_table;" df = session.sql(sql).collect() st.write(df)