This is an automated email from the ASF dual-hosted git repository. kaxilnaik pushed a commit to branch v3-1-test in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 1175d5108c0f0b3a5fb0640e9cc891619c5c0c04 Author: Wei Lee <[email protected]> AuthorDate: Tue Sep 16 05:32:30 2025 +0800 refactor(hitl): make hitl under task instance (#55603) (cherry picked from commit a9eecaf47305dc2ce87e83bc246039644a53b3e3) --- .../src/airflow/api_fastapi/common/parameters.py | 33 +-- .../core_api/openapi/v2-rest-api-generated.yaml | 46 ++-- .../api_fastapi/core_api/routes/public/__init__.py | 4 +- .../api_fastapi/core_api/routes/public/hitl.py | 30 +-- .../src/airflow/ui/openapi-gen/queries/common.ts | 60 ++--- .../ui/openapi-gen/queries/ensureQueryData.ts | 110 ++++----- .../src/airflow/ui/openapi-gen/queries/prefetch.ts | 110 ++++----- .../src/airflow/ui/openapi-gen/queries/queries.ts | 160 ++++++------- .../src/airflow/ui/openapi-gen/queries/suspense.ts | 110 ++++----- .../ui/openapi-gen/requests/services.gen.ts | 237 +++++++++---------- .../airflow/ui/openapi-gen/requests/types.gen.ts | 258 ++++++++++----------- .../core_api/routes/public/test_hitl.py | 119 +++++----- 12 files changed, 622 insertions(+), 655 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/common/parameters.py b/airflow-core/src/airflow/api_fastapi/common/parameters.py index c6ff8aa6f46..896c00d487d 100644 --- a/airflow-core/src/airflow/api_fastapi/common/parameters.py +++ b/airflow-core/src/airflow/api_fastapi/common/parameters.py @@ -987,14 +987,14 @@ QueryHITLDetailTaskIdPatternSearch = Annotated[ ) ), ] -QueryHITLDetailDagRunIdFilter = Annotated[ - FilterParam[str], +QueryHITLDetailTaskIdFilter = Annotated[ + FilterParam[str | None], Depends( filter_param_factory( - TaskInstance.run_id, - str, - filter_name="dag_run_id", - ), + TaskInstance.task_id, + str | None, + filter_name="task_id", + ) ), ] QueryHITLDetailSubjectSearch = Annotated[ @@ -1025,7 +1025,6 @@ QueryHITLDetailResponseReceivedFilter = Annotated[ ) ), ] - QueryHITLDetailRespondedUserIdFilter = Annotated[ FilterParam[list[str]], Depends( @@ -1050,23 +1049,3 @@ QueryHITLDetailRespondedUserNameFilter = Annotated[ ) ), ] -QueryHITLDetailDagIdFilter = Annotated[ - FilterParam[str | None], - Depends( - filter_param_factory( - TaskInstance.dag_id, - str | None, - filter_name="dag_id", - ) - ), -] -QueryHITLDetailTaskIdFilter = Annotated[ - FilterParam[str | None], - Depends( - filter_param_factory( - TaskInstance.task_id, - str | None, - filter_name="task_id", - ) - ), -] 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 7c8bba4e9aa..e853fcbd386 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 @@ -7956,10 +7956,10 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}: + /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails: patch: tags: - - HumanInTheLoop + - Task Instance summary: Update Hitl Detail description: Update a Human-in-the-loop detail. operationId: update_hitl_detail @@ -7986,11 +7986,10 @@ paths: type: string title: Task Id - name: map_index - in: query - required: false + in: path + required: true schema: type: integer - default: -1 title: Map Index requestBody: required: true @@ -8037,7 +8036,7 @@ paths: $ref: '#/components/schemas/HTTPValidationError' get: tags: - - HumanInTheLoop + - Task Instance summary: Get Hitl Detail description: Get a Human-in-the-loop detail of a specific task instance. operationId: get_hitl_detail @@ -8064,11 +8063,10 @@ paths: type: string title: Task Id - name: map_index - in: query - required: false + in: path + required: true schema: type: integer - default: -1 title: Map Index responses: '200': @@ -8101,10 +8099,10 @@ paths: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' - /api/v2/hitlDetails/: + /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/hitlDetails: get: tags: - - HumanInTheLoop + - Task Instance summary: Get Hitl Details description: Get Human-in-the-loop details. operationId: get_hitl_details @@ -8112,6 +8110,18 @@ paths: - OAuth2PasswordBearer: [] - HTTPBearer: [] parameters: + - name: dag_id + in: path + required: true + schema: + type: string + title: Dag Id + - name: dag_run_id + in: path + required: true + schema: + type: string + title: Dag Run Id - name: limit in: query required: false @@ -8138,14 +8148,6 @@ paths: default: - ti_id title: Order By - - name: dag_id - in: query - required: false - schema: - anyOf: - - type: string - - type: 'null' - title: Dag Id - name: dag_id_pattern in: query required: false @@ -8158,12 +8160,6 @@ paths: title: Dag Id Pattern description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. `%customer_%`).\ \ Regular expressions are **not** supported." - - name: dag_run_id - in: query - required: false - schema: - type: string - title: Dag Run Id - name: task_id in: query required: false diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py index 6db86ce2327..65cdbef6642 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/__init__.py @@ -37,7 +37,7 @@ from airflow.api_fastapi.core_api.routes.public.dag_warning import dag_warning_r from airflow.api_fastapi.core_api.routes.public.dags import dags_router from airflow.api_fastapi.core_api.routes.public.event_logs import event_logs_router from airflow.api_fastapi.core_api.routes.public.extra_links import extra_links_router -from airflow.api_fastapi.core_api.routes.public.hitl import hitl_router +from airflow.api_fastapi.core_api.routes.public.hitl import task_instances_hitl_router from airflow.api_fastapi.core_api.routes.public.import_error import import_error_router from airflow.api_fastapi.core_api.routes.public.job import job_router from airflow.api_fastapi.core_api.routes.public.log import task_instances_log_router @@ -84,7 +84,7 @@ authenticated_router.include_router(task_instances_log_router) authenticated_router.include_router(dag_parsing_router) authenticated_router.include_router(dag_tags_router) authenticated_router.include_router(dag_versions_router) -authenticated_router.include_router(hitl_router) +authenticated_router.include_router(task_instances_hitl_router) # Include authenticated router in public router 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 c444a759ef3..60d9f99fab9 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 @@ -28,9 +28,7 @@ from airflow.api_fastapi.auth.managers.models.resource_details import DagAccessE from airflow.api_fastapi.common.db.common import SessionDep, paginated_select from airflow.api_fastapi.common.parameters import ( QueryHITLDetailBodySearch, - QueryHITLDetailDagIdFilter, QueryHITLDetailDagIdPatternSearch, - QueryHITLDetailDagRunIdFilter, QueryHITLDetailRespondedUserIdFilter, QueryHITLDetailRespondedUserNameFilter, QueryHITLDetailResponseReceivedFilter, @@ -56,7 +54,11 @@ from airflow.models.dagrun import DagRun from airflow.models.hitl import HITLDetail as HITLDetailModel, HITLUser from airflow.models.taskinstance import TaskInstance as TI -hitl_router = AirflowRouter(tags=["HumanInTheLoop"], prefix="/hitlDetails") +task_instances_hitl_router = AirflowRouter( + tags=["Task Instance"], + prefix="/dags/{dag_id}/dagRuns/{dag_run_id}", +) +task_instance_hitl_path = "/taskInstances/{task_id}/{map_index}/hitlDetails" log = structlog.get_logger(__name__) @@ -100,8 +102,8 @@ def _get_task_instance_with_hitl_detail( return task_instance -@hitl_router.patch( - "/{dag_id}/{dag_run_id}/{task_id}", +@task_instances_hitl_router.patch( + task_instance_hitl_path, responses=create_openapi_http_exception_doc( [ status.HTTP_403_FORBIDDEN, @@ -165,8 +167,8 @@ def update_hitl_detail( return HITLDetailResponse.model_validate(hitl_detail_model) -@hitl_router.get( - "/{dag_id}/{dag_run_id}/{task_id}", +@task_instances_hitl_router.get( + task_instance_hitl_path, status_code=status.HTTP_200_OK, responses=create_openapi_http_exception_doc([status.HTTP_404_NOT_FOUND]), dependencies=[Depends(requires_access_dag(method="GET", access_entity=DagAccessEntity.HITL_DETAIL))], @@ -189,12 +191,14 @@ def get_hitl_detail( return task_instance.hitl_detail -@hitl_router.get( - "/", +@task_instances_hitl_router.get( + "/hitlDetails", status_code=status.HTTP_200_OK, dependencies=[Depends(requires_access_dag(method="GET", access_entity=DagAccessEntity.HITL_DETAIL))], ) def get_hitl_details( + dag_id: str, + dag_run_id: str, limit: QueryLimit, offset: QueryOffset, order_by: Annotated[ @@ -220,9 +224,7 @@ def get_hitl_details( session: SessionDep, # ti related filter readable_ti_filter: ReadableTIFilterDep, - dag_id: QueryHITLDetailDagIdFilter, dag_id_pattern: QueryHITLDetailDagIdPatternSearch, - dag_run_id: QueryHITLDetailDagRunIdFilter, task_id: QueryHITLDetailTaskIdFilter, task_id_pattern: QueryHITLDetailTaskIdPatternSearch, ti_state: QueryTIStateFilter, @@ -244,14 +246,16 @@ def get_hitl_details( ) ) ) + if dag_id != "~": + query = query.where(TI.dag_id == dag_id) + if dag_run_id != "~": + query = query.where(TI.run_id == dag_run_id) hitl_detail_select, total_entries = paginated_select( statement=query, filters=[ # ti related filter readable_ti_filter, - dag_id, dag_id_pattern, - dag_run_id, task_id, task_id_pattern, ti_state, diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts index d4ffa8098f9..3a937cdd85f 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts @@ -1,7 +1,7 @@ // generated with @7nohe/[email protected] import { UseQueryResult } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, Structu [...] +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstance [...] import { DagRunState, DagWarningType } from "../requests/types.gen"; export type AssetServiceGetAssetsDefaultResponse = Awaited<ReturnType<typeof AssetService.getAssets>>; export type AssetServiceGetAssetsQueryResult<TData = AssetServiceGetAssetsDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>; @@ -552,6 +552,34 @@ export const UseTaskInstanceServiceGetExternalLogUrlKeyFn = ({ dagId, dagRunId, taskId: string; tryNumber: number; }, queryKey?: Array<unknown>) => [useTaskInstanceServiceGetExternalLogUrlKey, ...(queryKey ?? [{ dagId, dagRunId, mapIndex, taskId, tryNumber }])]; +export type TaskInstanceServiceGetHitlDetailDefaultResponse = Awaited<ReturnType<typeof TaskInstanceService.getHitlDetail>>; +export type TaskInstanceServiceGetHitlDetailQueryResult<TData = TaskInstanceServiceGetHitlDetailDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>; +export const useTaskInstanceServiceGetHitlDetailKey = "TaskInstanceServiceGetHitlDetail"; +export const UseTaskInstanceServiceGetHitlDetailKeyFn = ({ dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}, queryKey?: Array<unknown>) => [useTaskInstanceServiceGetHitlDetailKey, ...(queryKey ?? [{ dagId, dagRunId, mapIndex, taskId }])]; +export type TaskInstanceServiceGetHitlDetailsDefaultResponse = Awaited<ReturnType<typeof TaskInstanceService.getHitlDetails>>; +export type TaskInstanceServiceGetHitlDetailsQueryResult<TData = TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>; +export const useTaskInstanceServiceGetHitlDetailsKey = "TaskInstanceServiceGetHitlDetails"; +export const UseTaskInstanceServiceGetHitlDetailsKeyFn = ({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}, queryKey?: Array<unknown>) => [useTaskInstanceServiceGetHitlDetailsKey, ...(queryKey ?? [{ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }])]; export type ImportErrorServiceGetImportErrorDefaultResponse = Awaited<ReturnType<typeof ImportErrorService.getImportError>>; export type ImportErrorServiceGetImportErrorQueryResult<TData = ImportErrorServiceGetImportErrorDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>; export const useImportErrorServiceGetImportErrorKey = "ImportErrorServiceGetImportError"; @@ -705,34 +733,6 @@ export const UseDagVersionServiceGetDagVersionsKeyFn = ({ bundleName, bundleVers orderBy?: string[]; versionNumber?: number; }, queryKey?: Array<unknown>) => [useDagVersionServiceGetDagVersionsKey, ...(queryKey ?? [{ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }])]; -export type HumanInTheLoopServiceGetHitlDetailDefaultResponse = Awaited<ReturnType<typeof HumanInTheLoopService.getHitlDetail>>; -export type HumanInTheLoopServiceGetHitlDetailQueryResult<TData = HumanInTheLoopServiceGetHitlDetailDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>; -export const useHumanInTheLoopServiceGetHitlDetailKey = "HumanInTheLoopServiceGetHitlDetail"; -export const UseHumanInTheLoopServiceGetHitlDetailKeyFn = ({ dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}, queryKey?: Array<unknown>) => [useHumanInTheLoopServiceGetHitlDetailKey, ...(queryKey ?? [{ dagId, dagRunId, mapIndex, taskId }])]; -export type HumanInTheLoopServiceGetHitlDetailsDefaultResponse = Awaited<ReturnType<typeof HumanInTheLoopService.getHitlDetails>>; -export type HumanInTheLoopServiceGetHitlDetailsQueryResult<TData = HumanInTheLoopServiceGetHitlDetailsDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>; -export const useHumanInTheLoopServiceGetHitlDetailsKey = "HumanInTheLoopServiceGetHitlDetails"; -export const UseHumanInTheLoopServiceGetHitlDetailsKeyFn = ({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedByUserId?: string[]; - respondedByUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}, queryKey?: Array<unknown>) => [useHumanInTheLoopServiceGetHitlDetailsKey, ...(queryKey ?? [{ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }])]; export type MonitorServiceGetHealthDefaultResponse = Awaited<ReturnType<typeof MonitorService.getHealth>>; export type MonitorServiceGetHealthQueryResult<TData = MonitorServiceGetHealthDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>; export const useMonitorServiceGetHealthKey = "MonitorServiceGetHealth"; @@ -870,12 +870,12 @@ export type TaskInstanceServicePatchTaskInstanceByMapIndexMutationResult = Await export type TaskInstanceServiceBulkTaskInstancesMutationResult = Awaited<ReturnType<typeof TaskInstanceService.bulkTaskInstances>>; export type TaskInstanceServicePatchTaskInstanceDryRunByMapIndexMutationResult = Awaited<ReturnType<typeof TaskInstanceService.patchTaskInstanceDryRunByMapIndex>>; export type TaskInstanceServicePatchTaskInstanceDryRunMutationResult = Awaited<ReturnType<typeof TaskInstanceService.patchTaskInstanceDryRun>>; +export type TaskInstanceServiceUpdateHitlDetailMutationResult = Awaited<ReturnType<typeof TaskInstanceService.updateHitlDetail>>; export type PoolServicePatchPoolMutationResult = Awaited<ReturnType<typeof PoolService.patchPool>>; export type PoolServiceBulkPoolsMutationResult = Awaited<ReturnType<typeof PoolService.bulkPools>>; export type XcomServiceUpdateXcomEntryMutationResult = Awaited<ReturnType<typeof XcomService.updateXcomEntry>>; export type VariableServicePatchVariableMutationResult = Awaited<ReturnType<typeof VariableService.patchVariable>>; export type VariableServiceBulkVariablesMutationResult = Awaited<ReturnType<typeof VariableService.bulkVariables>>; -export type HumanInTheLoopServiceUpdateHitlDetailMutationResult = Awaited<ReturnType<typeof HumanInTheLoopService.updateHitlDetail>>; export type AssetServiceDeleteAssetQueuedEventsMutationResult = Awaited<ReturnType<typeof AssetService.deleteAssetQueuedEvents>>; export type AssetServiceDeleteDagAssetQueuedEventsMutationResult = Awaited<ReturnType<typeof AssetService.deleteDagAssetQueuedEvents>>; export type AssetServiceDeleteDagAssetQueuedEventMutationResult = Awaited<ReturnType<typeof AssetService.deleteDagAssetQueuedEvent>>; diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts index da76a35a8ce..bad321b274c 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts @@ -1,7 +1,7 @@ // generated with @7nohe/[email protected] import { type QueryClient } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInst [...] +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskServic [...] import { DagRunState, DagWarningType } from "../requests/types.gen"; import * as Common from "./common"; /** @@ -1049,6 +1049,60 @@ export const ensureUseTaskInstanceServiceGetExternalLogUrlData = (queryClient: Q tryNumber: number; }) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const ensureUseTaskInstanceServiceGetHitlDetailData = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const ensureUseTaskInstanceServiceGetHitlDetailsData = (queryClient: QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}) => queryClient.ensureQueryData({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) }); +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1341,60 +1395,6 @@ export const ensureUseDagVersionServiceGetDagVersionsData = (queryClient: QueryC versionNumber?: number; }) => queryClient.ensureQueryData({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const ensureUseHumanInTheLoopServiceGetHitlDetailData = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}) => queryClient.ensureQueryData({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedByUserId -* @param data.respondedByUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const ensureUseHumanInTheLoopServiceGetHitlDetailsData = (queryClient: QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedByUserId?: string[]; - respondedByUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}) => queryClient.ensureQueryData({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskId [...] -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts index af773c94bdd..0f3565e9fe0 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts @@ -1,7 +1,7 @@ // generated with @7nohe/[email protected] import { type QueryClient } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInst [...] +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskServic [...] import { DagRunState, DagWarningType } from "../requests/types.gen"; import * as Common from "./common"; /** @@ -1049,6 +1049,60 @@ export const prefetchUseTaskInstanceServiceGetExternalLogUrl = (queryClient: Que tryNumber: number; }) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const prefetchUseTaskInstanceServiceGetHitlDetail = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const prefetchUseTaskInstanceServiceGetHitlDetails = (queryClient: QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}) => queryClient.prefetchQuery({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }) }); +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1341,60 +1395,6 @@ export const prefetchUseDagVersionServiceGetDagVersions = (queryClient: QueryCli versionNumber?: number; }) => queryClient.prefetchQuery({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const prefetchUseHumanInTheLoopServiceGetHitlDetail = (queryClient: QueryClient, { dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}) => queryClient.prefetchQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedByUserId -* @param data.respondedByUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const prefetchUseHumanInTheLoopServiceGetHitlDetails = (queryClient: QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedByUserId?: string[]; - respondedByUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}) => queryClient.prefetchQuery({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPa [...] -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts index 6c70c69ac5c..9d23ddbcfe6 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts @@ -1,7 +1,7 @@ // generated with @7nohe/[email protected] import { UseMutationOptions, UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, Structu [...] +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagParsingService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstance [...] import { BackfillPostBody, BulkBody_BulkTaskInstanceBody_, BulkBody_ConnectionBody_, BulkBody_PoolBody_, BulkBody_VariableBody_, ClearTaskInstancesBody, ConnectionBody, CreateAssetEventsBody, DAGPatchBody, DAGRunClearBody, DAGRunPatchBody, DAGRunsBatchBody, DagRunState, DagWarningType, PatchTaskInstanceBody, PoolBody, PoolPatchBody, TaskInstancesBatchBody, TriggerDAGRunPostBody, UpdateHITLDetailPayload, VariableBody, XComCreateBody, XComUpdateBody } from "../requests/types.gen"; import * as Common from "./common"; /** @@ -1049,6 +1049,60 @@ export const useTaskInstanceServiceGetExternalLogUrl = <TData = Common.TaskInsta tryNumber: number; }, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }, queryKey), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) as TData, ...options }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetail = <TData = Common.TaskInstanceServiceGetHitlDetailDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetails = <TData = Common.TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, res [...] +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1341,60 +1395,6 @@ export const useDagVersionServiceGetDagVersions = <TData = Common.DagVersionServ versionNumber?: number; }, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }, queryKey), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) as TData, ...options }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetail = <TData = Common.HumanInTheLoopServiceGetHitlDetailDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedByUserId -* @param data.respondedByUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetails = <TData = Common.HumanInTheLoopServiceGetHitlDetailsDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedByUserId?: string[]; - respondedByUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, ord [...] -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError @@ -2141,6 +2141,31 @@ export const useTaskInstanceServicePatchTaskInstanceDryRun = <TData = Common.Tas updateMask?: string[]; }, TContext>({ mutationFn: ({ dagId, dagRunId, mapIndex, requestBody, taskId, updateMask }) => TaskInstanceService.patchTaskInstanceDryRun({ dagId, dagRunId, mapIndex, requestBody, taskId, updateMask }) as unknown as Promise<TData>, ...options }); /** +* Update Hitl Detail +* Update a Human-in-the-loop detail. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @param data.requestBody +* @returns HITLDetailResponse Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceUpdateHitlDetail = <TData = Common.TaskInstanceServiceUpdateHitlDetailMutationResult, TError = unknown, TContext = unknown>(options?: Omit<UseMutationOptions<TData, TError, { + dagId: string; + dagRunId: string; + mapIndex: number; + requestBody: UpdateHITLDetailPayload; + taskId: string; +}, TContext>, "mutationFn">) => useMutation<TData, TError, { + dagId: string; + dagRunId: string; + mapIndex: number; + requestBody: UpdateHITLDetailPayload; + taskId: string; +}, TContext>({ mutationFn: ({ dagId, dagRunId, mapIndex, requestBody, taskId }) => TaskInstanceService.updateHitlDetail({ dagId, dagRunId, mapIndex, requestBody, taskId }) as unknown as Promise<TData>, ...options }); +/** * Patch Pool * Update a Pool. * @param data The data for the request. @@ -2230,31 +2255,6 @@ export const useVariableServiceBulkVariables = <TData = Common.VariableServiceBu requestBody: BulkBody_VariableBody_; }, TContext>({ mutationFn: ({ requestBody }) => VariableService.bulkVariables({ requestBody }) as unknown as Promise<TData>, ...options }); /** -* Update Hitl Detail -* Update a Human-in-the-loop detail. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.requestBody -* @param data.mapIndex -* @returns HITLDetailResponse Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceUpdateHitlDetail = <TData = Common.HumanInTheLoopServiceUpdateHitlDetailMutationResult, TError = unknown, TContext = unknown>(options?: Omit<UseMutationOptions<TData, TError, { - dagId: string; - dagRunId: string; - mapIndex?: number; - requestBody: UpdateHITLDetailPayload; - taskId: string; -}, TContext>, "mutationFn">) => useMutation<TData, TError, { - dagId: string; - dagRunId: string; - mapIndex?: number; - requestBody: UpdateHITLDetailPayload; - taskId: string; -}, TContext>({ mutationFn: ({ dagId, dagRunId, mapIndex, requestBody, taskId }) => HumanInTheLoopService.updateHitlDetail({ dagId, dagRunId, mapIndex, requestBody, taskId }) as unknown as Promise<TData>, ...options }); -/** * Delete Asset Queued Events * Delete queued asset events for an asset. * @param data The data for the request. diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts index 79a5f974e07..4d5fea56dac 100644 --- a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts +++ b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts @@ -1,7 +1,7 @@ // generated with @7nohe/[email protected] import { UseQueryOptions, useSuspenseQuery } from "@tanstack/react-query"; -import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, HumanInTheLoopService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInst [...] +import { AssetService, AuthLinksService, BackfillService, CalendarService, ConfigService, ConnectionService, DagReportService, DagRunService, DagService, DagSourceService, DagStatsService, DagVersionService, DagWarningService, DashboardService, DependenciesService, EventLogService, ExperimentalService, ExtraLinksService, GridService, ImportErrorService, JobService, LoginService, MonitorService, PluginService, PoolService, ProviderService, StructureService, TaskInstanceService, TaskServic [...] import { DagRunState, DagWarningType } from "../requests/types.gen"; import * as Common from "./common"; /** @@ -1049,6 +1049,60 @@ export const useTaskInstanceServiceGetExternalLogUrlSuspense = <TData = Common.T tryNumber: number; }, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: Common.UseTaskInstanceServiceGetExternalLogUrlKeyFn({ dagId, dagRunId, mapIndex, taskId, tryNumber }, queryKey), queryFn: () => TaskInstanceService.getExternalLogUrl({ dagId, dagRunId, mapIndex, taskId, tryNumber }) as TData, ...options }); /** +* Get Hitl Detail +* Get a Human-in-the-loop detail of a specific task instance. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.taskId +* @param data.mapIndex +* @returns HITLDetail Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetailSuspense = <TData = Common.TaskInstanceServiceGetHitlDetailDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => TaskInstanceService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); +/** +* Get Hitl Details +* Get Human-in-the-loop details. +* @param data The data for the request. +* @param data.dagId +* @param data.dagRunId +* @param data.limit +* @param data.offset +* @param data.orderBy +* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.taskId +* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.state +* @param data.responseReceived +* @param data.respondedByUserId +* @param data.respondedByUserName +* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. +* @returns HITLDetailCollection Successful Response +* @throws ApiError +*/ +export const useTaskInstanceServiceGetHitlDetailsSuspense = <TData = Common.TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { + bodySearch?: string; + dagId: string; + dagIdPattern?: string; + dagRunId: string; + limit?: number; + offset?: number; + orderBy?: string[]; + respondedByUserId?: string[]; + respondedByUserName?: string[]; + responseReceived?: boolean; + state?: string[]; + subjectSearch?: string; + taskId?: string; + taskIdPattern?: string; +}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => TaskInstanceService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orde [...] +/** * Get Import Error * Get an import error. * @param data The data for the request. @@ -1341,60 +1395,6 @@ export const useDagVersionServiceGetDagVersionsSuspense = <TData = Common.DagVer versionNumber?: number; }, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: Common.UseDagVersionServiceGetDagVersionsKeyFn({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }, queryKey), queryFn: () => DagVersionService.getDagVersions({ bundleName, bundleVersion, dagId, limit, offset, orderBy, versionNumber }) as TData, ...options }); /** -* Get Hitl Detail -* Get a Human-in-the-loop detail of a specific task instance. -* @param data The data for the request. -* @param data.dagId -* @param data.dagRunId -* @param data.taskId -* @param data.mapIndex -* @returns HITLDetail Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetailSuspense = <TData = Common.HumanInTheLoopServiceGetHitlDetailDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ dagId, dagRunId, mapIndex, taskId }: { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailKeyFn({ dagId, dagRunId, mapIndex, taskId }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetail({ dagId, dagRunId, mapIndex, taskId }) as TData, ...options }); -/** -* Get Hitl Details -* Get Human-in-the-loop details. -* @param data The data for the request. -* @param data.limit -* @param data.offset -* @param data.orderBy -* @param data.dagId -* @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.dagRunId -* @param data.taskId -* @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.state -* @param data.responseReceived -* @param data.respondedByUserId -* @param data.respondedByUserName -* @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. -* @returns HITLDetailCollection Successful Response -* @throws ApiError -*/ -export const useHumanInTheLoopServiceGetHitlDetailsSuspense = <TData = Common.HumanInTheLoopServiceGetHitlDetailsDefaultResponse, TError = unknown, TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }: { - bodySearch?: string; - dagId?: string; - dagIdPattern?: string; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: string[]; - respondedByUserId?: string[]; - respondedByUserName?: string[]; - responseReceived?: boolean; - state?: string[]; - subjectSearch?: string; - taskId?: string; - taskIdPattern?: string; -} = {}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: Common.UseHumanInTheLoopServiceGetHitlDetailsKeyFn({ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => HumanInTheLoopService.getHitlDetails({ bodySearch, dagId, dagIdPattern, dagRunId, limit, off [...] -/** * Get Health * @returns HealthInfoResponse Successful Response * @throws ApiError 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 ed570c2fc9d..468bea4460d 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 @@ -3,7 +3,7 @@ import type { CancelablePromise } from './core/CancelablePromise'; import { OpenAPI } from './core/OpenAPI'; import { request as __request } from './core/request'; -import type { GetAssetsData, GetAssetsResponse, GetAssetAliasesData, GetAssetAliasesResponse, GetAssetAliasData, GetAssetAliasResponse, GetAssetEventsData, GetAssetEventsResponse, CreateAssetEventData, CreateAssetEventResponse, MaterializeAssetData, MaterializeAssetResponse, GetAssetQueuedEventsData, GetAssetQueuedEventsResponse, DeleteAssetQueuedEventsData, DeleteAssetQueuedEventsResponse, GetAssetData, GetAssetResponse, GetDagAssetQueuedEventsData, GetDagAssetQueuedEventsResponse, Dele [...] +import type { GetAssetsData, GetAssetsResponse, GetAssetAliasesData, GetAssetAliasesResponse, GetAssetAliasData, GetAssetAliasResponse, GetAssetEventsData, GetAssetEventsResponse, CreateAssetEventData, CreateAssetEventResponse, MaterializeAssetData, MaterializeAssetResponse, GetAssetQueuedEventsData, GetAssetQueuedEventsResponse, DeleteAssetQueuedEventsData, DeleteAssetQueuedEventsResponse, GetAssetData, GetAssetResponse, GetDagAssetQueuedEventsData, GetDagAssetQueuedEventsResponse, Dele [...] export class AssetService { /** @@ -2710,6 +2710,121 @@ export class TaskInstanceService { }); } + /** + * Update Hitl Detail + * Update a Human-in-the-loop detail. + * @param data The data for the request. + * @param data.dagId + * @param data.dagRunId + * @param data.taskId + * @param data.mapIndex + * @param data.requestBody + * @returns HITLDetailResponse Successful Response + * @throws ApiError + */ + public static updateHitlDetail(data: UpdateHitlDetailData): CancelablePromise<UpdateHitlDetailResponse> { + return __request(OpenAPI, { + method: 'PATCH', + url: '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails', + path: { + dag_id: data.dagId, + dag_run_id: data.dagRunId, + task_id: data.taskId, + map_index: data.mapIndex + }, + body: data.requestBody, + mediaType: 'application/json', + errors: { + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not Found', + 409: 'Conflict', + 422: 'Validation Error' + } + }); + } + + /** + * Get Hitl Detail + * Get a Human-in-the-loop detail of a specific task instance. + * @param data The data for the request. + * @param data.dagId + * @param data.dagRunId + * @param data.taskId + * @param data.mapIndex + * @returns HITLDetail Successful Response + * @throws ApiError + */ + public static getHitlDetail(data: GetHitlDetailData): CancelablePromise<GetHitlDetailResponse> { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails', + path: { + dag_id: data.dagId, + dag_run_id: data.dagRunId, + task_id: data.taskId, + map_index: data.mapIndex + }, + errors: { + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not Found', + 422: 'Validation Error' + } + }); + } + + /** + * Get Hitl Details + * Get Human-in-the-loop details. + * @param data The data for the request. + * @param data.dagId + * @param data.dagRunId + * @param data.limit + * @param data.offset + * @param data.orderBy + * @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.taskId + * @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.state + * @param data.responseReceived + * @param data.respondedByUserId + * @param data.respondedByUserName + * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + * @returns HITLDetailCollection Successful Response + * @throws ApiError + */ + public static getHitlDetails(data: GetHitlDetailsData): CancelablePromise<GetHitlDetailsResponse> { + return __request(OpenAPI, { + method: 'GET', + url: '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/hitlDetails', + path: { + dag_id: data.dagId, + dag_run_id: data.dagRunId + }, + query: { + limit: data.limit, + offset: data.offset, + order_by: data.orderBy, + dag_id_pattern: data.dagIdPattern, + task_id: data.taskId, + task_id_pattern: data.taskIdPattern, + state: data.state, + response_received: data.responseReceived, + responded_by_user_id: data.respondedByUserId, + responded_by_user_name: data.respondedByUserName, + subject_search: data.subjectSearch, + body_search: data.bodySearch + }, + errors: { + 401: 'Unauthorized', + 403: 'Forbidden', + 422: 'Validation Error' + } + }); + } + } export class ImportErrorService { @@ -3540,126 +3655,6 @@ export class DagVersionService { } -export class HumanInTheLoopService { - /** - * Update Hitl Detail - * Update a Human-in-the-loop detail. - * @param data The data for the request. - * @param data.dagId - * @param data.dagRunId - * @param data.taskId - * @param data.requestBody - * @param data.mapIndex - * @returns HITLDetailResponse Successful Response - * @throws ApiError - */ - public static updateHitlDetail(data: UpdateHitlDetailData): CancelablePromise<UpdateHitlDetailResponse> { - return __request(OpenAPI, { - method: 'PATCH', - url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}', - path: { - dag_id: data.dagId, - dag_run_id: data.dagRunId, - task_id: data.taskId - }, - query: { - map_index: data.mapIndex - }, - body: data.requestBody, - mediaType: 'application/json', - errors: { - 401: 'Unauthorized', - 403: 'Forbidden', - 404: 'Not Found', - 409: 'Conflict', - 422: 'Validation Error' - } - }); - } - - /** - * Get Hitl Detail - * Get a Human-in-the-loop detail of a specific task instance. - * @param data The data for the request. - * @param data.dagId - * @param data.dagRunId - * @param data.taskId - * @param data.mapIndex - * @returns HITLDetail Successful Response - * @throws ApiError - */ - public static getHitlDetail(data: GetHitlDetailData): CancelablePromise<GetHitlDetailResponse> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}', - path: { - dag_id: data.dagId, - dag_run_id: data.dagRunId, - task_id: data.taskId - }, - query: { - map_index: data.mapIndex - }, - errors: { - 401: 'Unauthorized', - 403: 'Forbidden', - 404: 'Not Found', - 422: 'Validation Error' - } - }); - } - - /** - * Get Hitl Details - * Get Human-in-the-loop details. - * @param data The data for the request. - * @param data.limit - * @param data.offset - * @param data.orderBy - * @param data.dagId - * @param data.dagIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @param data.dagRunId - * @param data.taskId - * @param data.taskIdPattern SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @param data.state - * @param data.responseReceived - * @param data.respondedByUserId - * @param data.respondedByUserName - * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - * @returns HITLDetailCollection Successful Response - * @throws ApiError - */ - public static getHitlDetails(data: GetHitlDetailsData = {}): CancelablePromise<GetHitlDetailsResponse> { - return __request(OpenAPI, { - method: 'GET', - url: '/api/v2/hitlDetails/', - query: { - limit: data.limit, - offset: data.offset, - order_by: data.orderBy, - dag_id: data.dagId, - dag_id_pattern: data.dagIdPattern, - dag_run_id: data.dagRunId, - task_id: data.taskId, - task_id_pattern: data.taskIdPattern, - state: data.state, - response_received: data.responseReceived, - responded_by_user_id: data.respondedByUserId, - responded_by_user_name: data.respondedByUserName, - subject_search: data.subjectSearch, - body_search: data.bodySearch - }, - errors: { - 401: 'Unauthorized', - 403: 'Forbidden', - 422: 'Validation Error' - } - }); - } - -} - export class MonitorService { /** * Get Health 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 21a81305bd8..18d40ed2531 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 @@ -2827,6 +2827,56 @@ export type GetExternalLogUrlData = { export type GetExternalLogUrlResponse = ExternalLogUrlResponse; +export type UpdateHitlDetailData = { + dagId: string; + dagRunId: string; + mapIndex: number; + requestBody: UpdateHITLDetailPayload; + taskId: string; +}; + +export type UpdateHitlDetailResponse = HITLDetailResponse; + +export type GetHitlDetailData = { + dagId: string; + dagRunId: string; + mapIndex: number; + taskId: string; +}; + +export type GetHitlDetailResponse = HITLDetail; + +export type GetHitlDetailsData = { + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + bodySearch?: string | null; + dagId: string; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + dagIdPattern?: string | null; + dagRunId: string; + limit?: number; + offset?: number; + orderBy?: Array<(string)>; + respondedByUserId?: Array<(string)>; + respondedByUserName?: Array<(string)>; + responseReceived?: boolean | null; + state?: Array<(string)>; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + subjectSearch?: string | null; + taskId?: string | null; + /** + * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. + */ + taskIdPattern?: string | null; +}; + +export type GetHitlDetailsResponse = HITLDetailCollection; + export type GetImportErrorData = { importErrorId: number; }; @@ -3073,56 +3123,6 @@ export type GetDagVersionsData = { export type GetDagVersionsResponse = DAGVersionCollectionResponse; -export type UpdateHitlDetailData = { - dagId: string; - dagRunId: string; - mapIndex?: number; - requestBody: UpdateHITLDetailPayload; - taskId: string; -}; - -export type UpdateHitlDetailResponse = HITLDetailResponse; - -export type GetHitlDetailData = { - dagId: string; - dagRunId: string; - mapIndex?: number; - taskId: string; -}; - -export type GetHitlDetailResponse = HITLDetail; - -export type GetHitlDetailsData = { - /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - */ - bodySearch?: string | null; - dagId?: string | null; - /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - */ - dagIdPattern?: string | null; - dagRunId?: string; - limit?: number; - offset?: number; - orderBy?: Array<(string)>; - respondedByUserId?: Array<(string)>; - respondedByUserName?: Array<(string)>; - responseReceived?: boolean | null; - state?: Array<(string)>; - /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - */ - subjectSearch?: string | null; - taskId?: string | null; - /** - * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). Regular expressions are **not** supported. - */ - taskIdPattern?: string | null; -}; - -export type GetHitlDetailsResponse = HITLDetailCollection; - export type GetHealthResponse = HealthInfoResponse; export type GetVersionResponse = VersionInfo; @@ -5392,6 +5392,85 @@ export type $OpenApiTs = { }; }; }; + '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/{map_index}/hitlDetails': { + patch: { + req: UpdateHitlDetailData; + res: { + /** + * Successful Response + */ + 200: HITLDetailResponse; + /** + * Unauthorized + */ + 401: HTTPExceptionResponse; + /** + * Forbidden + */ + 403: HTTPExceptionResponse; + /** + * Not Found + */ + 404: HTTPExceptionResponse; + /** + * Conflict + */ + 409: HTTPExceptionResponse; + /** + * Validation Error + */ + 422: HTTPValidationError; + }; + }; + get: { + req: GetHitlDetailData; + res: { + /** + * Successful Response + */ + 200: HITLDetail; + /** + * Unauthorized + */ + 401: HTTPExceptionResponse; + /** + * Forbidden + */ + 403: HTTPExceptionResponse; + /** + * Not Found + */ + 404: HTTPExceptionResponse; + /** + * Validation Error + */ + 422: HTTPValidationError; + }; + }; + }; + '/api/v2/dags/{dag_id}/dagRuns/{dag_run_id}/hitlDetails': { + get: { + req: GetHitlDetailsData; + res: { + /** + * Successful Response + */ + 200: HITLDetailCollection; + /** + * Unauthorized + */ + 401: HTTPExceptionResponse; + /** + * Forbidden + */ + 403: HTTPExceptionResponse; + /** + * Validation Error + */ + 422: HTTPValidationError; + }; + }; + }; '/api/v2/importErrors/{import_error_id}': { get: { req: GetImportErrorData; @@ -6104,85 +6183,6 @@ export type $OpenApiTs = { }; }; }; - '/api/v2/hitlDetails/{dag_id}/{dag_run_id}/{task_id}': { - patch: { - req: UpdateHitlDetailData; - res: { - /** - * Successful Response - */ - 200: HITLDetailResponse; - /** - * Unauthorized - */ - 401: HTTPExceptionResponse; - /** - * Forbidden - */ - 403: HTTPExceptionResponse; - /** - * Not Found - */ - 404: HTTPExceptionResponse; - /** - * Conflict - */ - 409: HTTPExceptionResponse; - /** - * Validation Error - */ - 422: HTTPValidationError; - }; - }; - get: { - req: GetHitlDetailData; - res: { - /** - * Successful Response - */ - 200: HITLDetail; - /** - * Unauthorized - */ - 401: HTTPExceptionResponse; - /** - * Forbidden - */ - 403: HTTPExceptionResponse; - /** - * Not Found - */ - 404: HTTPExceptionResponse; - /** - * Validation Error - */ - 422: HTTPValidationError; - }; - }; - }; - '/api/v2/hitlDetails/': { - get: { - req: GetHitlDetailsData; - res: { - /** - * Successful Response - */ - 200: HITLDetailCollection; - /** - * Unauthorized - */ - 401: HTTPExceptionResponse; - /** - * Forbidden - */ - 403: HTTPExceptionResponse; - /** - * Validation Error - */ - 422: HTTPValidationError; - }; - }; - }; '/api/v2/monitor/health': { get: { 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 f29fe60cfef..61f6488d5fc 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 @@ -65,7 +65,7 @@ def sample_ti( @pytest.fixture def sample_ti_url_identifier() -> str: - return f"{DAG_ID}/test/{TASK_ID}" + return f"/dags/{DAG_ID}/dagRuns/test/taskInstances/{TASK_ID}/-1" @pytest.fixture @@ -269,11 +269,10 @@ def cleanup_audit_log(session: Session) -> None: session.commit() -def _assert_sample_audit_log(audit_log: Log, map_index: int | None) -> None: +def _assert_sample_audit_log(audit_log: Log) -> None: assert audit_log.dag_id == DAG_ID assert audit_log.task_id == TASK_ID assert audit_log.run_id == "test" - assert audit_log.map_index is None assert audit_log.try_number is None assert audit_log.owner == "test" assert audit_log.owner_display_name == "test" @@ -286,9 +285,8 @@ def _assert_sample_audit_log(audit_log: Log, map_index: int | None) -> None: "chosen_options": ["Approve"], "params_input": {"input_1": 2}, "method": "PATCH", + "map_index": "-1", } - if map_index is not None: - expected_extra["map_index"] = str(map_index) assert json.loads(audit_log.extra) == expected_extra @@ -301,21 +299,17 @@ def sample_update_payload() -> dict[str, Any]: class TestUpdateHITLDetailEndpoint: @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail") - @pytest.mark.parametrize("map_index", [None, -1]) def test_should_respond_200_with_existing_response( self, test_client: TestClient, sample_ti_url_identifier: str, - map_index: int | None, sample_update_payload: dict[str, Any], session: Session, ) -> None: - query_param = "" if map_index is None else f"?map_index={map_index}" response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) - assert response.status_code == 200 assert response.json() == { "params_input": {"input_1": 2}, @@ -325,23 +319,20 @@ class TestUpdateHITLDetailEndpoint: } audit_log = session.scalar(select(Log)) - _assert_sample_audit_log(audit_log, map_index=map_index) + _assert_sample_audit_log(audit_log) @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail_respondent") - @pytest.mark.parametrize("map_index", [None, -1]) def test_should_respond_200_to_assigned_users( self, test_client: TestClient, sample_ti_url_identifier: str, - map_index: int | None, sample_update_payload: dict[str, Any], session: Session, ): """Test with an authorized user and the user is a respondent to the task.""" - query_param = "" if map_index is None else f"?map_index={map_index}" response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) @@ -354,37 +345,32 @@ class TestUpdateHITLDetailEndpoint: } audit_log = session.scalar(select(Log)) - _assert_sample_audit_log(audit_log, map_index=map_index) + _assert_sample_audit_log(audit_log) - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_401( self, unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, ) -> None: response = unauthenticated_test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 401 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_403( self, unauthorized_test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, ) -> None: response = unauthorized_test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 403 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail_non_respondent") def test_should_respond_403_to_non_respondent_user( @@ -392,58 +378,51 @@ class TestUpdateHITLDetailEndpoint: test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, ): """Test with an authorized user but the user is not a respondent to the task.""" response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 403 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_ti( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) assert response.status_code == 404 assert response.json() == {"detail": expected_ti_not_found_error_msg} - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_hitl_detail( self, test_client: TestClient, sample_ti_url_identifier: str, sample_update_payload: dict[str, Any], - query_param: str, expected_hitl_detail_not_found_error_msg: str, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json=sample_update_payload, ) assert response.status_code == 404 assert response.json() == {"detail": expected_hitl_detail_not_found_error_msg} - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @time_machine.travel(datetime(2025, 7, 3, 0, 0, 0), tick=False) @pytest.mark.usefixtures("sample_hitl_detail") def test_should_respond_409( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, sample_ti: TaskInstance, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": ["Approve"], "params_input": {"input_1": 2}}, ) @@ -457,7 +436,7 @@ class TestUpdateHITLDetailEndpoint: assert response.json() == expected_response response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": ["Approve"], "params_input": {"input_1": 3}}, ) assert response.status_code == 409 @@ -469,16 +448,14 @@ class TestUpdateHITLDetailEndpoint: ) } - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @pytest.mark.usefixtures("sample_hitl_detail") def test_should_respond_422_with_empty_option( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: response = test_client.patch( - f"/hitlDetails/{sample_ti_url_identifier}{query_param}", + f"{sample_ti_url_identifier}/hitlDetails", json={"chosen_options": [], "params_input": {"input_1": 2}}, ) @@ -486,59 +463,49 @@ class TestUpdateHITLDetailEndpoint: class TestGetHITLDetailEndpoint: - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) @pytest.mark.usefixtures("sample_hitl_detail") def test_should_respond_200_with_existing_response( self, test_client: TestClient, sample_ti_url_identifier: str, expected_sample_hitl_detail_dict: dict[str, Any], - query_param: str, ) -> None: - response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 200 assert response.json() == expected_sample_hitl_detail_dict - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_401( self, unauthenticated_test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: - response = unauthenticated_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = unauthenticated_test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 401 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_403( self, unauthorized_test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: - response = unauthorized_test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = unauthorized_test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 403 - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_ti( self, test_client: TestClient, sample_ti_url_identifier: str, - query_param: str, ) -> None: - response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 404 assert response.json() == {"detail": expected_ti_not_found_error_msg} - @pytest.mark.parametrize("query_param", ["", "?map_index=-1"]) def test_should_respond_404_without_hitl_detail( self, test_client: TestClient, sample_ti_url_identifier: str, expected_hitl_detail_not_found_error_msg: str, - query_param: str, ) -> None: - response = test_client.get(f"/hitlDetails/{sample_ti_url_identifier}{query_param}") + response = test_client.get(f"{sample_ti_url_identifier}/hitlDetails") assert response.status_code == 404 assert response.json() == {"detail": expected_hitl_detail_not_found_error_msg} @@ -550,7 +517,7 @@ class TestGetHITLDetailsEndpoint: test_client: TestClient, expected_sample_hitl_detail_dict: dict[str, Any], ) -> None: - response = test_client.get("/hitlDetails/") + response = test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 200 assert response.json() == { "hitl_details": [expected_sample_hitl_detail_dict], @@ -564,8 +531,6 @@ class TestGetHITLDetailsEndpoint: # ti related filter ({"dag_id_pattern": "hitl_dag"}, 5), ({"dag_id_pattern": "other_Dag_"}, 3), - ({"dag_id": "hitl_dag_0"}, 1), - ({"dag_run_id": "hitl_run_0"}, 1), ({"task_id": "hitl_task_0"}, 1), ({"task_id_pattern": "another_hitl"}, 3), ({"state": "running"}, 5), @@ -581,8 +546,6 @@ class TestGetHITLDetailsEndpoint: ids=[ "dag_id_pattern_hitl_dag", "dag_id_pattern_other_dag", - "dag_id", - "dag_run_id", "task_id_pattern", "task_id", "ti_state_running", @@ -601,11 +564,39 @@ class TestGetHITLDetailsEndpoint: params: dict[str, Any], expected_ti_count: int, ) -> None: - response = test_client.get("/hitlDetails/", params=params) + response = test_client.get("/dags/~/dagRuns/~/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 + @pytest.mark.usefixtures("sample_hitl_details") + def test_should_respond_200_with_existing_response_and_concrete_query( + self, + test_client: TestClient, + ) -> None: + response = test_client.get("/dags/hitl_dag_0/dagRuns/hitl_run_0/hitlDetails") + assert response.status_code == 200 + assert response.json() == { + "hitl_details": [ + { + "task_instance": mock.ANY, + "options": ["Approve", "Reject"], + "subject": "This is subject 0", + "body": "this is body 0", + "defaults": ["Approve"], + "multiple": False, + "params": {"input_1": 1}, + "assigned_users": [], + "responded_by_user": None, + "responded_at": None, + "chosen_options": None, + "params_input": {}, + "response_received": False, + } + ], + "total_entries": 1, + } + @pytest.mark.usefixtures("sample_hitl_details") @pytest.mark.parametrize("asc_desc_mark", ["", "-"], ids=["asc", "desc"]) @pytest.mark.parametrize( @@ -642,7 +633,9 @@ class TestGetHITLDetailsEndpoint: ) -> None: reverse = asc_desc_mark == "-" - response = test_client.get("/hitlDetails/", params={"order_by": f"{asc_desc_mark}{key}"}) + response = test_client.get( + "/dags/~/dagRuns/~/hitlDetails", params={"order_by": f"{asc_desc_mark}{key}"} + ) data = response.json() hitl_details = data["hitl_details"] @@ -664,7 +657,7 @@ class TestGetHITLDetailsEndpoint: assert hitl_details == sorted_hitl_details def test_should_respond_200_without_response(self, test_client: TestClient) -> None: - response = test_client.get("/hitlDetails/") + response = test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 200 assert response.json() == { "hitl_details": [], @@ -672,9 +665,9 @@ class TestGetHITLDetailsEndpoint: } def test_should_respond_401(self, unauthenticated_test_client: TestClient) -> None: - response = unauthenticated_test_client.get("/hitlDetails/") + response = unauthenticated_test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 401 def test_should_respond_403(self, unauthorized_test_client: TestClient) -> None: - response = unauthorized_test_client.get("/hitlDetails/") + response = unauthorized_test_client.get("/dags/~/dagRuns/~/hitlDetails") assert response.status_code == 403
