apache-airflow-providers-openlineage 1.12.2__py3-none-any.whl → 1.13.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "1.12.2"
32
+ __version__ = "1.13.0"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
35
  "2.8.0"
@@ -18,7 +18,9 @@ from __future__ import annotations
18
18
 
19
19
  from typing import TYPE_CHECKING, Iterator
20
20
 
21
- from airflow.providers.common.compat.openlineage.utils.utils import translate_airflow_asset
21
+ from airflow.providers.common.compat.openlineage.utils.utils import (
22
+ translate_airflow_asset,
23
+ )
22
24
  from airflow.providers.openlineage import conf
23
25
  from airflow.providers.openlineage.extractors import BaseExtractor, OperatorLineage
24
26
  from airflow.providers.openlineage.extractors.base import DefaultExtractor
@@ -61,7 +63,8 @@ class ExtractorManager(LoggingMixin):
61
63
  extractor: type[BaseExtractor] | None = try_import_from_string(extractor_path)
62
64
  if not extractor:
63
65
  self.log.warning(
64
- "OpenLineage is unable to import custom extractor `%s`; will ignore it.", extractor_path
66
+ "OpenLineage is unable to import custom extractor `%s`; will ignore it.",
67
+ extractor_path,
65
68
  )
66
69
  continue
67
70
  for operator_class in extractor.get_operator_classnames():
@@ -95,13 +98,21 @@ class ExtractorManager(LoggingMixin):
95
98
  # Extracting advanced metadata is only possible when extractor for particular operator
96
99
  # is defined. Without it, we can't extract any input or output data.
97
100
  try:
98
- self.log.debug("Using extractor %s %s", extractor.__class__.__name__, str(task_info))
101
+ self.log.debug(
102
+ "Using extractor %s %s",
103
+ extractor.__class__.__name__,
104
+ str(task_info),
105
+ )
99
106
  if complete:
100
107
  task_metadata = extractor.extract_on_complete(task_instance)
101
108
  else:
102
109
  task_metadata = extractor.extract()
103
110
 
104
- self.log.debug("Found task metadata for operation %s: %s", task.task_id, str(task_metadata))
111
+ self.log.debug(
112
+ "Found task metadata for operation %s: %s",
113
+ task.task_id,
114
+ str(task_metadata),
115
+ )
105
116
  task_metadata = self.validate_task_metadata(task_metadata)
106
117
  if task_metadata:
107
118
  if (not task_metadata.inputs) and (not task_metadata.outputs):
@@ -115,7 +126,10 @@ class ExtractorManager(LoggingMixin):
115
126
 
116
127
  except Exception as e:
117
128
  self.log.warning(
118
- "Failed to extract metadata using found extractor %s - %s %s", extractor, e, task_info
129
+ "Failed to extract metadata using found extractor %s - %s %s",
130
+ extractor,
131
+ e,
132
+ task_info,
119
133
  )
120
134
  elif (hook_lineage := self.get_hook_lineage()) is not None:
121
135
  inputs, outputs = hook_lineage
@@ -178,16 +192,9 @@ class ExtractorManager(LoggingMixin):
178
192
 
179
193
  def get_hook_lineage(self) -> tuple[list[Dataset], list[Dataset]] | None:
180
194
  try:
181
- from importlib.util import find_spec
182
-
183
- if find_spec("airflow.assets"):
184
- from airflow.lineage.hook import get_hook_lineage_collector
185
- else:
186
- # TODO: import from common.compat directly after common.compat providers with
187
- # asset_compat_lineage_collector released
188
- from airflow.providers.openlineage.utils.asset_compat_lineage_collector import (
189
- get_hook_lineage_collector,
190
- )
195
+ from airflow.providers.common.compat.lineage.hook import (
196
+ get_hook_lineage_collector,
197
+ )
191
198
  except ImportError:
192
199
  return None
193
200
 
@@ -28,8 +28,9 @@ def get_provider_info():
28
28
  "name": "OpenLineage Airflow",
29
29
  "description": "`OpenLineage <https://openlineage.io/>`__\n",
30
30
  "state": "ready",
