Apache Airflow Provider 全生命周期管理:从创建、发布到暂停、移除的完整技术指南
【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflow
本文基于 Apache Airflow 仓库中的 providers/MANAGING_PROVIDERS_LIFECYCLE.rst 撰写,系统讲解社区 Provider(Community Provider)从创建、测试、文档化、发布,到暂停、恢复、移除的完整技术流程。文中每一步均结合仓库内真实 Provider(如http、standard、apache系列)的源码、配置文件与测试结构进行佐证,读者可据此独立完成一个新 Provider 的落地与上线,也能从容应对 Provider 因依赖问题被暂停或移除时的连锁修复。
1. 生命周期管理全景:治理框架与技术步骤的分工
Airflow 的 Provider 生态拥有 90+ 个独立发行包、超过 1,600 个 hooks/operators/sensors(见 providers/PROVIDER_GOVERNANCE.rst)。如此庞大的生态必须有一套清晰的治理与操作规范:
- 治理框架(Governance)描述 Provider 的生命周期阶段(Incubation 孵化、Production 生产、Attic/Deprecation 归档)、Stewardship 托管模型、健康度量化指标,见 providers/PROVIDER_GOVERNANCE.rst;
- 技术操作(Lifecycle)即本文主题,覆盖创建、发布、暂停、恢复、移除的具体技术步骤与命令;
- 准入流程(Acceptance)说明新 Provider 如何通过 devlist 讨论被接受,见 providers/ACCEPTING_PROVIDERS.rst;
- 暂停与移除策略说明触发条件与社区表决过程,见 providers/SUSPENDING_AND_REMOVING_PROVIDERS.rst。
在开始任何技术操作之前,建议先通读上述治理文档,理解 Provider 所处的生命周期阶段,因为"暂停(suspend)"与"移除(remove)"是两种不同强度的操作,其技术路径在本文后续章节分别给出。
2. 创建新社区 Provider 的前置条件
提出新 Provider 之前,务必先审查 providers/ACCEPTING_PROVIDERS.rst 中的准入流程,并确保满足以下 4 项硬性条件:
- 至少两位 Steward(托管人):愿意长期负责该 Provider 的健康度维护;
- 至少一位现有 Airflow Committer 的赞助:如果 Steward 本人不是 Committer,必须有一位 Committer 赞助并负责 PR 审查与合并;
- 6 个月内达成孵化健康指标的承诺:孵化阶段要求至少 10 个 PR、15 个独立 issue、3 位贡献者、50% issue 在 90 天内关闭等(详见治理文档的孵化毕业标准);
- 参与季度治理更新的计划:每季度在 devlist 上同步 Provider 健康状态。
上述信息需要包含在 devlist 上的[DISCUSSION]讨论帖中(不需要正式投票,7 天无异议即视为接受,讨论帖模板见 providers/ACCEPTING_PROVIDERS.rst)。
3. 搭建开发环境:使用 Breeze 本地开发
文档建议使用breeze进行本地开发,它提供与 GitHub CI 工作流一致的环境。进入仓库根目录后运行:
./breezebreeze会拉起 Docker 容器并把本地代码挂载到容器内部卷中——在 IDE 中做的修改会立即同步到容器内,方便快速跑测试。这也是 Airflow 官方推荐的开发方式(Quick Start 见 contributing-docs/03_contributors_quick_start.rst 与 contributing-docs/03a_contributors_quick_start_beginners.rst)。
本文后续以<PROVIDER>作为 Provider 名的占位符。
4. Provider 代码结构规范
仓库中每个 Provider 都遵循统一的目录布局(例如 providers/http、providers/standard)。新建 Provider 时按如下结构组织(各子目录均为可选,按需创建):
GIT apache/airflow/ └── providers/ └── <PROVIDER>/ ├── pyproject.toml ├── provider.yaml ├── src/ │ └── airflow/ │ └── providers/<PROVIDER>/ │ ├── __init__.py │ ├── executors/ │ │ ├── __init__.py │ │ └── *.py │ ├── hooks/ │ │ ├── __init__.py │ │ └── *.py │ ├── notifications/ │ │ ├── __init__.py │ │ └── *.py │ ├── operators/ │ │ ├── __init__.py │ │ └── *.py │ ├── transfers/ │ │ ├── __init__.py │ │ └── *.py │ └── triggers/ │ ├── __init__.py │ └── *.py └── tests/ ├── unit/ │ └── <PROVIDER>/ │ ├── __init__.py │ ├── executors/ │ │ ├── __init__.py │ │ └── test_*.py │ ├── hooks/ │ │ ├── __init__.py │ │ └── test_*.py │ ├── notifications/ │ │ ├── __init__.py │ │ └── test_*.py │ ├── operators/ │ │ ├── __init__.py │ │ └── test_*.py │ ├── transfers/ │ │ ├── __init__.py │ │ └── test_*.py │ └── triggers/ │ ├── __init__.py │ └── test_*.py ├── integration/<PROVIDER>/ │ ├── __init__.py │ └── test_integration_*.py └── system/<PROVIDER>/ ├── __init__.py └── example_*.py要点说明:
src/下按功能模块拆分子包(operators、hooks、sensors、triggers、notifications、transfers、executors、secrets、links、logs等,列表随生态演进持续变化);tests/下按unit/integration/system三层拆分,与 src 目录结构一一对应;- 每个 Python 子目录都必须包含
__init__.py。
文档建议:找一个与你需求相近的现有 Provider 作为参考模板,从结构、依赖到测试全套照搬再改造,这是最高效的起步方式。
5. 测试体系:单元、集成与系统测试
5.1 单元测试
为 Provider 的每个组件编写单元测试。在 breeze 容器内运行单元测试的命令如下(以 hook 测试为例):
[Breeze:3.10.19] root@fafd8d630e46:/opt/airflow# python -m pytest providers/<PROVIDER>/tests/<PROVIDER>/hook/test_*.py5.2 集成测试
涉及真实外部服务的测试放在tests/integration/<PROVIDER>/下,命名为test_integration_*.py,具体编写与运行方式参见 contributing-docs/testing/integration_tests.rst。
5.3 系统测试
对接真实外部服务的 Provider 建议编写系统测试(tests/system/<PROVIDER>/example_*.py),并在公开仪表盘上发布测试结果,便于社区持续验证集成可用性(参见 providers/ACCEPTING_PROVIDERS.rst 的准入要求)。
6. Provider 文档体系
文档是 Provider 质量的重要组成部分。仓库中有几个与 Provider 文档相关的关键机制:
- 根目录
pyproject.toml由prek hook根据各 Provider 的provider.yaml自动生成(不要手工编辑); airflow-core/docs/extra-packages-ref.rst(即文档中提到的extra-packages-ref.rst)需要手工维护,prek hook只校验其中关于 Provider 的信息是否已更新;commits.rst与CHANGELOG由发布经理在发布时通过breeze release-management命令自动更新。
6.1 文档文件结构
├── pyproject.toml └── providers/<PROVIDER>/src/airflow/providers/ ├── provider.yaml ├── pyproject.toml ├── CHANGELOG.rst │ └── docs/ ├── integration-logos │ └── <PROVIDER>.png ├── index.rst ├── commits.rst ├── connections.rst └── operators/ └── <PROVIDER>.rst6.2 文档编写要求
- 若 Provider 名称不是常见英文单词,将其加入
docs/spelling_wordlist.txt(仓库根目录下存在该文件); - 在
provider.yaml的dependencies键下声明 Provider 依赖;无依赖时写空列表; - 在
docs/apache-airflow-providers-<PROVIDER>/connections.rst中说明如何配置该 Provider 的 Connection; - 在 Provider 的
docs/operators/<PROVIDER>.rst中说明 Operator 的使用方法,尤其当 Operator 有额外参数时,务必给出示例。
Operator 文档的 RST 骨架如下,其中exampleinclude指令会从 example DAG 中按标记截取代码片段,保证文档示例与真实可运行代码一致:
.. _howto/operator:NewProviderOperator: NewProviderOperator =================== Use the :class:`~airflow.providers.<PROVIDER>.operators.NewProviderOperator` to do something amazing with Airflow! Using the Operator ^^^^^^^^^^^^^^^^^^ The NewProviderOperator requires a ``connection_id`` and this other awesome parameter. You can see an example below: .. exampleinclude:: /../../<PROVIDER>/example_dags/example_<PROVIDER>.py :language: python :start-after: [START howto_operator_<PROVIDER>] :end-before: [END howto_operator_<PROVIDER>]6.3 必备文档清单
从一个相似 Provider 复制docs/*.rst并改写,至少需要保留以下文件:
| 文件 | 用途 |
|---|---|
security.rst | 安全说明 |
changelog.rst | 变更日志 |
commits.rst | 提交记录 |
index.rst | 文档首页 |
installing-providers-from-sources.rst | 从源码安装说明 |
configurations-ref.rst | 仅当provider.yaml的config元素中声明了本 Provider 专属配置项时才需要 |
7. provider.yaml 配置详解
providers/<PROVIDER>/src/airflow/providers/<PROVIDER>/provider.yaml是 Provider 的元数据中枢。新建 Provider 时的最小配置如下:
package-name: apache-airflow-providers-<PROVIDER> name: <PROVIDER> description: | `<PROVIDER> <https://example.io/>`__ versions: - 1.0.0 integrations: - integration-name: <PROVIDER> external-doc-url: https://www.example.io/ logo: /docs/integration-logos/<PROVIDER>.png how-to-guide: - /docs/apache-airflow-providers-<PROVIDER>/operators/<PROVIDER>.rst tags: [service] operators: - integration-name: <PROVIDER> python-modules: - airflow.providers.<PROVIDER>.operators.<PROVIDER> hooks: - integration-name: <PROVIDER> python-modules: - airflow.providers.<PROVIDER>.hooks.<PROVIDER> sensors: - integration-name: <PROVIDER> python-modules: - airflow.providers.<PROVIDER>.sensors.<PROVIDER> connection-types: - hook-class-name: airflow.providers.<PROVIDER>.hooks.<PROVIDER>.NewProviderHook - connection-type: provider-connection-type7.1 真实示例对照
仓库中真实 Provider 的provider.yaml比上面的骨架更丰富。以 providers/http/provider.yaml 为例,可以看到它还包含state: ready、lifecycle: production、source-date-epoch、完整的历史versions列表,以及notifications(如airflow.providers.http.notifications.HttpNotifier)、triggers、connection-types中的hook-name、ui-field-behaviour(隐藏字段、重命名、占位符)等高级字段。
再看 providers/standard/provider.yaml,它额外展示了三类值得借鉴的字段:
config:Provider 专属配置项。例如standard提供venv_install_method选项(auto/pip/uv,默认auto),对应 Airflow 配置中的[standard] venv_install_method;extra-links:如TriggerDagRunLink、ExternalDagLink等自定义链接;task-decorators:将 task 装饰器(如python、bash、virtualenv、sensor、short_circuit)注册到 Provider 中。
state字段是生命周期管理的核心开关,取值含义如下(详见 providers/PROVIDER_RELEASES.rst):
| state | 含义 |
|---|---|
not-ready | 有进行中的改动(通常是 API 变更),暂不纳入常规发布周期,但仍参与测试与依赖贡献 |
ready | 常规状态,正常参与发布、文档构建、打包 |
suspended | 因依赖问题暂停发布,不参与 CI 与文档构建,不贡献依赖 |
removed | 仅用于最后一个发布周期(一次性),发布带移除公告的最终版本 |
8. 本地构建文档
创建并更新完文件后,在本地构建文档验证正确性。第一条命令构建 Provider 自身的文档,第二条确保主 Airflow 文档不受影响:
breeze build-docs <provider id> breeze build-docs apache-airflow9. 条件性 Provider 变体(version_compat.py)
某些 Provider 需要针对不同 Airflow 版本提供不同实现,仓库的做法是:
- 从已有条件变体的 Provider 中复制
version_compat.py到目标 Provider 的根包目录; - 从该
version_compat.py导入所需的AIRFLOW_V_X_Y_PLUS常量。
采用这种"复制文件"而非"跨 Provider 导入"方式的原因:
- 预发布版本比较陷阱:Python 中
>=比较版本时,预发布版本(RC)总被认为低于正式版。使用AIRFLOW_V_X_Y_PLUS可以保证 RC 候选版与正式版一视同仁(因为 RC 已包含正式版中的新特性); - 避免无谓的 Provider 间依赖:不想为了一个兼容常量给 Provider 引入对另一个 Provider(如
common.compat)的依赖; - 维护成本低:即使代码重复,也只是整体复制一个
version_compat.py文件,可维护性可接受; - 防止误用:
prek hook中的check-imports-in-providers会检查并拒绝从其他 Provider 或测试代码导入version_compat模块,避免引入意外的跨 Provider 依赖。
真实实现可参考 providers/http/src/airflow/providers/http/version_compat.py:它基于airflow.__version__解析出版本三元组,并导出AIRFLOW_V_3_0_PLUS、AIRFLOW_V_3_1_PLUS常量,文件头注释明确说明"此文件被刻意手工复制到其他 Provider,以避免 Provider 之间产生不必要的依赖"。仓库 87 个 Provider 都带有各自的version_compat.py(如 providers/amazon/src/airflow/providers/amazon/version_compat.py、providers/apache/hive/src/airflow/providers/apache/hive/version_compat.py 等)。
10. 发布 Provider
10.1 首次发布:先以not-ready状态发布
新 Provider 首次发布时必须处于not-ready状态。这样它能被发布管理命令识别,但不会被加入 Airflow 预装 Provider 列表,从而保证 main 分支的 CI 构建不依赖一个尚未出现在 PyPI 上的包。
- 若希望将
not-readyProvider 纳入发布管理命令的候选列表,需追加--include-not-ready-providers参数; - Provider 一旦正式发布,应立即将其
state更新为ready。
10.2 为历史版本发布 Provider
当主分支已发布(或已 bump)新 MAJOR 版本时,仍可能需要为旧 MAJOR 发布补丁版本。做法是从providers-<PROVIDER>/vX-Y分支发布——例如providers-fab/v1-5分支可用于在2.0.0已发布或投票期间发布1.5.2。
该场景下发布流程与常规一致,唯一区别是:使用该特定分支发布并更新全部文档,相关变更与 cherry-pick 都需指向该分支。
10.3 升级最低 Airflow 版本
Airflow 会定期为所有待发布 Provider 提升最低支持的 Airflow 版本(bump min Airflow version),该操作依据 providers/PROVIDER_RELEASES.rst 中的 Provider 策略执行,仅适用于未暂停/未移除的 Provider。CI 会运行基础的 import 兼容性检查,bump 后需同步更新这些兼容性检查。
11. 暂停 Provider(Suspending)
自 2023 年 4 月起,Airflow 支持暂停单个 Provider,避免其过旧依赖阻塞 Airflow 及其他 Provider 的依赖升级。暂停属于临时性运营措施(而非生命周期阶段),适用于任何阶段(孵化/生产/成熟)的 Provider,触发标准与表决过程详见 providers/SUSPENDING_AND_REMOVING_PROVIDERS.rst:依赖维护者需被提前至少 1 周通知、其他方案已穷尽、且 devlist 上通过[LAZY CONSENSUS]或[VOTE]达成多数共识。
11.1 技术步骤
第一步:修改provider.yaml
将 Provider 的state改为suspended并提交。
第二步:运行 prek hooks
提交后prek会自动运行(若已安装);也可手动运行prek --last-commit只检查最近一次提交。由于一个 prek hook 的修改可能影响其他 hook,可能需要多次运行直到所有静态检查通过。若想跑全部静态检查,使用:
prek --all-files第三步:重建 CI 镜像(按需)
暂停 Provider 可能导致依赖变化,如果出现缺失依赖导入、类不可用等错误,需要先用以下命令本地重建 CI 镜像,再重新运行静态检查:
breeze build-image --python 3.9 --upgrade-to-newer-dependencies第四步:手动修正衍生文件
prek会提示你完成以下手工修改:
- 运行
breeze setup regenerate-command-images重新生成 breeze 帮助文件; - 更新
airflow-core/docs/extra-packages-ref.rst(文档中提到的extra-packages-ref.rst),必要时同步更新根pyproject.toml,将 Provider 从依赖列表中移除。
11.2 底层机制
暂停的最终效果是:pyproject.toml被更新为包含"可用 Provider 及其依赖"的信息,项目工具链据此将暂停的 Provider 从构建与 CI 的所有相关环节中排除——包括 CI 镜像依赖安装、文档构建、测试运行等。
11.3 暂停引发的连锁反应处理(交叉依赖 Provider)
上述步骤对独立 Provider 通常足够,但对被其他 Provider 依赖或属于默认 PROD Dockerfile 组成部分的 Provider,还需处理以下连锁反应:
(1)测试收集失败
暂停 Provider 的测试大多会被 pytest collection 自动排除;但依赖它的其他 Provider 的测试可能收集失败。解决方法:在失败测试模块顶部添加pytest.importorskip。
文档给出的真实失败示例(googleProvider 被暂停后,apache/beam的测试因ModuleNotFoundError: No module named 'google.cloud.dataflow_v1beta3'收集失败),修复方式:
pytest.importorskip("apache.airflow.providers.google")(2)Provider 校验阶段的导入失败
某些 Provider 会无条件导入被暂停的 Provider,导致 CI 的 provider 校验步骤失败(例如mysql的s3_to_mysqltransfer 无条件导入S3Hook而amazon已被暂停)。修复方式是将其改造成可选 Provider 特性:
try: from airflow.providers.amazon.aws.hooks.s3 import S3Hook except ImportError as e: from airflow.exceptions import AirflowOptionalProviderFeatureException raise AirflowOptionalProviderFeatureException(e)(3)其他潜在影响
- 若被暂停 Provider 属于默认 Dockerfile,可能需要更新 PROD 镜像测试 docker-tests/tests/docker_tests/test_prod_image.py;
- 少数 breeze 单元测试假定了一组固定的 Provider 集合,可能需相应调整(此类测试只使用最常见 Provider,实际发生概率较低)。
12. 恢复 Provider(Resuming)
恢复即回滚当初的暂停变更。如果回滚后的 Provider 存在需要修复的问题,CI 会自动检测出来,你需要在回滚暂停的同一个 PR 中一并修复。暂停解除的前提是依赖已与 Airflow 及其他 Provider 兼容,社区合并解除暂停的 PR 且 CI 全绿。
13. 移除 Provider(Removing)
13.1 技术步骤
移除流程要求发布经理:
- 在 Provider 的
provider.yaml中添加state: removed; - 将该 Provider 纳入下一波发布(这是它的最后一次发布,用于在文档与 PyPI 包描述中标记移除公告);
- 随后删除与该 Provider 相关的全部代码与文档。
state: removed使该 Provider 仅对以下命令可见(必须显式指定才会纳入,默认不会出现在可用列表或文档构建中):
breeze build-docs breeze release-management prepare-provider-documentation breeze release-management prepare-provider-distributions breeze release-management publish-docs执行上述命令时,发布经理需追加--include-removed-providers(当构建所有 Provider 时)或在发布过程中显式添加该 Provider 的 id。除需手工维护的 changelog 外,其余文档(Provider 文档主页、PyPI README)都会自动更新,加入移除公告。
13.2 移除的后果与后续
参照 providers/SUSPENDING_AND_REMOVING_PROVIDERS.rst,Provider 移除后:
- 代码(含测试与文档)从
main分支删除,不再参与 CI,依赖不再进入 CI 镜像与 constraints; - 从下一个 MINOR 版本的 Airflow extras 列表与 constraints 中移除;
- 已发布的包仍保留在 PyPI 与 ASF 归档中,文档索引中标注
(not maintained); - 通过
[ANNOUNCE]邮件通知 devlist 与用户列表; - 若出现必须修复的安全问题:有可行替代方案时建议用户卸载并迁移;确无替代方案时,可从 Git 历史中最后发布的版本出发发布安全修复版本;
- 被移除的 Provider 若想回归,需重新走一遍 providers/ACCEPTING_PROVIDERS.rst 描述的新 Provider 准入流程。
14. 关键路径速查
| 操作 | 核心动作 | 关键命令/标记 |
|---|---|---|
| 开发环境 | 启动 breeze | ./breeze |
| 单测 | 运行测试 | python -m pytest providers/<PROVIDER>/tests/... |
| 构建文档 | 本地验证 | breeze build-docs <provider id> |
| 首次发布 | 标记 not-ready | --include-not-ready-providers |
| 历史版本发布 | 使用分支 | providers-<PROVIDER>/vX-Y |
| 暂停 | 改 state | state: suspended+prek --all-files+ 重建 CI 镜像 |
| 恢复 | 回滚变更 | 回滚暂停 PR 并修复 CI |
| 移除 | 改 state + 最终发布 | state: removed+--include-removed-providers |
15. 总结
Provider 的生命周期管理是 Apache Airflow 生态可持续发展的技术基石:创建阶段依赖统一目录结构、三层测试体系、provider.yaml元数据与完整文档;发布阶段通过not-ready/ready状态与版本分支策略保证发布节奏可控;暂停/恢复阶段借助prek工具链与AirflowOptionalProviderFeatureException、pytest.importorskip等模式化解交叉依赖冲击;移除阶段则以state: removed完成最后一次带公告的发布。理解这套机制后,无论是贡献新集成、修复被暂停 Provider 的依赖问题,还是主导 Provider 的退役流程,都能按图索骥、有据可依。
【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考