Skip to content

Commit 4a528d2

Browse files
committed
Support Airflow 2.x operators (runtime specific components)
Signed-off-by: Luciano Resende <[email protected]>
1 parent b510626 commit 4a528d2

File tree

10 files changed

+3037
-3038
lines changed

10 files changed

+3037
-3038
lines changed

docs/source/user_guide/best-practices-custom-pipeline-components.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ The [URL component catalog](pipeline-components.html#pipeline-components.html#ur
131131
The [Apache Airflow package catalog](pipeline-components.html#apache-airflow-package-catalog) provides access to Apache Airflow operators that are stored in built distributions.
132132

133133
1. Take note of the displayed `airflow_package`, which identifies the Apache Airflow built distribution that includes the missing operator.
134-
1. [Add a new Apache Airflow package catalog](pipeline-components.html#adding-a-component-catalog), providing the _download URL_ for the listed distribution as input. For example, if the value of `airflow_package` is `apache_airflow-1.10.15-py2.py3-none-any.whl`, specify as URL
134+
1. [Add a new Apache Airflow package catalog](pipeline-components.html#adding-a-component-catalog), providing the _download URL_ for the listed distribution as input. For example, if the value of `airflow_package` is `apache_airflow-2.10.4-py2.py3-none-any.whl`, specify as URL
135135
```
136-
https://files.pythonhosted.org/packages/f0/3a/f5ce74b2bdbbe59c925bb3398ec0781b66a64b8a23e2f6adc7ab9f1005d9/apache_airflow-1.10.15-py2.py3-none-any.whl
136+
https://archive.apache.org/dist/airflow/2.10.4/apache_airflow-2.10.4-py3-none-any.whl
137137
```
138138

139139
#### Apache Airflow provider package catalog (type: `airflow-provider-package-catalog`)

docs/source/user_guide/pipeline-components.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,11 +445,11 @@ The [Apache Airflow package catalog connector](https://github.com/elyra-ai/elyra
445445
Examples:
446446
- [Apache Airflow](https://pypi.org/project/apache-airflow/) (v1.10.15):
447447
```
448-
https://files.pythonhosted.org/packages/f0/3a/f5ce74b2bdbbe59c925bb3398ec0781b66a64b8a23e2f6adc7ab9f1005d9/apache_airflow-1.10.15-py2.py3-none-any.whl
448+
https://archive.apache.org/dist/airflow/2.10.4/apache_airflow-2.10.4-py3-none-any.whl
449449
```
450450
- Local copy of a downloaded Apache Airflow package
451451
```
452-
file:///absolute/path/to/apache_airflow-1.10.15-py2.py3-none-any.whl
452+
file:///absolute/path/to/apache_airflow-2.10.4-py2.py3-none-any.whl
453453
```
454454

455455
#### Apache Airflow provider package catalog

elyra/pipeline/airflow/package_catalog_connector/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ If the Airflow package is stored on PyPI:
1919
1. Search for the Apache Airflow package on PyPI.
2020
1. Open the package's release history and choose the desired version.
2121
1. Open the `Download files` link.
22-
1. Copy the download link for the package's wheel. ([Example download URL for Apache Airflow 1.10.15](https://files.pythonhosted.org/packages/f0/3a/f5ce74b2bdbbe59c925bb3398ec0781b66a64b8a23e2f6adc7ab9f1005d9/apache_airflow-1.10.15-py2.py3-none-any.whl))
22+
1. Copy the download link for the package's wheel. ([Example download URL for Apache Airflow 2.10.4](https://archive.apache.org/dist/airflow/2.10.4/apache_airflow-2.10.4-py3-none-any.whl))
2323
1. Save the catalog entry.
2424
1. Open the Visual Pipeline Editor and expand the palette. The loaded Apache Airflow operators are displayed.
2525

@@ -28,4 +28,4 @@ If the Airflow package is stored on PyPI:
2828
If the palette does not include the expected operators check the JupyterLab log file for error messages. Error messages include the component catalog name, as shown in this example:
2929
```
3030
Error. The Airflow package connector '<CATALOG_NAME>' encountered an issue downloading '<URL>'. HTTP response code: <HTTP_CODE>
31-
```
31+
```

elyra/pipeline/airflow/package_catalog_connector/airflow_package_catalog_connector.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ def get_catalog_entries(self, catalog_metadata: Dict[str, Any]) -> List[Dict[str
6161

6262
# Read the user-supplied 'airflow_package_download_url', which is a required
6363
# input defined in the 'airflow-package-catalog-catalog.json' schema file.
64-
# Example value: https://archive.apache.org/dist/airflow/1.10.15/apache_airflow-1.10.15-py2.py3-none-any.whl
64+
# Example value: https://archive.apache.org/dist/airflow/2.10.4/apache_airflow-2.10.4-py3-none-any.whl
6565
airflow_package_download_url = catalog_metadata["airflow_package_download_url"]
66-
# extract the package name, e.g. 'apache_airflow-1.10.15-py2.py3-none-any.whl'
66+
# extract the package name, e.g. 'apache_airflow-2.10.4-py3-none-any.whl'
6767
airflow_package_name = Path(urlparse(airflow_package_download_url).path).name
6868

6969
if not airflow_package_name:
@@ -161,7 +161,7 @@ def get_catalog_entries(self, catalog_metadata: Dict[str, Any]) -> List[Dict[str
161161

162162
#
163163
# Identify Python scripts that define classes that extend the
164-
# airflow.models.BaseOperator class
164+
# airflow.models.baseoperator.BaseOperator class
165165
#
166166
scripts_with_operator_class: List[str] = [] # Python scripts that contain operator definitions
167167
extends_baseoperator: List[str] = [] # Classes that extend BaseOperator
@@ -188,8 +188,11 @@ def get_catalog_entries(self, catalog_metadata: Dict[str, Any]) -> List[Dict[str
188188
elif isinstance(node, ast.ImportFrom):
189189
node_module = node.module
190190
for name in node.names:
191-
if "airflow.models" == node_module and name.name == "BaseOperator":
191+
if "airflow.models.baseoperator" == node_module and name.name == "BaseOperator":
192192
imported_operator_classes.append(name.name)
193+
# TODO: Support sensor operators
194+
# if "airflow.sensors.base" == node_module and name.name == "BaseSensorOperator":
195+
# imported_operator_classes.append(name.name)
193196
elif isinstance(node, ast.ClassDef):
194197
# determine whether this class extends the BaseOperator class
195198
self.log.debug(f"Analyzing class '{node.name}' in {script_id} ...")

elyra/tests/pipeline/airflow/test_airflow_package_connector.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@
2323
)
2424
from elyra.pipeline.catalog_connector import AirflowEntryData
2525

26-
AIRFLOW_1_10_15_PKG_URL = (
27-
"https://files.pythonhosted.org/packages/f0/3a/"
28-
"f5ce74b2bdbbe59c925bb3398ec0781b66a64b8a23e2f6adc7ab9f1005d9/"
29-
"apache_airflow-1.10.15-py2.py3-none-any.whl"
30-
)
26+
AIRFLOW_2_10_4_PKG_URL = "https://archive.apache.org/dist/airflow/2.10.4/apache_airflow-2.10.4-py3-none-any.whl"
3127

3228
AIRFLOW_SUPPORTED_FILE_TYPES = [".py"]
3329

@@ -115,19 +111,19 @@ def test_invalid_get_entry_data():
115111
# ----------------------------------
116112

117113

118-
def test_1_10_15_distribution():
114+
def test_2_10_4_distribution():
119115
"""
120-
Test connector using Apache Airflow 1.10.15 built distribution.
116+
Test connector using Apache Airflow 2.10.4 built distribution.
121117
"""
122118
apc = AirflowPackageCatalogConnector(AIRFLOW_SUPPORTED_FILE_TYPES)
123119
# get catalog entries for the specified distribution
124-
ces = apc.get_catalog_entries({"airflow_package_download_url": AIRFLOW_1_10_15_PKG_URL})
125-
# this distribution should contain 37 Python scripts with operator definitions
126-
assert len(ces) == 37
120+
ces = apc.get_catalog_entries({"airflow_package_download_url": AIRFLOW_2_10_4_PKG_URL})
121+
# this distribution should contain 12 Python scripts with operator definitions
122+
assert len(ces) == 11
127123
# each entry must contain two keys
128124
for entry in ces:
129125
# built distribution package file name
130-
assert entry.get("airflow_package") == "apache_airflow-1.10.15-py2.py3-none-any.whl"
126+
assert entry.get("airflow_package") == "apache_airflow-2.10.4-py3-none-any.whl"
131127
# a Python script
132128
assert entry.get("file", "").endswith(".py")
133129

elyra/tests/pipeline/airflow/test_airflow_provider_package_connector.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
from elyra.pipeline.catalog_connector import AirflowEntryData
2929

3030
HTTP_PROVIDER_PKG_URL = (
31-
"https://files.pythonhosted.org/packages/a1/08/"
32-
"91653e9f394cbefe356ac07db809be7e69cc89b094379ad91d6cef3d2bc9/"
33-
"apache_airflow_providers_http-2.0.2-py3-none-any.whl"
31+
"https://files.pythonhosted.org/packages/bb/55/"
32+
"9f38da212c29e1c429ddadef082f2bdaccebb0b0d9c88e72463ad25c786a/"
33+
"apache_airflow_providers_http-5.0.0-py3-none-any.whl"
3434
)
3535

3636
AIRFLOW_SUPPORTED_FILE_TYPES = [".py"]
@@ -134,7 +134,7 @@ def test_valid_url_http_provider_package():
134134
# each entry must contain three keys
135135
for entry in ces:
136136
# provider package file name
137-
assert entry.get("provider_package") == "apache_airflow_providers_http-2.0.2-py3-none-any.whl"
137+
assert entry.get("provider_package") == "apache_airflow_providers_http-5.0.0-py3-none-any.whl"
138138
# provider name
139139
assert entry.get("provider") == "apache_airflow_providers_http"
140140
# a Python script

elyra/tests/pipeline/resources/components/airflow_test_operator.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
#
16-
from typing import Any
1716
from typing import Dict
1817
from typing import List
1918
from typing import Optional
2019

21-
from airflow.models import BaseOperator
20+
from airflow.models.baseoperator import BaseOperator
21+
from airflow.utils.context import Context # New context type in Airflow 2.x
2222
from airflow.operators.imported_operator import ImportedOperator # noqa TODO
2323

2424

@@ -87,7 +87,7 @@ def __init__(
8787
):
8888
super().__init__(*args, **kwargs)
8989

90-
def execute(self, context: Any):
90+
def execute(self, context: Context):
9191
pass
9292

9393

@@ -132,7 +132,7 @@ def __init__(
132132
):
133133
super().__init__(**kwargs)
134134

135-
def execute(self, context: Any):
135+
def execute(self, context: Context):
136136
pass
137137

138138

@@ -173,7 +173,7 @@ def __init__(
173173
):
174174
super().__init__(**kwargs)
175175

176-
def execute(self, context: Any):
176+
def execute(self, context: Context):
177177
pass
178178

179179

elyra/tests/pipeline/resources/components/airflow_test_operator_no_inputs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
#
16-
from typing import Any
1716

18-
from airflow.models import BaseOperator
17+
from airflow.models.baseoperator import BaseOperator
18+
from airflow.utils.context import Context # New context type in Airflow 2.x
1919

2020

2121
class TestOperatorNoInputs(BaseOperator):
@@ -27,5 +27,5 @@ class TestOperatorNoInputs(BaseOperator):
2727
def __init__(self, *args, **kwargs):
2828
super().__init__(*args, **kwargs)
2929

30-
def execute(self, context: Any):
30+
def execute(self, context: Context):
3131
pass

elyra/tests/pipeline/resources/components/airflow_test_operator_type_hints.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from typing import List
1818
from typing import Optional
1919

20-
from airflow.models import BaseOperator
20+
from airflow.models.baseoperator import BaseOperator
2121
from airflow.utils.decorators import apply_defaults
2222

2323

0 commit comments

Comments
 (0)