From 178ec3c79166426791f51fe90b4d705c426c3013 Mon Sep 17 00:00:00 2001 From: Karthikeyan Singaravelan Date: Sun, 5 Jul 2026 21:13:06 +0530 Subject: [PATCH 1/2] Fix HTTP_422_UNPROCESSABLE_ENTITY deprecation warnings. --- airflow-core/src/airflow/api_fastapi/common/exceptions.py | 3 ++- .../api_fastapi/core_api/routes/public/connections.py | 5 +++-- .../tests/unit/api_fastapi/common/test_exceptions.py | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/common/exceptions.py b/airflow-core/src/airflow/api_fastapi/common/exceptions.py index 29d7c45394007..6a80d302c3bc6 100644 --- a/airflow-core/src/airflow/api_fastapi/common/exceptions.py +++ b/airflow-core/src/airflow/api_fastapi/common/exceptions.py @@ -26,6 +26,7 @@ from fastapi import HTTPException, Request, status from sqlalchemy.exc import DatabaseError, DataError, IntegrityError +from airflow.api_fastapi.compat import HTTP_422_UNPROCESSABLE_CONTENT from airflow.configuration import conf from airflow.exceptions import DeserializationError from airflow.utils.strings import get_random_string @@ -137,7 +138,7 @@ class DataErrorHandler(_DatabaseErrorHandler[DataError]): range, or the wrong type for its column), so it is a client error, not a 500. """ - status_code = status.HTTP_422_UNPROCESSABLE_ENTITY + status_code = HTTP_422_UNPROCESSABLE_CONTENT reason = "Value rejected by database" def __init__(self): diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py index 0d1229462085a..c1d89c8979866 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/connections.py @@ -36,6 +36,7 @@ SortParam, ) from airflow.api_fastapi.common.router import AirflowRouter +from airflow.api_fastapi.compat import HTTP_422_UNPROCESSABLE_CONTENT from airflow.api_fastapi.core_api.datamodels.common import ( BulkBody, BulkResponse, @@ -97,7 +98,7 @@ def _ensure_executor_is_configured(executor: str | None) -> None: executor in (name.alias, name.module_path, name.module_path.split(".")[-1]) for name in configured ): raise HTTPException( - status.HTTP_422_UNPROCESSABLE_ENTITY, + HTTP_422_UNPROCESSABLE_CONTENT, f"Executor '{executor}' is not configured. " f"Configured executors: {[name.alias or name.module_path for name in configured]}", ) @@ -371,7 +372,7 @@ def test_connection( [ status.HTTP_403_FORBIDDEN, status.HTTP_409_CONFLICT, - status.HTTP_422_UNPROCESSABLE_ENTITY, + HTTP_422_UNPROCESSABLE_CONTENT, ] ), dependencies=[Depends(action_logging())], diff --git a/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py b/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py index 82893a202b662..b9849d86509c4 100644 --- a/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py +++ b/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py @@ -27,6 +27,7 @@ from sqlalchemy.exc import DataError, IntegrityError from sqlalchemy.orm import Session +from airflow.api_fastapi.compat import HTTP_422_UNPROCESSABLE_CONTENT from airflow.api_fastapi.common.exceptions import ( ERROR_HANDLERS, DagErrorHandler, @@ -453,7 +454,7 @@ def test_data_error_hides_db_internals_without_stacktrace( exc = self._make_data_error(orig_msg) with pytest.raises(HTTPException) as exc_info: self.handler.exception_handler(Mock(), exc) - assert exc_info.value.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY + assert exc_info.value.status_code == HTTP_422_UNPROCESSABLE_CONTENT assert exc_info.value.detail == { "reason": "Value rejected by database", "statement": "hidden", @@ -472,7 +473,7 @@ def test_data_error_exposes_db_internals_with_stacktrace( exc = self._make_data_error(orig_msg) with pytest.raises(HTTPException) as exc_info: self.handler.exception_handler(Mock(), exc) - assert exc_info.value.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY + assert exc_info.value.status_code == HTTP_422_UNPROCESSABLE_CONTENT detail = exc_info.value.detail assert isinstance(detail, dict) assert detail["reason"] == "Value rejected by database" @@ -491,7 +492,7 @@ def trigger_data_error(): raise self._make_data_error("(1406, \"Data too long for column 'conf' at row 1\")") response = TestClient(app, raise_server_exceptions=False).post("/test") - assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY + assert response.status_code == HTTP_422_UNPROCESSABLE_CONTENT detail = response.json()["detail"] assert detail["reason"] == "Value rejected by database" assert detail["statement"] == "hidden" From 07484bbf9e061edfd77e4297a568d3ef982c28eb Mon Sep 17 00:00:00 2001 From: Karthikeyan Singaravelan Date: Sun, 5 Jul 2026 22:11:09 +0530 Subject: [PATCH 2/2] Fix static check. --- airflow-core/tests/unit/api_fastapi/common/test_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py b/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py index b9849d86509c4..118f0b1a5d794 100644 --- a/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py +++ b/airflow-core/tests/unit/api_fastapi/common/test_exceptions.py @@ -27,7 +27,6 @@ from sqlalchemy.exc import DataError, IntegrityError from sqlalchemy.orm import Session -from airflow.api_fastapi.compat import HTTP_422_UNPROCESSABLE_CONTENT from airflow.api_fastapi.common.exceptions import ( ERROR_HANDLERS, DagErrorHandler, @@ -35,6 +34,7 @@ _DatabaseDialect, _UniqueConstraintErrorHandler, ) +from airflow.api_fastapi.compat import HTTP_422_UNPROCESSABLE_CONTENT from airflow.configuration import conf from airflow.exceptions import DeserializationError from airflow.models import DagRun, Pool, Variable