news 2026/10/8 19:16:31

Papermill 存储后端实战:在 AWS S3、Azure Blob/Data Lake 与更多远程存储之间读写 Notebook

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Papermill 存储后端实战:在 AWS S3、Azure Blob/Data Lake 与更多远程存储之间读写 Notebook
  • 开发工具
  • CLI
  • 数据工程

【免费下载链接】papermill

📚 Parameterize, execute, and analyze notebooks

项目地址:https://gitcode.com/gh_mirrors/pa/papermill
点击查看免费下载

本篇技术指南围绕 Papermill 的存储(Store)能力展开:Papermill 不仅能读写本地 Notebook,还能把 Notebook 直接存取到 AWS S3、Azure Blob Storage、Azure Data Lake 等远程对象存储中,并通过模块化 I/O 架构按需扩展新后端。读完本文,你将掌握各类存储路径的 URI 规范、对应依赖与认证方式、CLI/Python API 的读写用法,以及如何注册自定义存储 Handler。

存储层在 Papermill 工作流中的位置

Papermill 的典型工作流是**参数化(parameterize)→ 执行(execute)→ 存储(store)**三件套(见 docs/usage-workflow.rst)。存储环节决定了输入 Notebook 从哪里读、执行结果往哪里写:

  • 输入路径可以来自本地磁盘,也可以来自s3://、abs://、adl://、gs://、hdfs://等远程位置;
  • 输出路径同样支持这些位置,例如"本地输入、S3 输出"或"S3 输入、S3 输出"均可;
  • 官方文档 docs/usage-store.rst 明确指出:Papermill 可以将 Notebook 存储到多种位置,包括 AWS S3、Azure data blobs 与 Azure data lakes,且模块化架构允许在后续持续新增数据存储后端。

这一设计让"批量执行结果直接归档到云上"成为可能,也是 Papermill 被广泛用于数据管线与调度系统的关键原因。

核心机制:PapermillIO 与 Handler 注册表

