contributing-docs/27_cli_implementation_guide.rst
.. Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
.. http://www.apache.org/licenses/LICENSE-2.0
.. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
This document describes the direction for implementing new CLI functionality in Apache Airflow.
.. contents:: Table of Contents :depth: 2 :local:
Airflow ships two CLIs:
airflow-core) — bundled with the core distribution. Hosts both legacy
remote commands (being rewired internally) and admin/local commands that have no Public
API equivalent.airflow-ctl) — a standalone CLI distributed separately that talks to a
running Airflow instance exclusively through the Public (Core) API.Following AIP-94 (tracked via GitHub Projects #570 and #571 <https://github.com/orgs/apache/projects/570>_), CLI work follows two rules:
airflowctl
only. Adding the same command to the airflow CLI as well is discouraged — it
duplicates maintenance surface without user benefit.airflow CLI remote commands stay in place (so users keep running
airflow dags list, airflow pools get, …) but are rewired internally to call the
Public API via the airflowctl HTTP client instead of accessing the metadata
database directly.Both rules enforce RBAC, remove direct database exposure for remote operations, and eliminate duplicate code paths. This builds on AIP-81, which introduced the distinction between local and remote commands.
.. list-table:: :header-rows: 1 :widths: 35 35 30
airflowctl onlyairflow CLI unless strongly needed in coreairflow CLI (admin/local)airflow CLI command, achievable via Public APIairflow CLI → delegates to the airflowctl HTTP clientsession usageairflow CLI command, not achievable via Public APIairflow CLI, unchangedairflow-core implementation"Not achievable via the Public API" means the operation has no API representation and is inherently admin/local in nature — database shell, schema migrations, process management, or deployment configuration that requires direct infrastructure access.
Add the command to airflowctl only. Do not also add it to the airflow CLI unless
there is a strong reason it must live in core (e.g., it is tightly coupled to a local process
or a deployment concern with no API representation).
Source location: airflow-ctl/src/airflowctl/ctl/commands/
HTTP client and operations: airflow-ctl/src/airflowctl/api/ (client.py, operations.py).
Add the command under the appropriate group module in
airflow-ctl/src/airflowctl/ctl/commands/.
Call the Public API through the airflowctl HTTP client (airflowctl.api.client) and
the operations layer in airflowctl.api.operations. Do not import airflow-core
models or touch the metadata database.
If the required API endpoint does not exist yet, add it first
(see Adding API Endpoints <16_adding_api_endpoints.rst>__).
Add tests under airflow-ctl/tests/.
Run integration tests with:
.. code-block:: bash
breeze testing airflow-ctl-integration-test
airflow CLI CommandUse this when an existing airflow CLI remote command still talks to the database
directly and needs to go through the Public API instead. The user-facing command name and
arguments stay the same.
Source location: airflow-core/src/airflow/cli/
airflowctl HTTP client
(airflowctl.api.client / airflowctl.api.operations). Remove SQLAlchemy model
imports and session-based helpers from the command.Adding API Endpoints <16_adding_api_endpoints.rst>__).airflow-core/tests/cli/ to mock or exercise the HTTP client
instead of the database.Use this only when the operation cannot reasonably be exposed through the Public API — typically database shell, schema migrations, process management, or deployment-time configuration.
Source location: airflow-core/src/airflow/cli/
db, config).(admin only) to the help string so users know the command requires direct
infrastructure access.airflow-core/tests/cli/.AIP-94 Confluence page <https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=382175838>_Adding API Endpoints <16_adding_api_endpoints.rst>__Airflow Ctl Tests <testing/airflow_ctl_tests.rst>__GitHub Project #570 <https://github.com/orgs/apache/projects/570>_GitHub Project #571 <https://github.com/orgs/apache/projects/571>_