Customize view of Apache from Airflow web UI

Airflow has feature that allows to integrate a custom UI along with its core UI using the Plugin manager

This is an example plugin for Airflow that displays absolutely nothing.

In this plugin, two object reference are derived from the base class airflow.plugins_manager.AirflowPlugin. They are flask_blueprints and appbuilder_views

Using flask_blueprints in Airflow plugin, the core application can be extended to support the application that is customized to view Empty Plugin. In this object reference, the list of Blueprint object with the static template for rendering the information.

Using appbuilder_views in Airflow plugin, a class that represents a concept is added and presented with views and methods to implement it. In this object reference, the list of dictionaries with FlaskAppBuilder BaseView object and metadata information like name and category is passed on.

Custom view Registration

A custom view with object reference to flask_appbuilder and Blueprint from flask and be registered as a part of a plugin.

The following is a skeleton for us to implement a new custom view:

docs/apache-airflow/empty_plugin/empty_plugin.py[source]

  1. #
  2. # Licensed to the Apache Software Foundation (ASF) under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. The ASF licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing,
  13. # software distributed under the License is distributed on an
  14. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. # KIND, either express or implied. See the License for the
  16. # specific language governing permissions and limitations
  17. # under the License.
  18. """Plugins example"""
  19. from __future__ import annotations
  20. from flask import Blueprint
  21. from flask_appbuilder import BaseView, expose
  22. from airflow.plugins_manager import AirflowPlugin
  23. from airflow.security import permissions
  24. from airflow.www.auth import has_access
  25. class EmptyPluginView(BaseView):
  26. """Creating a Flask-AppBuilder View"""
  27. default_view = "index"
  28. @expose("/")
  29. @has_access(
  30. [
  31. (permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE),
  32. ]
  33. )
  34. def index(self):
  35. """Create default view"""
  36. return self.render_template("empty_plugin/index.html", name="Empty Plugin")
  37. # Creating a flask blueprint
  38. bp = Blueprint(
  39. "Empty Plugin",
  40. __name__,
  41. template_folder="templates",
  42. static_folder="static",
  43. static_url_path="/static/empty_plugin",
  44. )
  45. class EmptyPlugin(AirflowPlugin):
  46. """Defining the plugin class"""
  47. name = "Empty Plugin"
  48. flask_blueprints = [bp]
  49. appbuilder_views = [{"name": "Empty Plugin", "category": "Extra Views", "view": EmptyPluginView()}]

Plugins specified in the category key of appbuilder_views dictionary is the name of the tab in the navigation bar of the Airflow UI. Empty Plugin is the name of the link under the tab Plugins, which will launch the plugin

We have to add Blueprint for generating the part of the application that needs to be rendered in Airflow web UI. We can define templates, static files and this blueprint will be registered as part of the Airflow application when the plugin gets loaded.

The $AIRFLOW_HOME/plugins folder with custom view UI have the following folder structure.

  1. plugins
  2. ├── empty_plugin.py
  3. ├── templates
  4. | └── empty_plugin
  5. | ├── index.html
  6. └── README.md

The HTML files required to render the views built is added as part of the Airflow plugin into $AIRFLOW_HOME/plugins/templates folder and defined in the blueprint.