This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new c5da9502deb Create Airflow CLI implementation guide (#66566)
c5da9502deb is described below

commit c5da9502deb7184f81c639a65f6fd33aa84f59d7
Author: Bugra Ozturk <[email protected]>
AuthorDate: Sat May 9 22:26:14 2026 +0200

    Create Airflow CLI implementation guide (#66566)
    
    * Create Airflow CLI implementation guide for 3.3.0 and later
    
    * Remove airflowctl tests from contributors docs as it is coupled with ctl 
not core
    
    * Clarify document
    
    * Update version and simplify
---
 contributing-docs/27_cli_implementation_guide.rst | 144 ++++++++++++++++++++++
 contributing-docs/README.rst                      |   4 +
 2 files changed, 148 insertions(+)

diff --git a/contributing-docs/27_cli_implementation_guide.rst 
b/contributing-docs/27_cli_implementation_guide.rst
new file mode 100644
index 00000000000..50b96ec59b2
--- /dev/null
+++ b/contributing-docs/27_cli_implementation_guide.rst
@@ -0,0 +1,144 @@
+ .. 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.
+
+CLI Implementation Guide
+==================================
+
+This document describes the direction for implementing new CLI functionality 
in Apache Airflow.
+
+.. contents:: Table of Contents
+   :depth: 2
+   :local:
+
+
+Overview
+--------
+
+Airflow ships two CLIs:
+
+- **airflow** (``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.
+- **airflowctl** (``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:
+
+1. **New commands** that are achievable via the Public API are added to 
``airflowctl``
+   **only**. Adding the same command to the ``airflow`` CLI as well is 
discouraged — it
+   duplicates maintenance surface without user benefit.
+2. **Existing** ``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.
+
+Decision Table
+---------------
+
+.. list-table::
+   :header-rows: 1
+   :widths: 35 35 30
+
+   * - Scenario
+     - Where it goes
+     - Notes
+   * - New command, achievable via Public API
+     - ``airflowctl`` only
+     - Do not add to the ``airflow`` CLI unless strongly needed in core
+   * - New command, not achievable via Public API
+     - ``airflow`` CLI (admin/local)
+     - Admin/local commands only — see below
+   * - Existing ``airflow`` CLI command, achievable via Public API
+     - ``airflow`` CLI → delegates to the ``airflowctl`` HTTP client
+     - Rewire; no direct DB access, no SQLAlchemy/``session`` usage
+   * - Existing ``airflow`` CLI command, not achievable via Public API
+     - ``airflow`` CLI, unchanged
+     - Stays as a pure ``airflow-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.
+
+Adding a New Command (Public API achievable)
+---------------------------------------------
+
+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``).
+
+1. Add the command under the appropriate group module in
+   ``airflow-ctl/src/airflowctl/ctl/commands/``.
+2. 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.
+3. If the required API endpoint does not exist yet, add it first
+   (see `Adding API Endpoints <16_adding_api_endpoints.rst>`__).
+4. Add tests under ``airflow-ctl/tests/``.
+5. Run integration tests with:
+
+   .. code-block:: bash
+
+      breeze testing airflow-ctl-integration-test
+
+Rewiring an Existing ``airflow`` CLI Command
+---------------------------------------------
+
+Use 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/``
+
+1. Replace direct database access with calls through the ``airflowctl`` HTTP 
client
+   (``airflowctl.api.client`` / ``airflowctl.api.operations``). Remove 
SQLAlchemy model
+   imports and ``session``\-based helpers from the command.
+2. If the required API endpoint does not exist yet, add it first
+   (see `Adding API Endpoints <16_adding_api_endpoints.rst>`__).
+3. Update tests under ``airflow-core/tests/cli/`` to mock or exercise the HTTP 
client
+   instead of the database.
+
+Adding an Admin/Local Command (no Public API equivalent)
+---------------------------------------------------------
+
+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/``
+
+1. Add the command to an appropriate admin group (e.g., ``db``, ``config``).
+2. Add ``(admin only)`` to the ``help`` string so users know the command 
requires direct
+   infrastructure access.
+3. Add tests under ``airflow-core/tests/cli/``.
+
+References
+-----------
+
+- `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>`_
diff --git a/contributing-docs/README.rst b/contributing-docs/README.rst
index 6313acf1a96..505f0064429 100644
--- a/contributing-docs/README.rst
+++ b/contributing-docs/README.rst
@@ -136,3 +136,7 @@ Maintainer Tools
   ``pr-triage`` and ``pr-stats`` skills that maintainers invoke from Claude 
Code to sweep the
   open Pull Request queue (run deterministic quality checks, propose actions 
under explicit
   per-batch confirmation) and to surface backlog statistics by ``area:*`` 
label.
+
+* `CLI Implementation Guide <27_cli_implementation_guide.rst>`__ describes 
where to implement new
+  CLI features following AIP-94: remote commands go to ``airflowctl``, 
admin/deployment commands
+  stay in the ``airflow`` CLI.

Reply via email to