mcpField
D
debugging-streamlit

debugging-streamlit

github.com/streamlit开发46.2k494 次安装今天更新
代码仓库

关于 debugging-streamlit

用于调试 Streamlit 应用的开发技能,可同时启动 Python 后端与 Vite/React 前端并启用热重载。它说明如何检查会话日志、定位错误,以及使用 Playwright 测试界面。

主要功能

  1. 01同时启动后端和前端
  2. 02应用与前端代码热重载
  3. 03分别记录每次会话的前后端日志
  4. 04搜索日志中的错误和调试输出
  5. 05使用 Playwright 截图和交互测试

适用场景

  1. 01跨前后端调试 Streamlit 应用
  2. 02检查启动或应用运行后的错误
  3. 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.logPython 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 文件)中。

工作流

  1. 在 work-tmp/debug/ 中创建或使用测试脚本(例如 work-tmp/debug/test_feature.py)
  2. 运行 make debug work-tmp/debug/test_feature.py
  3. 验证启动:检查 work-tmp/debug/latest/backend.log 中是否有 Error/Exception,以及 work-tmp/debug/latest/frontend.log 中是否有控制台错误,以确保两个服务器都正确启动
  4. 在浏览器中访问打印出的 App URL(默认为 http://localhost:3001,但也可能是 3002+)
  5. 验证脚本执行:在首次访问应用后,再次检查 work-tmp/debug/latest/backend.log 中是否有任何错误
  6. 通过检查 work-tmp/debug/latest/backend.log 和 work-tmp/debug/latest/frontend.log 来监控日志
  7. 编辑代码——更改会通过热重载自动生效
  8. 检查日志以查看调试输出

快速错误检查:

# 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/ 中移除临时脚本和截图。

相关技能

评论

支持 Markdown