DNAnexus dxapp.json 配置完全指南:构建可复现基因组学应用与 Applet
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
导读
dxapp.json是 DNAnexus 平台上所有应用(App)与应用小程序(Applet)的源头清单(source manifest),它统一描述元数据、输入输出契约、执行环境、依赖、超时/重启策略与权限边界。本指南以 scientific-agent-skills 仓库中dnanexus-integration技能的配置文档为主线,结合仓库内离线校验器源码与测试用例,系统讲解dxapp.json的每个字段、App 与 Applet 的差异、区域资源与实例选型、重试/超时策略、依赖管理、最小权限访问,以及一套可直接执行的构建前校验流程。读完本文,你将能够独立编写、校验并构建一个符合当前 DNAnexus 平台基线(Ubuntu 24.04 / 20.04 AEE、dxpy 0.410.0)的生产级dxapp.json。
dxapp.json控制什么
dxapp.json是dx build与dx build --create-app消费的源头清单(source manifest)。它描述的内容包括:
- 应用元数据与版本号
- 输入与输出契约(I/O contract)
- 入口点解释器与源文件
- 应用执行环境(AEE, Application Execution Environment)
- 依赖
- 超时与重启策略
- 请求的项目、网络与开发者权限
- 区域专属资源(region-specific resources)
一个关键概念需要厘清:source manifest 不等于构建工具生成的规范化 API 载荷(canonical API payload)。对于字段约束,/applet/new、/app/new这两个 API 方法以及 I/O 与 Run Specifications 才是权威来源。也就是说,dxapp.json只是你手写的意图描述,真正落地成平台对象时以 API 规范为准。
本仓库中该技能对应的整体定位可参考 SKILL.md:它负责“构建并运行可复现的基因组学工作负载”,而dxapp.json正是应用定义的入口。配置文档的版本基线在 references/sources.md 中记录:校验日期为 2026-07-23,dxpy 基线为 0.410.0,AEE 支持 Ubuntu 24.04 与 20.04 且环境版本为0。
Applet 与 App:先分清对象模型
配置项的要求因目标对象是 Applet 还是 App 而不同,下表是原文档给出的核心对照:
| 需求项 | Applet | App |
|---|---|---|
name | 必需 | 必需 |
runSpec | 必需 | 必需 |
version | 可选 | 必需 |
inputSpec | 推荐 | 必需 |
outputSpec | 推荐 | 必需 |
| 区域 | 构建项目所在区域 | 声明支持的区域 |
| 生命周期 | 项目数据对象 | 可版本化、可发布的可执行对象 |
生命周期差异决定了两者的用途:Applet 是不可变、固定在单个项目中的数据对象,适合开发、测试与项目内工具;App 是跨项目/跨区域可授权、可发布、带版本的执行体,适合需要长期维护和对外复用的产品。另外有一条硬性约束:一个 Applet 若同时缺少 inputSpec 和 outputSpec,则无法被添加为工作流(workflow)的一个阶段。
仓库的离线校验器 scripts/validate_dxapp.py 用determine_kind()实现了这一判定逻辑:--kind auto时,清单中出现version字段即推断为 App,否则为 Applet;而validate_metadata()与validate_specs()则会按类型收紧规则——App 缺version、inputSpec、outputSpec时直接报 error,Applet 同样缺失只报 warning(tests/dnanexus-integration/test_scripts.py 中的test_kind_is_inferred_from_the_presence_of_version与test_an_applet_only_gets_a_warning_for_missing_specs验证了这一行为差异)。校验器代码定义的正则还揭示了平台约束的细节:应用名name只允许字母、数字、点、下划线与连字符(APP_NAME_RE = ^[A-Za-z0-9._-]+$),App 版本号必须符合语义化版本语法(VERSION_RE,接受1.2.3、1.2.3-beta.1、1.2.3+build5等,拒绝1.2、v1.2.3、1.02.3)。
最小 Applet 清单
下面这份最小 Applet 清单是合法 JSON(原文档特意省略注释,因为dxapp.json不支持注释):
{ "name": "qc-fastq", "inputSpec": [ { "name": "reads", "class": "file", "patterns": ["*.fastq", "*.fastq.gz"], "help": "Input FASTQ file" } ], "outputSpec": [ { "name": "report", "class": "file", "patterns": ["*.html"] } ], "runSpec": { "interpreter": "python3", "file": "src/qc_fastq.py", "distribution": "Ubuntu", "release": "24.04", "version": "0" } }要点说明:
name是必填字段,且受字符集约束。runSpec.file指向构建目录下的入口源文件(上例为src/qc_fastq.py),该路径相对于dxapp.json所在目录。distribution、release、version三者共同指定 AEE 镜像:当前基线为 Ubuntu 24.04(或刻意保留的 20.04),AEE 版本字符串为"0"。dxapi字段是可选的,不是必填清单字段——这是本技能纠正过的一个历史错误模式(见 references/sources.md 的 “Corrected Legacy Patterns” 一节)。
validate_dxapp.py对runSpec的校验与上述要求一一对应(validate_run_spec):
- 必须提供非空的
file或code作为入口源(missing-entry-source),但二者同时出现会告警(multiple-entry-sources),要求只保留一个权威入口源; interpreter只能是bash或python3;distribution必须为"Ubuntu";release只能是20.04或24.04,其中 20.04 会被标记legacy-release警告;- AEE
version必须是字符串"0"。
生产级 App 骨架与离线校验
当需要发布为可版本化的 App 时,使用下面的生产骨架。注意:区域与实例类型必须替换为目标项目实际可用的值,不要从旧文档拷贝静态实例列表(已退役的实例类型在创建/更新 App 或 Applet 时会被平台拒绝)。
{ "name": "qc-fastq", "title": "FASTQ quality control", "summary": "Creates a quality-control report for one FASTQ file", "version": "1.0.0", "inputSpec": [ { "name": "reads", "label": "Reads", "class": "file", "patterns": ["*.fastq.gz"], "help": "A gzip-compressed FASTQ file" } ], "outputSpec": [ { "name": "report", "label": "QC report", "class": "file", "patterns": ["*.html"] } ], "runSpec": { "interpreter": "python3", "file": "src/qc_fastq.py", "distribution": "Ubuntu", "release": "24.04", "version": "0", "timeoutPolicy": { "main": {"hours": 4} }, "executionPolicy": { "restartOn": { "ExecutionError": 1, "UnresponsiveWorker": 2, "SpotInstanceInterruption": 2 }, "maxRestarts": 3 } }, "access": { "network": [] }, "regionalOptions": { "aws:us-east-1": { "systemRequirements": { "main": { "instanceType": "mem2_ssd1_v2_x4" } } } } }在生产骨架中可以看到几个进阶字段:title/summary用于界面展示;timeoutPolicy与executionPolicy控制运行时限与重启;access.network默认为空数组(无外网);regionalOptions.<region>.systemRequirements.<entry-point>是当前推荐的资源声明位置。
构建前先跑离线校验。本技能随附的校验器位于 scripts/validate_dxapp.py,从技能根目录执行:
uv run python "scripts/validate_dxapp.py" \ "path/to/dxapp.json" --kind app --strict--kind可选auto(有version视为 App)、app、applet;--strict会把警告(warning)一并视为失败,适合纳入 CI;--json可输出机器可读的 JSON 报告。校验器能捕获结构错误、已弃用字段位置、过宽权限、区域资源不一致等,但正如 SKILL.md 所强调的,它只是dx build平台校验的补充而非替代。命令行行为在 tests/dnanexus-integration/test_scripts.py 中有完整测试:合法清单退出码 0、有 error 退出码 1、--strict下警告也导致退出码 1、无法解析的 JSON 退出码 2 并产生parse问题。
通过校验后即可构建:
dx build "path/to/my-app" # 构建 Applet dx build "path/to/my-app" --create-app # 构建带版本的 App输入与输出规范(inputSpec / outputSpec)
参数class的常见取值分为三类:
- 原始类型:
string、int、float、boolean、hash - 数据对象:
file、record、applet - 数组类型:
array:string、array:int、array:file等
每个参数必须有唯一的name和class。常用可选字段包括:
label:界面显示名help:帮助文本optional:是否可选(布尔值)default:默认值choices:可选项枚举patterns:文件后缀提示,如["*.fastq.gz"]suggestions:输入建议group:参数分组
两条重要纪律:
patterns只是用户界面提示,不是安全或内容校验边界。真正的文件内容校验必须在 App 代码内完成。default必须与声明的class一致;文件与 record 类型的默认值必须使用 DNAnexus 链接(dxlink),而不是本地路径。
校验器在 scripts/validate_dxapp.py 的validate_parameter_list中对上述规则做了程序化约束,并且补充了两个容易踩坑的点:
- 参数名必须匹配
^[A-Za-z_][A-Za-z0-9_]*$,即不允许以数字开头、不允许含连字符或空格;同一规格中参数名不得重复(duplicate-parameter)。 default、suggestions、choices是仅限 inputSpec 的字段,出现在 outputSpec 中会直接报错(output-only-field)。测试用例test_input_only_fields_are_rejected_in_the_output_spec验证了这一点。class必须属于校验器CLASSES集合中的 15 个合法值之一。
runSpec:入口点与执行环境
在 source manifest 中,runSpec的标准形态如下:
{ "runSpec": { "interpreter": "python3", "file": "src/main.py", "distribution": "Ubuntu", "release": "24.04", "version": "0" } }当前基线支持的解释器与 AEE 组合只有两种:
- Ubuntu 24.04,环境版本
0,解释器python3或bash - Ubuntu 20.04,环境版本
0,解释器python3或bash
新开发优先选用 Ubuntu 24.04;只有存在已验证的兼容性需求时才保留 20.04,并应规划迁移。
runSpec还可以携带timeoutPolicy、executionPolicy、execDepends等(详见后文)。validate_dxapp.py对runSpec的校验(validate_run_spec、validate_exec_depends、validate_execution_policy、validate_timeout_policy)覆盖了入口源、解释器、发行版、AEE 版本、已弃用的systemRequirements位置、restartableEntryPoints取值(只能是"master"或"all",且设为all时会警告所有入口点必须幂等)以及依赖/策略字段的合法性。
值得注意的执行环境行为:平台在临时 worker 上按“预置 worker 与容器 → 安装 execDepends → 配置 API/网络/日志 → 解包捆绑依赖与资产 → 运行入口点 → 采集 stdout/stderr → 处理 job_output.json 或 job_error.json → 销毁工作区”的顺序执行作业。因此runSpec.file指向的入口脚本应当遵循平台的执行契约(相关开发细节可参见 references/app-development.md)。
区域资源与实例选型
当前推荐位置
新清单中,资源需求应放在:
regionalOptions.<region>.systemRequirements.<entry-point>以下旧位置已弃用,虽然部分单区域兼容场景仍被接受,但新应用不应使用:
runSpec.systemRequirements- 顶层
resources
校验器会分别发出deprecated-system-requirements与deprecated-resources警告(测试见test_top_level_resources_is_flagged_as_deprecated与test_deprecated_system_requirements_location_is_flagged)。
还有一条一致性规则:如果一个区域声明了systemRequirements,那么regionalOptions中列出的每个区域都必须声明。校验器的inconsistent-regional-requirements错误正是为此设计(test_system_requirements_must_cover_every_region_or_none)。区域绑定的资产与资源 ID 也必须在对应区域可用。
固定实例类型
{ "regionalOptions": { "aws:us-east-1": { "systemRequirements": { "main": {"instanceType": "mem2_ssd1_v2_x4"}, "process": {"instanceType": "mem3_ssd1_v2_x8"} } } } }不同云厂商与区域的可用实例类型不同,已退役的类型在创建/更新 App 或 Applet 时会被拒绝,所以务必动态查询当前可用的实例列表。
动态实例选择
在获得许可(licensed)的前提下,可以提供有序的候选列表,让平台按序尝试:
{ "regionalOptions": { "aws:us-east-1": { "systemRequirements": { "main": { "instanceTypeSelector": { "allowedInstanceTypes": [ "mem1_ssd1_v2_x4", "mem1_ssd1_v2_x8", "mem2_ssd1_v2_x4" ] } } } } } }关于instanceTypeSelector,原文档给出了精确的平台行为:
- 与同一入口点的
instanceType、clusterSpec互斥。校验器的resource-selector-conflict错误确保这一点(test_resource_selectors_are_mutually_exclusive)。 - 平台按列表顺序给每个允许类型10 分钟的尝试窗口;若全部失败,则以翻倍窗口(20 分钟、40 分钟……)重复整个列表。
- 普通优先级作业在 Spot 等待超时后,对按需(on-demand)回退采用相同序列。
- 每次尝试会记录在作业描述的
instanceTypeTransitions字段中。 allowedInstanceTypes必须是非空字符串数组,且重复项只会被告警(不提供额外回退价值)。
集群
集群请求在入口点的 system requirements 中使用clusterSpec。当前集群类型为dxspark、apachespark与generic。Spark 版本与实例可用性会变化,应查询实时的 I/O 与 Run Specifications,而非硬编码旧值。
重试与超时策略
完整示例:
{ "runSpec": { "executionPolicy": { "restartOn": { "AppInsufficientResourceError": 2, "ExecutionError": 1, "JMInternalError": 1, "UnresponsiveWorker": 2, "SpotInstanceInterruption": 3, "*": 0 }, "maxRestarts": 4 }, "timeoutPolicy": { "main": {"hours": 12}, "process": {"hours": 2} }, "restartableEntryPoints": "all" } }使用原则:
- 只对可能自愈的失败启用重试。对确定性的
AppError或非法输入重试只会浪费计算费用。 maxRestarts是跨所有失败原因的总重启上限:必须是非负整数且小于 10,默认值为 9。出于成本控制,应显式设置更小的上限。校验器与测试(test_max_restarts_is_bounded_and_rejects_booleans)严格校验0 <= maxRestarts < 10且拒绝布尔值。restartOn中的失败原因会对照当前文档化的可重启集合检查(ExecutionError、UnresponsiveWorker、JMInternalError、AppInternalError、AppInsufficientResourceError、JobTimeoutExceeded、SpotInstanceInterruption、*),未知原因产生unknown-restart-reason警告;每个原因的重试次数必须是非负整数。restartableEntryPoints: "all"意味着所有入口点都必须具备幂等性,否则应保持默认或设为"master"。AppInsufficientResourceError后的自动升配需要同时满足三个条件:① 有适用的restartOn次数;② 组织策略允许重启时实例升级;③ 同一实例族中存在更大的实例。若初始使用了动态实例选择,资源不足重试将采用平台的升级决策,而不是原始的 selector 列表。- 作业默认最长运行 30 天,只要可能就应设置更短、面向具体工作负载的超时。
timeoutPolicy的键为入口点名称,值为{days/hours/minutes: 数值}字典;不支持的单位(如weeks)会被校验器拒绝(timeout-unit),负值同样报错(timeout-value)。
依赖管理:按可复现性排序
原文档给出的依赖策略优先级(从最可复现到最宽松):
- 捆绑源码/资源(Bundled source/resources):适合小而受版本控制管理的文件。
- 资产包(Asset bundles):适合可复用的系统与 Python 环境。
- 已保存的 Docker 镜像 tar 包:以项目数据对象或资产形式存储。
execDepends:适合简单 APT 依赖,可接受版本漂移。- 运行时下载(Runtime downloads):仅当无法避免且经过完整性校验时使用。
捆绑资源
resources/目录下的文件会被dx build打包并解包到 AEE 中。严禁捆绑密钥、私钥或可变凭据。
execDepends
运行时软件包仓库在不同执行之间可能变化,包管理器支持时务必锁定版本;监管或生产工作负载不要依赖浮动包。
在 Ubuntu 24.04 AEE 上,平台设置了PIP_BREAK_SYSTEM_PACKAGES=1以兼容,但 PyPI 包仍可能与 APT 管理的 Python 包冲突,导致DXExecDependencyError。因此更推荐虚拟环境方案:
python3 -m venv "/home/dnanexus/venv" source "/home/dnanexus/venv/bin/activate" python3 -m pip install --requirement "requirements.txt"将 requirements 锁定并构建进资产包,供生产环境重复使用。对于 Python 命令行工具,pipx可以隔离该工具。校验器要求每个execDepends项必须是带name的对象,且建议提供version或tag,否则发出floating-dependency警告(测试见test_unpinned_dependencies_are_warned_about与test_dependency_entries_must_be_named_objects)。
资产包(Asset bundles)
资产源码布局:
my-asset/ ├── dxasset.json ├── Makefile └── resources/在隔离的平台 worker 中构建:
dx build_asset "my-asset"资产的 distribution 与 release 必须与 App 一致;多区域 App 需要提供在每个目标区域都可用的资产。
Docker 镜像
Ubuntu 24.04 与 20.04 AEE 均支持原生 Docker CLI。生产环境推荐以下流程:
- 用不可变 digest锁定镜像。
docker save保存为 tar 包。- 上传 tar 包或纳入资产。
- 在 App 内
docker load加载。
这样可以避免运行时对注册表的依赖,并可能消除对外部网络的宽泛访问需求。若必须使用私有注册表,凭据应作为显式输入或受保护的项目对象提供——任何对该项目有VIEW权限的人都可能读取这些凭据,因此应使用范围极小、仅可拉取的凭据,并确认项目成员构成。
访问需求:最小权限
默认从无外网开始:
{ "access": { "network": [] } }平台对默认权限 App 的行为:将声明的输入克隆进临时工作区,只在该工作区授予作业CONTRIBUTE权限,并将声明的输出克隆回发起项目。除非 App 必须直接读取、修改或删除已有项目对象,否则省略project与allProjects字段。Applet 的默认值不同(project默认为VIEW),因此仍应只声明其行为所需的最小访问权限。
按需声明以下权限:
network:显式主机白名单,避免["*"]project:发起项目级别allProjects:访问其他用户项目developer:创建/修改或使用未发布 App 的能力
安全语义要点:
- 有效项目访问权限永远不会超过发起用户(launching user)的访问权限。
- 宽泛的
allProjects、ADMINISTER、developer以及不受限的网络权限需要明确论证。校验器会相应发出broad-network、admin-project-access、all-projects-access、developer-access警告(测试见test_broad_and_privileged_access_is_warned_about)。 project/allProjects取值必须是NONE、VIEW、UPLOAD、CONTRIBUTE、ADMINISTER之一(access-level错误)。- 对 HTTPS App,需要单独配置
httpsApp并定义所需共享访问;httpsApp.ports只能是 443、8080、8081 的非空子集。不要暴露一个没有自身授权检查就返回凭据或受保护数据的服务。
校验器还有一个很实用的安全扫描:scan_for_embedded_secrets会递归遍历整个清单,识别键名中含token、password、passwd、secret、private-key等字样的疑似凭据值并告警(embedded-secret)。占位符值(空串、changeme、<token>、redacted等)会被放过,布尔开关(如use_token: False)不算凭据,且匹配是整词锚定的(tokenizer不会误报)。详见测试test_embedded_credentials_are_found_at_any_depth、test_placeholder_credentials_are_not_flagged、test_a_secret_key_holding_false_is_a_setting_not_a_credential。
发布前的验证清单
将原文档的校验清单与校验器/测试证据整合,形成一份可勾选的发布前检查表:
- JSON 可解析且不含注释(
dxapp.json是严格 JSON)。 name与应用version符合平台约束(名称字符集、语义化版本)。- 输入/输出参数名称唯一、
class正确;default/suggestions/choices未误用进 outputSpec。 - App 清单包含
version、inputSpec、outputSpec(空则用[])。 - AEE 为 Ubuntu 24.04 或有意保留的 20.04,环境版本为
"0",解释器为python3或bash。 - 未使用已弃用的顶层
resources与runSpec.systemRequirements位置。 - 每个配置了
systemRequirements的区域都有一致的资源声明,且资产/资源在对应区域可用。 - 每个区域使用的实例类型当前仍然可用。
- 重试策略只针对瞬时/可恢复错误;
maxRestarts有显式的小于 10 的上限。 - 定义了超时与启动成本上限(作业默认上限 30 天,应设置更短的工作负载级超时)。
- 依赖已锁定且受完整性控制(优先 venv/资产包/保存的镜像,
execDepends明确锁定版本)。 - 网络与项目访问遵循最小权限(
network: []起步,避免["*"]与宽泛allProjects)。 - 清单中无嵌入的密钥或凭据。
- 发布前在非生产项目中
dx build成功。
最后一条实践建议:把上面所有检查交给仓库自带的校验器自动完成——
uv run python "skills/dnanexus-integration/scripts/validate_dxapp.py" \ "path/to/dxapp.json" --kind app --strict在严格模式下,任何 error 或 warning 都会导致非零退出码,便于接入本地开发流程或 CI。由于校验器完全离线、不访问网络(相关设计与测试见 tests/dnanexus-integration/test_scripts.py),它可以在任何具备 Python 3.11+ 的环境中使用;对已安装 SDK 的符号/签名基线检查,还可以使用 scripts/inspect_dxpy.py 对照 dxpy 0.410.0 基线做离线探测。
结语:一份配置,一条可复现的发布路径
dxapp.json是 DNAnexus 应用开发的“单点事实来源”:从 I/O 契约到执行环境,从区域资源到重试/超时,从依赖策略到权限边界,全部集中在一个 JSON 文件中。结合本仓库随附的离线校验器与测试套件,你可以在编写阶段就拦截大多数结构性与安全性问题,再以“先构建 Applet 测试 → 通过后--create-app发布”的节奏推进到生产。记住三个当前基线关键词:Ubuntu 24.04(AEE 版本0)、regionalOptions.<region>.systemRequirements资源位置、最小权限访问——遵循它们,你的工作负载将更容易跨区域复现、更可控地运行,也更符合平台对成本与安全的要求。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考