streamlit-snowflake

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Streamlit in Snowflake Skill

Snowflake中的Streamlit技能指南

Build and deploy Streamlit apps natively within Snowflake, including Marketplace publishing as Native Apps.
在Snowflake中原生构建和部署Streamlit应用,包括将应用作为原生应用发布到Snowflake Marketplace。

Quick Start

快速开始

1. Initialize Project

1. 初始化项目

Copy the templates to your project:
bash
undefined
将模板复制到你的项目中:
bash
undefined

Create project directory

Create project directory

mkdir my-streamlit-app && cd my-streamlit-app
mkdir my-streamlit-app && cd my-streamlit-app

Copy templates (Claude will provide these)

Copy templates (Claude will provide these)

undefined
undefined

2. Configure snowflake.yml

2. 配置snowflake.yml

Update placeholders in
snowflake.yml
:
yaml
definition_version: 2
entities:
  my_app:
    type: streamlit
    identifier: my_streamlit_app        # ← Your app name
    stage: my_app_stage                 # ← Your stage name
    query_warehouse: my_warehouse       # ← Your warehouse
    main_file: streamlit_app.py
    pages_dir: pages/
    artifacts:
      - common/
      - environment.yml
更新
snowflake.yml
中的占位符:
yaml
definition_version: 2
entities:
  my_app:
    type: streamlit
    identifier: my_streamlit_app        # ← Your app name
    stage: my_app_stage                 # ← Your stage name
    query_warehouse: my_warehouse       # ← Your warehouse
    main_file: streamlit_app.py
    pages_dir: pages/
    artifacts:
      - common/
      - environment.yml

3. Deploy

3. 部署

bash
undefined
bash
undefined

Deploy to Snowflake

Deploy to Snowflake

snow streamlit deploy --replace
snow streamlit deploy --replace

Open in browser

Open in browser

snow streamlit deploy --replace --open
undefined
snow streamlit deploy --replace --open
undefined

When to Use This Skill

适用场景

Use when:
  • Building data apps that run natively in Snowflake
  • Need Snowpark integration for data access
  • Publishing apps to Snowflake Marketplace
  • Setting up CI/CD for Streamlit in Snowflake
Don't use when:
  • Hosting Streamlit externally (use Streamlit Community Cloud)
  • Building general Snowpark pipelines (use a Snowpark-specific skill)
  • Need custom Streamlit components (not supported in SiS)
适用情况:
  • 构建在Snowflake中原生运行的数据应用
  • 需要Snowpark集成来访问数据
  • 将应用发布到Snowflake Marketplace
  • 为Snowflake中的Streamlit设置CI/CD流程
不适用情况:
  • 在外部托管Streamlit应用(请使用Streamlit Community Cloud)
  • 构建通用Snowpark管道(请使用Snowpark专属技能)
  • 需要自定义Streamlit组件(SiS不支持)

Runtime Environments

运行时环境

Snowflake offers two runtime options for Streamlit apps:
Snowflake为Streamlit应用提供两种运行时选项

Warehouse Runtime (Default)

仓库运行时(默认)

  • Creates a personal instance for each viewer
  • Uses
    environment.yml
    with Snowflake Anaconda Channel
  • Python 3.9, 3.10, or 3.11
  • Streamlit 1.22.0 - 1.35.0
  • Best for: Sporadic usage, isolated sessions
  • 为每个查看者创建独立实例
  • 使用带有Snowflake Anaconda Channel的
    environment.yml
  • 支持Python 3.9、3.10或3.11
  • 支持Streamlit 1.22.0 - 1.35.0
  • 最佳适用场景:零散使用、隔离会话

Container Runtime (Preview)

容器运行时(预览版)

  • Creates a shared instance for all viewers
  • Uses
    requirements.txt
    or
    pyproject.toml
    with PyPI packages
  • Python 3.11 only
  • Streamlit 1.49+
  • Significantly lower cost (~$2.88/day vs ~$48/day for equivalent compute)
  • Best for: Frequent usage, cost optimization
