diff --git a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml index 333263f1b4172..4ddb35c29899b 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml +++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml @@ -7275,7 +7275,7 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}: + /api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}: patch: tags: - HumanInTheLoop @@ -7406,7 +7406,7 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}/{map_index}: + /api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}/{map_index}: patch: tags: - HumanInTheLoop @@ -7549,7 +7549,7 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/hitl-details/: + /api/v2/hitlDetails/: get: tags: - HumanInTheLoop diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py index dfa8d039ac15e..804162ba8086f 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py @@ -50,7 +50,7 @@ from airflow.models.hitl import HITLDetail as HITLDetailModel from airflow.models.taskinstance import TaskInstance as TI -hitl_router = AirflowRouter(tags=["HumanInTheLoop"], prefix="/hitl-details") +hitl_router = AirflowRouter(tags=["HumanInTheLoop"], prefix="/hitlDetails") log = structlog.get_logger(__name__) diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/__init__.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/__init__.py index ab163f0bac569..89d96083876db 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/__init__.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/__init__.py @@ -49,6 +49,6 @@ ) authenticated_router.include_router(variables.router, prefix="/variables", tags=["Variables"]) authenticated_router.include_router(xcoms.router, prefix="/xcoms", tags=["XComs"]) -authenticated_router.include_router(hitl.router, prefix="/hitl-details", tags=["Human in the Loop"]) +authenticated_router.include_router(hitl.router, prefix="/hitlDetails", tags=["Human in the Loop"]) execution_api_router.include_router(authenticated_router) diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts index 1251d2f83d0d0..89332283ad968 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts @@ -3397,7 +3397,7 @@ export class HumanInTheLoopService { public static updateHitlDetail(data: UpdateHitlDetailData): CancelablePromise { return __request(OpenAPI, { method: 'PATCH', - url: '/api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}', + url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}', path: { dag_id: data.dagId, dag_run_id: data.dagRunId, @@ -3428,7 +3428,7 @@ export class HumanInTheLoopService { public static getHitlDetail(data: GetHitlDetailData): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}', + url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}', path: { dag_id: data.dagId, dag_run_id: data.dagRunId, @@ -3458,7 +3458,7 @@ export class HumanInTheLoopService { public static updateMappedTiHitlDetail(data: UpdateMappedTiHitlDetailData): CancelablePromise { return __request(OpenAPI, { method: 'PATCH', - url: '/api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}/{map_index}', + url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}/{map_index}', path: { dag_id: data.dagId, dag_run_id: data.dagRunId, @@ -3491,7 +3491,7 @@ export class HumanInTheLoopService { public static getMappedTiHitlDetail(data: GetMappedTiHitlDetailData): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}/{map_index}', + url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}/{map_index}', path: { dag_id: data.dagId, dag_run_id: data.dagRunId, @@ -3527,7 +3527,7 @@ export class HumanInTheLoopService { public static getHitlDetails(data: GetHitlDetailsData = {}): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/api/v2/hitl-details/', + url: '/api/v2/hitlDetails/', query: { limit: data.limit, offset: data.offset, diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts index b777ca39767e1..f825bc5ab0934 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts @@ -5927,7 +5927,7 @@ export type $OpenApiTs = { }; }; }; - '/api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}': { + '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}': { patch: { req: UpdateHitlDetailData; res: { @@ -5983,7 +5983,7 @@ export type $OpenApiTs = { }; }; }; - '/api/v2/hitl-details/{dag_id}/{dag_run_id}/{task_id}/{map_index}': { + '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}/{map_index}': { patch: { req: UpdateMappedTiHitlDetailData; res: { @@ -6039,7 +6039,7 @@ export type $OpenApiTs = { }; }; }; - '/api/v2/hitl-details/': { + '/api/v2/hitlDetails/': { get: { req: GetHitlDetailsData; res: { diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py index 0c50be6223de2..51420f1e2423f 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py @@ -238,7 +238,7 @@ def test_should_respond_200_with_existing_response( sample_ti_url_identifier: str, ) -> None: response = test_client.patch( - f"/hitl-details/{sample_ti_url_identifier}", + f"/hitlDetails/{sample_ti_url_identifier}", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) @@ -256,7 +256,7 @@ def test_should_respond_404( sample_ti_url_identifier: str, expected_ti_not_found_error_msg: str, ) -> None: - response = test_client.get(f"/hitl-details/{sample_ti_url_identifier}") + response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}") assert response.status_code == 404 assert response.json() == {"detail": expected_ti_not_found_error_msg} @@ -269,7 +269,7 @@ def test_should_respond_409( sample_ti: TaskInstance, ) -> None: response = test_client.patch( - f"/hitl-details/{sample_ti_url_identifier}", + f"/hitlDetails/{sample_ti_url_identifier}", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) @@ -283,7 +283,7 @@ def test_should_respond_409( assert response.json() == expected_response response = test_client.patch( - f"/hitl-details/{sample_ti_url_identifier}", + f"/hitlDetails/{sample_ti_url_identifier}", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) assert response.status_code == 409 @@ -300,7 +300,7 @@ def test_should_respond_401( unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthenticated_test_client.get(f"/hitl-details/{sample_ti_url_identifier}") + response = unauthenticated_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}") assert response.status_code == 401 def test_should_respond_403( @@ -308,7 +308,7 @@ def test_should_respond_403( unauthorized_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthorized_test_client.get(f"/hitl-details/{sample_ti_url_identifier}") + response = unauthorized_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}") assert response.status_code == 403 @@ -321,7 +321,7 @@ def test_should_respond_200_with_existing_response( sample_ti_url_identifier: str, ) -> None: response = test_client.patch( - f"/hitl-details/{sample_ti_url_identifier}/-1", + f"/hitlDetails/{sample_ti_url_identifier}/-1", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) @@ -339,7 +339,7 @@ def test_should_respond_404( sample_ti_url_identifier: str, expected_mapped_ti_not_found_error_msg: str, ) -> None: - response = test_client.get(f"/hitl-details/{sample_ti_url_identifier}/-1") + response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}/-1") assert response.status_code == 404 assert response.json() == {"detail": expected_mapped_ti_not_found_error_msg} @@ -352,7 +352,7 @@ def test_should_respond_409( sample_ti: TaskInstance, ) -> None: response = test_client.patch( - f"/hitl-details/{sample_ti_url_identifier}/-1", + f"/hitlDetails/{sample_ti_url_identifier}/-1", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) @@ -366,7 +366,7 @@ def test_should_respond_409( assert response.json() == expected_response response = test_client.patch( - f"/hitl-details/{sample_ti_url_identifier}/-1", + f"/hitlDetails/{sample_ti_url_identifier}/-1", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) assert response.status_code == 409 @@ -383,7 +383,7 @@ def test_should_respond_401( unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthenticated_test_client.get(f"/hitl-details/{sample_ti_url_identifier}/-1") + response = unauthenticated_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}/-1") assert response.status_code == 401 def test_should_respond_403( @@ -391,7 +391,7 @@ def test_should_respond_403( unauthorized_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthorized_test_client.get(f"/hitl-details/{sample_ti_url_identifier}/-1") + response = unauthorized_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}/-1") assert response.status_code == 403 @@ -403,7 +403,7 @@ def test_should_respond_200_with_existing_response( sample_ti_url_identifier: str, expected_sample_hitl_detail_dict: dict[str, Any], ) -> None: - response = test_client.get(f"/hitl-details/{sample_ti_url_identifier}") + response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}") assert response.status_code == 200 assert response.json() == expected_sample_hitl_detail_dict @@ -413,7 +413,7 @@ def test_should_respond_404( sample_ti_url_identifier: str, expected_ti_not_found_error_msg: str, ) -> None: - response = test_client.get(f"/hitl-details/{sample_ti_url_identifier}") + response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}") assert response.status_code == 404 assert response.json() == {"detail": expected_ti_not_found_error_msg} @@ -422,7 +422,7 @@ def test_should_respond_401( unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthenticated_test_client.get(f"/hitl-details/{sample_ti_url_identifier}") + response = unauthenticated_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}") assert response.status_code == 401 def test_should_respond_403( @@ -430,7 +430,7 @@ def test_should_respond_403( unauthorized_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthorized_test_client.get(f"/hitl-details/{sample_ti_url_identifier}") + response = unauthorized_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}") assert response.status_code == 403 @@ -442,7 +442,7 @@ def test_should_respond_200_with_existing_response( sample_ti_url_identifier: str, expected_sample_hitl_detail_dict: dict[str, Any], ) -> None: - response = test_client.get(f"/hitl-details/{sample_ti_url_identifier}/-1") + response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}/-1") assert response.status_code == 200 assert response.json() == expected_sample_hitl_detail_dict @@ -452,7 +452,7 @@ def test_should_respond_404( sample_ti_url_identifier: str, expected_mapped_ti_not_found_error_msg: str, ) -> None: - response = test_client.get(f"/hitl-details/{sample_ti_url_identifier}/-1") + response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}/-1") assert response.status_code == 404 assert response.json() == {"detail": expected_mapped_ti_not_found_error_msg} @@ -461,7 +461,7 @@ def test_should_respond_401( unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthenticated_test_client.get(f"/hitl-details/{sample_ti_url_identifier}/-1") + response = unauthenticated_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}/-1") assert response.status_code == 401 def test_should_respond_403( @@ -469,7 +469,7 @@ def test_should_respond_403( unauthorized_test_client: TestClient, sample_ti_url_identifier: str, ) -> None: - response = unauthorized_test_client.get(f"/hitl-details/{sample_ti_url_identifier}/-1") + response = unauthorized_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}/-1") assert response.status_code == 403 @@ -480,7 +480,7 @@ def test_should_respond_200_with_existing_response( test_client: TestClient, expected_sample_hitl_detail_dict: dict[str, Any], ) -> None: - response = test_client.get("/hitl-details/") + response = test_client.get("/hitlDetails/") assert response.status_code == 200 assert response.json() == { "hitl_details": [expected_sample_hitl_detail_dict], @@ -523,13 +523,13 @@ def test_should_respond_200_with_existing_response_and_query( params: dict[str, Any], expected_ti_count: int, ) -> None: - response = test_client.get("/hitl-details/", params=params) + response = test_client.get("/hitlDetails/", params=params) assert response.status_code == 200 assert response.json()["total_entries"] == expected_ti_count assert len(response.json()["hitl_details"]) == expected_ti_count def test_should_respond_200_without_response(self, test_client: TestClient) -> None: - response = test_client.get("/hitl-details/") + response = test_client.get("/hitlDetails/") assert response.status_code == 200 assert response.json() == { "hitl_details": [], @@ -537,9 +537,9 @@ def test_should_respond_200_without_response(self, test_client: TestClient) -> N } def test_should_respond_401(self, unauthenticated_test_client: TestClient) -> None: - response = unauthenticated_test_client.get("/hitl-details/") + response = unauthenticated_test_client.get("/hitlDetails/") assert response.status_code == 401 def test_should_respond_403(self, unauthorized_test_client: TestClient) -> None: - response = unauthorized_test_client.get("/hitl-details/") + response = unauthorized_test_client.get("/hitlDetails/") assert response.status_code == 403 diff --git a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py index ec61542c48541..90c6d6350dbe4 100644 --- a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py +++ b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_hitl.py @@ -121,7 +121,7 @@ def test_upsert_hitl_detail( session.commit() response = client.post( - f"/execution/hitl-details/{ti.id}", + f"/execution/hitlDetails/{ti.id}", json={ "ti_id": ti.id, **default_hitl_detail_request_kwargs, @@ -138,7 +138,7 @@ def test_upsert_hitl_detail( @pytest.mark.usefixtures("sample_hitl_detail") def test_update_hitl_detail(client: Client, sample_ti: TaskInstance) -> None: response = client.patch( - f"/execution/hitl-details/{sample_ti.id}", + f"/execution/hitlDetails/{sample_ti.id}", json={ "ti_id": sample_ti.id, "chosen_options": ["Reject"], @@ -157,6 +157,6 @@ def test_update_hitl_detail(client: Client, sample_ti: TaskInstance) -> None: @pytest.mark.usefixtures("sample_hitl_detail") def test_get_hitl_detail(client: Client, sample_ti: TaskInstance) -> None: - response = client.get(f"/execution/hitl-details/{sample_ti.id}") + response = client.get(f"/execution/hitlDetails/{sample_ti.id}") assert response.status_code == 200 assert response.json() == expected_empty_hitl_detail_response_part diff --git a/task-sdk/src/airflow/sdk/api/client.py b/task-sdk/src/airflow/sdk/api/client.py index c720d93f3fd19..8f09e88dbc2ce 100644 --- a/task-sdk/src/airflow/sdk/api/client.py +++ b/task-sdk/src/airflow/sdk/api/client.py @@ -734,7 +734,7 @@ def add_response( params=params, ) resp = self.client.post( - f"/hitl-details/{ti_id}", + f"/hitlDetails/{ti_id}", content=payload.model_dump_json(), ) return HITLDetailRequestResult.model_validate_json(resp.read()) @@ -753,14 +753,14 @@ def update_response( params_input=params_input, ) resp = self.client.patch( - f"/hitl-details/{ti_id}", + f"/hitlDetails/{ti_id}", content=payload.model_dump_json(), ) return HITLDetailResponse.model_validate_json(resp.read()) def get_detail_response(self, ti_id: uuid.UUID) -> HITLDetailResponse: """Get content part of a Human-in-the-loop response for a specific Task Instance.""" - resp = self.client.get(f"/hitl-details/{ti_id}") + resp = self.client.get(f"/hitlDetails/{ti_id}") return HITLDetailResponse.model_validate_json(resp.read()) diff --git a/task-sdk/tests/task_sdk/api/test_client.py b/task-sdk/tests/task_sdk/api/test_client.py index b1a2ef63926aa..f3ad40674e196 100644 --- a/task-sdk/tests/task_sdk/api/test_client.py +++ b/task-sdk/tests/task_sdk/api/test_client.py @@ -1256,7 +1256,7 @@ def test_add_response(self) -> None: ti_id = uuid7() def handle_request(request: httpx.Request) -> httpx.Response: - if request.url.path in (f"/hitl-details/{ti_id}"): + if request.url.path in (f"/hitlDetails/{ti_id}"): return httpx.Response( status_code=201, json={ @@ -1295,7 +1295,7 @@ def test_update_response(self, time_machine: TimeMachineFixture) -> None: ti_id = uuid7() def handle_request(request: httpx.Request) -> httpx.Response: - if request.url.path in (f"/hitl-details/{ti_id}"): + if request.url.path in (f"/hitlDetails/{ti_id}"): return httpx.Response( status_code=200, json={ @@ -1326,7 +1326,7 @@ def test_get_detail_response(self, time_machine: TimeMachineFixture) -> None: ti_id = uuid7() def handle_request(request: httpx.Request) -> httpx.Response: - if request.url.path in (f"/hitl-details/{ti_id}"): + if request.url.path in (f"/hitlDetails/{ti_id}"): return httpx.Response( status_code=200, json={