Pushkal-Gupta opened a new pull request, #71647:
URL: https://github.com/apache/airflow/pull/71647

   Follow-up to #67570, #67571, #70992 and #71011, which each found and patched 
instances of
   the same drift by hand: a route handler raises an HTTP status that
   `create_openapi_http_exception_doc(...)` never declares, so the generated 
spec — and every
   client built from it — has no model for a response the API really returns.
   
   The helper's own docstring names the problem:
   
   > There is no easy way to introspect the code and automatically see what 
HTTPException are
   > actually raised by the endpoint implementation. This piece of 
documentation needs to be
   > kept in sync with the endpoint code manually.
   
   This adds the check that makes it automatic, so the next divergence fails in 
CI instead of
   shipping. Running it over `api_fastapi/**/routes/` found 15 statuses still 
undeclared after
   the four manual passes:
   
   | Endpoint | Undeclared | Reached when |
   | --- | --- | --- |
   | `POST /connections/test` | `400` | the host/port to test differs from the 
stored connection and no password is supplied |
   | `GET 
/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/logs/{try_number}` 
| `400` | the configured task log handler does not support reading |
   | `POST /variables` | `404` | the variable is not readable back after being 
written |
   | `GET /ui/next_run_assets/{dag_id}` | `404` | the Dag does not exist |
   | `GET /ui/partitioned_dag_runs` | `404` | filtered by a `dag_id` that does 
not exist |
   | `GET /ui/pending_partitioned_dag_run/{dag_id}` | `404` | no pending 
partitioned run for that Dag/partition key |
   | `GET /ui/teams` | `403` | multi-team mode is not configured |
   | `GET /execution/asset-events/by-asset` | `400` | neither `name` nor `uri` 
is supplied |
   | `GET /execution/store/asset/by-name/value` | `404` | the asset is unknown, 
or has no value for the key |
   | `GET /execution/store/asset/by-uri/value` | `404` | the asset is unknown, 
or has no value for the key |
   | `PATCH /execution/hitlDetails/{task_instance_id}` | `409` | a response has 
already been received |
   | `PATCH /execution/task-instances/{task_instance_id}/run` | `500` | the 
serialized TaskFlow arg spec for a stub task fails validation |
   | `GET /execution/store/ti/{task_instance_id}/{key}` | `404` | the task 
instance is unknown, or has no value for the key |
   | `HEAD /execution/xcoms/{dag_id}/{run_id}/{task_id}/{key}` | `400` | 
`map_index` is passed to a HEAD request |
   | `POST /execution/xcoms/{dag_id}/{run_id}/{task_id}/{key}` | `400` | the 
key is empty, the value is too large to map, or is unserializable |
   
   The regenerated spec and UI client show the effect: seven public/UI 
endpoints gain error
   models their clients previously had no type for.
   
   ### About the check
   
   It is deliberately conservative — it is meant to be trustworthy enough to 
gate CI, so it
   under-reports rather than over-reports, and stays silent whenever it cannot 
see the whole
   picture:
   
   - Only `HTTPException(...)` raised in the handler's own body counts. 
Statuses raised by a
     shared dependency or a service helper are not required to be declared.
   - `422` is never required (FastAPI documents validation errors itself), and 
neither are
     `401`/`403` — routers contribute those wholesale via their auth 
dependencies, and the
     router that does so is often built in another module 
(`routes/public/__init__.py`
     declares both for every public route).
   - A route inherits whatever its own router declares, so the `responses=` on
     `APIRouter(...)` (as in `execution_api/routes/xcoms.py`) counts as 
declared.
   - Statuses that are not resolvable constants, and `responses=` blocks that 
are not a
     literal `create_openapi_http_exception_doc([...])` call or mapping, are 
skipped rather
     than guessed at.
   
   The `GET /ui/teams` `403` above sits outside what the check enforces, for 
the `401`/`403`
   reason just described; it is included because it is a real gap in 
`_private_ui.yaml` that
   the same audit turned up.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Opus 5)
   
   Generated-by: Claude Code (Opus 5) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to