Container Runtime Configuration:
sql
CREATE STREAMLIT my_app
  FROM '@my_stage/app_folder'
  MAIN_FILE = 'streamlit_app.py'
  RUNTIME_NAME = 'SYSTEM$ST_CONTAINER_RUNTIME_PY3_11'
  COMPUTE_POOL = my_compute_pool
  QUERY_WAREHOUSE = my_warehouse;
Key difference: Container runtime allows external PyPI packages - not limited to Snowflake Anaconda Channel.
  • 为所有查看者创建共享实例
  • 使用
    requirements.txt
    pyproject.toml
    搭配PyPI包
  • 仅支持Python 3.11
  • 支持Streamlit 1.49+
  • 成本显著降低(同等计算能力下约2.88美元/天 vs 约48美元/天)
  • 最佳适用场景:频繁使用、成本优化
容器运行时配置:
sql
CREATE STREAMLIT my_app
  FROM '@my_stage/app_folder'
  MAIN_FILE = 'streamlit_app.py'
  RUNTIME_NAME = 'SYSTEM$ST_CONTAINER_RUNTIME_PY3_11'
  COMPUTE_POOL = my_compute_pool
  QUERY_WAREHOUSE = my_warehouse;
核心差异:容器运行时支持外部PyPI包 - 不再局限于Snowflake Anaconda Channel。

Security Model

安全模型

Streamlit apps support two privilege models:
Streamlit应用支持两种权限模型

Owner's Rights (Default)

所有者权限(默认)

  • Apps execute with the owner's privileges, not the viewer's
  • Apps use the warehouse provisioned by the owner
  • Viewers can interact with data using all owner role privileges
Security implications:
  • Exercise caution when granting write privileges to app roles
  • Use dedicated roles for app creation/viewing
  • Viewers can access any data the owner role can access
  • Best for: Internal tools with trusted users
  • 应用以所有者的权限执行,而非查看者的权限
  • 应用使用所有者配置的仓库
  • 查看者可使用所有者角色的所有权限与数据交互
安全注意事项:
  • 为应用角色授予写入权限时需谨慎
  • 使用专用角色进行应用创建/查看
  • 查看者可访问所有者角色能访问的所有数据
  • 最佳适用场景:内部工具、可信用户

Caller's Rights (v1.53.0+)

调用者权限(v1.53.0+)

  • Apps execute with the viewer's privileges
  • Each viewer sees only data they have permission to access
  • Provides data isolation in multi-tenant scenarios
Use caller's rights when:
  • Building public or external-facing apps
  • Need per-user data access control
  • Multi-tenant applications requiring data isolation
See Caller's Rights Connection pattern below.
  • 应用以查看者的权限执行
  • 每个查看者仅能看到自己有权限访问的数据
  • 在多租户场景中提供数据隔离
适用调用者权限的场景:
  • 构建公开或面向外部的应用
  • 需要按用户控制数据访问
  • 需要数据隔离的多租户应用
参考下文的调用者权限连接模式。

Project Structure

项目结构

my-streamlit-app/
├── snowflake.yml           # Project definition (required)
├── environment.yml         # Package dependencies (required)
├── streamlit_app.py        # Main entry point
├── pages/                  # Multi-page apps
│   └── data_explorer.py
├── common/                 # Shared utilities
│   └── utils.py
└── .gitignore
my-streamlit-app/
├── snowflake.yml           # 项目定义(必填)
├── environment.yml         # 包依赖(必填)
├── streamlit_app.py        # 主入口文件
├── pages/                  # 多页面应用目录
│   └── data_explorer.py
├── common/                 # 共享工具目录
│   └── utils.py
└── .gitignore

Key Patterns

核心模式

Snowpark Session Connection

Snowpark会话连接

python
import streamlit as st
python
import streamlit as st

Get Snowpark session (native SiS connection)

获取Snowpark会话(原生SiS连接)

conn = st.connection("snowflake") session = conn.session()
conn = st.connection("snowflake") session = conn.session()

Query data

查询数据

