Working in Snowflake
View

Streamlit in Snowflake

Build Python data apps that run inside Snowflake — no separate hosting, no connection strings. The app executes in Snowpark using its own role and warehouse, so it only ever sees what that role can SELECT.

What it is

Streamlit in Snowflake (SiS) runs a Streamlit app entirely inside Snowflake. The Python code, the compute, and the data access all live in the account: there is no external web server to provision, no credentials to store, and no egress of RWD data to a third-party host. You write a normal Streamlit script, deploy it as a Snowflake object, and Snowsight serves it.

This is different from running Streamlit externally (on your laptop, a container, or a VM) and connecting back to Snowflake over the network. That external pattern needs a connector, stored credentials, and a network path, and it pulls data out of the platform. SiS avoids all of that — the app already runs where the data lives and inherits the calling role's grants.

Access

The add-on role is requested via Slack in #ndp-rwd-connect-core. See the How to Grant Access page for the request flow and the Snowflake Role Reference page for where this role sits in the hierarchy and what your base role can read — the app inherits exactly those grants.

Create and deploy an app

In Snowsight (app.snowflake.com), set your role to RWD_STREAMLIT_DEVELOPER_ROLE and warehouse to RWD_PRODUCTION_AI_WH, then:

  1. Go to Projects → Streamlit and choose + Streamlit App.
  2. Pick the database and schema where the app object will live (use a schema your role can create objects in), and the query warehouse (RWD_PRODUCTION_AI_WH).
  3. Edit the app in the built-in editor — left pane is code, right pane is the live preview. Saving redeploys automatically.
  4. Share by granting USAGE on the Streamlit object to other roles. Viewers run the app under their role context, so they still only see what they're entitled to.

Exact menu labels move occasionally; if the layout differs, look for Streamlit under the Projects section of the left nav.

Accessing RWD data

Inside a SiS app, grab the running Snowpark session with get_active_session() — no login, no connection config. Use session.table(...) or session.sql(...) to get a Snowpark DataFrame, then materialize it for display.

data_access.py
import streamlit as stfrom snowflake.snowpark.context import get_active_session
# Active session in a warehouse-runtime SiS app — uses the app's role + warehouse.session = get_active_session()
# A Snowpark DataFrame (lazy): pick a table your role can SELECT.df = session.table("CLINICOGENOMICS.LIMS_PUB.BASE_SIGNATERA")
# Or raw SQL when you need it:# df = session.sql("SELECT * FROM CLINICOGENOMICS.LIMS_PUB.BASE_SIGNATERA LIMIT 100")
# Materialize to pandas and render.st.dataframe(df.limit(100).to_pandas(), use_container_width=True)

Example app

A small aggregate over a real RWD table, rendered as a metric and a chart:

signatera_summary.py
import streamlit as stfrom snowflake.snowpark.context import get_active_sessionfrom snowflake.snowpark.functions import col, count
st.title("Signatera — sample summary")
session = get_active_session()
# Lazy aggregate: count records per result code, pushed down to Snowflake.summary = (    session.table("CLINICOGENOMICS.LIMS_PUB.BASE_SIGNATERA")    .group_by(col("RESULT_CODE"))    .agg(count("*").alias("N"))    .sort(col("N").desc()))
pdf = summary.to_pandas()
total = int(pdf["N"].sum())st.metric("Total results", f"{total:,}")
st.bar_chart(pdf, x="RESULT_CODE", y="N", use_container_width=True)st.dataframe(pdf, use_container_width=True)

Aggregations stay server-side until .to_pandas(), so only the small result set crosses into the app — keep heavy work in Snowpark/SQL rather than pulling raw rows into pandas.

Help

Questions on app setup, roles, or data access — ask in #rwd-snowflake-help.