关于 debugging-streamlit
用于调试 Streamlit 应用的开发技能,可同时启动 Python 后端与 Vite/React 前端并启用热重载。它说明如何检查会话日志、定位错误,以及使用 Playwright 测试界面。
主要功能
- 01同时启动后端和前端
- 02应用与前端代码热重载
- 03分别记录每次会话的前后端日志
- 04搜索日志中的错误和调试输出
- 05使用 Playwright 截图和交互测试
适用场景
- 01跨前后端调试 Streamlit 应用
- 02检查启动或应用运行后的错误
- 03测试界面行为并捕获截图
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ streamlit/ streamlit --skill debugging-streamlit安装后在 Claude Code 中输入/debugging-streamlit确认已加载。
详细介绍
调试 Streamlit 应用
快速开始
make debug my_app.py
这会同时启动后端(Streamlit/Python)和前端(Vite/React),并支持热重载。应用 URL 会在启动时打印(默认为 http://localhost:3001;3000 预留给手动执行的 make frontend-dev;如果同时有其他调试会话在运行,可能会使用 3002+)。除非你有明确的硬性需求,否则避免固定 VITE_PORT(这是最后的手段)。
热重载行为:
- 前端:对
frontend/代码的更改会在几秒内生效。 - 后端:只有对应用脚本的更改才会触发重新运行。对 Streamlit 库本身(
lib/streamlit/)的更改需要重启make debug。
日志文件
每次 make debug 运行都会将日志写入 work-tmp/debug/ 下按会话划分的目录,并更新 work-tmp/debug/latest/ 指向最近的会话。
由于 latest/* 是符号链接,它可能会移动,如果有多个调试会话正在同时启动/停止——当你需要稳定的日志引用时,请优先使用 make debug 打印出的会话目录路径。
你可以在 make debug 启动输出的 Log files 部分找到确切的会话目录。
| 文件 | 内容 |
|---|---|
work-tmp/debug/latest/backend.log | Python print() 语句、Streamlit 日志、错误 |
work-tmp/debug/latest/frontend.log | 浏览器 console.log()、React 错误、Vite 输出 |
日志会在每个会话开始时清空,并在退出后保留,以便进行事后分析。
日志大小警告: 在长时间的调试会话中,日志可能会变得很大。与其读取整个日志文件,不如使用 rg 搜索特定模式:
# Search for specific debug messages
rg "DEBUG:" work-tmp/debug/latest/backend.log
# Search for errors (case-insensitive)
rg -i "error|exception|traceback" work-tmp/debug/latest/backend.log
# Search with context (3 lines before/after)
rg -C 3 "my_function" work-tmp/debug/latest/backend.log
# Search frontend logs for specific component
rg "MyComponent" work-tmp/debug/latest/frontend.log
将所有调试产物(脚本、截图等)放在此目录中,以保持井然有序。
添加调试输出
后端(Python):
print(f"DEBUG: session_state = {st.session_state}")
前端(TypeScript/React):
console.log("DEBUG: props =", props)
前端 console.log() 输出会出现在 work-tmp/debug/latest/frontend.log(或当前会话的 frontend.log 文件)中。
工作流
- 在
work-tmp/debug/中创建或使用测试脚本(例如work-tmp/debug/test_feature.py) - 运行
make debug work-tmp/debug/test_feature.py - 验证启动:检查
work-tmp/debug/latest/backend.log中是否有Error/Exception,以及work-tmp/debug/latest/frontend.log中是否有控制台错误,以确保两个服务器都正确启动 - 在浏览器中访问打印出的 App URL(默认为
http://localhost:3001,但也可能是3002+) - 验证脚本执行:在首次访问应用后,再次检查
work-tmp/debug/latest/backend.log中是否有任何错误 - 通过检查
work-tmp/debug/latest/backend.log和work-tmp/debug/latest/frontend.log来监控日志 - 编辑代码——更改会通过热重载自动生效
- 检查日志以查看调试输出
快速错误检查:
# Backend errors
rg -i "error|exception" work-tmp/debug/latest/backend.log
# Frontend console errors
rg -i "error" work-tmp/debug/latest/frontend.log
用于截图和测试的临时 Playwright 脚本
用于带截图或自动化 UI 交互的高级调试。
快速方式:Playwright CLI
对于简单的截图和交互,使用 @playwright/cli(已在前端 devDependencies 中提供):
cd frontend
STREAMLIT_APP_URL=http://localhost:3001
yarn playwright-cli open "$STREAMLIT_APP_URL"
yarn playwright-cli screenshot --filename ../work-tmp/debug/screenshot.png --full-page
yarn playwright-cli close
更多命令(snapshot、click、fill 等)请参见 https://github.com/microsoft/playwright-cli。
自定义脚本
对于复杂的交互,在 work-tmp/debug/ 中创建临时 Playwright 脚本:
# work-tmp/debug/debug_screenshot.py
"""Temporary Playwright script for debugging - run against make debug."""
import os
from playwright.sync_api import sync_playwright, expect
from e2e_playwright.shared.app_utils import get_text_input, click_button
from e2e_playwright.conftest import wait_for_app_loaded, wait_for_app_run
def main():
app_url = os.environ.get("STREAMLIT_APP_URL", "http://localhost:3001")
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={"width": 1280, "height": 720})
# Connect to app started with `make debug`
page.goto(app_url)
wait_for_app_loaded(page)
# Interact with the app
text_input = get_text_input(page, "Name")
text_input.fill("Test User")
click_button(page, "Submit")
wait_for_app_run(page)
# Verify and screenshot
expect(page.get_by_text("Hello, Test User")).to_be_visible()
page.screenshot(path="work-tmp/debug/debug_screenshot.png", full_page=True)
print("Screenshot saved to work-tmp/debug/debug_screenshot.png")
browser.close()
if __name__ == "__main__":
main()
运行临时脚本
首先确保 make debug <app.py> 正在运行(如有需要,可在后台任务中启动它)。如果你的 make debug 会话使用的是非默认端口,请相应地设置 STREAMLIT_APP_URL,然后运行 Playwright 脚本:
STREAMLIT_APP_URL=http://localhost:3001 \
PYTHONPATH=. uv run python work-tmp/debug/debug_screenshot.py
这会使用由 uv 管理的环境,其中包含所有依赖(playwright 等),并使 e2e_playwright 无需路径操作即可导入。
e2e_playwright 中的可用工具
元素定位器与交互(e2e_playwright.shared.app_utils):
提供诸如 get_text_input()、get_button()、click_button()、get_checkbox() 等辅助函数。
同步(e2e_playwright.conftest):
wait_for_app_loaded(page)- 等待初始加载完成wait_for_app_run(page)- 等待交互后的脚本执行完成wait_until(page, fn, timeout)- 轮询直到条件为真
Playwright API 参考:https://playwright.dev/python/docs/api/class-playwright
截图最佳实践
# Full page screenshot
page.screenshot(path="work-tmp/debug/full.png", full_page=True)
# Element screenshot
element = page.get_by_test_id("stDataFrame")
element.screenshot(path="work-tmp/debug/dataframe.png")
故障排查
端口已被占用 / 存在多个会话:
make debug会自动选择一个空闲的前端端口(通常在3001-3100范围内),因此可以同时运行多个调试会话。- 前端端口
3000保留给手动运行的make frontend-dev会话。 - 如果你硬性要求使用特定的前端端口,可以通过
VITE_PORT=3002 make debug <app.py>固定该端口(最后的手段)。
热重载不生效:
- 后端:仅监视 app 脚本。对
lib/streamlit/的更改需要重启make debug。 - 前端:检查
work-tmp/debug/latest/frontend.log中的 Vite 错误。TypeScript 错误可能会破坏 HMR。
Playwright 脚本连接失败:
- 确认
make debug正在运行且状态正常 - 检查打印出的 App URL 在浏览器中是否可访问
- 确保在
page.goto()之后调用了wait_for_app_loaded(page)
清理
调试完成后,从 work-tmp/debug/ 中移除临时脚本和截图。
相关技能
- understanding-streamlit-architecture skill:在调试跨层问题时,用于更深入地理解后端/前端内部机制