Skip to content

Commit cba34ad

Browse files
authored
Merge branch 'apache:main' into main
2 parents e96a7bf + 64e2892 commit cba34ad

File tree

19 files changed

+1092
-0
lines changed

19 files changed

+1092
-0
lines changed

airflow-core/tests/unit/always/test_project_structure.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def test_providers_modules_should_have_tests(self):
6161
# We should make sure that one goes to 0
6262
# TODO(potiuk) - check if that test actually tests something
6363
OVERLOOKED_TESTS = [
64+
"providers/alibaba/tests/unit/alibaba/test_version_compat.py",
6465
"providers/amazon/tests/unit/amazon/aws/auth_manager/datamodels/test_login.py",
6566
"providers/amazon/tests/unit/amazon/aws/auth_manager/security_manager/test_aws_security_manager_override.py",
6667
"providers/amazon/tests/unit/amazon/aws/executors/batch/test_batch_executor_config.py",

docs/spelling_wordlist.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,8 @@ masterType
10901090
materializations
10911091
Matomo
10921092
matomo
1093+
MaxCompute
1094+
maxcompute
10931095
Maxime
10941096
MaxRuntimeInSeconds
10951097
mb
@@ -1220,6 +1222,7 @@ objectstorage
12201222
observability
12211223
od
12221224
odbc
1225+
odps
12231226
ok
12241227
Okta
12251228
okta

providers/alibaba/provider.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ operators:
7878
- integration-name: Alibaba Cloud AnalyticDB Spark
7979
python-modules:
8080
- airflow.providers.alibaba.cloud.operators.analyticdb_spark
81+
- integration-name: Alibaba Cloud MaxCompute
82+
python-modules:
83+
- airflow.providers.alibaba.cloud.operators.maxcompute
8184

8285
sensors:
8386
- integration-name: Alibaba Cloud OSS
@@ -94,13 +97,26 @@ hooks:
9497
- integration-name: Alibaba Cloud AnalyticDB Spark
9598
python-modules:
9699
- airflow.providers.alibaba.cloud.hooks.analyticdb_spark
100+
- integration-name: Alibaba Cloud
101+
python-modules:
102+
- airflow.providers.alibaba.cloud.hooks.base_alibaba
103+
- integration-name: Alibaba Cloud MaxCompute
104+
python-modules:
105+
- airflow.providers.alibaba.cloud.hooks.maxcompute
97106

98107

99108
connection-types:
100109
- hook-class-name: airflow.providers.alibaba.cloud.hooks.oss.OSSHook
101110
connection-type: oss
102111
- hook-class-name: airflow.providers.alibaba.cloud.hooks.analyticdb_spark.AnalyticDBSparkHook
103112
connection-type: adb_spark
113+
- hook-class-name: airflow.providers.alibaba.cloud.hooks.base_alibaba.AlibabaBaseHook
114+
connection-type: alibaba_cloud
115+
- hook-class-name: airflow.providers.alibaba.cloud.hooks.maxcompute.MaxComputeHook
116+
connection-type: maxcompute
104117

105118
logging:
106119
- airflow.providers.alibaba.cloud.log.oss_task_handler.OSSTaskHandler
120+
121+
extra-links:
122+
- airflow.providers.alibaba.cloud.links.maxcompute.MaxComputeLogViewLink

providers/alibaba/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ dependencies = [
6161
"oss2>=2.14.0",
6262
"alibabacloud_adb20211201>=1.0.0",
6363
"alibabacloud_tea_openapi>=0.3.7",
64+
"pyodps>=0.12.2.2",
6465
]
6566

6667
[dependency-groups]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
from __future__ import annotations
18+
19+
20+
class MaxComputeConfigurationException(Exception):
21+
"""Raised when MaxCompute project or endpoint is not configured properly."""
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
from __future__ import annotations
18+
19+
from typing import Any, NamedTuple
20+
21+
from airflow.hooks.base import BaseHook
22+
23+
24+
class AccessKeyCredentials(NamedTuple):
25+
"""
26+
A NamedTuple to store Alibaba Cloud Access Key credentials.
27+
28+
:param access_key_id: The Access Key ID for Alibaba Cloud authentication.
29+
:param access_key_secret: The Access Key Secret for Alibaba Cloud authentication.
30+
"""
31+
32+
access_key_id: str
33+
access_key_secret: str
34+
35+
36+
class AlibabaBaseHook(BaseHook):
37+
"""
38+
A base hook for Alibaba Cloud-related hooks.
39+
40+
This hook provides a common interface for authenticating using Alibaba Cloud credentials.
41+
42+
Supports Access Key-based authentication.
43+
44+
:param alibaba_cloud_conn_id: The connection ID to use when fetching connection info.
45+
"""
46+
47+
conn_name_attr = "alibabacloud_conn_id"
48+
default_conn_name = "alibabacloud_default"
49+
conn_type = "alibaba_cloud"
50+
hook_name = "Alibaba Cloud"
51+
52+
def __init__(
53+
self,
54+
alibabacloud_conn_id: str = "alibabacloud_default",
55+
**kwargs,
56+
) -> None:
57+
super().__init__(**kwargs)
58+
self.alibaba_cloud_conn_id = alibabacloud_conn_id
59+
self.extras: dict = self.get_connection(self.alibaba_cloud_conn_id).extra_dejson
60+
61+
@classmethod
62+
def get_connection_form_widgets(cls) -> dict[str, Any]:
63+
"""Return connection widgets to add to connection form."""
64+
from flask_appbuilder.fieldwidgets import BS3PasswordFieldWidget
65+
from flask_babel import lazy_gettext
66+
from wtforms import PasswordField
67+
68+
return {
69+
"access_key_id": PasswordField(lazy_gettext("Access Key ID"), widget=BS3PasswordFieldWidget()),
70+
"access_key_secret": PasswordField(
71+
lazy_gettext("Access Key Secret"), widget=BS3PasswordFieldWidget()
72+
),
73+
}
74+
75+
@classmethod
76+
def get_ui_field_behaviour(cls) -> dict[str, Any]:
77+
"""Return custom field behaviour."""
78+
return super().get_ui_field_behaviour()
79+
80+
def _get_field(self, field_name: str, default: Any = None) -> Any:
81+
"""Fetch a field from extras, and returns it."""
82+
value = self.extras.get(field_name)
83+
return value if value is not None else default
84+
85+
def get_access_key_credential(self) -> AccessKeyCredentials:
86+
"""
87+
Fetch Access Key Credential for authentication.
88+
89+
:return: AccessKeyCredentials object containing access_key_id and access_key_secret.
90+
"""
91+
access_key_id = self._get_field("access_key_id", None)
92+
access_key_secret = self._get_field("access_key_secret", None)
93+
if not access_key_id:
94+
raise ValueError("No access_key_id is specified.")
95+
96+
if not access_key_secret:
97+
raise ValueError("No access_key_secret is specified.")
98+
99+
return AccessKeyCredentials(access_key_id, access_key_secret)

0 commit comments

Comments
 (0)