数据与AI
在将 marimo notebook 发布到…
当需要确认 marimo notebook 能否在 WASM 环境(playground、community cloud 或导出的 WASM HTML)中运行时,用它自动 lint 加人工排查并输出 PASS/WARN/FAIL 报告。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在将 marimo notebook 发特定
解决思路
- 读取目标 notebook 文件;如果用户没有指定要检查的 notebook,先询问是哪一个。
- 优先运行 marimo 内置的 WASM lint 规则,用它们自动捕获大多数 WASM 不兼容问题,并基于其输出构建报告,而不是手工重新推导这些检查:`marimo check <notebook> --select MW --format json`。
- 处理 MW001 `incompatible-import`:检查 Pyodide 中缺失或不可用的标准库模块(`subprocess`、`pdb`、`dbm`、`resource`、`fcntl`、`termios`、`readline`、`curses`、`tkinter`、`pydecimal`、`test`),以及需要原生同步、共享内存、管道或进程 fork 的 multiprocessing 导出和子模块(`Lock`、`Condition`、`Semaphore`、`Barrier`、`Manager`、`Pipe`、`RLock`、`shared_memory`、`ForkContext`/`ForkProcess`、`ThreadPool` 等);`Process`、`Queue`、`SimpleQueue`、`Pool`、`ProcessPoolExecutor` 仍允许,因为它们运行在 WASM 兼容的协作式适配器上(见步骤 3)。
- 处理 MW002 `unsafe-system-call`:检查 `os.system()`、`os.fork()`、`signal.signal()`、`breakpoint()` 等调用,它们在 Pyodide 中即使导入成功也会失败。
- 处理 MW003 `incompatible-package`:解析 notebook 的 PEP 723 依赖树(跳过被 `sys_platform != 'emscripten'` 标记排除的内容),并检查 PyPI 是否有 WASM 兼容 wheel,用于发现如 `jaxlib` 通过 `jax` 间接引入等情况。
- 处理 MW001 注意事项:MW001 只标记导入语句(例如 `from multiprocessing import Lock`、`import multiprocessing.synchronize`),不标记后续属性访问;裸 `import multiprocessing` 后再 `multiprocessing.Lock()` 可能漏掉;对于含并发代码的 notebook,还要人工扫查这种情况。
- 处理 MW003 注意事项:MW003 结果为干净不代表包在浏览器中安全;如果 notebook 用 `sys_platform != 'emscripten'` 标记某包,MW003 会完全跳过它,这只说明该包不会在 WASM 中安装,不说明 notebook 可以使用它;检查 notebook 是否同时有 `cache_cells = true` 且用 `--execute` 导出(见第 4 步);如果有,被排除的包仍可通过缓存使用;如果没有,任何导入或触碰该包的代码路径都会在浏览器中失败,而 MW003 不会警告。
- 人工检查 PEP 723 元数据:如果 notebook 没有 `# /// script` 块,或导入的包未列在 `dependencies`,标记 WARN;没有该元数据时,包在 WASM 中启动 notebook 时不会自动安装;版本 pin 和下界没问题,因为 marimo 在 WASM 中运行时会剥离版本约束。
- 人工检查仅运行时模式:静态 lint 不捕获的包括读取环境变量(`os.environ`、`os.getenv`)、硬编码绝对文件路径或期望真实文件系统的 `Path.home()`/`Path.cwd()`、以及大型内存数据集(WASM notebook 上限 2GB);看到就标记。
- 人工检查并发语义:WASM notebook 对 `threading.Thread`、`Event`、`local`、`ThreadPoolExecutor`、`wait`、`as_completed`,以及进程形态的 `multiprocessing.Process`、`Queue`、`SimpleQueue`、`Pool`、`ProcessPoolExecutor` 运行协作式适配器;API 形态真实,但没有 OS 线程、没有共享内存、没有真正并行;所有任务在单个 Pyodide 解释器中一次运行一个;如果 notebook 依赖实际并发加速而非仅 API 形态,警告它会正确但顺序运行。
- 人工检查缓存执行是否已就位:检查 notebook 的 `pyproject.toml`(或内联 `# /// script` 块)中的 `[tool.marimo.runtime] cache_cells = true`;如果已设置,被 `sys_platform != 'emscripten'` 标记的不兼容包不自动是 FAIL,见第 4 步逃生方案。
- 生成明确、可操作的报告,给出 `Compatibility: PASS / FAIL / WARN`:PASS 表示 lint 检查和第 3 步都没发现任何问题;WARN 表示没有失败,但第 3 步发现值得复查的问题(缺少 PEP 723 元数据、仅运行时模式、或会运行但不并行的并发);FAIL 表示 lint 检查报告了诊断,或第 3 步发现完全无法运行的问题。
- 在报告中粘贴第 2 步的 lint 诊断原文(文件、行、代码、消息)。
- 在报告中列出手工发现,包含 cell 或 line 以及建议修复。
- 对 FAIL/WARN 的 notebook 给出具体修复建议:用 WASM 友好的替代包替换不兼容包;重写不兼容的代码模式。
- 对于没有 WASM build 的包,没有直接替代品;提供两个解决不同问题的逃生方案,并检查 notebook 实际需要哪一个。
- 逃生方案 1:预计算所有可达结果并缓存。用 `sys_platform != 'emscripten'` 标记从 WASM 中排除该包;marimo 会在服务端运行一次真实计算,并把结果打包进导出。TOML 示例:`# /// script` `# dependencies = [` `# "marimo",` `# "torch; sys_platform != 'emscripten'",` `# ]` `# [tool.marimo.runtime]` `# cache_cells = true` `# ///`。然后运行 `marimo export html-wasm notebook.py -o output_dir --execute`。这直接覆盖单个静态结果(图、一次性计算)。对于小型可枚举结果集——下拉框或滑块对应固定选项列表——改用 `@mo.persistent_cache(method="lazy")` 装饰计算;在导出前添加一个 cell,对每个选项调用一次。参见缓存预计算值。无论哪种,被排除的包从不在浏览器中运行——notebook 只读取其缓存结果。
- 逃生方案 2:使用兼容层在浏览器中运行真实计算。预计算不覆盖无法提前枚举的输入空间——例如滑块驱动连续范围上的实时推理;这里 notebook 需要计算的实际 WASM 原生实现。`moutils.onnx.OnnxRuntime` 是这种模式的一个示例:它将 PyTorch 或 JAX 模型转换为 ONNX,返回对象在浏览器中用 `onnxruntime-web` 运行推理,而不是用原框架。
- 参考额外背景用于判断和报告:WASM notebook 通过浏览器中的 Pyodide 运行;内存上限 2GB;网络请求可用但可能需要 CORS 兼容端点;Chrome 的 WASM 性能最好,Firefox、Edge、Safari 也支持;`micropip` 可在运行时安装 PyPI 上任何纯 Python wheel;marimo WASM lint 规则完整列表见 lint 规则参考;Pyodide 内置包的手工维护快照见 `references/pyodide-packages.md`,它便于人工阅读,但 `marimo check --select MW003` 直接查询 PyPI 并自动保持最新。
适用边界 · 注意事项
- 目标不是 marimo notebook,或不需要在 WASM/浏览器环境(playground、community cloud、导出的 WASM HTML)中运行。
- notebook 必须依赖真实 OS 线程并行、共享内存、子进程 fork、真实文件系统或超过 2GB 内存,且无法用预计算缓存或 WASM 兼容层替代。
- 环境无法安装或运行 marimo CLI,因而不能执行 `marimo check` 和 `marimo export`。