Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Airflow Web UI and adding Static HTML pages and CSS

I have been trying to extend the UI of airflow by adding airflow plugins. My goal is to be able to show internal project documentation from airflow. I am using MKDocs for this.

I have followed the airflow documentation process(https://airflow.apache.org/plugins.html#example) and created a plugin successfully. The link is appearing and when I click on it, it takes me to index.html. My problem is it is not rendering any CSS, images and other .md or .html files. They are all in the same folder.

I found a similar thread on StackOverflow (Airlfow serving static html directory). I have tried to follow the solution posted there, but it is not helping.

I have also posted the query on the airflow help forum but I have not received any solution yet. I would appreciate any leads. Thank you.

#Creating a flask appbuilder BaseView
class TestAppBuilderBaseView(AppBuilderBaseView):
    template_folder = '/home/airflow/airflow/plugins/test-project/site'

    @expose("/")
    def list(self):
        return self.render_template("index.html", content="")

v_appbuilder_view = TestAppBuilderBaseView()

v_appbuilder_package = {"name": "Test View",
                        "category": "Test Plugin",
                        "view": v_appbuilder_view}

Plugin Class:

# Defining the plugin class
class AirflowTestPlugin(AirflowPlugin):
    name = "test_plugin"
    appbuilder_views = [v_appbuilder_package]
like image 723
Natasha Avatar asked Aug 22 '19 12:08

Natasha


1 Answers

Faced a similar issue: I had to show images in doc_md of a DAG. Long story short we need to configure a Blueprint properly to host static files and templates.

Following works for me for airflow=1.10.14.

test_plugin.py

from airflow.plugins_manager import AirflowPlugin
from flask import Blueprint
from flask_admin import base, BaseView, expose


# Creating a flask admin BaseView
class TestView(BaseView):

    @expose('/')
    def list(self):
        return self.render("index.html", content="")


v = TestView(category="Test Plugin", name="Test View")


# Creating a flask blueprint to integrate the templates and static folder
bp = Blueprint(
    "test_blueprint", __name__,
    template_folder='templates/testview',
    static_folder='static/testview',
    static_url_path='/admin/testview/static')


class AirflowTestPlugin(AirflowPlugin):
    name = "test_plugin"

    admin_views = [v]
    flask_blueprints = [bp]

index.html

<!DOCTYPE html>
<HTML>
    <body>
        <p>This is a paragraph.</p>
        <img alt="initial-state" src="static/img/initial-state.png">
    </body>
</html>

Directory Structure

airflow 
    - plugins
        - test_plugin.py
        - templates
            - testview
                - index.html
        - static
            - testview
                - img
                    - initial-state.png

like image 155
damjad Avatar answered Nov 15 '22 10:11

damjad