Airflow REST API Plugin

Description

A plugin for Apache Airflow that exposes REST endpoints for the Command Line Interfaces listed in the airflow documentation:

http://airflow.apache.org/cli.html

The plugin also includes other custom REST APIs.

System Requirements

Dependencies

Deployment Instructions

  1. Create the plugins folder if it doesn't exist.

    • The location you should put it is usually at {AIRFLOW_HOME}/plugins. The specific location can be found in your airflow.cfg file:

      plugins_folder = /home/{USER_NAME}/airflow/plugins

  2. Download the release code you want to deploy

    • Releases Available:

      • v0.0.1
      • v0.0.2
      • v1.0.0
      • v1.0.1
      • v1.0.2
      • v1.0.3
      • v1.0.4
      • v1.0.5
      • v1.0.6
      • v1.0.7
      • v1.0.8
    • Branches Available:

      • master
      • v0.0.2-branch
      • v1.0.0-branch
      • v1.0.1-branch
      • v1.0.2-branch
      • v1.0.3-branch
      • v1.0.4-branch
      • v1.0.5-branch
      • v1.0.6-branch
      • v1.0.7-branch
      • v1.0.8-branch
    • URL to Download From:

      https://github.com/teamclairvoyant/airflow-rest-api-plugin/archive/{RELEASE_VERSION_OR_BRANCH_NAME}.zip

    • Note: Each release/branch has its own README.md file that describes the specific options and steps you should take to deploy and configure. Verify the options available in each release/branch after you download it.

  3. Unzip the file and move the contents of the plugins folder into your Airflow plugins directory

    unzip airflow-rest-api-plugin-{RELEASE_VERSION_OR_BRANCH_NAME}.zip
    
    cp -r airflow-rest-api-plugin-{RELEASE_VERSION_OR_BRANCH_NAME}/plugins/* {AIRFLOW_PLUGINS_FOLDER} 
  4. Update the base_url configuration in the airflow.cfg file to the public host or ip of the machine the Airflow instance is running on (Optional)

    • This is required for the API admin page to display the correct host
  5. (Optional) Append the following content to the end of the {AIRFLOW_HOME}/airflow.cfg file to give you control over execution:

    [rest_api_plugin]
    
    # Logs global variables used in the REST API plugin when the plugin is loaded. Set to False by default to avoid too many logging messages.
    # DEFAULT: False
    log_loading = False
    
    # Filters out loading messages from the standard out 
    # DEFAULT: True
    filter_loading_messages_in_cli_response = True
    
    # HTTP Header Name to be used for authenticating REST calls for the REST API Plugin
    # DEFAULT: 'rest_api_plugin_http_token'
    #rest_api_plugin_http_token_header_name = rest_api_plugin_http_token
    
    # HTTP Token  to be used for authenticating REST calls for the REST API Plugin
    # DEFAULT: None
    # Comment this out to disable Authentication
    #rest_api_plugin_expected_http_token = changeme
  6. (Optional) Setup Authentication for Security

    a. Note: Requires that step #5 above be completed.

    b. Follow the "Enabling Authentication" section below.

  7. We need to replace the CSRF_ENABLED attribute with WTF_CSRF_ENABLED. This change is required to support the POST method when RBAC is enabled with JWT. Please add the following property in the {AIRFLOW_HOME}/webserver_config.py file.

    # Flask-WTF flag for CSRF
    WTF_CSRF_ENABLED = False
  8. Restart the Airflow Web Server

Enabling Authentication

The REST API client supports a simple token based authentication mechanism where you can require users to pass in a specific http header to authenticate. By default this authentication mechanism is disabled but can be enabled with the "Setup" steps bellow.

Setup

  1. Edit your {AIRFLOW_HOME}/airflow.cfg file

    a. Under the [rest_api_plugin] section you added in step #5 of the "Deployment Instructions", uncomment the following configs:

    rest_api_plugin_http_token_header_name = rest_api_plugin_http_token
    
    rest_api_plugin_expected_http_token = changeme
  2. (Optional) Update the 'rest_api_plugin_http_token_header_name' to the desired value

  3. Change the value of 'rest_api_plugin_expected_http_token' to the desired token people should pass

  4. Restart the Airflow Web Server

Authenticating

Once the steps above have been followed to enable authentication, users will need to pass a specific header along with their request to properly call the REST API. The header name is: rest_api_plugin_http_token

Example CURL Command:

curl --header "rest_api_plugin_http_token: changeme" http://{HOST}:{PORT}/admin/rest_api/api?api=version

What happens when you fail to Authenticate?

In the event that you have authentication enabled and the user calling the REST Endpoint doesn't include the header, you will get the following response:

{
  "call_time": "{TIMESTAMP}",
  "http_response_code": 403,
  "output": "Token Authentication Failed",
  "response_time": "{TIMESTAMP}",
  "status": "ERROR"
}

RBAC Support

Plugin supports RBAC feature for Airflow versions 1.10.4 or higher.

Note: Once you enable the RBAC support, it will create new set of Database Tables. So, you need to manually migrate your existing users from users table to the new table ab_users. While migrating you need to specify the role for each user. Please check Create User for more details.

Enabling the plugin UI support under RBAC

Plugin works out of the box. If you need to access the plugin UI please follow the below steps.

Working with JWT Auth tokens

Plugin enables JWT Token based authentication for Airflow versions 1.10.4 or higher when RBAC support is enabled.

Generating the JWT access token

curl -XPOST http://{AIRFLOW_HOST}:{AIRFLOW_PORT}/api/v1/security/login -H "Content-Type: application/json" 
-d '{"username":"username", "password":"password", "refresh":true, "provider": "db"}' 

sample response which includes access_token and refresh_token.

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1Njc3NzMxODcsIm5iZiI6MTU2Nzc3MzE4NywianRpIjoiYzFiOWRkNTgtNGY5OC00MTI5LTk1OTctMDc4YWJkOGM4ZjdkIiwiZXhwIjoxNTY3NzczNDg3LCJpZGVudGl0eSI6NiwiZnJlc2giOnRydWUsInR5cGUiOiJhY2Nlc3MifQ.pD1rCXt2NmjRlHxuoiLcZJ1RNUuHS_hV2Dudsqw6wCY",
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1Njc3NzMxODcsIm5iZiI6MTU2Nzc3MzE4NywianRpIjoiNmZlZTQ1MmItYzBkYy00NTc4LWFmZWItNTc3OTAwODAzN2FiIiwiZXhwIjoxNTcwMzY1MTg3LCJpZGVudGl0eSI6NiwidHlwZSI6InJlZnJlc2gifQ.Gjcr08qrDM4wCmKIJS8muJN_5AkGyYZfOQKH_HUKPqE"
}

By default, JWT access token is valid for 15 mins and refresh token is valid for 30 days. You can renew the access token with the help of refresh token as shown below.

Renewing the Access Token

curl -XPOST "http://{AIRFLOW_HOST}:{AIRFLOW_PORT}/api/v1/security/refresh" -H 'Authorization: Bearer <refresh_token>'

sample response returns the renewed access token as shown below.

{
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1Njc3NzI4NzUsIm5iZiI6MTU2Nzc3Mjg3NSwianRpIjoiMjE3Y2FhYzItYTQ1NS00MWMxLWI5OGUtOTRhYWU0OTcyZTljIiwiZXhwIjoxNTY3NzczMTc1LCJpZGVudGl0eSI6NSwiZnJlc2giOmZhbHNlLCJ0eXBlIjoiYWNjZXNzIn0.NoHaqc9caqk2B_cfutGO3U3Ih95lF0m9hvTPs5B_sE0"
}

Working with the rest_api_plugin and JWT Auth tokens

Pass the additional Authorization:Bearer <access_token> header in the rest API request

curl -H 'Authorization:Bearer <access_token>' 'http://{AIRFLOW_HOST}:{AIRFLOW_PORT}/admin/rest_api/api?api=version'  

If you have rest_api_plugin_http_token_header authentication enabled then you need to pass both headers as shown below.

curl -H 'Authorization:Bearer <access_token>'  -H 'rest_api_plugin_http_token: changeme' http://{AIRFLOW_HOST}:{AIRFLOW_PORT}/admin/rest_api/api?api=version

If JWT Authorization header is missing in the request you will get the following response. (Status Code: 401)

{ "msg": "Missing Authorization Header" }

If JWT access token expires you will get the following response. (Status Code: 401)

{ "msg": "Token has expired" }

If JWT access token is invalid you will get the following response. (Status Code: 422)

{ "msg": "Invalid payload padding" }

Please refer Flask-JWT-Extended module documentation for more details

Using the REST API

Once you deploy the plugin and restart the web server, you can start to use the REST API. Bellow you will see the endpoints that are supported. In addition, you can also interact with the REST API from the Airflow Web Server. When you reload the page, you will see a link under the Admin tab called "REST API". Clicking on the link will navigate you to the following URL:

http://{AIRFLOW_HOST}:{AIRFLOW_PORT}/admin/rest_api/

This web page will show the Endpoints supported and provide a form for you to test submitting to them.

Endpoints

version

Gets the version of Airflow currently running. Supports both http GET and POST methods.

Available in Airflow Version: 1.0.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=version

Query Arguments:

None

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=version

rest_api_plugin_version

Displays the version of this REST API Plugin you're using. Supports both http GET and POST methods.

Available in Airflow Version: None - Custom API

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=rest_api_plugin_version

Query Arguments:

None

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=rest_api_plugin_version

render

Render a task instance's template(s). Supports both http GET and POST methods.

Available in Airflow Version: 1.7.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=render

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=render

http://{HOST}:{PORT}/admin/rest_api/api?api=render&dag_id=value&task_id=value&execution_date=2017-01-02T03:04:05&subdir=value

variables

CRUD operations on variables. Supports both http GET and POST methods.

Available in Airflow Version: 1.7.1 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=variables

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=variables

http://{HOST}:{PORT}/admin/rest_api/api?api=variables&cmd=set&key=value&value=value&get=value&json&default=value&import=value&export=value&delete=value

For setting a variable like myVar1=myValue1 use

http://{HOST}:{PORT}/admin/rest_api/api?api=variables&cmd=set&key=myVar1&value=myValue1

connections

List/Add/Delete connections. Supports both http GET and POST methods.

Available in Airflow Version: 1.8.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=connections

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=connections

pause

Pauses a DAG. Supports both http GET and POST methods.

Available in Airflow Version: 1.7.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=pause

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=pause&dag_id=test_id

unpause

Resume a paused DAG. Supports both http GET and POST methods.

Available in Airflow Version: 1.7.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=unpause

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=unpause&dag_id=test_id

task_failed_deps

Returns the unmet dependencies for a task instance from the perspective of the scheduler. In other words, why a task instance doesn't get scheduled and then queued by the scheduler, and then run by an executor). Supports both http GET and POST methods.

Available in Airflow Version: 1.8.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=task_failed_deps

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=task_failed_deps&dag_id=value&task_id=value&execution_date=2017-01-02T03:04:05

trigger_dag

Triggers a Dag to Run. Supports both http GET and POST methods.

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=trigger_dag

Available in Airflow Version: 1.6.0 or greater

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=trigger_dag&dag_id=test_id

http://{HOST}:{PORT}/admin/rest_api/api?api=trigger_dag&dag_id=test_id&run_id=run_id_2016_01_01&conf=%7B%22key%22%3A%22value%22%7D

test

Test a task instance. This will run a task without checking for dependencies or recording it's state in the database.

Available in Airflow Version: 0.1 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=test

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=test&dag_id=value&task_id=value&execution_date=2017-01-02T03:04:05

dag_state

Get the status of a dag run. Supports both http GET and POST methods.

Available in Airflow Version: 1.8.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=dag_state

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=dag_state&dag_id=test_id&execution_date=2017-01-02T03:04:05

run

Run a single task instance. Supports both http GET and POST methods.

Available in Airflow Version: 1.0.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=run

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=run&dag_id=value&task_id=value&execution_date=2017-01-02T03:04:05

list_tasks

List the tasks within a DAG. Supports both http GET and POST methods.

Available in Airflow Version: 0.1 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=list_tasks

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=list_tasks&dag_id=test_id

backfill

Run subsections of a DAG for a specified date range. Supports both http GET and POST methods.

Available in Airflow Version: 0.1 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=backfill

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=backfill&dag_id=test_id

list_dags

List all the DAGs. Supports both http GET and POST methods.

Available in Airflow Version: 0.1 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=list_dags

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=list_dags

kerberos

Start a kerberos ticket renewer. Supports both http GET and POST methods.

Available in Airflow Version: 1.6.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=kerberos

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=kerberos

worker

Start a Celery worker node. Supports both http GET and POST methods.

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=worker

Available in Airflow Version: 0.1 or greater

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=worker

flower

Start a Celery worker node. Supports both http GET and POST methods.

Available in Airflow Version: 1.0.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=flower

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=flower

scheduler

Start a scheduler instance. Supports both http GET and POST methods.

Available in Airflow Version: 1.0.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=scheduler

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=scheduler

task_state

Get the status of a task instance. Supports both http GET and POST methods.

Available in Airflow Version: 1.0.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=task_state

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=task_state&dag_id=value&task_id=value&execution_date=2017-01-02T03:04:05

pool

CRUD operations on pools. Supports both http GET and POST methods.

Available in Airflow Version: 1.8.0 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=pool

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=pool

http://{HOST}:{PORT}/admin/rest_api/api?api=pool&cmd=set&pool_name=value&slot_count=value&description=value&get=value&delete=value

For setting a myTestpool with a slot count of 10 and with myTestpoolDescription description.

http://{HOST}:{PORT}/admin/rest_api/api?api=pool&cmd=set&pool_name=myTestpool&slot_count=10&description=myTestpoolDescription

serve_logs

Serve logs generate by worker. Supports both http GET and POST methods.

Available in Airflow Version: 0.1 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=serve_logs

Query Arguments:

None

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=serve_logs

clear

Clear a set of task instance, as if they never ran. Supports both http GET and POST methods.

Available in Airflow Version: 0.1 or greater

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=clear

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=clear

deploy_dag

Deploy a new DAG. Supports both http GET and POST methods.

Available in Airflow Version: None - Custom API

POST - http://{HOST}:{PORT}/admin/rest_api/api?api=deploy_dag

POST Body Arguments:

Examples:

Header: multipart/form-data

URL: http://{HOST}:{PORT}/admin/rest_api/api?api=deploy_dag

Body: dag_file=path_to_file&force=on

CURL Example:

curl -X POST -H 'Content-Type: multipart/form-data' -F 'dag_file=@/path/to/dag.py' -F 'force=on' http://{HOST}:{PORT}/admin/rest_api/api?api=deploy_dag

refresh_dag

Refresh a DAG. Supports both http GET and POST methods.

Available in Airflow Version: None - Custom API

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=refresh_dag

Query Arguments:

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=refresh_dag&dag_id=test_id

refresh_all_dags

Refresh all DAGs. Supports both http GET and POST methods.

Available in Airflow Version: None - Custom API

GET - http://{HOST}:{PORT}/admin/rest_api/api?api=refresh_all_dags

Query Arguments:

None

Examples:

http://{HOST}:{PORT}/admin/rest_api/api?api=refresh_all_dags

API Response

The API's will all return a common response object. It is a JSON object with the following entries in it:

Sample (Result of calling the versions endpoint)

{
  "airflow_cmd": "airflow version",
  "arguments": {},
  "call_time": "Tue, 29 Nov 2016 14:22:26 GMT",
  "http_response_code": 200,
  "output": "1.7.0",
  "response_time": "Tue, 29 Nov 2016 14:27:59 GMT",
  "status": "OK"
}