df = session.sql("SELECT * FROM my_table LIMIT 100").to_pandas() st.dataframe(df)
undefined
df = session.sql("SELECT * FROM my_table LIMIT 100").to_pandas() st.dataframe(df)
undefined

Caller's Rights Connection (v1.53.0+)

调用者权限连接(v1.53.0+)

Execute queries with viewer's privileges instead of owner's privileges:
python
import streamlit as st
以查看者的权限而非所有者的权限执行查询:
python
import streamlit as st

Use caller's rights for data isolation

使用调用者权限实现数据隔离

conn = st.connection("snowflake", type="callers_rights")
conn = st.connection("snowflake", type="callers_rights")

Each viewer sees only data they have permission to access

每个查看者仅能看到自己有权限访问的数据

df = conn.query("SELECT * FROM sensitive_customer_data") st.dataframe(df)

**Security comparison:**

| Connection Type | Privilege Model | Use Case |
|-----------------|-----------------|----------|
| `type="snowflake"` (default) | Owner's rights | Internal tools, trusted users |
| `type="callers_rights"` (v1.53.0+) | Caller's rights | Public apps, data isolation |

**Source**: [Streamlit v1.53.0 Release](https://github.com/streamlit/streamlit/releases/tag/1.53.0)
df = conn.query("SELECT * FROM sensitive_customer_data") st.dataframe(df)

**安全对比:**

| 连接类型 | 权限模型 | 适用场景 |
|-----------------|-----------------|----------|
| `type="snowflake"`(默认) | 所有者权限 | 内部工具、可信用户 |
| `type="callers_rights"`(v1.53.0+) | 调用者权限 | 公开应用、数据隔离 |

**来源**:[Streamlit v1.53.0 发布说明](https://github.com/streamlit/streamlit/releases/tag/1.53.0)

Caching Expensive Queries

缓存昂贵查询

python
@st.cache_data(ttl=600)  # Cache for 10 minutes
def load_data(query: str):
    conn = st.connection("snowflake")
    return conn.session().sql(query).to_pandas()
python
@st.cache_data(ttl=600)  # 缓存10分钟
def load_data(query: str):
    conn = st.connection("snowflake")
    return conn.session().sql(query).to_pandas()

Use cached function

使用缓存函数

df = load_data("SELECT * FROM large_table")

**Warning**: In Streamlit v1.22.0-1.53.0, `params` argument is not included in cache key. Use `ttl=0` to disable caching when using parametrized queries, or upgrade to 1.54.0+ when available ([Issue #13644](https://github.com/streamlit/streamlit/issues/13644)).
df = load_data("SELECT * FROM large_table")

**警告**:在Streamlit v1.22.0-1.53.0版本中,`params`参数不会被包含在缓存键中。当使用参数化查询时,设置`ttl=0`禁用缓存,或等待升级到1.54.0+版本(参考[Issue #13644](https://github.com/streamlit/streamlit/issues/13644))。

Optimizing Snowpark DataFrame Performance

优化Snowpark DataFrame性能

When using Snowpark DataFrames with charts or tables, select only required columns to avoid fetching unnecessary data:
python
undefined
当使用Snowpark DataFrames搭配图表或表格时,仅选择所需列以避免获取不必要的数据:
python
undefined

❌ Fetches all 50 columns even though chart only needs 2

❌ 即使图表只需要2列,仍会获取全部50列

df = session.table("wide_table") # 50 columns st.line_chart(df, x="date", y="value")
df = session.table("wide_table") # 50列 st.line_chart(df, x="date", y="value")

✅ Fetch only needed columns for better performance

✅ 仅获取所需列以提升性能

df = session.table("wide_table").select("date", "value") st.line_chart(df, x="date", y="value")
df = session.table("wide_table").select("date", "value") st.line_chart(df, x="date", y="value")

5-10x faster for wide tables

宽表场景下速度提升5-10倍


**Why it matters**: `st.dataframe()` and chart components call `df.to_pandas()` which evaluates ALL columns, even if the visualization only needs some. Pre-selecting columns reduces data transfer and improves performance ([Issue #11701](https://github.com/streamlit/streamlit/issues/11701)).

**重要原因**:`st.dataframe()`和图表组件会调用`df.to_pandas()`,这会评估所有列,即使可视化只需要部分列。预先选择列可减少数据传输并提升性能(参考[Issue #11701](https://github.com/streamlit/streamlit/issues/11701))。

Environment Configuration

环境配置

environment.yml (required format):
yaml
name: sf_env
channels:
  - snowflake          # REQUIRED - only supported channel
dependencies:
  - streamlit=1.35.0   # Explicit version (default is old 1.22.0)
  - pandas
  - plotly
  - altair=4.0         # Version 4.0 supported in SiS
  - snowflake-snowpark-python
environment.yml(必填格式):
yaml
name: sf_env
channels:
  - snowflake          # REQUIRED - only supported channel
dependencies:
  - streamlit=1.35.0   # 显式指定版本(默认是旧版本1.22.0)
  - pandas
  - plotly
  - altair=4.0         # SiS支持4.0版本
  - snowflake-snowpark-python

Error Prevention

错误预防

This skill prevents 14 documented errors:
ErrorCausePrevention
PackageNotFoundError
Using conda-forge or external channelUse
channels: - snowflake
(or Container Runtime for PyPI)
Missing Streamlit featuresDefault version 1.22.0Explicitly set
streamlit=1.35.0
(or use Container Runtime for 1.49+)
ROOT_LOCATION deprecated
Old CLI syntaxUse Snowflake CLI 3.14.0+ with
FROM source_location
Auth failures (2026+)Password-only authenticationUse key-pair or OAuth (see references/authentication.md)
File upload failsFile >200MBKeep uploads under 200MB limit
DataFrame display failsData >32MBPaginate or limit data before display
page_title not supported
SiS limitationDon't use
page_title
,
page_icon
, or
menu_items
in
st.set_page_config()
Custom component errorSiS limitationOnly components without external service calls work
_snowflake module not found
Container Runtime migrationUse
from snowflake.snowpark.context import get_active_session
instead of
from _snowflake import get_active_session
(Migration Guide)
Cached query returns wrong data with different params
params
not in cache key (v1.22.0-1.53.0)
Use
ttl=0
to disable caching for parametrized queries, or upgrade to 1.54.0+ when available (Issue #13644)
Invalid connection_name 'default'
with kwargs only
Missing secrets.toml or connections.tomlCreate minimal
.streamlit/secrets.toml
with
[connections.snowflake]
section (Issue #9016)
Native App upgrades unexpectedlyImplicit default Streamlit version (BCR-1857)Explicitly set
streamlit=1.35.0
in environment.yml to prevent automatic version changes (BCR-1857)
File paths fail in Container Runtime subdirectoriesSome commands use entrypoint-relative pathsUse
pathlib
to resolve absolute paths:
Path(__file__).parent / "assets/logo.png"
(Runtime Docs)
Slow performance with wide Snowpark DataFrames
st.dataframe()
fetches all columns even if unused
Pre-select only needed columns:
df.select("col1", "col2")
before passing to Streamlit (Issue #11701)
本技能可预防14种已记录的错误
错误原因预防措施
PackageNotFoundError
使用conda-forge或外部通道使用
channels: - snowflake
(或使用容器运行时搭配PyPI)
缺失Streamlit功能默认版本为1.22.0显式设置
streamlit=1.35.0
(或使用容器运行时获取1.49+版本)
ROOT_LOCATION deprecated
旧版CLI语法使用Snowflake CLI 3.14.0+搭配
FROM source_location
身份验证失败(2026+)仅密码身份验证使用密钥对或OAuth(参考references/authentication.md)
文件上传失败文件大小超过200MB保持上传文件在200MB限制内
DataFrame显示失败数据大小超过32MB在显示前分页或限制数据量
page_title not supported
SiS限制不要在
st.set_page_config()
中使用
page_title
page_icon
menu_items
自定义组件错误SiS限制仅使用无需外部服务调用的组件
_snowflake module not found
容器运行时迁移使用
from snowflake.snowpark.context import get_active_session
替代
from _snowflake import get_active_session
(参考迁移指南
参数不同时缓存查询返回错误数据
params
未包含在缓存键中(v1.22.0-1.53.0)
对参数化查询设置
ttl=0
禁用缓存,或等待升级到1.54.0+版本(参考Issue #13644
Invalid connection_name 'default'
仅使用关键字参数
缺少secrets.toml或connections.toml创建包含
[connections.snowflake]
节的最小
.streamlit/secrets.toml
(参考Issue #9016
原生应用意外升级Streamlit版本隐式默认(BCR-1857)在environment.yml中显式设置
streamlit=1.35.0
以防止版本自动变更(参考BCR-1857
容器运行时子目录中文件路径失败部分命令使用入口点相对路径使用
pathlib
解析绝对路径:
Path(__file__).parent / "assets/logo.png"
(参考运行时文档
宽Snowpark DataFrames性能缓慢
st.dataframe()
会获取所有列即使未使用
在传递给Streamlit前预先选择所需列:
df.select("col1", "col2")
(参考Issue #11701

Deployment Commands

部署命令

Basic Deployment

基础部署

bash
undefined
bash
undefined

Deploy and replace existing

部署到Snowflake并替换现有应用

snow streamlit deploy --replace
snow streamlit deploy --replace

Deploy and open in browser

部署并在浏览器中打开

snow streamlit deploy --replace --open
snow streamlit deploy --replace --open

Deploy specific entity (if multiple in snowflake.yml)

部署指定实体(如果snowflake.yml中有多个)

snow streamlit deploy my_app --replace
undefined
snow streamlit deploy my_app --replace
undefined

CI/CD Deployment

CI/CD部署

See
references/ci-cd.md
for GitHub Actions workflow template.
参考
references/ci-cd.md
获取GitHub Actions工作流模板。

Marketplace Publishing (Native App)

Marketplace发布(原生应用)

To publish your Streamlit app to Snowflake Marketplace:
  1. Convert to Native App - Use
    templates-native-app/
    templates
  2. Create Provider Profile - Required for Marketplace listings
  3. Submit for Approval - Snowflake reviews before publishing
See
templates-native-app/README.md
for complete workflow.
要将你的Streamlit应用发布到Snowflake Marketplace:
  1. 转换为原生应用 - 使用
    templates-native-app/
    模板
  2. 创建提供者资料 - 发布到Marketplace的必填项
  3. 提交审核 - Snowflake会在发布前进行审核
完整工作流请参考
templates-native-app/README.md

Native App Structure

原生应用结构

my-native-app/
├── manifest.yml            # Native App manifest
├── setup.sql               # Installation script
├── streamlit/
│   ├── environment.yml
│   ├── streamlit_app.py
│   └── pages/
└── README.md
my-native-app/
├── manifest.yml            # 原生应用清单
├── setup.sql               # 安装脚本
├── streamlit/
│   ├── environment.yml
│   ├── streamlit_app.py
│   └── pages/
└── README.md

Package Availability

包可用性

Only packages from the Snowflake Anaconda Channel are available:
sql
-- Query available packages
SELECT * FROM information_schema.packages
WHERE language = 'python'
ORDER BY package_name;

-- Search for specific package
SELECT * FROM information_schema.packages
WHERE language = 'python'
AND package_name ILIKE '%plotly%';
Common available packages:
  • pandas, numpy, scipy
  • plotly, altair (4.0), matplotlib
  • scikit-learn, xgboost
  • snowflake-snowpark-python
  • streamlit (1.22.0 default, 1.35.0 with explicit version)
Not available:
  • Packages from conda-forge
  • Custom/private packages
  • Packages requiring native compilation
仅支持Snowflake Anaconda Channel中的包:
sql
-- 查询可用包
SELECT * FROM information_schema.packages
WHERE language = 'python'
ORDER BY package_name;

-- 搜索特定包
SELECT * FROM information_schema.packages
WHERE language = 'python'
AND package_name ILIKE '%plotly%';
常见可用包:
  • pandas、numpy、scipy
  • plotly、altair(4.0)、matplotlib
  • scikit-learn、xgboost
  • snowflake-snowpark-python
  • streamlit(默认1.22.0,显式指定可使用1.35.0)
不可用包:
  • conda-forge中的包
  • 自定义/私有包
  • 需要原生编译的包

Known Limitations

已知限制

Data & Size Limits

数据与大小限制

  • 32 MB message size between backend/frontend (affects large
    st.dataframe
    )
  • 200 MB file upload limit via
    st.file_uploader
  • No
    .so
    files
    - Native compiled libraries unsupported
  • No external stages - Internal stages only (client-side encryption)
  • 后端/前端之间的32 MB消息大小限制(影响大型
    st.dataframe
  • st.file_uploader
    200 MB文件上传限制
  • 不支持**.so文件** - 原生编译库不受支持
  • 不支持外部阶段 - 仅支持内部阶段(客户端加密)

UI Restrictions

UI限制

  • st.set_page_config
    -
    page_title
    ,
    page_icon
    ,
    menu_items
    not supported
  • st.bokeh_chart
    - Not supported
  • Custom Streamlit components - Only components without external service calls
  • Content Security Policy - Blocks external scripts, styles, fonts, iframes
  • eval()
    blocked
    - CSP prevents unsafe JavaScript execution
  • st.set_page_config
    - 不支持
    page_title
    page_icon
    menu_items
  • st.bokeh_chart
    - 不受支持
  • 自定义Streamlit组件 - 仅支持无需外部服务调用的组件
  • 内容安全策略 - 阻止外部脚本、样式、字体、iframe
  • eval()
    被阻止
    - CSP阻止不安全的JavaScript执行

Caching (Warehouse Runtime)

缓存(仓库运行时)

  • Session-scoped only -
    st.cache_data
    and
    st.cache_resource
    don't persist across users
  • Container runtime has full caching support across viewers
  • 仅会话范围有效 -
    st.cache_data
    st.cache_resource
    不会在用户间持久化
  • 容器运行时支持跨查看者的完整缓存功能

Package Restrictions (Warehouse Runtime)

包限制(仓库运行时)

  • Snowflake Anaconda Channel only - No conda-forge, no pip
  • Container runtime allows PyPI packages
  • 仅支持Snowflake Anaconda Channel - 不支持conda-forge或pip
  • 容器运行时支持PyPI包

Network & Access

网络与访问

  • No Azure Private Link / GCP Private Service Connect
  • No replication of Streamlit objects
  • 不支持Azure Private Link / GCP Private Service Connect
  • 不支持Streamlit对象的复制

Authentication (Important - 2026 Deadline)

身份验证(重要 - 2026年截止日期)

Password-only authentication is being deprecated:
MilestoneDateRequirement
Milestone 1Sept 2025 - Jan 2026MFA required for Snowsight users
Milestone 2May - July 2026All new users must use MFA
Milestone 3Aug - Oct 2026All users must use MFA or key-pair/OAuth
Recommended authentication methods:
  • Key-pair authentication (for service accounts)
  • OAuth client credentials (for M2M)
  • Workload Identity Federation (for cloud-native apps)
See
references/authentication.md
for implementation patterns.
仅密码身份验证将被弃用:
里程碑日期要求
里程碑12025年9月 - 2026年1月Snowsight用户必须启用MFA
里程碑22026年5月 - 7月所有新用户必须使用MFA
里程碑32026年8月 - 10月所有用户必须使用MFA或密钥对/OAuth
推荐的身份验证方式:
  • 密钥对身份验证(适用于服务账户)
  • OAuth客户端凭证(适用于机器到机器场景)
  • 工作负载身份联合(适用于云原生应用)
实现模式请参考
references/authentication.md

Resources

资源

Official Documentation

官方文档

Examples

示例

Tools

工具