This is an automated email from the ASF dual-hosted git repository.
jscheffl pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 353919045aa Add service endpoint to provide hook meta data for UI
(#47588)
353919045aa is described below
commit 353919045aa83fd6fe9e5b1d9f93873f139610f6
Author: Jens Scheffler <[email protected]>
AuthorDate: Wed Mar 12 23:28:19 2025 +0100
Add service endpoint to provide hook meta data for UI (#47588)
* Add service endpoint to provide hook meta data for UI
* Review Feedback
* Add pytest, re-wire ui connection endpoint
* Re-naming class feedback
* Revert import formatting change
* Make test as DB test for FAB auth
---
.../api_fastapi/core_api/datamodels/connections.py | 48 +++
.../api_fastapi/core_api/openapi/v1-generated.yaml | 124 ++++++
airflow/api_fastapi/core_api/routes/ui/__init__.py | 2 +
.../api_fastapi/core_api/routes/ui/connections.py | 40 ++
.../core_api/services/ui/connections.py | 210 ++++++++++
airflow/ui/openapi-gen/queries/common.ts | 106 ++---
airflow/ui/openapi-gen/queries/prefetch.ts | 109 ++---
airflow/ui/openapi-gen/queries/queries.ts | 249 +++++------
airflow/ui/openapi-gen/queries/suspense.ts | 147 ++++---
airflow/ui/openapi-gen/requests/schemas.gen.ts | 185 +++++++++
airflow/ui/openapi-gen/requests/services.gen.ts | 444 ++++++++++----------
airflow/ui/openapi-gen/requests/types.gen.ts | 453 ++++++++++++---------
.../core_api/routes/ui/test_connections.py | 41 ++
13 files changed, 1471 insertions(+), 687 deletions(-)
diff --git a/airflow/api_fastapi/core_api/datamodels/connections.py
b/airflow/api_fastapi/core_api/datamodels/connections.py
index 19a50eac79b..fee330e1fd1 100644
--- a/airflow/api_fastapi/core_api/datamodels/connections.py
+++ b/airflow/api_fastapi/core_api/datamodels/connections.py
@@ -18,6 +18,8 @@
from __future__ import annotations
import json
+from collections import abc
+from typing import Annotated
from pydantic import Field, field_validator
from pydantic_core.core_schema import ValidationInfo
@@ -75,6 +77,52 @@ class ConnectionTestResponse(BaseModel):
message: str
+class ConnectionHookFieldBehavior(BaseModel):
+ """A class to store the behavior of each standard field of a Hook."""
+
+ hidden: Annotated[
+ bool,
+ Field(description="Flag if the form field should be hidden."),
+ ] = False
+ title: Annotated[
+ str | None,
+ Field(
+ description="Label / title for the field that should be displayed,
if re-labelling is needed. Use `None` to display standard title."
+ ),
+ ] = None
+ placeholder: Annotated[
+ str | None,
+ Field(description="Placeholder text that should be populated to the
form."),
+ ] = None
+
+
+class StandardHookFields(BaseModel):
+ """Standard fields of a Hook that a form will render."""
+
+ description: ConnectionHookFieldBehavior | None
+ url_schema: ConnectionHookFieldBehavior | None
+ host: ConnectionHookFieldBehavior | None
+ port: ConnectionHookFieldBehavior | None
+ login: ConnectionHookFieldBehavior | None
+ password: ConnectionHookFieldBehavior | None
+
+
+class ConnectionHookMetaData(BaseModel):
+ """
+ Response model for Hook information == Connection type meta data.
+
+ It is used to transfer providers information loaded by providers_manager
such that
+ the API server/Web UI can use this data to render connection form UI.
+ """
+
+ connection_type: str | None
+ hook_class_name: str | None
+ default_conn_name: str | None
+ hook_name: str
+ standard_fields: StandardHookFields | None
+ extra_fields: abc.MutableMapping | None
+
+
# Request Models
class ConnectionBody(StrictBaseModel):
"""Connection Serializer for requests body."""
diff --git a/airflow/api_fastapi/core_api/openapi/v1-generated.yaml
b/airflow/api_fastapi/core_api/openapi/v1-generated.yaml
index 0eab45da497..984a40ff228 100644
--- a/airflow/api_fastapi/core_api/openapi/v1-generated.yaml
+++ b/airflow/api_fastapi/core_api/openapi/v1-generated.yaml
@@ -58,6 +58,26 @@ paths:
$ref: '#/components/schemas/HTTPExceptionResponse'
security:
- OAuth2PasswordBearer: []
+ /ui/connections/hook_meta:
+ get:
+ tags:
+ - Connection
+ summary: Hook Meta Data
+ description: Retrieve information about available connection types (hook
classes)
+ and their parameters.
+ operationId: hook_meta_data
+ responses:
+ '200':
+ description: Successful Response
+ content:
+ application/json:
+ schema:
+ items:
+ $ref: '#/components/schemas/ConnectionHookMetaData'
+ type: array
+ title: Response Hook Meta Data
+ security:
+ - OAuth2PasswordBearer: []
/ui/dags/recent_dag_runs:
get:
tags:
@@ -8121,6 +8141,74 @@ components:
- total_entries
title: ConnectionCollectionResponse
description: Connection Collection serializer for responses.
+ ConnectionHookFieldBehavior:
+ properties:
+ hidden:
+ type: boolean
+ title: Hidden
+ description: Flag if the form field should be hidden.
+ default: false
+ title:
+ anyOf:
+ - type: string
+ - type: 'null'
+ title: Title
+ description: Label / title for the field that should be displayed,
if re-labelling
+ is needed. Use `None` to display standard title.
+ placeholder:
+ anyOf:
+ - type: string
+ - type: 'null'
+ title: Placeholder
+ description: Placeholder text that should be populated to the form.
+ type: object
+ title: ConnectionHookFieldBehavior
+ description: A class to store the behavior of each standard field of a
Hook.
+ ConnectionHookMetaData:
+ properties:
+ connection_type:
+ anyOf:
+ - type: string
+ - type: 'null'
+ title: Connection Type
+ hook_class_name:
+ anyOf:
+ - type: string
+ - type: 'null'
+ title: Hook Class Name
+ default_conn_name:
+ anyOf:
+ - type: string
+ - type: 'null'
+ title: Default Conn Name
+ hook_name:
+ type: string
+ title: Hook Name
+ standard_fields:
+ anyOf:
+ - $ref: '#/components/schemas/StandardHookFields'
+ - type: 'null'
+ extra_fields:
+ anyOf:
+ - type: object
+ - type: 'null'
+ title: Extra Fields
+ type: object
+ required:
+ - connection_type
+ - hook_class_name
+ - default_conn_name
+ - hook_name
+ - standard_fields
+ - extra_fields
+ title: ConnectionHookMetaData
+ description: 'Response model for Hook information == Connection type
meta data.
+
+
+ It is used to transfer providers information loaded by
providers_manager such
+ that
+
+ the API server/Web UI can use this data to render connection form UI.'
ConnectionResponse:
properties:
connection_id:
@@ -10228,6 +10316,42 @@ components:
- latest_scheduler_heartbeat
title: SchedulerInfoResponse
description: Scheduler info serializer for responses.
+ StandardHookFields:
+ properties:
+ description:
+ anyOf:
+ - $ref: '#/components/schemas/ConnectionHookFieldBehavior'
+ - type: 'null'
+ url_schema:
+ anyOf:
+ - $ref: '#/components/schemas/ConnectionHookFieldBehavior'
+ - type: 'null'
+ host:
+ anyOf:
+ - $ref: '#/components/schemas/ConnectionHookFieldBehavior'
+ - type: 'null'
+ port:
+ anyOf:
+ - $ref: '#/components/schemas/ConnectionHookFieldBehavior'
+ - type: 'null'
+ login:
+ anyOf:
+ - $ref: '#/components/schemas/ConnectionHookFieldBehavior'
+ - type: 'null'
+ password:
+ anyOf:
+ - $ref: '#/components/schemas/ConnectionHookFieldBehavior'
+ - type: 'null'
+ type: object
+ required:
+ - description
+ - url_schema
+ - host
+ - port
+ - login
+ - password
+ title: StandardHookFields
+ description: Standard fields of a Hook that a form will render.
StructureDataResponse:
properties:
edges:
diff --git a/airflow/api_fastapi/core_api/routes/ui/__init__.py
b/airflow/api_fastapi/core_api/routes/ui/__init__.py
index cd01ee44232..b43b4141b9d 100644
--- a/airflow/api_fastapi/core_api/routes/ui/__init__.py
+++ b/airflow/api_fastapi/core_api/routes/ui/__init__.py
@@ -20,6 +20,7 @@ from airflow.api_fastapi.common.router import AirflowRouter
from airflow.api_fastapi.core_api.routes.ui.assets import assets_router
from airflow.api_fastapi.core_api.routes.ui.backfills import backfills_router
from airflow.api_fastapi.core_api.routes.ui.config import config_router
+from airflow.api_fastapi.core_api.routes.ui.connections import
connections_router
from airflow.api_fastapi.core_api.routes.ui.dags import dags_router
from airflow.api_fastapi.core_api.routes.ui.dashboard import dashboard_router
from airflow.api_fastapi.core_api.routes.ui.dependencies import
dependencies_router
@@ -30,6 +31,7 @@ ui_router = AirflowRouter(prefix="/ui",
include_in_schema=False)
ui_router.include_router(assets_router)
ui_router.include_router(config_router)
+ui_router.include_router(connections_router)
ui_router.include_router(dags_router)
ui_router.include_router(dependencies_router)
ui_router.include_router(dashboard_router)
diff --git a/airflow/api_fastapi/core_api/routes/ui/connections.py
b/airflow/api_fastapi/core_api/routes/ui/connections.py
new file mode 100644
index 00000000000..2ce95265e04
--- /dev/null
+++ b/airflow/api_fastapi/core_api/routes/ui/connections.py
@@ -0,0 +1,40 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+from fastapi import Depends
+
+from airflow.api_fastapi.common.router import AirflowRouter
+from airflow.api_fastapi.core_api.datamodels.connections import
ConnectionHookMetaData
+from airflow.api_fastapi.core_api.security import requires_access_connection
+from airflow.api_fastapi.core_api.services.ui.connections import
HookMetaService
+
+connections_router = AirflowRouter(tags=["Connection"], prefix="/connections")
+
+
+@connections_router.get(
+ "/hook_meta",
+ dependencies=[Depends(requires_access_connection(method="GET"))],
+)
+def hook_meta_data() -> list[ConnectionHookMetaData]:
+ """Retrieve information about available connection types (hook classes)
and their parameters."""
+ # Note:
+ # This endpoint is implemented to serve the connections form in the UI. It
is building on providers
+ # manager and hooks being loaded in the API server. Target should be that
the API server reads the
+ # information from a database table to un-bundle the dependency for
provider package install from
+ # the API server.
+ return HookMetaService.hook_meta_data()
diff --git a/airflow/api_fastapi/core_api/services/ui/connections.py
b/airflow/api_fastapi/core_api/services/ui/connections.py
new file mode 100644
index 00000000000..482b3a6b5cb
--- /dev/null
+++ b/airflow/api_fastapi/core_api/services/ui/connections.py
@@ -0,0 +1,210 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from __future__ import annotations
+
+import logging
+from collections.abc import MutableMapping
+from functools import cache
+from typing import TYPE_CHECKING
+
+from airflow.api_fastapi.core_api.datamodels.connections import (
+ ConnectionHookFieldBehavior,
+ ConnectionHookMetaData,
+ StandardHookFields,
+)
+from airflow.sdk import Param
+
+if TYPE_CHECKING:
+ from airflow.providers_manager import ConnectionFormWidgetInfo, HookInfo
+
+log = logging.getLogger(__name__)
+
+
+class HookMetaService:
+ """Service for retrieving details about hooks to render UI."""
+
+ class MockOptional:
+ """Mock for wtforms.validators.Optional."""
+
+ def __init__(
+ self,
+ *args,
+ **kwargs,
+ ):
+ pass
+
+ class MockEnum:
+ """Mock for wtforms.validators.Optional."""
+
+ def __init__(self, allowed_values):
+ self.allowed_values = allowed_values
+
+ class MockBaseField:
+ """Mock of WTForms Field."""
+
+ param_type: str = "UNDEFINED"
+ param_format: str | None = None
+ widget = None
+
+ def __init__(
+ self,
+ label: str | None = None,
+ validators=None,
+ description: str = "",
+ default: str | None = None,
+ widget=None,
+ ):
+ type: str | list[str] = self.param_type
+ enum = {}
+ format = {"format": self.param_format} if self.param_format else {}
+ if validators:
+ if any(isinstance(v, HookMetaService.MockOptional) for v in
validators):
+ type = [self.param_type, "null"]
+ for v in validators:
+ if isinstance(v, HookMetaService.MockEnum):
+ enum = {"enum": v.allowed_values}
+ self.param = Param(
+ default=default,
+ title=label,
+ description=description or None,
+ type=type,
+ **format,
+ **enum,
+ )
+ self.widget = widget
+ self.field_class = self.__class__
+
+ class MockStringField(MockBaseField):
+ """Mock of WTForms StringField."""
+
+ param_type: str = "string"
+
+ class MockIntegerField(MockBaseField):
+ """Mock of WTForms IntegerField."""
+
+ param_type: str = "integer"
+
+ class MockPasswordField(MockBaseField):
+ """Mock of WTForms PasswordField."""
+
+ param_type: str = "string"
+ param_format: str | None = "password"
+
+ class MockBooleanField(MockBaseField):
+ """Mock of WTForms BooleanField."""
+
+ param_type: str = "boolean"
+
+ class MockAnyWidget:
+ """Mock any flask appbuilder widget."""
+
+ @staticmethod
+ def _get_hooks_with_mocked_fab() -> (
+ tuple[MutableMapping[str, HookInfo | None], dict[str,
ConnectionFormWidgetInfo], dict[str, dict]]
+ ):
+ """Get hooks with all details w/o FAB needing to be installed."""
+ from unittest import mock
+
+ from airflow.providers_manager import ProvidersManager
+
+ def mock_lazy_gettext(txt: str) -> str:
+ """Mock for flask_babel.lazy_gettext."""
+ return txt
+
+ def mock_any_of(allowed_values: list) -> HookMetaService.MockEnum:
+ """Mock for wtforms.validators.any_of."""
+ return HookMetaService.MockEnum(allowed_values)
+
+ with (
+ mock.patch("wtforms.StringField", HookMetaService.MockStringField),
+ mock.patch("wtforms.fields.StringField",
HookMetaService.MockStringField),
+ mock.patch("wtforms.fields.simple.StringField",
HookMetaService.MockStringField),
+ mock.patch("wtforms.IntegerField",
HookMetaService.MockIntegerField),
+ mock.patch("wtforms.fields.IntegerField",
HookMetaService.MockIntegerField),
+ mock.patch("wtforms.PasswordField",
HookMetaService.MockPasswordField),
+ mock.patch("wtforms.BooleanField",
HookMetaService.MockBooleanField),
+ mock.patch("wtforms.fields.BooleanField",
HookMetaService.MockBooleanField),
+ mock.patch("wtforms.fields.simple.BooleanField",
HookMetaService.MockBooleanField),
+ mock.patch("flask_babel.lazy_gettext", mock_lazy_gettext),
+ mock.patch("flask_appbuilder.fieldwidgets.BS3TextFieldWidget",
HookMetaService.MockAnyWidget),
+ mock.patch("flask_appbuilder.fieldwidgets.BS3TextAreaFieldWidget",
HookMetaService.MockAnyWidget),
+ mock.patch("flask_appbuilder.fieldwidgets.BS3PasswordFieldWidget",
HookMetaService.MockAnyWidget),
+ mock.patch("wtforms.validators.Optional",
HookMetaService.MockOptional),
+ mock.patch("wtforms.validators.any_of", mock_any_of),
+ ):
+ pm = ProvidersManager()
+ return pm.hooks, pm.connection_form_widgets, pm.field_behaviours
+
+ @staticmethod
+ def _make_standard_fields(field_behaviour: dict | None) ->
StandardHookFields | None:
+ if not field_behaviour:
+ return None
+
+ def make_field(field_name: str, field_behaviour: dict) ->
ConnectionHookFieldBehavior | None:
+ hidden_fields = field_behaviour.get("hidden_fields", [])
+ relabeling = field_behaviour.get("relabeling", {}).get(field_name)
+ placeholder = field_behaviour.get("placeholders",
{}).get(field_name)
+ if any([field_name in hidden_fields, relabeling, placeholder]):
+ return ConnectionHookFieldBehavior(
+ hidden=field_name in hidden_fields,
+ title=relabeling,
+ placeholder=placeholder,
+ )
+ return None
+
+ return StandardHookFields(
+ description=make_field("description", field_behaviour),
+ url_schema=make_field("schema", field_behaviour),
+ host=make_field("host", field_behaviour),
+ port=make_field("port", field_behaviour),
+ login=make_field("login", field_behaviour),
+ password=make_field("password", field_behaviour),
+ )
+
+ @staticmethod
+ def _convert_extra_fields(form_widgets: dict[str,
ConnectionFormWidgetInfo]) -> dict[str, MutableMapping]:
+ result: dict[str, MutableMapping] = {}
+ for key, form_widget in form_widgets.items():
+ hook_key = key.split("__")[1]
+ if isinstance(form_widget.field, HookMetaService.MockBaseField):
+ hook_widgets = result.get(hook_key, {})
+ hook_widgets[form_widget.field_name] =
form_widget.field.param.dump()
+ result[hook_key] = hook_widgets
+ else:
+ log.error("Unknown form widget in %s: %s", hook_key,
form_widget)
+ return result
+
+ @staticmethod
+ @cache
+ def hook_meta_data() -> list[ConnectionHookMetaData]:
+ hooks, connection_form_widgets, field_behaviours =
HookMetaService._get_hooks_with_mocked_fab()
+ result: list[ConnectionHookMetaData] = []
+ widgets =
HookMetaService._convert_extra_fields(connection_form_widgets)
+ for hook_key, hook_info in hooks.items():
+ if not hook_info:
+ continue
+ hook_meta = ConnectionHookMetaData(
+ connection_type=hook_key,
+ hook_class_name=hook_info.hook_class_name,
+ default_conn_name=None, # TODO: later
+ hook_name=hook_info.hook_name,
+
standard_fields=HookMetaService._make_standard_fields(field_behaviours.get(hook_key)),
+ extra_fields=widgets.get(hook_key),
+ )
+ result.append(hook_meta)
+ return result
diff --git a/airflow/ui/openapi-gen/queries/common.ts
b/airflow/ui/openapi-gen/queries/common.ts
index e16aef39170..728d3e8fcda 100644
--- a/airflow/ui/openapi-gen/queries/common.ts
+++ b/airflow/ui/openapi-gen/queries/common.ts
@@ -279,6 +279,59 @@ export const UseConfigServiceGetConfigValueKeyFn = (
},
queryKey?: Array<unknown>,
) => [useConfigServiceGetConfigValueKey, ...(queryKey ?? [{ accept, option,
section }])];
+export type ConnectionServiceHookMetaDataDefaultResponse = Awaited<
+ ReturnType<typeof ConnectionService.hookMetaData>
+>;
+export type ConnectionServiceHookMetaDataQueryResult<
+ TData = ConnectionServiceHookMetaDataDefaultResponse,
+ TError = unknown,
+> = UseQueryResult<TData, TError>;
+export const useConnectionServiceHookMetaDataKey =
"ConnectionServiceHookMetaData";
+export const UseConnectionServiceHookMetaDataKeyFn = (queryKey?:
Array<unknown>) => [
+ useConnectionServiceHookMetaDataKey,
+ ...(queryKey ?? []),
+];
+export type ConnectionServiceGetConnectionDefaultResponse = Awaited<
+ ReturnType<typeof ConnectionService.getConnection>
+>;
+export type ConnectionServiceGetConnectionQueryResult<
+ TData = ConnectionServiceGetConnectionDefaultResponse,
+ TError = unknown,
+> = UseQueryResult<TData, TError>;
+export const useConnectionServiceGetConnectionKey =
"ConnectionServiceGetConnection";
+export const UseConnectionServiceGetConnectionKeyFn = (
+ {
+ connectionId,
+ }: {
+ connectionId: string;
+ },
+ queryKey?: Array<unknown>,
+) => [useConnectionServiceGetConnectionKey, ...(queryKey ?? [{ connectionId
}])];
+export type ConnectionServiceGetConnectionsDefaultResponse = Awaited<
+ ReturnType<typeof ConnectionService.getConnections>
+>;
+export type ConnectionServiceGetConnectionsQueryResult<
+ TData = ConnectionServiceGetConnectionsDefaultResponse,
+ TError = unknown,
+> = UseQueryResult<TData, TError>;
+export const useConnectionServiceGetConnectionsKey =
"ConnectionServiceGetConnections";
+export const UseConnectionServiceGetConnectionsKeyFn = (
+ {
+ connectionIdPattern,
+ limit,
+ offset,
+ orderBy,
+ }: {
+ connectionIdPattern?: string;
+ limit?: number;
+ offset?: number;
+ orderBy?: string;
+ } = {},
+ queryKey?: Array<unknown>,
+) => [
+ useConnectionServiceGetConnectionsKey,
+ ...(queryKey ?? [{ connectionIdPattern, limit, offset, orderBy }]),
+];
export type DagsServiceRecentDagRunsDefaultResponse =
Awaited<ReturnType<typeof DagsService.recentDagRuns>>;
export type DagsServiceRecentDagRunsQueryResult<
TData = DagsServiceRecentDagRunsDefaultResponse,
@@ -515,47 +568,6 @@ export const UseGridServiceGridDataKeyFn = (
},
]),
];
-export type ConnectionServiceGetConnectionDefaultResponse = Awaited<
- ReturnType<typeof ConnectionService.getConnection>
->;
-export type ConnectionServiceGetConnectionQueryResult<
- TData = ConnectionServiceGetConnectionDefaultResponse,
- TError = unknown,
-> = UseQueryResult<TData, TError>;
-export const useConnectionServiceGetConnectionKey =
"ConnectionServiceGetConnection";
-export const UseConnectionServiceGetConnectionKeyFn = (
- {
- connectionId,
- }: {
- connectionId: string;
- },
- queryKey?: Array<unknown>,
-) => [useConnectionServiceGetConnectionKey, ...(queryKey ?? [{ connectionId
}])];
-export type ConnectionServiceGetConnectionsDefaultResponse = Awaited<
- ReturnType<typeof ConnectionService.getConnections>
->;
-export type ConnectionServiceGetConnectionsQueryResult<
- TData = ConnectionServiceGetConnectionsDefaultResponse,
- TError = unknown,
-> = UseQueryResult<TData, TError>;
-export const useConnectionServiceGetConnectionsKey =
"ConnectionServiceGetConnections";
-export const UseConnectionServiceGetConnectionsKeyFn = (
- {
- connectionIdPattern,
- limit,
- offset,
- orderBy,
- }: {
- connectionIdPattern?: string;
- limit?: number;
- offset?: number;
- orderBy?: string;
- } = {},
- queryKey?: Array<unknown>,
-) => [
- useConnectionServiceGetConnectionsKey,
- ...(queryKey ?? [{ connectionIdPattern, limit, offset, orderBy }]),
-];
export type DagRunServiceGetDagRunDefaultResponse = Awaited<ReturnType<typeof
DagRunService.getDagRun>>;
export type DagRunServiceGetDagRunQueryResult<
TData = DagRunServiceGetDagRunDefaultResponse,
@@ -1759,12 +1771,6 @@ export type AssetServiceCreateAssetEventMutationResult =
Awaited<
export type AssetServiceMaterializeAssetMutationResult = Awaited<
ReturnType<typeof AssetService.materializeAsset>
>;
-export type BackfillServiceCreateBackfillMutationResult = Awaited<
- ReturnType<typeof BackfillService.createBackfill>
->;
-export type BackfillServiceCreateBackfillDryRunMutationResult = Awaited<
- ReturnType<typeof BackfillService.createBackfillDryRun>
->;
export type ConnectionServicePostConnectionMutationResult = Awaited<
ReturnType<typeof ConnectionService.postConnection>
>;
@@ -1774,6 +1780,12 @@ export type
ConnectionServiceTestConnectionMutationResult = Awaited<
export type ConnectionServiceCreateDefaultConnectionsMutationResult = Awaited<
ReturnType<typeof ConnectionService.createDefaultConnections>
>;
+export type BackfillServiceCreateBackfillMutationResult = Awaited<
+ ReturnType<typeof BackfillService.createBackfill>
+>;
+export type BackfillServiceCreateBackfillDryRunMutationResult = Awaited<
+ ReturnType<typeof BackfillService.createBackfillDryRun>
+>;
export type DagRunServiceClearDagRunMutationResult = Awaited<ReturnType<typeof
DagRunService.clearDagRun>>;
export type DagRunServiceTriggerDagRunMutationResult = Awaited<
ReturnType<typeof DagRunService.triggerDagRun>
diff --git a/airflow/ui/openapi-gen/queries/prefetch.ts
b/airflow/ui/openapi-gen/queries/prefetch.ts
index 8f50495dbda..ef029329f6b 100644
--- a/airflow/ui/openapi-gen/queries/prefetch.ts
+++ b/airflow/ui/openapi-gen/queries/prefetch.ts
@@ -366,6 +366,66 @@ export const prefetchUseConfigServiceGetConfigValue = (
queryKey: Common.UseConfigServiceGetConfigValueKeyFn({ accept, option,
section }),
queryFn: () => ConfigService.getConfigValue({ accept, option, section }),
});
+/**
+ * Hook Meta Data
+ * Retrieve information about available connection types (hook classes) and
their parameters.
+ * @returns ConnectionHookMetaData Successful Response
+ * @throws ApiError
+ */
+export const prefetchUseConnectionServiceHookMetaData = (queryClient:
QueryClient) =>
+ queryClient.prefetchQuery({
+ queryKey: Common.UseConnectionServiceHookMetaDataKeyFn(),
+ queryFn: () => ConnectionService.hookMetaData(),
+ });
+/**
+ * Get Connection
+ * Get a connection entry.
+ * @param data The data for the request.
+ * @param data.connectionId
+ * @returns ConnectionResponse Successful Response
+ * @throws ApiError
+ */
+export const prefetchUseConnectionServiceGetConnection = (
+ queryClient: QueryClient,
+ {
+ connectionId,
+ }: {
+ connectionId: string;
+ },
+) =>
+ queryClient.prefetchQuery({
+ queryKey: Common.UseConnectionServiceGetConnectionKeyFn({ connectionId }),
+ queryFn: () => ConnectionService.getConnection({ connectionId }),
+ });
+/**
+ * Get Connections
+ * Get all connection entries.
+ * @param data The data for the request.
+ * @param data.limit
+ * @param data.offset
+ * @param data.orderBy
+ * @param data.connectionIdPattern
+ * @returns ConnectionCollectionResponse Successful Response
+ * @throws ApiError
+ */
+export const prefetchUseConnectionServiceGetConnections = (
+ queryClient: QueryClient,
+ {
+ connectionIdPattern,
+ limit,
+ offset,
+ orderBy,
+ }: {
+ connectionIdPattern?: string;
+ limit?: number;
+ offset?: number;
+ orderBy?: string;
+ } = {},
+) =>
+ queryClient.prefetchQuery({
+ queryKey: Common.UseConnectionServiceGetConnectionsKeyFn({
connectionIdPattern, limit, offset, orderBy }),
+ queryFn: () => ConnectionService.getConnections({ connectionIdPattern,
limit, offset, orderBy }),
+ });
/**
* Recent Dag Runs
* Get recent DAG runs.
@@ -702,55 +762,6 @@ export const prefetchUseGridServiceGridData = (
state,
}),
});
-/**
- * Get Connection
- * Get a connection entry.
- * @param data The data for the request.
- * @param data.connectionId
- * @returns ConnectionResponse Successful Response
- * @throws ApiError
- */
-export const prefetchUseConnectionServiceGetConnection = (
- queryClient: QueryClient,
- {
- connectionId,
- }: {
- connectionId: string;
- },
-) =>
- queryClient.prefetchQuery({
- queryKey: Common.UseConnectionServiceGetConnectionKeyFn({ connectionId }),
- queryFn: () => ConnectionService.getConnection({ connectionId }),
- });
-/**
- * Get Connections
- * Get all connection entries.
- * @param data The data for the request.
- * @param data.limit
- * @param data.offset
- * @param data.orderBy
- * @param data.connectionIdPattern
- * @returns ConnectionCollectionResponse Successful Response
- * @throws ApiError
- */
-export const prefetchUseConnectionServiceGetConnections = (
- queryClient: QueryClient,
- {
- connectionIdPattern,
- limit,
- offset,
- orderBy,
- }: {
- connectionIdPattern?: string;
- limit?: number;
- offset?: number;
- orderBy?: string;
- } = {},
-) =>
- queryClient.prefetchQuery({
- queryKey: Common.UseConnectionServiceGetConnectionsKeyFn({
connectionIdPattern, limit, offset, orderBy }),
- queryFn: () => ConnectionService.getConnections({ connectionIdPattern,
limit, offset, orderBy }),
- });
/**
* Get Dag Run
* @param data The data for the request.
diff --git a/airflow/ui/openapi-gen/queries/queries.ts
b/airflow/ui/openapi-gen/queries/queries.ts
index 02b647cdfa1..8aac17090b3 100644
--- a/airflow/ui/openapi-gen/queries/queries.ts
+++ b/airflow/ui/openapi-gen/queries/queries.ts
@@ -463,6 +463,89 @@ export const useConfigServiceGetConfigValue = <
queryFn: () => ConfigService.getConfigValue({ accept, option, section })
as TData,
...options,
});
+/**
+ * Hook Meta Data
+ * Retrieve information about available connection types (hook classes) and
their parameters.
+ * @returns ConnectionHookMetaData Successful Response
+ * @throws ApiError
+ */
+export const useConnectionServiceHookMetaData = <
+ TData = Common.ConnectionServiceHookMetaDataDefaultResponse,
+ TError = unknown,
+ TQueryKey extends Array<unknown> = unknown[],
+>(
+ queryKey?: TQueryKey,
+ options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
+) =>
+ useQuery<TData, TError>({
+ queryKey: Common.UseConnectionServiceHookMetaDataKeyFn(queryKey),
+ queryFn: () => ConnectionService.hookMetaData() as TData,
+ ...options,
+ });
+/**
+ * Get Connection
+ * Get a connection entry.
+ * @param data The data for the request.
+ * @param data.connectionId
+ * @returns ConnectionResponse Successful Response
+ * @throws ApiError
+ */
+export const useConnectionServiceGetConnection = <
+ TData = Common.ConnectionServiceGetConnectionDefaultResponse,
+ TError = unknown,
+ TQueryKey extends Array<unknown> = unknown[],
+>(
+ {
+ connectionId,
+ }: {
+ connectionId: string;
+ },
+ queryKey?: TQueryKey,
+ options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
+) =>
+ useQuery<TData, TError>({
+ queryKey: Common.UseConnectionServiceGetConnectionKeyFn({ connectionId },
queryKey),
+ queryFn: () => ConnectionService.getConnection({ connectionId }) as TData,
+ ...options,
+ });
+/**
+ * Get Connections
+ * Get all connection entries.
+ * @param data The data for the request.
+ * @param data.limit
+ * @param data.offset
+ * @param data.orderBy
+ * @param data.connectionIdPattern
+ * @returns ConnectionCollectionResponse Successful Response
+ * @throws ApiError
+ */
+export const useConnectionServiceGetConnections = <
+ TData = Common.ConnectionServiceGetConnectionsDefaultResponse,
+ TError = unknown,
+ TQueryKey extends Array<unknown> = unknown[],
+>(
+ {
+ connectionIdPattern,
+ limit,
+ offset,
+ orderBy,
+ }: {
+ connectionIdPattern?: string;
+ limit?: number;
+ offset?: number;
+ orderBy?: string;
+ } = {},
+ queryKey?: TQueryKey,
+ options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
+) =>
+ useQuery<TData, TError>({
+ queryKey: Common.UseConnectionServiceGetConnectionsKeyFn(
+ { connectionIdPattern, limit, offset, orderBy },
+ queryKey,
+ ),
+ queryFn: () => ConnectionService.getConnections({ connectionIdPattern,
limit, offset, orderBy }) as TData,
+ ...options,
+ });
/**
* Recent Dag Runs
* Get recent DAG runs.
@@ -852,70 +935,6 @@ export const useGridServiceGridData = <
}) as TData,
...options,
});
-/**
- * Get Connection
- * Get a connection entry.
- * @param data The data for the request.
- * @param data.connectionId
- * @returns ConnectionResponse Successful Response
- * @throws ApiError
- */
-export const useConnectionServiceGetConnection = <
- TData = Common.ConnectionServiceGetConnectionDefaultResponse,
- TError = unknown,
- TQueryKey extends Array<unknown> = unknown[],
->(
- {
- connectionId,
- }: {
- connectionId: string;
- },
- queryKey?: TQueryKey,
- options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
-) =>
- useQuery<TData, TError>({
- queryKey: Common.UseConnectionServiceGetConnectionKeyFn({ connectionId },
queryKey),
- queryFn: () => ConnectionService.getConnection({ connectionId }) as TData,
- ...options,
- });
-/**
- * Get Connections
- * Get all connection entries.
- * @param data The data for the request.
- * @param data.limit
- * @param data.offset
- * @param data.orderBy
- * @param data.connectionIdPattern
- * @returns ConnectionCollectionResponse Successful Response
- * @throws ApiError
- */
-export const useConnectionServiceGetConnections = <
- TData = Common.ConnectionServiceGetConnectionsDefaultResponse,
- TError = unknown,
- TQueryKey extends Array<unknown> = unknown[],
->(
- {
- connectionIdPattern,
- limit,
- offset,
- orderBy,
- }: {
- connectionIdPattern?: string;
- limit?: number;
- offset?: number;
- orderBy?: string;
- } = {},
- queryKey?: TQueryKey,
- options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
-) =>
- useQuery<TData, TError>({
- queryKey: Common.UseConnectionServiceGetConnectionsKeyFn(
- { connectionIdPattern, limit, offset, orderBy },
- queryKey,
- ),
- queryFn: () => ConnectionService.getConnections({ connectionIdPattern,
limit, offset, orderBy }) as TData,
- ...options,
- });
/**
* Get Dag Run
* @param data The data for the request.
@@ -2989,14 +3008,15 @@ export const useAssetServiceMaterializeAsset = <
...options,
});
/**
- * Create Backfill
+ * Post Connection
+ * Create connection entry.
* @param data The data for the request.
* @param data.requestBody
- * @returns BackfillResponse Successful Response
+ * @returns ConnectionResponse Successful Response
* @throws ApiError
*/
-export const useBackfillServiceCreateBackfill = <
- TData = Common.BackfillServiceCreateBackfillMutationResult,
+export const useConnectionServicePostConnection = <
+ TData = Common.ConnectionServicePostConnectionMutationResult,
TError = unknown,
TContext = unknown,
>(
@@ -3005,7 +3025,7 @@ export const useBackfillServiceCreateBackfill = <
TData,
TError,
{
- requestBody: BackfillPostBody;
+ requestBody: ConnectionBody;
},
TContext
>,
@@ -3016,23 +3036,28 @@ export const useBackfillServiceCreateBackfill = <
TData,
TError,
{
- requestBody: BackfillPostBody;
+ requestBody: ConnectionBody;
},
TContext
>({
mutationFn: ({ requestBody }) =>
- BackfillService.createBackfill({ requestBody }) as unknown as
Promise<TData>,
+ ConnectionService.postConnection({ requestBody }) as unknown as
Promise<TData>,
...options,
});
/**
- * Create Backfill Dry Run
+ * Test Connection
+ * Test an API connection.
+ *
+ * This method first creates an in-memory transient conn_id & exports that to
an env var,
+ * as some hook classes tries to find out the `conn` from their __init__
method & errors out if not found.
+ * It also deletes the conn id env connection after the test.
* @param data The data for the request.
* @param data.requestBody
- * @returns DryRunBackfillCollectionResponse Successful Response
+ * @returns ConnectionTestResponse Successful Response
* @throws ApiError
*/
-export const useBackfillServiceCreateBackfillDryRun = <
- TData = Common.BackfillServiceCreateBackfillDryRunMutationResult,
+export const useConnectionServiceTestConnection = <
+ TData = Common.ConnectionServiceTestConnectionMutationResult,
TError = unknown,
TContext = unknown,
>(
@@ -3041,7 +3066,7 @@ export const useBackfillServiceCreateBackfillDryRun = <
TData,
TError,
{
- requestBody: BackfillPostBody;
+ requestBody: ConnectionBody;
},
TContext
>,
@@ -3052,24 +3077,40 @@ export const useBackfillServiceCreateBackfillDryRun = <
TData,
TError,
{
- requestBody: BackfillPostBody;
+ requestBody: ConnectionBody;
},
TContext
>({
mutationFn: ({ requestBody }) =>
- BackfillService.createBackfillDryRun({ requestBody }) as unknown as
Promise<TData>,
+ ConnectionService.testConnection({ requestBody }) as unknown as
Promise<TData>,
...options,
});
/**
- * Post Connection
- * Create connection entry.
+ * Create Default Connections
+ * Create default connections.
+ * @returns void Successful Response
+ * @throws ApiError
+ */
+export const useConnectionServiceCreateDefaultConnections = <
+ TData = Common.ConnectionServiceCreateDefaultConnectionsMutationResult,
+ TError = unknown,
+ TContext = unknown,
+>(
+ options?: Omit<UseMutationOptions<TData, TError, void, TContext>,
"mutationFn">,
+) =>
+ useMutation<TData, TError, void, TContext>({
+ mutationFn: () => ConnectionService.createDefaultConnections() as unknown
as Promise<TData>,
+ ...options,
+ });
+/**
+ * Create Backfill
* @param data The data for the request.
* @param data.requestBody
- * @returns ConnectionResponse Successful Response
+ * @returns BackfillResponse Successful Response
* @throws ApiError
*/
-export const useConnectionServicePostConnection = <
- TData = Common.ConnectionServicePostConnectionMutationResult,
+export const useBackfillServiceCreateBackfill = <
+ TData = Common.BackfillServiceCreateBackfillMutationResult,
TError = unknown,
TContext = unknown,
>(
@@ -3078,7 +3119,7 @@ export const useConnectionServicePostConnection = <
TData,
TError,
{
- requestBody: ConnectionBody;
+ requestBody: BackfillPostBody;
},
TContext
>,
@@ -3089,28 +3130,23 @@ export const useConnectionServicePostConnection = <
TData,
TError,
{
- requestBody: ConnectionBody;
+ requestBody: BackfillPostBody;
},
TContext
>({
mutationFn: ({ requestBody }) =>
- ConnectionService.postConnection({ requestBody }) as unknown as
Promise<TData>,
+ BackfillService.createBackfill({ requestBody }) as unknown as
Promise<TData>,
...options,
});
/**
- * Test Connection
- * Test an API connection.
- *
- * This method first creates an in-memory transient conn_id & exports that to
an env var,
- * as some hook classes tries to find out the `conn` from their __init__
method & errors out if not found.
- * It also deletes the conn id env connection after the test.
+ * Create Backfill Dry Run
* @param data The data for the request.
* @param data.requestBody
- * @returns ConnectionTestResponse Successful Response
+ * @returns DryRunBackfillCollectionResponse Successful Response
* @throws ApiError
*/
-export const useConnectionServiceTestConnection = <
- TData = Common.ConnectionServiceTestConnectionMutationResult,
+export const useBackfillServiceCreateBackfillDryRun = <
+ TData = Common.BackfillServiceCreateBackfillDryRunMutationResult,
TError = unknown,
TContext = unknown,
>(
@@ -3119,7 +3155,7 @@ export const useConnectionServiceTestConnection = <
TData,
TError,
{
- requestBody: ConnectionBody;
+ requestBody: BackfillPostBody;
},
TContext
>,
@@ -3130,29 +3166,12 @@ export const useConnectionServiceTestConnection = <
TData,
TError,
{
- requestBody: ConnectionBody;
+ requestBody: BackfillPostBody;
},
TContext
>({
mutationFn: ({ requestBody }) =>
- ConnectionService.testConnection({ requestBody }) as unknown as
Promise<TData>,
- ...options,
- });
-/**
- * Create Default Connections
- * Create default connections.
- * @returns void Successful Response
- * @throws ApiError
- */
-export const useConnectionServiceCreateDefaultConnections = <
- TData = Common.ConnectionServiceCreateDefaultConnectionsMutationResult,
- TError = unknown,
- TContext = unknown,
->(
- options?: Omit<UseMutationOptions<TData, TError, void, TContext>,
"mutationFn">,
-) =>
- useMutation<TData, TError, void, TContext>({
- mutationFn: () => ConnectionService.createDefaultConnections() as unknown
as Promise<TData>,
+ BackfillService.createBackfillDryRun({ requestBody }) as unknown as
Promise<TData>,
...options,
});
/**
diff --git a/airflow/ui/openapi-gen/queries/suspense.ts
b/airflow/ui/openapi-gen/queries/suspense.ts
index dd2c5fe4fcc..3e5ff4194bc 100644
--- a/airflow/ui/openapi-gen/queries/suspense.ts
+++ b/airflow/ui/openapi-gen/queries/suspense.ts
@@ -440,6 +440,89 @@ export const useConfigServiceGetConfigValueSuspense = <
queryFn: () => ConfigService.getConfigValue({ accept, option, section })
as TData,
...options,
});
+/**
+ * Hook Meta Data
+ * Retrieve information about available connection types (hook classes) and
their parameters.
+ * @returns ConnectionHookMetaData Successful Response
+ * @throws ApiError
+ */
+export const useConnectionServiceHookMetaDataSuspense = <
+ TData = Common.ConnectionServiceHookMetaDataDefaultResponse,
+ TError = unknown,
+ TQueryKey extends Array<unknown> = unknown[],
+>(
+ queryKey?: TQueryKey,
+ options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
+) =>
+ useSuspenseQuery<TData, TError>({
+ queryKey: Common.UseConnectionServiceHookMetaDataKeyFn(queryKey),
+ queryFn: () => ConnectionService.hookMetaData() as TData,
+ ...options,
+ });
+/**
+ * Get Connection
+ * Get a connection entry.
+ * @param data The data for the request.
+ * @param data.connectionId
+ * @returns ConnectionResponse Successful Response
+ * @throws ApiError
+ */
+export const useConnectionServiceGetConnectionSuspense = <
+ TData = Common.ConnectionServiceGetConnectionDefaultResponse,
+ TError = unknown,
+ TQueryKey extends Array<unknown> = unknown[],
+>(
+ {
+ connectionId,
+ }: {
+ connectionId: string;
+ },
+ queryKey?: TQueryKey,
+ options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
+) =>
+ useSuspenseQuery<TData, TError>({
+ queryKey: Common.UseConnectionServiceGetConnectionKeyFn({ connectionId },
queryKey),
+ queryFn: () => ConnectionService.getConnection({ connectionId }) as TData,
+ ...options,
+ });
+/**
+ * Get Connections
+ * Get all connection entries.
+ * @param data The data for the request.
+ * @param data.limit
+ * @param data.offset
+ * @param data.orderBy
+ * @param data.connectionIdPattern
+ * @returns ConnectionCollectionResponse Successful Response
+ * @throws ApiError
+ */
+export const useConnectionServiceGetConnectionsSuspense = <
+ TData = Common.ConnectionServiceGetConnectionsDefaultResponse,
+ TError = unknown,
+ TQueryKey extends Array<unknown> = unknown[],
+>(
+ {
+ connectionIdPattern,
+ limit,
+ offset,
+ orderBy,
+ }: {
+ connectionIdPattern?: string;
+ limit?: number;
+ offset?: number;
+ orderBy?: string;
+ } = {},
+ queryKey?: TQueryKey,
+ options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
+) =>
+ useSuspenseQuery<TData, TError>({
+ queryKey: Common.UseConnectionServiceGetConnectionsKeyFn(
+ { connectionIdPattern, limit, offset, orderBy },
+ queryKey,
+ ),
+ queryFn: () => ConnectionService.getConnections({ connectionIdPattern,
limit, offset, orderBy }) as TData,
+ ...options,
+ });
/**
* Recent Dag Runs
* Get recent DAG runs.
@@ -829,70 +912,6 @@ export const useGridServiceGridDataSuspense = <
}) as TData,
...options,
});
-/**
- * Get Connection
- * Get a connection entry.
- * @param data The data for the request.
- * @param data.connectionId
- * @returns ConnectionResponse Successful Response
- * @throws ApiError
- */
-export const useConnectionServiceGetConnectionSuspense = <
- TData = Common.ConnectionServiceGetConnectionDefaultResponse,
- TError = unknown,
- TQueryKey extends Array<unknown> = unknown[],
->(
- {
- connectionId,
- }: {
- connectionId: string;
- },
- queryKey?: TQueryKey,
- options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
-) =>
- useSuspenseQuery<TData, TError>({
- queryKey: Common.UseConnectionServiceGetConnectionKeyFn({ connectionId },
queryKey),
- queryFn: () => ConnectionService.getConnection({ connectionId }) as TData,
- ...options,
- });
-/**
- * Get Connections
- * Get all connection entries.
- * @param data The data for the request.
- * @param data.limit
- * @param data.offset
- * @param data.orderBy
- * @param data.connectionIdPattern
- * @returns ConnectionCollectionResponse Successful Response
- * @throws ApiError
- */
-export const useConnectionServiceGetConnectionsSuspense = <
- TData = Common.ConnectionServiceGetConnectionsDefaultResponse,
- TError = unknown,
- TQueryKey extends Array<unknown> = unknown[],
->(
- {
- connectionIdPattern,
- limit,
- offset,
- orderBy,
- }: {
- connectionIdPattern?: string;
- limit?: number;
- offset?: number;
- orderBy?: string;
- } = {},
- queryKey?: TQueryKey,
- options?: Omit<UseQueryOptions<TData, TError>, "queryKey" | "queryFn">,
-) =>
- useSuspenseQuery<TData, TError>({
- queryKey: Common.UseConnectionServiceGetConnectionsKeyFn(
- { connectionIdPattern, limit, offset, orderBy },
- queryKey,
- ),
- queryFn: () => ConnectionService.getConnections({ connectionIdPattern,
limit, offset, orderBy }) as TData,
- ...options,
- });
/**
* Get Dag Run
* @param data The data for the request.
diff --git a/airflow/ui/openapi-gen/requests/schemas.gen.ts
b/airflow/ui/openapi-gen/requests/schemas.gen.ts
index 6756181f8f8..acaf4580c32 100644
--- a/airflow/ui/openapi-gen/requests/schemas.gen.ts
+++ b/airflow/ui/openapi-gen/requests/schemas.gen.ts
@@ -1388,6 +1388,122 @@ export const $ConnectionCollectionResponse = {
description: "Connection Collection serializer for responses.",
} as const;
+export const $ConnectionHookFieldBehavior = {
+ properties: {
+ hidden: {
+ type: "boolean",
+ title: "Hidden",
+ description: "Flag if the form field should be hidden.",
+ default: false,
+ },
+ title: {
+ anyOf: [
+ {
+ type: "string",
+ },
+ {
+ type: "null",
+ },
+ ],
+ title: "Title",
+ description:
+ "Label / title for the field that should be displayed, if re-labelling
is needed. Use `None` to display standard title.",
+ },
+ placeholder: {
+ anyOf: [
+ {
+ type: "string",
+ },
+ {
+ type: "null",
+ },
+ ],
+ title: "Placeholder",
+ description: "Placeholder text that should be populated to the form.",
+ },
+ },
+ type: "object",
+ title: "ConnectionHookFieldBehavior",
+ description: "A class to store the behavior of each standard field of a
Hook.",
+} as const;
+
+export const $ConnectionHookMetaData = {
+ properties: {
+ connection_type: {
+ anyOf: [
+ {
+ type: "string",
+ },
+ {
+ type: "null",
+ },
+ ],
+ title: "Connection Type",
+ },
+ hook_class_name: {
+ anyOf: [
+ {
+ type: "string",
+ },
+ {
+ type: "null",
+ },
+ ],
+ title: "Hook Class Name",
+ },
+ default_conn_name: {
+ anyOf: [
+ {
+ type: "string",
+ },
+ {
+ type: "null",
+ },
+ ],
+ title: "Default Conn Name",
+ },
+ hook_name: {
+ type: "string",
+ title: "Hook Name",
+ },
+ standard_fields: {
+ anyOf: [
+ {
+ $ref: "#/components/schemas/StandardHookFields",
+ },
+ {
+ type: "null",
+ },
+ ],
+ },
+ extra_fields: {
+ anyOf: [
+ {
+ type: "object",
+ },
+ {
+ type: "null",
+ },
+ ],
+ title: "Extra Fields",
+ },
+ },
+ type: "object",
+ required: [
+ "connection_type",
+ "hook_class_name",
+ "default_conn_name",
+ "hook_name",
+ "standard_fields",
+ "extra_fields",
+ ],
+ title: "ConnectionHookMetaData",
+ description: `Response model for Hook information == Connection type meta
data.
+
+It is used to transfer providers information loaded by providers_manager such
that
+the API server/Web UI can use this data to render connection form UI.`,
+} as const;
+
export const $ConnectionResponse = {
properties: {
connection_id: {
@@ -4588,6 +4704,75 @@ export const $SchedulerInfoResponse = {
description: "Scheduler info serializer for responses.",
} as const;
+export const $StandardHookFields = {
+ properties: {
+ description: {
+ anyOf: [
+ {
+ $ref: "#/components/schemas/ConnectionHookFieldBehavior",
+ },
+ {
+ type: "null",
+ },
+ ],
+ },
+ url_schema: {
+ anyOf: [
+ {
+ $ref: "#/components/schemas/ConnectionHookFieldBehavior",
+ },
+ {
+ type: "null",
+ },
+ ],
+ },
+ host: {
+ anyOf: [
+ {
+ $ref: "#/components/schemas/ConnectionHookFieldBehavior",
+ },
+ {
+ type: "null",
+ },
+ ],
+ },
+ port: {
+ anyOf: [
+ {
+ $ref: "#/components/schemas/ConnectionHookFieldBehavior",
+ },
+ {
+ type: "null",
+ },
+ ],
+ },
+ login: {
+ anyOf: [
+ {
+ $ref: "#/components/schemas/ConnectionHookFieldBehavior",
+ },
+ {
+ type: "null",
+ },
+ ],
+ },
+ password: {
+ anyOf: [
+ {
+ $ref: "#/components/schemas/ConnectionHookFieldBehavior",
+ },
+ {
+ type: "null",
+ },
+ ],
+ },
+ },
+ type: "object",
+ required: ["description", "url_schema", "host", "port", "login", "password"],
+ title: "StandardHookFields",
+ description: "Standard fields of a Hook that a form will render.",
+} as const;
+
export const $StructureDataResponse = {
properties: {
edges: {
diff --git a/airflow/ui/openapi-gen/requests/services.gen.ts
b/airflow/ui/openapi-gen/requests/services.gen.ts
index 11b54997040..ef8a2d833af 100644
--- a/airflow/ui/openapi-gen/requests/services.gen.ts
+++ b/airflow/ui/openapi-gen/requests/services.gen.ts
@@ -36,6 +36,22 @@ import type {
GetConfigResponse,
GetConfigValueData,
GetConfigValueResponse,
+ HookMetaDataResponse,
+ DeleteConnectionData,
+ DeleteConnectionResponse,
+ GetConnectionData,
+ GetConnectionResponse,
+ PatchConnectionData,
+ PatchConnectionResponse,
+ GetConnectionsData,
+ GetConnectionsResponse,
+ PostConnectionData,
+ PostConnectionResponse,
+ BulkConnectionsData,
+ BulkConnectionsResponse,
+ TestConnectionData,
+ TestConnectionResponse,
+ CreateDefaultConnectionsResponse,
RecentDagRunsData,
RecentDagRunsResponse,
GetDependenciesData,
@@ -62,21 +78,6 @@ import type {
CreateBackfillDryRunResponse,
GridDataData,
GridDataResponse,
- DeleteConnectionData,
- DeleteConnectionResponse,
- GetConnectionData,
- GetConnectionResponse,
- PatchConnectionData,
- PatchConnectionResponse,
- GetConnectionsData,
- GetConnectionsResponse,
- PostConnectionData,
- PostConnectionResponse,
- BulkConnectionsData,
- BulkConnectionsResponse,
- TestConnectionData,
- TestConnectionResponse,
- CreateDefaultConnectionsResponse,
GetDagRunData,
GetDagRunResponse,
DeleteDagRunData,
@@ -698,6 +699,219 @@ export class ConfigService {
}
}
+export class ConnectionService {
+ /**
+ * Hook Meta Data
+ * Retrieve information about available connection types (hook classes) and
their parameters.
+ * @returns ConnectionHookMetaData Successful Response
+ * @throws ApiError
+ */
+ public static hookMetaData(): CancelablePromise<HookMetaDataResponse> {
+ return __request(OpenAPI, {
+ method: "GET",
+ url: "/ui/connections/hook_meta",
+ });
+ }
+
+ /**
+ * Delete Connection
+ * Delete a connection entry.
+ * @param data The data for the request.
+ * @param data.connectionId
+ * @returns void Successful Response
+ * @throws ApiError
+ */
+ public static deleteConnection(data: DeleteConnectionData):
CancelablePromise<DeleteConnectionResponse> {
+ return __request(OpenAPI, {
+ method: "DELETE",
+ url: "/public/connections/{connection_id}",
+ path: {
+ connection_id: data.connectionId,
+ },
+ errors: {
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ 404: "Not Found",
+ 422: "Validation Error",
+ },
+ });
+ }
+
+ /**
+ * Get Connection
+ * Get a connection entry.
+ * @param data The data for the request.
+ * @param data.connectionId
+ * @returns ConnectionResponse Successful Response
+ * @throws ApiError
+ */
+ public static getConnection(data: GetConnectionData):
CancelablePromise<GetConnectionResponse> {
+ return __request(OpenAPI, {
+ method: "GET",
+ url: "/public/connections/{connection_id}",
+ path: {
+ connection_id: data.connectionId,
+ },
+ errors: {
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ 404: "Not Found",
+ 422: "Validation Error",
+ },
+ });
+ }
+
+ /**
+ * Patch Connection
+ * Update a connection entry.
+ * @param data The data for the request.
+ * @param data.connectionId
+ * @param data.requestBody
+ * @param data.updateMask
+ * @returns ConnectionResponse Successful Response
+ * @throws ApiError
+ */
+ public static patchConnection(data: PatchConnectionData):
CancelablePromise<PatchConnectionResponse> {
+ return __request(OpenAPI, {
+ method: "PATCH",
+ url: "/public/connections/{connection_id}",
+ path: {
+ connection_id: data.connectionId,
+ },
+ query: {
+ update_mask: data.updateMask,
+ },
+ body: data.requestBody,
+ mediaType: "application/json",
+ errors: {
+ 400: "Bad Request",
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ 404: "Not Found",
+ 422: "Validation Error",
+ },
+ });
+ }
+
+ /**
+ * Get Connections
+ * Get all connection entries.
+ * @param data The data for the request.
+ * @param data.limit
+ * @param data.offset
+ * @param data.orderBy
+ * @param data.connectionIdPattern
+ * @returns ConnectionCollectionResponse Successful Response
+ * @throws ApiError
+ */
+ public static getConnections(data: GetConnectionsData = {}):
CancelablePromise<GetConnectionsResponse> {
+ return __request(OpenAPI, {
+ method: "GET",
+ url: "/public/connections",
+ query: {
+ limit: data.limit,
+ offset: data.offset,
+ order_by: data.orderBy,
+ connection_id_pattern: data.connectionIdPattern,
+ },
+ errors: {
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ 404: "Not Found",
+ 422: "Validation Error",
+ },
+ });
+ }
+
+ /**
+ * Post Connection
+ * Create connection entry.
+ * @param data The data for the request.
+ * @param data.requestBody
+ * @returns ConnectionResponse Successful Response
+ * @throws ApiError
+ */
+ public static postConnection(data: PostConnectionData):
CancelablePromise<PostConnectionResponse> {
+ return __request(OpenAPI, {
+ method: "POST",
+ url: "/public/connections",
+ body: data.requestBody,
+ mediaType: "application/json",
+ errors: {
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ 409: "Conflict",
+ 422: "Validation Error",
+ },
+ });
+ }
+
+ /**
+ * Bulk Connections
+ * Bulk create, update, and delete connections.
+ * @param data The data for the request.
+ * @param data.requestBody
+ * @returns BulkResponse Successful Response
+ * @throws ApiError
+ */
+ public static bulkConnections(data: BulkConnectionsData):
CancelablePromise<BulkConnectionsResponse> {
+ return __request(OpenAPI, {
+ method: "PATCH",
+ url: "/public/connections",
+ body: data.requestBody,
+ mediaType: "application/json",
+ errors: {
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ 422: "Validation Error",
+ },
+ });
+ }
+
+ /**
+ * Test Connection
+ * Test an API connection.
+ *
+ * This method first creates an in-memory transient conn_id & exports that
to an env var,
+ * as some hook classes tries to find out the `conn` from their __init__
method & errors out if not found.
+ * It also deletes the conn id env connection after the test.
+ * @param data The data for the request.
+ * @param data.requestBody
+ * @returns ConnectionTestResponse Successful Response
+ * @throws ApiError
+ */
+ public static testConnection(data: TestConnectionData):
CancelablePromise<TestConnectionResponse> {
+ return __request(OpenAPI, {
+ method: "POST",
+ url: "/public/connections/test",
+ body: data.requestBody,
+ mediaType: "application/json",
+ errors: {
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ 422: "Validation Error",
+ },
+ });
+ }
+
+ /**
+ * Create Default Connections
+ * Create default connections.
+ * @returns void Successful Response
+ * @throws ApiError
+ */
+ public static createDefaultConnections():
CancelablePromise<CreateDefaultConnectionsResponse> {
+ return __request(OpenAPI, {
+ method: "POST",
+ url: "/public/connections/defaults",
+ errors: {
+ 401: "Unauthorized",
+ 403: "Forbidden",
+ },
+ });
+ }
+}
+
export class DagsService {
/**
* Recent Dag Runs
@@ -1080,206 +1294,6 @@ export class GridService {
}
}
-export class ConnectionService {
- /**
- * Delete Connection
- * Delete a connection entry.
- * @param data The data for the request.
- * @param data.connectionId
- * @returns void Successful Response
- * @throws ApiError
- */
- public static deleteConnection(data: DeleteConnectionData):
CancelablePromise<DeleteConnectionResponse> {
- return __request(OpenAPI, {
- method: "DELETE",
- url: "/public/connections/{connection_id}",
- path: {
- connection_id: data.connectionId,
- },
- errors: {
- 401: "Unauthorized",
- 403: "Forbidden",
- 404: "Not Found",
- 422: "Validation Error",
- },
- });
- }
-
- /**
- * Get Connection
- * Get a connection entry.
- * @param data The data for the request.
- * @param data.connectionId
- * @returns ConnectionResponse Successful Response
- * @throws ApiError
- */
- public static getConnection(data: GetConnectionData):
CancelablePromise<GetConnectionResponse> {
- return __request(OpenAPI, {
- method: "GET",
- url: "/public/connections/{connection_id}",
- path: {
- connection_id: data.connectionId,
- },
- errors: {
- 401: "Unauthorized",
- 403: "Forbidden",
- 404: "Not Found",
- 422: "Validation Error",
- },
- });
- }
-
- /**
- * Patch Connection
- * Update a connection entry.
- * @param data The data for the request.
- * @param data.connectionId
- * @param data.requestBody
- * @param data.updateMask
- * @returns ConnectionResponse Successful Response
- * @throws ApiError
- */
- public static patchConnection(data: PatchConnectionData):
CancelablePromise<PatchConnectionResponse> {
- return __request(OpenAPI, {
- method: "PATCH",
- url: "/public/connections/{connection_id}",
- path: {
- connection_id: data.connectionId,
- },
- query: {
- update_mask: data.updateMask,
- },
- body: data.requestBody,
- mediaType: "application/json",
- errors: {
- 400: "Bad Request",
- 401: "Unauthorized",
- 403: "Forbidden",
- 404: "Not Found",
- 422: "Validation Error",
- },
- });
- }
-
- /**
- * Get Connections
- * Get all connection entries.
- * @param data The data for the request.
- * @param data.limit
- * @param data.offset
- * @param data.orderBy
- * @param data.connectionIdPattern
- * @returns ConnectionCollectionResponse Successful Response
- * @throws ApiError
- */
- public static getConnections(data: GetConnectionsData = {}):
CancelablePromise<GetConnectionsResponse> {
- return __request(OpenAPI, {
- method: "GET",
- url: "/public/connections",
- query: {
- limit: data.limit,
- offset: data.offset,
- order_by: data.orderBy,
- connection_id_pattern: data.connectionIdPattern,
- },
- errors: {
- 401: "Unauthorized",
- 403: "Forbidden",
- 404: "Not Found",
- 422: "Validation Error",
- },
- });
- }
-
- /**
- * Post Connection
- * Create connection entry.
- * @param data The data for the request.
- * @param data.requestBody
- * @returns ConnectionResponse Successful Response
- * @throws ApiError
- */
- public static postConnection(data: PostConnectionData):
CancelablePromise<PostConnectionResponse> {
- return __request(OpenAPI, {
- method: "POST",
- url: "/public/connections",
- body: data.requestBody,
- mediaType: "application/json",
- errors: {
- 401: "Unauthorized",
- 403: "Forbidden",
- 409: "Conflict",
- 422: "Validation Error",
- },
- });
- }
-
- /**
- * Bulk Connections
- * Bulk create, update, and delete connections.
- * @param data The data for the request.
- * @param data.requestBody
- * @returns BulkResponse Successful Response
- * @throws ApiError
- */
- public static bulkConnections(data: BulkConnectionsData):
CancelablePromise<BulkConnectionsResponse> {
- return __request(OpenAPI, {
- method: "PATCH",
- url: "/public/connections",
- body: data.requestBody,
- mediaType: "application/json",
- errors: {
- 401: "Unauthorized",
- 403: "Forbidden",
- 422: "Validation Error",
- },
- });
- }
-
- /**
- * Test Connection
- * Test an API connection.
- *
- * This method first creates an in-memory transient conn_id & exports that
to an env var,
- * as some hook classes tries to find out the `conn` from their __init__
method & errors out if not found.
- * It also deletes the conn id env connection after the test.
- * @param data The data for the request.
- * @param data.requestBody
- * @returns ConnectionTestResponse Successful Response
- * @throws ApiError
- */
- public static testConnection(data: TestConnectionData):
CancelablePromise<TestConnectionResponse> {
- return __request(OpenAPI, {
- method: "POST",
- url: "/public/connections/test",
- body: data.requestBody,
- mediaType: "application/json",
- errors: {
- 401: "Unauthorized",
- 403: "Forbidden",
- 422: "Validation Error",
- },
- });
- }
-
- /**
- * Create Default Connections
- * Create default connections.
- * @returns void Successful Response
- * @throws ApiError
- */
- public static createDefaultConnections():
CancelablePromise<CreateDefaultConnectionsResponse> {
- return __request(OpenAPI, {
- method: "POST",
- url: "/public/connections/defaults",
- errors: {
- 401: "Unauthorized",
- 403: "Forbidden",
- },
- });
- }
-}
-
export class DagRunService {
/**
* Get Dag Run
diff --git a/airflow/ui/openapi-gen/requests/types.gen.ts
b/airflow/ui/openapi-gen/requests/types.gen.ts
index 1ed2a13c959..ce1b31a13ea 100644
--- a/airflow/ui/openapi-gen/requests/types.gen.ts
+++ b/airflow/ui/openapi-gen/requests/types.gen.ts
@@ -448,6 +448,41 @@ export type ConnectionCollectionResponse = {
total_entries: number;
};
+/**
+ * A class to store the behavior of each standard field of a Hook.
+ */
+export type ConnectionHookFieldBehavior = {
+ /**
+ * Flag if the form field should be hidden.
+ */
+ hidden?: boolean;
+ /**
+ * Label / title for the field that should be displayed, if re-labelling is
needed. Use `None` to display standard title.
+ */
+ title?: string | null;
+ /**
+ * Placeholder text that should be populated to the form.
+ */
+ placeholder?: string | null;
+};
+
+/**
+ * Response model for Hook information == Connection type meta data.
+ *
+ * It is used to transfer providers information loaded by providers_manager
such that
+ * the API server/Web UI can use this data to render connection form UI.
+ */
+export type ConnectionHookMetaData = {
+ connection_type: string | null;
+ hook_class_name: string | null;
+ default_conn_name: string | null;
+ hook_name: string;
+ standard_fields: StandardHookFields | null;
+ extra_fields: {
+ [key: string]: unknown;
+ } | null;
+};
+
/**
* Connection serializer for responses.
*/
@@ -1204,6 +1239,18 @@ export type SchedulerInfoResponse = {
latest_scheduler_heartbeat: string | null;
};
+/**
+ * Standard fields of a Hook that a form will render.
+ */
+export type StandardHookFields = {
+ description: ConnectionHookFieldBehavior | null;
+ url_schema: ConnectionHookFieldBehavior | null;
+ host: ConnectionHookFieldBehavior | null;
+ port: ConnectionHookFieldBehavior | null;
+ login: ConnectionHookFieldBehavior | null;
+ password: ConnectionHookFieldBehavior | null;
+};
+
/**
* Structure Data serializer for responses.
*/
@@ -1734,6 +1781,57 @@ export type GetConfigValueData = {
export type GetConfigValueResponse = Config;
+export type HookMetaDataResponse = Array<ConnectionHookMetaData>;
+
+export type DeleteConnectionData = {
+ connectionId: string;
+};
+
+export type DeleteConnectionResponse = void;
+
+export type GetConnectionData = {
+ connectionId: string;
+};
+
+export type GetConnectionResponse = ConnectionResponse;
+
+export type PatchConnectionData = {
+ connectionId: string;
+ requestBody: ConnectionBody;
+ updateMask?: Array<string> | null;
+};
+
+export type PatchConnectionResponse = ConnectionResponse;
+
+export type GetConnectionsData = {
+ connectionIdPattern?: string | null;
+ limit?: number;
+ offset?: number;
+ orderBy?: string;
+};
+
+export type GetConnectionsResponse = ConnectionCollectionResponse;
+
+export type PostConnectionData = {
+ requestBody: ConnectionBody;
+};
+
+export type PostConnectionResponse = ConnectionResponse;
+
+export type BulkConnectionsData = {
+ requestBody: BulkBody_ConnectionBody_;
+};
+
+export type BulkConnectionsResponse = BulkResponse;
+
+export type TestConnectionData = {
+ requestBody: ConnectionBody;
+};
+
+export type TestConnectionResponse = ConnectionTestResponse;
+
+export type CreateDefaultConnectionsResponse = void;
+
export type RecentDagRunsData = {
dagDisplayNamePattern?: string | null;
dagIdPattern?: string | null;
@@ -1848,55 +1946,6 @@ export type GridDataData = {
export type GridDataResponse = GridResponse;
-export type DeleteConnectionData = {
- connectionId: string;
-};
-
-export type DeleteConnectionResponse = void;
-
-export type GetConnectionData = {
- connectionId: string;
-};
-
-export type GetConnectionResponse = ConnectionResponse;
-
-export type PatchConnectionData = {
- connectionId: string;
- requestBody: ConnectionBody;
- updateMask?: Array<string> | null;
-};
-
-export type PatchConnectionResponse = ConnectionResponse;
-
-export type GetConnectionsData = {
- connectionIdPattern?: string | null;
- limit?: number;
- offset?: number;
- orderBy?: string;
-};
-
-export type GetConnectionsResponse = ConnectionCollectionResponse;
-
-export type PostConnectionData = {
- requestBody: ConnectionBody;
-};
-
-export type PostConnectionResponse = ConnectionResponse;
-
-export type BulkConnectionsData = {
- requestBody: BulkBody_ConnectionBody_;
-};
-
-export type BulkConnectionsResponse = BulkResponse;
-
-export type TestConnectionData = {
- requestBody: ConnectionBody;
-};
-
-export type TestConnectionResponse = ConnectionTestResponse;
-
-export type CreateDefaultConnectionsResponse = void;
-
export type GetDagRunData = {
dagId: string;
dagRunId: string;
@@ -2975,29 +3024,32 @@ export type $OpenApiTs = {
};
};
};
- "/ui/dags/recent_dag_runs": {
+ "/ui/connections/hook_meta": {
get: {
- req: RecentDagRunsData;
res: {
/**
* Successful Response
*/
- 200: DAGWithLatestDagRunsCollectionResponse;
- /**
- * Validation Error
- */
- 422: HTTPValidationError;
+ 200: Array<ConnectionHookMetaData>;
};
};
};
- "/ui/dependencies": {
- get: {
- req: GetDependenciesData;
+ "/public/connections/{connection_id}": {
+ delete: {
+ req: DeleteConnectionData;
res: {
/**
* Successful Response
*/
- 200: BaseGraphResponse;
+ 204: void;
+ /**
+ * Unauthorized
+ */
+ 401: HTTPExceptionResponse;
+ /**
+ * Forbidden
+ */
+ 403: HTTPExceptionResponse;
/**
* Not Found
*/
@@ -3008,34 +3060,21 @@ export type $OpenApiTs = {
422: HTTPValidationError;
};
};
- };
- "/ui/dashboard/historical_metrics_data": {
get: {
- req: HistoricalMetricsData;
+ req: GetConnectionData;
res: {
/**
* Successful Response
*/
- 200: HistoricalMetricDataResponse;
- /**
- * Bad Request
- */
- 400: HTTPExceptionResponse;
+ 200: ConnectionResponse;
/**
- * Validation Error
+ * Unauthorized
*/
- 422: HTTPValidationError;
- };
- };
- };
- "/ui/structure/structure_data": {
- get: {
- req: StructureDataData;
- res: {
+ 401: HTTPExceptionResponse;
/**
- * Successful Response
+ * Forbidden
*/
- 200: StructureDataResponse;
+ 403: HTTPExceptionResponse;
/**
* Not Found
*/
@@ -3046,15 +3085,25 @@ export type $OpenApiTs = {
422: HTTPValidationError;
};
};
- };
- "/ui/backfills": {
- get: {
- req: ListBackfillsData;
+ patch: {
+ req: PatchConnectionData;
res: {
/**
* Successful Response
*/
- 200: BackfillCollectionResponse;
+ 200: ConnectionResponse;
+ /**
+ * Bad Request
+ */
+ 400: HTTPExceptionResponse;
+ /**
+ * Unauthorized
+ */
+ 401: HTTPExceptionResponse;
+ /**
+ * Forbidden
+ */
+ 403: HTTPExceptionResponse;
/**
* Not Found
*/
@@ -3066,14 +3115,14 @@ export type $OpenApiTs = {
};
};
};
- "/public/backfills": {
+ "/public/connections": {
get: {
- req: ListBackfills1Data;
+ req: GetConnectionsData;
res: {
/**
* Successful Response
*/
- 200: BackfillCollectionResponse;
+ 200: ConnectionCollectionResponse;
/**
* Unauthorized
*/
@@ -3082,6 +3131,10 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
+ /**
+ * Not Found
+ */
+ 404: HTTPExceptionResponse;
/**
* Validation Error
*/
@@ -3089,12 +3142,12 @@ export type $OpenApiTs = {
};
};
post: {
- req: CreateBackfillData;
+ req: PostConnectionData;
res: {
/**
* Successful Response
*/
- 200: BackfillResponse;
+ 201: ConnectionResponse;
/**
* Unauthorized
*/
@@ -3103,10 +3156,6 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
- /**
- * Not Found
- */
- 404: HTTPExceptionResponse;
/**
* Conflict
*/
@@ -3117,15 +3166,13 @@ export type $OpenApiTs = {
422: HTTPValidationError;
};
};
- };
- "/public/backfills/{backfill_id}": {
- get: {
- req: GetBackfillData;
+ patch: {
+ req: BulkConnectionsData;
res: {
/**
* Successful Response
*/
- 200: BackfillResponse;
+ 200: BulkResponse;
/**
* Unauthorized
*/
@@ -3134,10 +3181,6 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
- /**
- * Not Found
- */
- 404: HTTPExceptionResponse;
/**
* Validation Error
*/
@@ -3145,14 +3188,14 @@ export type $OpenApiTs = {
};
};
};
- "/public/backfills/{backfill_id}/pause": {
- put: {
- req: PauseBackfillData;
+ "/public/connections/test": {
+ post: {
+ req: TestConnectionData;
res: {
/**
* Successful Response
*/
- 200: BackfillResponse;
+ 200: ConnectionTestResponse;
/**
* Unauthorized
*/
@@ -3161,14 +3204,6 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
- /**
- * Not Found
- */
- 404: HTTPExceptionResponse;
- /**
- * Conflict
- */
- 409: HTTPExceptionResponse;
/**
* Validation Error
*/
@@ -3176,14 +3211,13 @@ export type $OpenApiTs = {
};
};
};
- "/public/backfills/{backfill_id}/unpause": {
- put: {
- req: UnpauseBackfillData;
+ "/public/connections/defaults": {
+ post: {
res: {
/**
* Successful Response
*/
- 200: BackfillResponse;
+ 204: void;
/**
* Unauthorized
*/
@@ -3192,14 +3226,17 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
+ };
+ };
+ };
+ "/ui/dags/recent_dag_runs": {
+ get: {
+ req: RecentDagRunsData;
+ res: {
/**
- * Not Found
- */
- 404: HTTPExceptionResponse;
- /**
- * Conflict
+ * Successful Response
*/
- 409: HTTPExceptionResponse;
+ 200: DAGWithLatestDagRunsCollectionResponse;
/**
* Validation Error
*/
@@ -3207,30 +3244,18 @@ export type $OpenApiTs = {
};
};
};
- "/public/backfills/{backfill_id}/cancel": {
- put: {
- req: CancelBackfillData;
+ "/ui/dependencies": {
+ get: {
+ req: GetDependenciesData;
res: {
/**
* Successful Response
*/
- 200: BackfillResponse;
- /**
- * Unauthorized
- */
- 401: HTTPExceptionResponse;
- /**
- * Forbidden
- */
- 403: HTTPExceptionResponse;
+ 200: BaseGraphResponse;
/**
* Not Found
*/
404: HTTPExceptionResponse;
- /**
- * Conflict
- */
- 409: HTTPExceptionResponse;
/**
* Validation Error
*/
@@ -3238,30 +3263,37 @@ export type $OpenApiTs = {
};
};
};
- "/public/backfills/dry_run": {
- post: {
- req: CreateBackfillDryRunData;
+ "/ui/dashboard/historical_metrics_data": {
+ get: {
+ req: HistoricalMetricsData;
res: {
/**
* Successful Response
*/
- 200: DryRunBackfillCollectionResponse;
+ 200: HistoricalMetricDataResponse;
/**
- * Unauthorized
+ * Bad Request
*/
- 401: HTTPExceptionResponse;
+ 400: HTTPExceptionResponse;
/**
- * Forbidden
+ * Validation Error
*/
- 403: HTTPExceptionResponse;
+ 422: HTTPValidationError;
+ };
+ };
+ };
+ "/ui/structure/structure_data": {
+ get: {
+ req: StructureDataData;
+ res: {
/**
- * Not Found
+ * Successful Response
*/
- 404: HTTPExceptionResponse;
+ 200: StructureDataResponse;
/**
- * Conflict
+ * Not Found
*/
- 409: HTTPExceptionResponse;
+ 404: HTTPExceptionResponse;
/**
* Validation Error
*/
@@ -3269,18 +3301,14 @@ export type $OpenApiTs = {
};
};
};
- "/ui/grid/{dag_id}": {
+ "/ui/backfills": {
get: {
- req: GridDataData;
+ req: ListBackfillsData;
res: {
/**
* Successful Response
*/
- 200: GridResponse;
- /**
- * Bad Request
- */
- 400: HTTPExceptionResponse;
+ 200: BackfillCollectionResponse;
/**
* Not Found
*/
@@ -3292,14 +3320,14 @@ export type $OpenApiTs = {
};
};
};
- "/public/connections/{connection_id}": {
- delete: {
- req: DeleteConnectionData;
+ "/public/backfills": {
+ get: {
+ req: ListBackfills1Data;
res: {
/**
* Successful Response
*/
- 204: void;
+ 200: BackfillCollectionResponse;
/**
* Unauthorized
*/
@@ -3308,23 +3336,19 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
- /**
- * Not Found
- */
- 404: HTTPExceptionResponse;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
- get: {
- req: GetConnectionData;
+ post: {
+ req: CreateBackfillData;
res: {
/**
* Successful Response
*/
- 200: ConnectionResponse;
+ 200: BackfillResponse;
/**
* Unauthorized
*/
@@ -3337,23 +3361,25 @@ export type $OpenApiTs = {
* Not Found
*/
404: HTTPExceptionResponse;
+ /**
+ * Conflict
+ */
+ 409: HTTPExceptionResponse;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
- patch: {
- req: PatchConnectionData;
+ };
+ "/public/backfills/{backfill_id}": {
+ get: {
+ req: GetBackfillData;
res: {
/**
* Successful Response
*/
- 200: ConnectionResponse;
- /**
- * Bad Request
- */
- 400: HTTPExceptionResponse;
+ 200: BackfillResponse;
/**
* Unauthorized
*/
@@ -3373,14 +3399,14 @@ export type $OpenApiTs = {
};
};
};
- "/public/connections": {
- get: {
- req: GetConnectionsData;
+ "/public/backfills/{backfill_id}/pause": {
+ put: {
+ req: PauseBackfillData;
res: {
/**
* Successful Response
*/
- 200: ConnectionCollectionResponse;
+ 200: BackfillResponse;
/**
* Unauthorized
*/
@@ -3393,19 +3419,25 @@ export type $OpenApiTs = {
* Not Found
*/
404: HTTPExceptionResponse;
+ /**
+ * Conflict
+ */
+ 409: HTTPExceptionResponse;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
- post: {
- req: PostConnectionData;
+ };
+ "/public/backfills/{backfill_id}/unpause": {
+ put: {
+ req: UnpauseBackfillData;
res: {
/**
* Successful Response
*/
- 201: ConnectionResponse;
+ 200: BackfillResponse;
/**
* Unauthorized
*/
@@ -3414,6 +3446,10 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
+ /**
+ * Not Found
+ */
+ 404: HTTPExceptionResponse;
/**
* Conflict
*/
@@ -3424,13 +3460,15 @@ export type $OpenApiTs = {
422: HTTPValidationError;
};
};
- patch: {
- req: BulkConnectionsData;
+ };
+ "/public/backfills/{backfill_id}/cancel": {
+ put: {
+ req: CancelBackfillData;
res: {
/**
* Successful Response
*/
- 200: BulkResponse;
+ 200: BackfillResponse;
/**
* Unauthorized
*/
@@ -3439,6 +3477,14 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
+ /**
+ * Not Found
+ */
+ 404: HTTPExceptionResponse;
+ /**
+ * Conflict
+ */
+ 409: HTTPExceptionResponse;
/**
* Validation Error
*/
@@ -3446,14 +3492,14 @@ export type $OpenApiTs = {
};
};
};
- "/public/connections/test": {
+ "/public/backfills/dry_run": {
post: {
- req: TestConnectionData;
+ req: CreateBackfillDryRunData;
res: {
/**
* Successful Response
*/
- 200: ConnectionTestResponse;
+ 200: DryRunBackfillCollectionResponse;
/**
* Unauthorized
*/
@@ -3462,6 +3508,14 @@ export type $OpenApiTs = {
* Forbidden
*/
403: HTTPExceptionResponse;
+ /**
+ * Not Found
+ */
+ 404: HTTPExceptionResponse;
+ /**
+ * Conflict
+ */
+ 409: HTTPExceptionResponse;
/**
* Validation Error
*/
@@ -3469,21 +3523,26 @@ export type $OpenApiTs = {
};
};
};
- "/public/connections/defaults": {
- post: {
+ "/ui/grid/{dag_id}": {
+ get: {
+ req: GridDataData;
res: {
/**
* Successful Response
*/
- 204: void;
+ 200: GridResponse;
/**
- * Unauthorized
+ * Bad Request
*/
- 401: HTTPExceptionResponse;
+ 400: HTTPExceptionResponse;
/**
- * Forbidden
+ * Not Found
*/
- 403: HTTPExceptionResponse;
+ 404: HTTPExceptionResponse;
+ /**
+ * Validation Error
+ */
+ 422: HTTPValidationError;
};
};
};
diff --git a/tests/api_fastapi/core_api/routes/ui/test_connections.py
b/tests/api_fastapi/core_api/routes/ui/test_connections.py
new file mode 100644
index 00000000000..68ad0e5e90c
--- /dev/null
+++ b/tests/api_fastapi/core_api/routes/ui/test_connections.py
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import pytest
+
+pytestmark = pytest.mark.db_test
+
+
+class TestHookMetaData:
+ def test_hook_meta_data(self, test_client):
+ response = test_client.get("/ui/connections/hook_meta")
+ response_data = response.json()
+ assert any(hook_data["connection_type"] == "generic" for hook_data in
response_data)
+ assert any(hook_data["connection_type"] == "fs" for hook_data in
response_data)
+
+ for hook_data in response_data:
+ if hook_data["connection_type"] == "fs":
+ assert hook_data["hook_name"] == "File (path)"
+
+ def test_should_respond_401(self, unauthenticated_test_client):
+ response = unauthenticated_test_client.get("/ui/connections/hook_meta")
+ assert response.status_code == 401
+
+ def test_should_respond_403(self, unauthorized_test_client):
+ response = unauthorized_test_client.get("/ui/connections/hook_meta")
+ assert response.status_code == 403