关于 earth2studio-create-datasource
此开发流程用于为 Earth2Studio 添加远程数据源封装,面向项目贡献者,涵盖设计、实现、测试、验证、文档和可选的 PR 审查。
主要功能
- 01选择数据源类型
- 02分析存储与访问模式
- 03实现异步数据源
- 04添加测试并注册到项目
- 05验证数据并准备 PR
适用场景
- 01为 Earth2Studio 添加远程气象数据源
- 02封装远程存储中的预报或站点数据
- 03提交前测试并验证新数据源
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nvidia/ skills --skill earth2studio-create-datasource安装后在 Claude Code 中输入/earth2studio-create-datasource确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
BENCHMARK.mdskill-card.mdskill.oms.sigevals/config.ymlevals.jsonevals/environment/Dockerfileevals/environment/setup/bootstrap.shevals/targets/eval_1_target.pyeval_2_target.pyeval_3_target.pyeval_4_target.pyevals/targets/test/eval_1_test_target.pyeval_2_test_target.pyeval_3_test_target.pyeval_4_test_target.pyreferences/implementation-guide.pytesting-guide.pyvalidation-guide.md详细介绍
创建并验证数据源
用途
端到端工作流,用于实现新的 Earth2Studio 数据源封装器,将远程数据存储(S3、GCS、Azure、HTTP、HuggingFace)连接到 Earth2Studio 的异步数据获取基础设施,涵盖分析、实现、测试、验证和提交 PR。
前提条件
- Earth2Studio 开发环境,已安装
uv(uv run python必须可用) - Git 已配置 fork(
origin)和 upstream(upstream)远程仓库 - 有权访问目标远程数据存储(若为私有存储,则需具备凭据)
- Python 3.10+
工作区
使用包含 pyproject.toml 的目录。对于 Harbor 评估,将文件写入 /workspace/output/ 并保留路径。切勿读取 evals/targets/。
说明
**Python 环境:**始终使用
uv run python或本地.venv。 切勿直接使用系统 Python。
请按顺序完成每个步骤。
**[CONFIRM] 门槛:**只有步骤 1(源类型)和步骤 12(合理性检查图表)需要用户明确批准。所有其他
[CONFIRM]标记仅供参考——请直接说明决策并继续,不要阻塞流程。**优先交付:**在进行深入探索、文档编写、注册、CHANGELOG 或 PR 工作之前,先编写源文件和测试文件(步骤 6–7)。如果用户只要求实现,则跳过步骤 8–14。
**完成前:**在仓库根目录运行验证命令,以便结果显示在会话日志中:
uv run pytest test/data/test_<source>.py -x make format && make lint**保持简洁:**避免编写冗长的架构报告;用几句话概述决策,然后继续编写文件。
卡住或收到用户反馈 如果 Agent 在使用此技能时卡住,或用户提出更正,请审慎检查技能中的相关部分并加以改进。保持简洁。
每次调用只处理一种源类型。 需要处理配套类型时,请再次调用。
参考文件
在相关步骤中按需加载以下文件:
| 文件 | 内容 | 加载时机 |
|---|---|---|
references/implementation-guide.py | 带有 FILL 注释的源代码骨架 | 步骤 3–10 |
references/testing-guide.py | 带有 FILL 注释的测试骨架 | 步骤 11 |
references/validation-guide.md | 绘图模板、PR 正文模板、Greptile 处理说明 | 步骤 12–14(可选,用于获取模板) |
工作流概览
Step 0: Obtain reference → Step 1: Determine type → Step 2: Dependencies
→ Step 3: Add deps → Step 4: Create lexicon → Step 5: Update vocab/schema
→ Step 6: Create skeleton → Step 7: Implement source → Step 8: Register
→ Step 9: Documentation → Step 10: CHANGELOG → Step 11: Tests
→ Step 12: Validate & plots (user confirms) → Step 13: PR + sanity comment
→ Step 14: Greptile review
步骤 0 — 获取远程数据存储参考资料
如果提供了 $ARGUMENTS,则使用它(URL → WebFetch;文件路径 → 读取)。
如果为空,请询问:
请提供 URL、API 文档链接或远程数据存储的说明。我们将据此了解存储格式、访问模式、变量清单以及时间和空间分辨率。
步骤 1 — 确定源类型
| 协议 | 返回值 | 是否有 lead_time? | 用途 |
|---|---|---|---|
| DataSource | xr.DataArray | 否 | 网格化分析/再分析 |
| ForecastSource | xr.DataArray | 是 | 网格化预报 |
| DataFrameSource | pd.DataFrame | 否 | 稀疏/站点观测 |
| ForecastFrameSource | pd.DataFrame | 是 | 稀疏预报观测 |
关键因素:网格化还是稀疏数据 → DataArray 还是 DataFrame;分析还是预报 → Source 还是 ForecastSource。
[CONFIRM — 源类型]
给出推荐类型并说明理由,然后征求确认。
第 2 步 — 检查远程存储并提出依赖建议
分析: 存储后端、文件格式、身份验证、访问模式、时间/空间分辨率、变量清单。
优先使用 fsspec:
| 后端 | 首选 | 避免 |
|---|---|---|
| AWS S3 | s3fs(核心依赖) | 直接使用 boto3 |
| GCS | gcsfs(核心依赖) | google-cloud-storage |
| Azure | adlfs | azure-storage-blob |
| HTTP | fsspec(核心依赖) | requests |
| HuggingFace | huggingface_hub(核心依赖) | 自定义脚本 |
只有在 fsspec 无法访问存储时,才改用专用库。
检查 pyproject.toml — 仅提出尚未包含在内的包。
核心依赖包括:s3fs、gcsfs、fsspec、zarr、netCDF4、h5py、
pygrib、huggingface-hub、pandas、pyarrow。
[确认 — 依赖与访问模式]
说明:后端、fsspec 文件系统、新增包(及许可证)、身份验证方式。
第 3 步 — 添加依赖
从此处开始,加载
references/implementation-guide.py,并在第 10 步之前持续参考。
如需新包:
uv add --extra data <package>uv lock- 使用
OptionalDependencyFailure模式添加可选依赖导入
第 4 步 — 创建词汇类
创建 earth2studio/lexicon/<source_name>.py,其中包含:
metaclass=LexiconTypeVOCAB: dict[str, str],将 E2S 名称映射到远程键get_item(cls, val),返回tuple[str, Callable]- 结构化键使用
::分隔符
将远程变量映射到 E2STUDIO_VOCAB(earth2studio/lexicon/base.py 中有 282 个条目)。
[确认 — 词汇表与变量映射]
说明:类名、键格式、完整映射表、修饰符、参考 URL。
第 5 步 — 更新 E2STUDIO_VOCAB / SCHEMA(如有需要)
- 新词汇:地表 = 描述性缩写;气压 =
{name}{level} - 新 Schema 字段:仅适用于 DataFrame 来源,检查
E2STUDIO_SCHEMA
[确认 — 词汇表与 Schema 更新]
如无需更新,则跳过。
第 6 步 — 创建数据源文件骨架
遵循规范的方法顺序:
- 类常量
- SCHEMA
__init___async_init__call__fetch_create_tasksfetch_wrapperfetch_array_validate_time- 辅助方法
cache属性available类方法
使用异步任务数据类模式实现并行执行。
[确认 — 骨架]
说明:类名、文件路径、骨架代码、任务数据类。
第 7 步 — 实现数据源与测试
测试文件与数据源文件同等重要。 在数据源文件旁创建
test/data/test_<filename>.py。 对异步数据源添加test_<source>_call_mock。
同步数据源: 使用 prep_data_inputs/prep_forecast_inputs,直接调用 __call__。
异步数据源: 所需模式请参阅 references/implementation-guide.py:
_sync_async、managed_session、gather_with_concurrency、async_retry、
纯异步 I/O、try/finally 清理。构造函数参数:cache=True、
verbose=True、async_timeout=600、async_workers=16、retries=3。
DataFrame 数据源添加 time_tolerance。
第 8 步 — 注册数据源
earth2studio/data/__init__.py— 按字母顺序导入earth2studio/lexicon/__init__.py— 按字母顺序导入- 验证
pyproject.toml依赖
第 9 步 — 更新文档
- 添加到正确的 RST 文件(
datasources_analysis.rst/_forecast.rst/_dataframe.rst) - 类文档字符串:Parameters、Warning(下载大小)、Note(参考 URL)、徽章(放在最后)
- 所有公共方法:使用 NumPy 风格的文档字符串
第 10 步 — 更新 CHANGELOG.md
在当前尚未发布的版本下添加条目。格式请参阅
references/implementation-guide.py 中的 REGISTRATION CHECKLIST。
每个数据源占一行。不要添加单独的词汇表条目。
步骤 11 — 验证风格并扩展测试
运行 make format && make lint && make license。加载 references/testing-guide.py
以获取测试骨架。必需的测试:test_<source>_fetch(慢速)、_cache(慢速)、
_call_mock、_exceptions、_available。使用 --slow 时,覆盖率目标为 90% 以上。
[确认 — 测试]
展示测试文件、函数和覆盖率。
步骤 12 — 验证变量并进行合理性检查
- 根据真实数据验证所有词汇表变量(运行脚本,但不要提交)
- 移除有效数据少于 10% 的变量
- 创建合理性检查图(网格或稀疏模板)
- 告知用户图表路径,并请求目视确认
[确认 — 合理性检查图表]
用户必须目视检查图表。未经确认不得继续。
步骤 13 — 创建分支、提交并创建 PR
- 创建分支
feat/data-source-<name> - 提交(不要添加合理性检查脚本/图像)
- 推送到 fork
gh pr create --repo NVIDIA/earth2studio- 立即在 PR 评论中发布合理性检查验证结果,包括:
- 变量覆盖率表(名称、数量、范围、单位)
- 数据验证摘要(区域、风暴/站点、时间范围)
- 关键发现(数值在物理上合理、转换已验证)
<details>块中的完整验证脚本- 图像占位符:``
[确认 — 准备提交]
创建 PR 前,确认所有步骤均已完成。
步骤 14 — 自动化代码审查
- 等待 Greptile 审查(超时 5 分钟)
- 对反馈分类(错误/风格/性能/文档/建议/误报)
- 向用户展示分类表
- 实施已接受的修复
- 回复 PR 评论
- 推送
[确认 — 审查分类]
由用户批准要处理的评论。
示例
User: Add a data source for the NOAA GFS analysis on S3
Agent: [loads skill, proceeds through Steps 0–14]
限制
- 每次调用仅处理一种源类型
- 验证需要网络访问(步骤 12)
- 所有文件都必须包含 SPDX 许可证头
提醒
应做: uv run python、loguru.logger、在 __init__.py/RST/CHANGELOG 中按字母顺序排列、
采用规范的方法顺序、使用异步工具(managed_session、gather_with_concurrency、
async_retry)、纯异步 I/O、在文档字符串中提供参考 URL、使用 try/finally 清理。
避免: asyncio.to_thread、直接使用 tqdm.gather、使用 xarray 加载数据、下载完整文件。
绝不: loop.set_default_executor()、提交机密信息、提交合理性检查脚本/图像。