用途:编写在 PostHog 沙箱中运行的 Streamlit 应用源码,源码会成为沙箱化 Streamlit 1.31 运行时根目录下的 app.py。部署机制(创建/启动/分享)由另一技能 managing-streamlit-apps 负责,本技能专注代码本身。
读取数据:唯一数据入口是沙箱内桥接 posthog_apps.query(),例如 import posthog_apps 后调用 posthog_apps.query("SELECT event, count() FROM events GROUP BY event LIMIT 10"),传入 HogQL 字符串、返回 pandas DataFrame。失败抛 RuntimeError,消息固定为通用文本,桥接不返回查询内部信息,因此无法在应用内诊断坏查询;应捕获并 st.error(str(e)) 展示给查看者,真实错误请到 SQL 编辑器测试。沙箱内不存在 import posthog(模块名故意区分于 posthog-python SDK)。桥接已预认证到应用所在项目,无需配置令牌。查询有服务端上限(30 秒执行、256MB 内存),不随沙箱规格放大,应限制时间范围、加 LIMIT、在 HogQL 内聚合而非拉取原始事件。
重跑模型:Streamlit 每次控件交互都会自上而下重跑整个脚本。需用 @st.cache_data(ttl=300, show_spinner="Running query...") 缓存每次桥接调用;跨重跑保留的状态用 st.session_state,模块级变量每次交互都会重置。控件驱动参数时,绝不能把自由文本控件值插值进 HogQL:桥接以版本作者的数据权限运行查询,而任何能查看应用的人都能操作控件。应改为从受控固定列表选择(如 st.selectbox)或强制转换类型(int(days)、st.date_input 的日期)并校验后再入查询。
布局与图表:先 st.set_page_config(page_title=..., layout="wide");用 st.columns 并排指标、st.tabs 切换视图、st.expander 详情、st.metric 展示头部数字;图表用 st.plotly_chart(fig, use_container_width=True) 配合 plotly express,表格用 st.dataframe(df, use_container_width=True),matplotlib/seaborn 可经 st.pyplot。
已安装:镜像为 Python 3.11,含 streamlit 1.31、pandas、numpy、polars、plotly、matplotlib、seaborn、scipy、scikit-learn、pyarrow、duckdb、requests、beautifulsoup4、lxml、sqlalchemy、aiohttp。无法添加依赖:沙箱不运行 pip,上传 zip 中的 requirements.txt 会被丢弃。
结构与限制:app.py 是入口,通过 MCP set-source 流程提交的源码即 app.py;辅助模块与数据文件可随 files(文本)与 assets(base64)映射一并提交,import utils 可用(应用目录在 sys.path),但进程不在该目录运行,读数据文件要用 Path(file).parent / "data/events.parquet",不能用裸相对路径;随附数据要小,因为每次 set-source 都以 JSON 内联发送。沙箱是临时的,磁盘写入会在停止/重启后消失,状态应通过缓存查询重算或保存在 st.session_state。代码以非特权用户运行,没有 posthog SDK,无法传入环境变量或密钥,不保证通用网络出口,不要读 os.environ。数据源应围绕 posthog_apps.query() 设计。