31
- "source-date-epoch": 1728485291,
31
+ "source-date-epoch": 1730013356,
32
32
  "versions": [
33
+ "1.13.0",
33
34
  "1.12.2",
34
35
  "1.12.1",
35
36
  "1.12.0",
@@ -56,7 +57,7 @@ def get_provider_info():
56
57
  "dependencies": [
57
58
  "apache-airflow>=2.8.0",
58
59
  "apache-airflow-providers-common-sql>=1.6.0",
59
- "apache-airflow-providers-common-compat>=1.2.0",
60
+ "apache-airflow-providers-common-compat>=1.2.1",
60
61
  "attrs>=22.2",
61
62
  "openlineage-integration-common>=1.22.0",
62
63
  "openlineage-python>=1.22.0",
@@ -31,8 +31,13 @@ from openlineage.client.utils import RedactMixin
31
31
  from packaging.version import Version
32
32
 
33
33
  from airflow import __version__ as AIRFLOW_VERSION
34
- from airflow.exceptions import AirflowProviderDeprecationWarning # TODO: move this maybe to Airflow's logic?
34
+ from airflow.exceptions import (
35
+ AirflowProviderDeprecationWarning,
36
+ )
37
+
38
+ # TODO: move this maybe to Airflow's logic?
35
39
  from airflow.models import DAG, BaseOperator, DagRun, MappedOperator
40
+ from airflow.providers.common.compat.assets import Asset
36
41
  from airflow.providers.openlineage import conf
37
42
  from airflow.providers.openlineage.plugins.facets import (
38
43
  AirflowDagRunFacet,
@@ -50,14 +55,14 @@ from airflow.providers.openlineage.utils.selective_enable import (
50
55
  )
51
56
  from airflow.serialization.serialized_objects import SerializedBaseOperator
52
57
  from airflow.utils.context import AirflowContextDeprecationWarning
53
- from airflow.utils.log.secrets_masker import Redactable, Redacted, SecretsMasker, should_hide_value_for_key
58
+ from airflow.utils.log.secrets_masker import (
59
+ Redactable,
60
+ Redacted,
61
+ SecretsMasker,
62
+ should_hide_value_for_key,
63
+ )
54
64
  from airflow.utils.module_loading import import_string
55
65
 
56
- try:
57
- from airflow.assets import Asset
58
- except ModuleNotFoundError:
59
- from airflow.datasets import Dataset as Asset # type: ignore[no-redef]
60
-
61
66
  if TYPE_CHECKING:
62
67
  from openlineage.client.event_v2 import Dataset as OpenLineageDataset
63
68
  from openlineage.client.facet_v2 import RunFacet
@@ -477,7 +482,6 @@ def _get_task_groups_details(dag: DAG) -> dict:
477
482
  return {
478
483
  tg_id: {
479
484
  "parent_group": tg.parent_group.group_id,
480
- "tooltip": tg.tooltip,
481
485
  "ui_color": tg.ui_color,
482
486
  "ui_fgcolor": tg.ui_fgcolor,
483
487
  "ui_label": tg.label,
@@ -501,7 +505,11 @@ def _emits_ol_events(task: BaseOperator | MappedOperator) -> bool:
501
505
  )
502
506
 
503
507
  emits_ol_events = all(
504
- (config_selective_enabled, not config_disabled_for_operators, not is_skipped_as_empty_operator)
508
+ (
509
+ config_selective_enabled,
510
+ not config_disabled_for_operators,
511
+ not is_skipped_as_empty_operator,
512
+ )
505
513
  )
506
514
  return emits_ol_events
507
515
 
@@ -567,7 +575,12 @@ class OpenLineageRedactor(SecretsMasker):
567
575
  setattr(
568
576
  item,
569
577
  dict_key,
570
- self._redact(subval, name=dict_key, depth=(depth + 1), max_depth=max_depth),
578
+ self._redact(
579
+ subval,
580
+ name=dict_key,
581
+ depth=(depth + 1),
582
+ max_depth=max_depth,
583
+ ),
571
584
  )
572
585
  return item
573
586
  elif is_json_serializable(item) and hasattr(item, "__dict__"):
@@ -578,7 +591,12 @@ class OpenLineageRedactor(SecretsMasker):
578
591
  setattr(
579
592
  item,
580
593
  dict_key,
581
- self._redact(subval, name=dict_key, depth=(depth + 1), max_depth=max_depth),
594
+ self._redact(
595
+ subval,
596
+ name=dict_key,
597
+ depth=(depth + 1),
598
+ max_depth=max_depth,
599
+ ),
582
600
  )
583
601
  return item
584
602
  else:
@@ -641,13 +659,17 @@ def normalize_sql(sql: str | Iterable[str]):
641
659
  def should_use_external_connection(hook) -> bool:
642
660
  # If we're at Airflow 2.10, the execution is process-isolated, so we can safely run those again.
643
661
  if not IS_AIRFLOW_2_10_OR_HIGHER:
644
- return hook.__class__.__name__ not in ["SnowflakeHook", "SnowflakeSqlApiHook", "RedshiftSQLHook"]
662
+ return hook.__class__.__name__ not in [
663
+ "SnowflakeHook",
664
+ "SnowflakeSqlApiHook",
665
+ "RedshiftSQLHook",
666
+ ]
645
667
  return True
646
668
 
647
669
 
648
670
  def translate_airflow_asset(asset: Asset, lineage_context) -> OpenLineageDataset | None:
649
671
  """
650
- Convert a Asset with an AIP-60 compliant URI to an OpenLineageDataset.
672
+ Convert an Asset with an AIP-60 compliant URI to an OpenLineageDataset.
651
673
 
652
674
  This function returns None if no URI normalizer is defined, no asset converter is found or
653
675
  some core Airflow changes are missing and ImportError is raised.
@@ -656,7 +678,7 @@ def translate_airflow_asset(asset: Asset, lineage_context) -> OpenLineageDataset
656
678
  from airflow.assets import _get_normalized_scheme
657
679
  except ModuleNotFoundError:
658
680
  try:
659
- from airflow.datasets import _get_normalized_scheme # type: ignore[no-redef]
681
+ from airflow.datasets import _get_normalized_scheme # type: ignore[no-redef, attr-defined]
660
682
  except ImportError:
661
683
  return None
662
684
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: apache-airflow-providers-openlineage
3
- Version: 1.12.2
3
+ Version: 1.13.0
4
4
  Summary: Provider package apache-airflow-providers-openlineage for Apache Airflow
5
5
  Keywords: airflow-provider,openlineage,airflow,integration
6
6
  Author-email: Apache Software Foundation <dev@airflow.apache.org>
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
20
20
  Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Topic :: System :: Monitoring
23
- Requires-Dist: apache-airflow-providers-common-compat>=1.2.0
23
+ Requires-Dist: apache-airflow-providers-common-compat>=1.2.1
24
24
  Requires-Dist: apache-airflow-providers-common-sql>=1.6.0
25
25
  Requires-Dist: apache-airflow>=2.8.0
26
26
  Requires-Dist: attrs>=22.2
@@ -29,8 +29,8 @@ Requires-Dist: openlineage-python>=1.22.0
29
29
  Requires-Dist: apache-airflow-providers-common-compat ; extra == "common.compat"
30
30
  Requires-Dist: apache-airflow-providers-common-sql ; extra == "common.sql"
31
31
  Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
32
- Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.12.2/changelog.html
33
- Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.12.2
32
+ Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0/changelog.html
33
+ Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0
34
34
  Project-URL: Slack Chat, https://s.apache.org/airflow-slack
35
35
  Project-URL: Source Code, https://github.com/apache/airflow
36
36
  Project-URL: Twitter, https://twitter.com/ApacheAirflow
@@ -82,7 +82,7 @@ Provides-Extra: common.sql
82
82
 
83
83
  Package ``apache-airflow-providers-openlineage``
84
84
 
85
- Release: ``1.12.2``
85
+ Release: ``1.13.0``
86
86
 
87
87
 
88
88
  `OpenLineage <https://openlineage.io/>`__
@@ -95,7 +95,7 @@ This is a provider package for ``openlineage`` provider. All classes for this pr
95
95
  are in ``airflow.providers.openlineage`` python package.
96
96
 
97
97
  You can find package information and changelog for the provider
98
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.12.2/>`_.
98
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0/>`_.
99
99
 
100
100
  Installation
101
101
  ------------
@@ -114,7 +114,7 @@ PIP package Version required
114
114
  ========================================== ==================
115
115
  ``apache-airflow`` ``>=2.8.0``
116
116
  ``apache-airflow-providers-common-sql`` ``>=1.6.0``
117
- ``apache-airflow-providers-common-compat`` ``>=1.2.0``
117
+ ``apache-airflow-providers-common-compat`` ``>=1.2.1``
118
118
  ``attrs`` ``>=22.2``
119
119
  ``openlineage-integration-common`` ``>=1.22.0``
120
120
  ``openlineage-python`` ``>=1.22.0``
@@ -141,4 +141,4 @@ Dependent package
141
141
  ================================================================================================================== =================
142
142
 
143
143
  The changelog for the provider package can be found in the
144
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.12.2/changelog.html>`_.
144
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0/changelog.html>`_.
@@ -1,12 +1,12 @@
1
1
  airflow/providers/openlineage/LICENSE,sha256=FFb4jd2AXnOOf7XLP04pQW6jbdhG49TxlGY6fFpCV1Y,13609
2
- airflow/providers/openlineage/__init__.py,sha256=ebc-6rZfaCgWlVuLsW6FA1fuGFXkFheh8ricGwCd3kw,1499
2
+ airflow/providers/openlineage/__init__.py,sha256=IjDwbAoImu75D6-6urGxe4iyvRUy0FKCLdbE7XPJW6s,1499
3
3
  airflow/providers/openlineage/conf.py,sha256=mOOiF25MhsDtDxewm5X-yf4uitH1eFr-LINucSgmdE8,5136
4
- airflow/providers/openlineage/get_provider_info.py,sha256=t1MzS0YvFEPXgdk_-KMzITB5l2qiKW0nMgFb6HRntKs,8971
4
+ airflow/providers/openlineage/get_provider_info.py,sha256=ZdtzQH8v6vCjKaOE-Qm50x-Wo1NjGKDed0a5kdA4RIc,8993
5
5
  airflow/providers/openlineage/sqlparser.py,sha256=c7q3VVw41S87ZFozrkrEr2oZK79N12mC3KdDs9V1IuM,15581
6
6
  airflow/providers/openlineage/extractors/__init__.py,sha256=I0X4f6zUniclyD9zT0DFHRImpCpJVP4MkPJT3cd7X5I,1081
7
7
  airflow/providers/openlineage/extractors/base.py,sha256=olafVPBKxeGjqXerCYM0vj2q78Lm4ErWjex_R6nhjKY,6635
8
8
  airflow/providers/openlineage/extractors/bash.py,sha256=3aR0PXs8fzRLibRxXN1R8wMZnGzyCur7mjpy8e5GC4A,2583
9
- airflow/providers/openlineage/extractors/manager.py,sha256=sDSp_ajHiRcbFfX3YL_bx7EhYSKHhCVU0jTx04VzRvQ,12386
9
+ airflow/providers/openlineage/extractors/manager.py,sha256=TU1flv6W3jtn5xxwpqw8K6f2Ni_mZbqqRZK2v3ZiE28,12261
10
10
  airflow/providers/openlineage/extractors/python.py,sha256=hVWOplMlBimrpPKPeW6vm75a8OmAYMU1oJzqMz8Jh90,3171
11
11
  airflow/providers/openlineage/facets/AirflowDagRunFacet.json,sha256=ie6c-J3-wGgk80WDTGWePz18o6DbW--TNM7BMF4WfcU,2251
12
12
  airflow/providers/openlineage/facets/AirflowDebugRunFacet.json,sha256=_zA5gFqGje5MOH1SmdMeA5ViOHvW_pV4oijEAvkuBbY,768
@@ -21,11 +21,10 @@ airflow/providers/openlineage/plugins/listener.py,sha256=j83NmEvdT46FTg2lko8yg-Y
21
21
  airflow/providers/openlineage/plugins/macros.py,sha256=hgFA3ZdQibyn4KXIOsKYBm4WRKDLA5q6Asscx5rvNfM,3076
22
22
  airflow/providers/openlineage/plugins/openlineage.py,sha256=T0L5Yxpyq_wzs2_hltJCMY5NKzgsYp0vuEn8LppV5PU,1915
23
23
  airflow/providers/openlineage/utils/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
24
- airflow/providers/openlineage/utils/asset_compat_lineage_collector.py,sha256=iixSY7KS4HE8X6kdJ6BxT3D0_E_ptn4OmhxVgmLrqYc,3697
25
24
  airflow/providers/openlineage/utils/selective_enable.py,sha256=dFJ7wK7J_-BFwcOKp9tqFOSrASV3lmLv7HtRkEuMk3Q,3087
26
25
  airflow/providers/openlineage/utils/sql.py,sha256=bnuU9WvjVKcWVMN3cUp0jaHtU5_ZRM5I1OP1WhIdztg,9583
27
- airflow/providers/openlineage/utils/utils.py,sha256=WAU65ERSk4_RKM2QXmIcrDnYcq44l9jMq7xLvkhQJe0,24210
28
- apache_airflow_providers_openlineage-1.12.2.dist-info/entry_points.txt,sha256=GAx0_i2OeZzqaiiiYuA-xchICDXiCT5kVqpKSxsOjt4,214
29
- apache_airflow_providers_openlineage-1.12.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
30
- apache_airflow_providers_openlineage-1.12.2.dist-info/METADATA,sha256=GFkuqMxjRmsgE3H6St7S4XYqJVsi3uzXFMdtAVUB6Dg,6751
31
- apache_airflow_providers_openlineage-1.12.2.dist-info/RECORD,,
26
+ airflow/providers/openlineage/utils/utils.py,sha256=mvMq5aaUnO3ujhj3tfot9mA4gShtdOHMzECzqj_OQvk,24582
27
+ apache_airflow_providers_openlineage-1.13.0.dist-info/entry_points.txt,sha256=GAx0_i2OeZzqaiiiYuA-xchICDXiCT5kVqpKSxsOjt4,214
28
+ apache_airflow_providers_openlineage-1.13.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
29
+ apache_airflow_providers_openlineage-1.13.0.dist-info/METADATA,sha256=7-z8N9RUOISyBlxu2Ume3Cm-4fhXGczUT-K-nVStVxA,6751
30
+ apache_airflow_providers_openlineage-1.13.0.dist-info/RECORD,,
@@ -1,108 +0,0 @@
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 importlib.util import find_spec
20
-
21
- # TODO: replace this module with common.compat provider once common.compat 1.3.0 released
22
-
23
-
24
- def _get_asset_compat_hook_lineage_collector():
25
- from airflow.lineage.hook import get_hook_lineage_collector
26
-
27
- collector = get_hook_lineage_collector()
28
-
29
- if all(
30
- getattr(collector, asset_method_name, None)
31
- for asset_method_name in ("add_input_asset", "add_output_asset", "collected_assets")
32
- ):
33
- return collector
34
-
35
- # dataset is renamed as asset in Airflow 3.0
36
-
37
- from functools import wraps
38
-
39
- from airflow.lineage.hook import DatasetLineageInfo, HookLineage
40
-
41
- DatasetLineageInfo.asset = DatasetLineageInfo.dataset
42
-
43
- def rename_dataset_kwargs_as_assets_kwargs(function):
44
- @wraps(function)
45
- def wrapper(*args, **kwargs):
46
- if "asset_kwargs" in kwargs:
47
- kwargs["dataset_kwargs"] = kwargs.pop("asset_kwargs")
48
-
49
- if "asset_extra" in kwargs:
50
- kwargs["dataset_extra"] = kwargs.pop("asset_extra")
51
-
52
- return function(*args, **kwargs)
53
-
54
- return wrapper
55
-
56
- collector.create_asset = rename_dataset_kwargs_as_assets_kwargs(collector.create_dataset)
57
- collector.add_input_asset = rename_dataset_kwargs_as_assets_kwargs(collector.add_input_dataset)
58
- collector.add_output_asset = rename_dataset_kwargs_as_assets_kwargs(collector.add_output_dataset)
59
-
60
- def collected_assets_compat(collector) -> HookLineage:
61
- """Get the collected hook lineage information."""
62
- lineage = collector.collected_datasets
63
- return HookLineage(
64
- [
65
- DatasetLineageInfo(dataset=item.dataset, count=item.count, context=item.context)
66
- for item in lineage.inputs
67
- ],
68
- [
69
- DatasetLineageInfo(dataset=item.dataset, count=item.count, context=item.context)
70
- for item in lineage.outputs
71
- ],
72
- )
73
-
74
- setattr(
75
- collector.__class__,
76
- "collected_assets",
77
- property(lambda collector: collected_assets_compat(collector)),
78
- )
79
-
80
- return collector
81
-
82
-
83
- def get_hook_lineage_collector():
84
- # HookLineageCollector added in 2.10
85
- try:
86
- if find_spec("airflow.assets"):
87
- # Dataset has been renamed as Asset in 3.0
88
- from airflow.lineage.hook import get_hook_lineage_collector
89
-
90
- return get_hook_lineage_collector()
91
-
92
- return _get_asset_compat_hook_lineage_collector()
93
- except ImportError:
94
-
95
- class NoOpCollector:
96
- """
97
- NoOpCollector is a hook lineage collector that does nothing.
98
-
99
- It is used when you want to disable lineage collection.
100
- """
101
-
102
- def add_input_asset(self, *_, **__):
103
- pass
104
-
105
- def add_output_asset(self, *_, **__):
106
- pass
107
-
108
- return NoOpCollector()