ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Apache Airflow 插件开发实战:从零编写一个自定义 Plugin 视图

Apache Airflow 插件开发实战:从零编写一个自定义 Plugin 视图 Apache Airflow 插件开发实战从零编写一个自定义 Plugin 视图【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflow导读Apache Airflow 提供了强大的插件Plugin机制允许开发者在不修改核心代码的前提下为 Web UI 添加自定义视图、Blueprint、宏、监听器等能力。本文以当前仓库 airflow-core/docs/empty_plugin 中的官方示例插件empty plugin为骨架从零讲解如何编写、安装并在 Airflow UI 中注册一个属于自己的自定义视图包括 Flask-AppBuilder 视图的写法、Blueprint 与模板的组织方式、AirflowPlugin子类的属性约定以及插件目录的配置与加载机制。读完本文你将能够复制该示例到自己的 Airflow 环境中运行并以此为模板扩展出带业务功能的插件页面。示例插件概览一个最小可运行的 Airflow 插件官方文档 empty_plugin/README.md 给出了一个非常精简的示例插件其作用是在 Airflow Web UI 中显示一个空视图empty view。整个插件目录包含三个文件airflow-core/docs/empty_plugin/ ├── README.md # 安装说明 ├── empty_plugin.py # 插件主代码 └── templates/ └── empty_plugin/ └── index.html # 视图模板这是一个刻意保持最小的示例它不包含任何业务逻辑、后端数据或复杂交互而是专注于演示一个插件要能够被 Airflow 识别并挂载到 Web UI 上所必须拥有的全部要素。理解了它就理解了 Airflow 插件体系的最小闭环。插件代码逐行解析插件主文件 empty_plugin.py 中依次定义了三类关键对象它们共同构成了一个可被 Airflow 加载的插件。1. Flask-AppBuilder 视图EmptyPluginViewfrom flask_appbuilder import BaseView, expose class EmptyPluginView(BaseView): Creating a Flask-AppBuilder View default_view index expose(/) has_access_view(AccessView.PLUGINS) def index(self): Create default view return self.render_template(empty_plugin/index.html, nameEmpty Plugin)要点说明继承BaseViewAirflow 3 的 Web UI 基于 Flask-AppBuilderFAB构建自定义视图需要继承 FAB 的BaseView在 providers/fab/src/airflow/providers/fab/www/auth.py 等 FAB 集成代码中可以看到这一体系的实际应用。default_view index指定视图的默认入口方法名访问该视图的根路径时自动路由到index。expose(/)FAB 装饰器把index方法暴露为可访问的 HTTP 端点。has_access_view(AccessView.PLUGINS)权限控制装饰器来自airflow.providers.fab.www.auth将视图访问限定为PLUGINS权限域。这意味着用户需要具备访问 Plugins 视图的权限才能看到该页面这也是新版 Airflow 对插件视图进行细粒度权限管控的体现。render_template(empty_plugin/index.html, nameEmpty Plugin)渲染模板并传入上下文变量name。2. Flask Blueprint静态资源与模板的载体from flask import Blueprint bp Blueprint( Empty Plugin, __name__, template_foldertemplates, static_folderstatic, static_url_path/static/empty_plugin, )Blueprint 的作用是让插件拥有独立的模板目录与静态资源命名空间template_foldertemplates声明插件自身携带的模板目录Airflow 在渲染时会找到templates/empty_plugin/index.htmlstatic_folderstatic、static_url_path/static/empty_plugin为插件的静态文件如 CSS/JS预留挂载路径避免与其他插件资源冲突当前示例未放置静态文件但保留了完整的挂载声明。3. 插件入口类继承 AirflowPluginfrom airflow.plugins_manager import AirflowPlugin class EmptyPlugin(AirflowPlugin): Defining the plugin class name Empty Plugin flask_blueprints [bp] appbuilder_views [{name: Empty Plugin, category: Extra Views, view: EmptyPluginView()}]这是整个插件的注册入口核心约定如下插件类必须继承airflow.plugins_manager.AirflowPlugin见 airflow-core/src/airflow/plugins_manager.pyAirflow 通过扫描并实例化该基类的子类来完成插件发现name插件唯一名称会显示在 Web UI 中flask_blueprints把前面定义的 Blueprint 挂到插件上appbuilder_views以字典列表形式注册 FAB 视图其中category指定 UI 导航菜单中的分组这里为 Extra Viewsname为菜单项名称view为视图实例。通过该配置用户即可在 Airflow UI 左侧导航的 Extra Views 分组下看到 Empty Plugin 入口。视图模板与 Airflow 主题融合模板文件 templates/empty_plugin/index.html 展示了插件页面与 Airflow 主 UI 无缝集成的方式{% extends base_template %} {% block head %} {{ super() }} {% endblock %} {% block body %} div h3 stylefloat: left {% block page_header %}{{ name }}{% endblock%} /h3 div idobject classselect2-drop-mask stylemargin-top: 25px; width: 400px;float: right/div div styleclear: both/div /div {% block plugin_content %}{% endblock %} {% endblock %} {% block tail %} {{ super() }} {% endblock %}关键点{% extends base_template %}base_template是 Airflow 在执行插件视图时注入的全局变量指向 Airflow 自身的主页面模板。插件页面因此自动继承 Airflow 的布局、样式与导航外壳视觉上与原生页面完全一致{{ name }}即EmptyPluginView.index中通过render_template(..., nameEmpty Plugin)传入的上下文变量演示了控制器如何向模板传值{% block plugin_content %}{% endblock %}预留的扩展点后续开发者可以基于该模板派生更多页面内容。安装与配置让 Airflow 发现你的插件官方文档给出的安装方式非常直接将整个插件目录empty_plugin.py与templates/拷贝到 Airflow 的插件目录即可。插件目录的路径由配置文件[core]小节中的plugins_folder选项指定其默认值为{AIRFLOW_HOME}/plugins。在 airflow-core/src/airflow/settings.py 中可以看到该配置项的解析逻辑PLUGINS_FOLDER conf.get(core, plugins_folder, fallbackos.path.join(AIRFLOW_HOME, plugins))在配置文件模板 airflow-core/src/airflow/config_templates/config.yml 中该选项的正式说明为Path to the folder containing Airflow plugins即存放 Airflow 插件的文件夹路径。完整的安装步骤如下确定你的AIRFLOW_HOME默认~/airflow插件目录即{AIRFLOW_HOME}/plugins目录不存在则创建它将示例目录中的empty_plugin.py和templates/子目录整体复制到插件目录最终结构为{AIRFLOW_HOME}/plugins/ ├── empty_plugin.py └── templates/ └── empty_plugin/ └── index.html如需自定义插件目录位置可通过环境变量覆盖export AIRFLOW__CORE__PLUGINS_FOLDER/path/to/my/plugins重启 Airflow Webserver或调度器等进程使插件生效。插件加载时Airflow 会扫描plugins_folder下的所有 Python 模块收集其中AirflowPlugin的子类并注册其声明的 Blueprint 与 FAB 视图对应 airflow-core/src/airflow/plugins_manager.py 中ensure_plugins_loaded与_get_plugins的加载流程。重启完成后在 Airflow Web UI 左侧导航的Extra Views → Empty Plugin即可看到渲染出的自定义页面。源码佐证插件加载与视图挂载的底层机制从源码结构看插件机制的核心调度都集中在 airflow-core/src/airflow/plugins_manager.pyensure_plugins_loaded()/_get_plugins()负责从插件目录和 entry points 加载插件且仅加载一次结果带缓存get_flask_plugins()第 302 行附近将插件的flask_blueprints逐一声明为{name: plugin.name, blueprint: bp}把appbuilder_views汇总为flask_appbuilder_views列表供 FAB 注册到 Web UI见 plugins_manager.pyget_plugin_info()可以输出插件的元信息包括flask_blueprints、appbuilder_views等属性便于调试确认插件是否被正确识别。这意味着示例插件中声明的flask_blueprints [bp]与appbuilder_views [...]最终会被 Airflow 汇总并挂载到 Web 应用上——这就是拷贝目录即可生效背后的完整链路。另外在 airflow-core/src/airflow/cli/commands/info_command.py 中airflow info命令也会输出plugins_folder的值你可以用它快速确认当前环境实际使用的插件目录排查插件不生效类问题。从示例到生产扩展建议掌握了示例的最小闭环后可以按以下方向扩展出真实可用的插件页面增加后端逻辑在index方法中查询 Airflow 的模型如 DAG、TaskInstance把数据传入模板展示扩展模板在block plugin_content中填充业务内容或添加自己的 CSS/JS 到static/目录细分权限调整has_access_view的权限域参数控制不同角色的可见性更多插件能力Airflow 插件体系还支持宏macros、操作符链接operator extra links、监听器listeners、时间表timetables等扩展点同样只需在AirflowPlugin子类中声明对应属性即可被框架识别。总结本文基于 Apache Airflow 官方示例插件 empty_plugin完整梳理了一个最小插件的三大组成Flask-AppBuilder 视图页面与路由、Flask Blueprint模板与静态资源、AirflowPlugin子类注册入口并说明了plugins_folder配置默认{AIRFLOW_HOME}/plugins与插件加载机制。照此实践你可以快速验证 Airflow 插件开发全流程并以此为骨架搭建属于自己的 Airflow UI 扩展页面。【免费下载链接】airflowApache Airflow - A platform to programmatically author, schedule, and monitor workflows项目地址: https://gitcode.com/GitHub_Trending/ai/airflow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表