所有存储后端都统一挂在papermill_io(PapermillIO实例)下。该实例在 papermill/iorw.py 中被初始化并注册了一批内置 Handler(见 papermill/iorw.py#L459-L472):

papermill_io = PapermillIO() papermill_io.register("local", LocalHandler()) papermill_io.register("s3://", S3Handler) papermill_io.register("adl://", ADLHandler()) papermill_io.register("abs://", ABSHandler()) papermill_io.register("http://", HttpHandler) papermill_io.register("https://", HttpHandler) papermill_io.register("gs://", GCSHandler()) papermill_io.register("hdfs://", HDFSHandler()) papermill_io.register("http://github.com/", GithubHandler()) papermill_io.register("https://github.com/", GithubHandler()) papermill_io.register("-", StreamHandler()) papermill_io.register_entry_points()

其中几个要点:

  • 按 scheme 前缀匹配:get_handler(path)会遍历注册表,找到第一个path.startswith(scheme)成立的 Handler(见 papermill/iorw.py#L122-L164);找不到匹配时回退到localHandler,否则抛出PapermillException。
  • 注册表采用 LIFO 顺序:register将新 Handler 插到列表头部(见 papermill/iorw.py#L113-L115),后注册的同前缀 Handler 优先命中。
  • 统一接口:每个 Handler 至少实现read(path)、write(buf, path)、listdir(path)、pretty_path(path)四个方法(部分只读后端如 GitHub 会针对write/listdir抛出PapermillException)。
  • entry points 扩展:register_entry_points()会加载所有注册在papermill.ioentry point 组下的第三方 Handler(见 papermill/iorw.py#L117-L120),这正是"模块化架构允许新增数据存储"的落地方式。
  • 特殊输入类型:路径为None时返回NoIOHandler(不写任何输出);路径为nbformat.NotebookNode对象时使用NotebookNodeHandler(见 papermill/iorw.py#L141-L145)。

依赖缺失时,相关 Handler 会被替换为missing_dependency_generator生成的占位实现(见 papermill/iorw.py#L24-L57),调用时会给出明确提示而非静默失败。

本地存储:LocalHandler 与默认回退

localHandler(见 papermill/iorw.py#L186-L224)是未匹配任何 scheme 时的默认后端,其行为要点:

  • read以 UTF-8 打开文件;若打开失败,会尝试把路径本身当作 JSON 字符串(即 Notebook 内容直接内联传入的场景);
  • write要求输出目录已存在,否则抛出FileNotFoundError: output folder ... doesn't exist.,这一点在跨目录输出时需注意;
  • 通过cwd()支持在读写期间临时切换工作目录,配合local_file_io_cwd上下文管理器使用(见 papermill/iorw.py#L531-L546)。

AWS S3:s3://后端

S3 是文档明确列出的三大目标存储之一,对应S3Handler(papermill/iorw.py#L227-L242),底层实现为 papermill/s3.py 中的S3类。

路径格式与依赖

s3://<bucket>/<key>

依赖boto3(见 requirements/s3.txt)。安装后即自动可用:

pip install papermill[s3]

底层实现要点(papermill/s3.py)

  • S3.__init__使用boto3.session.Session惰性创建 client/resource 并缓存为类级单例(线程安全),若设置了环境变量BOTO3_ENDPOINT_URL,会作为endpoint_url传入session.resource('s3')(见 papermill/s3.py#L141-L155),便于对接 S3 兼容服务(如 MinIO);
  • read逐行迭代文件内容(按\n切分),cat支持流式读取、断点续读与.gz自动解压(见 papermill/s3.py#L259-L355);
  • cp_string将字符串内容以put方式写入目标 key,上传策略默认bucket-owner-full-control(见 papermill/s3.py#L242-L249);
  • list/listdir通过list_objects_v2分页器实现,listdir额外以/作为 delimiter 模拟ls语义(见 papermill/s3.py#L374-L421);
  • Bucket、Key、Prefix三个类对 S3 对象模型做了一层轻封装,Key.__str__会还原成s3://bucket/key形式(见 papermill/s3.py#L16-L116)。

CLI 中使用 S3 作为输出

沿用 docs/usage-execute.rst 中的经典示例,将本地 Notebook 执行并输出到 S3:

$ papermill local/input.ipynb s3://bkt/output.ipynb -p alpha 0.6 -p l1_ratio 0.1
  • -p/--parameters传参数对,值会被自动解析为布尔、整数、浮点或字符串(解析逻辑见 papermill/cli.py#L260-L289);
  • 若希望值保持原始字符串,改用-r/--parameters_raw;
  • 需要 S3 输入 S3 输出时,两个路径都写成s3://...即可,例如papermill s3://in/input.ipynb s3://out/output.ipynb -f parameters.yaml。

多账号认证

访问 S3 时遵循 boto3 的标准凭证链。若使用多个 AWS 账号,可在命令行通过AWS_PROFILE环境变量指定账号:

$ AWS_PROFILE=dev_account papermill local/input.ipynb s3://bkt/output.ipynb -p alpha 0.6 -p l1_ratio 0.1

其他远程存储账号(Azure 等)也可采用类似的环境变量方式切换凭证。

Azure 对象存储:abs://与adl://后端

文档提到的 Azure data blobs 与 Azure data lakes 分别由ABSHandler与ADLHandler承载(papermill/iorw.py#L245-L288),底层实现见 papermill/abs.py 与 papermill/adl.py。

Azure Blob Storage:abs://

路径格式(见 papermill/abs.py#L30-L46 中的 URL 拆分逻辑):

abs://<account>.blob.core.windows.net/<container>/<blob>?<sas_token>

要点:

  • 凭证支持两种方式:URL 中携带 SAS token,或使用azure.identity.EnvironmentCredential()读取环境凭证(见 papermill/abs.py#L22-L28);
  • 依赖azure-storage-blob >= 12.1.0与azure-identity >= 1.3.1(见 requirements/azure.txt):
    pip install papermill[azure]
  • read将 blob 下载到内存流后按行解码为 UTF-8;write调用upload_blob(data=buf, overwrite=True)覆盖写入;listdir通过list_blobs(prefix)列出容器内对象(见 papermill/abs.py#L48-L70)。

CLI 示例:

$ papermill local/input.ipynb "abs://myaccount.blob.core.windows.net/mycontainer/output.ipynb?<sas_token>" -p alpha 0.6

Azure Data Lake:adl://

路径格式(见 papermill/adl.py#L23-L29):

adl://<store_name>.azuredatalakestore.net/<path>

要点:

  • 认证通过azure.datalake.store.lib.auth()完成,token 在ADL实例内缓存(见 papermill/adl.py#L31-L34);
  • 依赖azure-datalake-store >= 0.0.30, < 2.0.0(见 requirements/azure.txt);
  • read/write/listdir均基于core.AzureDLFileSystem适配器,listdir返回的路径会还原为adl://完整形式(见 papermill/adl.py#L39-L61)。

CLI 示例:

$ papermill local/input.ipynb adl://mystore.azuredatalakestore.net/output.ipynb -p alpha 0.6

更多内置后端:GCS、HDFS、GitHub、HTTP 与标准流

除文档重点列出的三类外,papermill_io还内置了以下后端(均有对应 Handler 与测试):

SchemeHandler底层依赖说明
gs://GCSHandlergcsfs >= 0.2.0(requirements/gcs.txt)Google Cloud Storage;写入对限流异常做指数退避重试,默认最多 3 次、初始延迟 1 秒、最大 4 秒(见 papermill/iorw.py#L291-L337)
hdfs://HDFSHandlerpyarrow >= 2.0(requirements/hdfs.txt)通过HadoopFileSystem(host="default")读写,listdir 使用FileSelector(见 papermill/iorw.py#L340-L361)
http(s)://github.com/...GithubHandlerPyGithub >= 1.55(requirements/github.txt)只读:从org/repo/blob/ref/path结构解析并读取仓库文件内容;支持GITHUB_ACCESS_TOKEN环境变量(见 papermill/iorw.py#L364-L394)
http:///https://HttpHandlerrequests >= 2.21.0通用 HTTP 读写:GET 读取、PUT 写回 JSON(见 papermill/iorw.py#L167-L183)
-StreamHandler内置从 stdin 读、向 stdout 写(见 papermill/iorw.py#L397-L415),支持管道式调用... | papermill - - | ...

GCS 与 S3 均有对应的测试夹具 Notebook(papermill/tests/notebooks/gcs/gcs_in/gcs-simple_notebook.ipynb、papermill/tests/notebooks/s3/s3_in/s3-simple_notebook.ipynb),可在编写用例时参考。

Python API 中的远程存储

execute_notebook对路径的处理完全透明——输入输出路径都走papermill_io,因此 Python API 与 CLI 一样支持任意已注册的存储后端:

import papermill as pm pm.execute_notebook( 's3://my-bucket/input.ipynb', # 从 S3 读取 's3://my-bucket/output.ipynb', # 写回 S3 parameters=dict(alpha=0.6, ratio=0.1), )

同理,读入端也可以是abs://、adl://、gs://等;输出路径传None时不落盘(对应NoIOHandler,见 papermill/iorw.py#L434-L447)。

此外,papermill_io还暴露了若干便捷函数供上层调用:read_yaml_file(读取 YAML 参数文件)、write_ipynb(序列化 Notebook 写盘)、load_notebook_node(读取并补齐 papermill 元数据)、list_notebook_files(列出目录下所有.ipynb),全部定义在 papermill/iorw.py。

自定义存储后端:模块化扩展

新增存储类型的标准做法是复用papermill.ioentry point 机制:

  1. 实现一个 Handler 类,提供read/write/listdir/pretty_path四个方法(读写能力可按后端取舍,不支持的方法抛PapermillException);
  2. 在项目打包配置中声明 entry point,组名为papermill.io,名字为该后端的 URI scheme(如mycloud://);
  3. 安装该包后,papermill_io.register_entry_points()会自动加载它(见 papermill/iorw.py#L117-L120),随后即可直接使用mycloud://...路径。

该机制的注册与匹配行为有测试覆盖:test_entrypoint_register验证了 entry point 的加载,test_register_ordering验证了 LIFO 匹配顺序(见 papermill/tests/test_iorw.py)。S3 后端的Bucket/Key/Prefix与S3.list等接口也有专门的单测(papermill/tests/test_s3.py),并配套test_adl.py、test_abs.py、test_gcs.py等针对各云后端的测试文件,可作为实现自定义 Handler 的行为参考。

依赖速查

各存储后端对应的可选依赖(见 requirements/ 目录):

  • S3:boto3(requirements/s3.txt)
  • Azure Blob + Data Lake:azure-datalake-store >= 0.0.30,<2.0.0、azure-storage-blob >= 12.1.0、azure-identity >= 1.3.1、requests >= 2.21.0(requirements/azure.txt)
  • GCS:gcsfs >= 0.2.0(requirements/gcs.txt)
  • HDFS:pyarrow >= 2.0(requirements/hdfs.txt)
  • GitHub:PyGithub >= 1.55(requirements/github.txt)

未安装对应依赖时,相关 Handler 会被替换为缺失依赖占位实现,调用时给出提示,不影响其他后端使用。

小结

Papermill 的存储层是"按 URI scheme 分发、Handler 统一接口、entry point 可扩展"的模块化设计:文档明确支持的 AWS S3、Azure Blob、Azure Data Lake 开箱即用,GCS、HDFS、GitHub、HTTP 与标准流作为内置补充;本地路径始终是默认回退。理解 papermill/iorw.py 中的注册表与各后端路径规范后,即可在 CLI 与 Python API 中自由组合输入输出位置,也可以按同一套接口快速接入新的存储系统。更多底层 API 细节可查阅 docs/reference/papermill-storage.rst 与 papermill-storage 相关模块。

  • 开发工具
  • CLI
  • 数据工程

【免费下载链接】papermill

📚 Parameterize, execute, and analyze notebooks

项目地址:https://gitcode.com/gh_mirrors/pa/papermill
点击查看免费下载
上一篇:JupyterHub认证系统全解析:PAM、OAuth与LDAP方案对比
下一篇:从0到1:用mlx-optiq量化自己的Gemma模型,mlx-community/gemma-4-31B-it-OptiQ-4bit制作全流程 🚀

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 19:15:21

claude-mem:为Claude Code打造长期记忆的终端AI扩展工具

1. 项目整体设计与思路拆解1.1 为什么需要 claude-mem 这类记忆工具用过 Claude Code 或者经常和 Claude 聊天的人应该都有同感&#xff1a;单次会话里它能记住你交代的上下文&#xff0c;但一旦关闭终端、开启一个新会话&#xff0c;之前聊过的内容就像被格式化了一样&#xf…

作者头像 李华
网站建设 2026/10/8 19:15:18

t3code轻量代码片段管理:SQLite全文检索与CLI实践

1. 从“t3code”这个关键词说起&#xff1a;它到底指什么第一次看到“t3code”这个词&#xff0c;很多人会一头雾水。它不像“Python”“Docker”那样有明确的官方定义&#xff0c;也不像某个大厂框架那样有完整的文档站。我在几个技术社区翻了一圈&#xff0c;发现这个词的用法…

作者头像 李华
网站建设 2026/10/8 19:13:01

题解:洛谷 P1553 数字反转(升级版)

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大家订阅我的专栏:算法…

作者头像 李华
网站建设 2026/10/8 19:10:15

TPS259483与STM32L031构建嵌入式电源路径保护系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华