apache-airflow-providers-openlineage 1.13.0rc1__tar.gz → 1.14.0rc1__tar.gz

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.

Potentially problematic release.


This version of apache-airflow-providers-openlineage might be problematic. Click here for more details.

Files changed (29) hide show
  1. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/PKG-INFO +17 -17
  2. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/README.rst +6 -6
  3. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/__init__.py +1 -1
  4. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/extractors/manager.py +2 -0
  5. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/get_provider_info.py +5 -4
  6. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/plugins/adapter.py +6 -16
  7. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/sqlparser.py +5 -2
  8. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/utils/utils.py +37 -3
  9. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/pyproject.toml +7 -8
  10. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/LICENSE +0 -0
  11. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/conf.py +0 -0
  12. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/extractors/__init__.py +0 -0
  13. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/extractors/base.py +0 -0
  14. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/extractors/bash.py +0 -0
  15. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/extractors/python.py +0 -0
  16. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/facets/AirflowDagRunFacet.json +0 -0
  17. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/facets/AirflowDebugRunFacet.json +0 -0
  18. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/facets/AirflowJobFacet.json +0 -0
  19. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/facets/AirflowRunFacet.json +0 -0
  20. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/facets/AirflowStateRunFacet.json +0 -0
  21. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/facets/__init__.py +0 -0
  22. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/plugins/__init__.py +0 -0
  23. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/plugins/facets.py +0 -0
  24. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/plugins/listener.py +0 -0
  25. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/plugins/macros.py +0 -0
  26. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/plugins/openlineage.py +0 -0
  27. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/utils/__init__.py +0 -0
  28. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/utils/selective_enable.py +0 -0
  29. {apache_airflow_providers_openlineage-1.13.0rc1 → apache_airflow_providers_openlineage-1.14.0rc1}/airflow/providers/openlineage/utils/sql.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: apache-airflow-providers-openlineage
3
- Version: 1.13.0rc1
3
+ Version: 1.14.0rc1
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>
@@ -21,22 +21,22 @@ Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Topic :: System :: Monitoring
23
23
  Requires-Dist: apache-airflow-providers-common-compat>=1.2.1rc0
24
- Requires-Dist: apache-airflow-providers-common-sql>=1.6.0rc0
24
+ Requires-Dist: apache-airflow-providers-common-sql>=1.20.0rc0
25
25
  Requires-Dist: apache-airflow>=2.8.0rc0
26
26
  Requires-Dist: attrs>=22.2
27
- Requires-Dist: openlineage-integration-common>=1.22.0
28
- Requires-Dist: openlineage-python>=1.22.0
29
- Requires-Dist: apache-airflow-providers-common-compat ; extra == "common.compat"
30
- Requires-Dist: apache-airflow-providers-common-sql ; extra == "common.sql"
27
+ Requires-Dist: openlineage-integration-common>=1.24.2
28
+ Requires-Dist: openlineage-python>=1.24.2
29
+ Requires-Dist: apache-airflow-providers-common-compat ; extra == "common-compat"
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.13.0/changelog.html
33
- Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0
32
+ Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.0/changelog.html
33
+ Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.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
37
37
  Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
38
- Provides-Extra: common.compat
39
- Provides-Extra: common.sql
38
+ Provides-Extra: common-compat
39
+ Provides-Extra: common-sql
40
40
 
41
41
 
42
42
  .. Licensed to the Apache Software Foundation (ASF) under one
@@ -82,7 +82,7 @@ Provides-Extra: common.sql
82
82
 
83
83
  Package ``apache-airflow-providers-openlineage``
84
84
 
85
- Release: ``1.13.0.rc1``
85
+ Release: ``1.14.0.rc1``
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.13.0/>`_.
98
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.0/>`_.
99
99
 
100
100
  Installation
101
101
  ------------
@@ -113,11 +113,11 @@ Requirements
113
113
  PIP package Version required
114
114
  ========================================== ==================
115
115
  ``apache-airflow`` ``>=2.8.0``
116
- ``apache-airflow-providers-common-sql`` ``>=1.6.0``
116
+ ``apache-airflow-providers-common-sql`` ``>=1.20.0``
117
117
  ``apache-airflow-providers-common-compat`` ``>=1.2.1``
118
118
  ``attrs`` ``>=22.2``
119
- ``openlineage-integration-common`` ``>=1.22.0``
120
- ``openlineage-python`` ``>=1.22.0``
119
+ ``openlineage-integration-common`` ``>=1.24.2``
120
+ ``openlineage-python`` ``>=1.24.2``
121
121
  ========================================== ==================
122
122
 
123
123
  Cross provider package dependencies
@@ -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.13.0/changelog.html>`_.
144
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.0/changelog.html>`_.
@@ -42,7 +42,7 @@
42
42
 
43
43
  Package ``apache-airflow-providers-openlineage``
44
44
 
45
- Release: ``1.13.0.rc1``
45
+ Release: ``1.14.0.rc1``
46
46
 
47
47
 
48
48
  `OpenLineage <https://openlineage.io/>`__
@@ -55,7 +55,7 @@ This is a provider package for ``openlineage`` provider. All classes for this pr
55
55
  are in ``airflow.providers.openlineage`` python package.
56
56
 
57
57
  You can find package information and changelog for the provider
58
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0/>`_.
58
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.0/>`_.
59
59
 
60
60
  Installation
61
61
  ------------
@@ -73,11 +73,11 @@ Requirements
73
73
  PIP package Version required
74
74
  ========================================== ==================
75
75
  ``apache-airflow`` ``>=2.8.0``
76
- ``apache-airflow-providers-common-sql`` ``>=1.6.0``
76
+ ``apache-airflow-providers-common-sql`` ``>=1.20.0``
77
77
  ``apache-airflow-providers-common-compat`` ``>=1.2.1``
78
78
  ``attrs`` ``>=22.2``
79
- ``openlineage-integration-common`` ``>=1.22.0``
80
- ``openlineage-python`` ``>=1.22.0``
79
+ ``openlineage-integration-common`` ``>=1.24.2``
80
+ ``openlineage-python`` ``>=1.24.2``
81
81
  ========================================== ==================
82
82
 
83
83
  Cross provider package dependencies
@@ -101,4 +101,4 @@ Dependent package
101
101
  ================================================================================================================== =================
102
102
 
103
103
  The changelog for the provider package can be found in the
104
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0/changelog.html>`_.
104
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.0/changelog.html>`_.
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "1.13.0"
32
+ __version__ = "1.14.0"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
35
  "2.8.0"
@@ -198,6 +198,8 @@ class ExtractorManager(LoggingMixin):
198
198
  except ImportError:
199
199
  return None
200
200
 
201
+ if not hasattr(get_hook_lineage_collector(), "has_collected"):
202
+ return None
201
203
  if not get_hook_lineage_collector().has_collected:
202
204
  return None
203
205
 
@@ -30,6 +30,7 @@ def get_provider_info():
30
30
  "state": "ready",
31
31
  "source-date-epoch": 1730013356,
32
32
  "versions": [
33
+ "1.14.0",
33
34
  "1.13.0",
34
35
  "1.12.2",
35
36
  "1.12.1",
@@ -56,11 +57,11 @@ def get_provider_info():
56
57
  ],
57
58
  "dependencies": [
58
59
  "apache-airflow>=2.8.0",
59
- "apache-airflow-providers-common-sql>=1.6.0",
60
+ "apache-airflow-providers-common-sql>=1.20.0",
60
61
  "apache-airflow-providers-common-compat>=1.2.1",
61
62
  "attrs>=22.2",
62
- "openlineage-integration-common>=1.22.0",
63
- "openlineage-python>=1.22.0",
63
+ "openlineage-integration-common>=1.24.2",
64
+ "openlineage-python>=1.24.2",
64
65
  ],
65
66
  "integrations": [
66
67
  {
@@ -90,7 +91,7 @@ def get_provider_info():
90
91
  "disabled_for_operators": {
91
92
  "description": "Exclude some Operators from emitting OpenLineage events by passing a string of semicolon separated\nfull import paths of Operators to disable.\n",
92
93
  "type": "string",
93
- "example": "airflow.providers.standard.operators.bash.BashOperator; airflow.operators.python.PythonOperator",
94
+ "example": "airflow.providers.standard.operators.bash.BashOperator; airflow.providers.standard.operators.python.PythonOperator",
94
95
  "default": "",
95
96
  "version_added": "1.1.0",
96
97
  },
@@ -32,7 +32,6 @@ from openlineage.client.facet_v2 import (
32
32
  nominal_time_run,
33
33
  ownership_job,
34
34
  parent_run,
35
- processing_engine_run,
36
35
  source_code_location_job,
37
36
  )
38
37
  from openlineage.client.uuid import generate_static_uuid
@@ -42,6 +41,7 @@ from airflow.providers.openlineage.utils.utils import (
42
41
  OpenLineageRedactor,
43
42
  get_airflow_debug_facet,
44
43
  get_airflow_state_run_facet,
44
+ get_processing_engine_facet,
45
45
  )
46
46
  from airflow.stats import Stats
47
47
  from airflow.utils.log.logging_mixin import LoggingMixin
@@ -84,7 +84,7 @@ class OpenLineageAdapter(LoggingMixin):
84
84
  "OpenLineage configuration found. Transport type: `%s`",
85
85
  config.get("type", "no type provided"),
86
86
  )
87
- self._client = OpenLineageClient.from_dict(config=config)
87
+ self._client = OpenLineageClient(config=config)
88
88
  else:
89
89
  self.log.debug(
90
90
  "OpenLineage configuration not found directly in Airflow. "
@@ -98,9 +98,7 @@ class OpenLineageAdapter(LoggingMixin):
98
98
  openlineage_config_path = conf.config_path(check_legacy_env_var=False)
99
99
  if openlineage_config_path:
100
100
  config = self._read_yaml_config(openlineage_config_path)
101
- if config:
102
- return config.get("transport", None)
103
- self.log.debug("OpenLineage config file is empty: `%s`", openlineage_config_path)
101
+ return config
104
102
  else:
105
103
  self.log.debug("OpenLineage config_path configuration not found.")
106
104
 
@@ -109,7 +107,7 @@ class OpenLineageAdapter(LoggingMixin):
109
107
  if not transport_config:
110
108
  self.log.debug("OpenLineage transport configuration not found.")
111
109
  return None
112
- return transport_config
110
+ return {"transport": transport_config}
113
111
 
114
112
  @staticmethod
115
113
  def _read_yaml_config(path: str) -> dict | None:
@@ -197,18 +195,10 @@ class OpenLineageAdapter(LoggingMixin):
197
195
  :param task: metadata container with information extracted from operator
198
196
  :param run_facets: custom run facets
199
197
  """
200
- from airflow.version import version as AIRFLOW_VERSION
201
-
202
- processing_engine_version_facet = processing_engine_run.ProcessingEngineRunFacet(
203
- version=AIRFLOW_VERSION,
204
- name="Airflow",
205
- openlineageAdapterVersion=OPENLINEAGE_PROVIDER_VERSION,
206
- )
207
-
208
198
  run_facets = run_facets or {}
209
199
  if task:
210
200
  run_facets = {**task.run_facets, **run_facets}
211
- run_facets["processing_engine"] = processing_engine_version_facet # type: ignore
201
+ run_facets = {**run_facets, **get_processing_engine_facet()} # type: ignore
212
202
  event = RunEvent(
213
203
  eventType=RunState.START,
214
204
  eventTime=event_time,
@@ -364,7 +354,7 @@ class OpenLineageAdapter(LoggingMixin):
364
354
  job_name=dag_id,
365
355
  nominal_start_time=nominal_start_time,
366
356
  nominal_end_time=nominal_end_time,
367
- run_facets={**run_facets, **get_airflow_debug_facet()},
357
+ run_facets={**run_facets, **get_airflow_debug_facet(), **get_processing_engine_facet()},
368
358
  ),
369
359
  inputs=[],
370
360
  outputs=[],
@@ -331,8 +331,11 @@ class SQLParser(LoggingMixin):
331
331
  split_statement = DbApiHook.split_sql_string
332
332
  except (ImportError, AttributeError):
333
333
  # No common.sql Airflow provider available or version is too old.
334
- def split_statement(sql: str) -> list[str]:
335
- splits = sqlparse.split(sqlparse.format(sql, strip_comments=True))
334
+ def split_statement(sql: str, strip_semicolon: bool = False) -> list[str]:
335
+ splits = sqlparse.split(
336
+ sql=sqlparse.format(sql, strip_comments=True),
337
+ strip_semicolon=strip_semicolon,
338
+ )
336
339
  return [s for s in splits if s]
337
340
 
338
341
  if isinstance(sql, str):
@@ -38,7 +38,7 @@ from airflow.exceptions import (
38
38
  # TODO: move this maybe to Airflow's logic?
39
39
  from airflow.models import DAG, BaseOperator, DagRun, MappedOperator
40
40
  from airflow.providers.common.compat.assets import Asset
41
- from airflow.providers.openlineage import conf
41
+ from airflow.providers.openlineage import __version__ as OPENLINEAGE_PROVIDER_VERSION, conf
42
42
  from airflow.providers.openlineage.plugins.facets import (
43
43
  AirflowDagRunFacet,
44
44
  AirflowDebugRunFacet,
@@ -65,7 +65,7 @@ from airflow.utils.module_loading import import_string
65
65
 
66
66
  if TYPE_CHECKING:
67
67
  from openlineage.client.event_v2 import Dataset as OpenLineageDataset
68
- from openlineage.client.facet_v2 import RunFacet
68
+ from openlineage.client.facet_v2 import RunFacet, processing_engine_run
69
69
 
70
70
  from airflow.models import TaskInstance
71
71
  from airflow.utils.state import DagRunState, TaskInstanceState
@@ -262,9 +262,31 @@ class DagInfo(InfoJsonEncodable):
262
262
  "start_date",
263
263
  "tags",
264
264
  ]
265
- casts = {"timetable": lambda dag: dag.timetable.serialize() if getattr(dag, "timetable", None) else None}
265
+ casts = {"timetable": lambda dag: DagInfo.serialize_timetable(dag)}
266
266
  renames = {"_dag_id": "dag_id"}
267
267
 
268
+ @classmethod
269
+ def serialize_timetable(cls, dag: DAG) -> dict[str, Any]:
270
+ serialized = dag.timetable.serialize()
271
+ if serialized != {} and serialized is not None:
272
+ return serialized
273
+ if (
274
+ hasattr(dag, "dataset_triggers")
275
+ and isinstance(dag.dataset_triggers, list)
276
+ and len(dag.dataset_triggers)
277
+ ):
278
+ triggers = dag.dataset_triggers
279
+ return {
280
+ "dataset_condition": {
281
+ "__type": "dataset_all",
282
+ "objects": [
283
+ {"__type": "dataset", "uri": trigger.uri, "extra": trigger.extra}
284
+ for trigger in triggers
285
+ ],
286
+ }
287
+ }
288
+ return {}
289
+
268
290
 
269
291
  class DagRunInfo(InfoJsonEncodable):
270
292
  """Defines encoding DagRun object to JSON."""
@@ -406,6 +428,18 @@ def _get_all_packages_installed() -> dict[str, str]:
406
428
  return {dist.metadata["Name"]: dist.version for dist in metadata.distributions()}
407
429
 
408
430
 
431
+ def get_processing_engine_facet() -> dict[str, processing_engine_run.ProcessingEngineRunFacet]:
432
+ from openlineage.client.facet_v2 import processing_engine_run
433
+
434
+ return {
435
+ "processing_engine": processing_engine_run.ProcessingEngineRunFacet(
436
+ version=AIRFLOW_VERSION,
437
+ name="Airflow",
438
+ openlineageAdapterVersion=OPENLINEAGE_PROVIDER_VERSION,
439
+ )
440
+ }
441
+
442
+
409
443
  def get_airflow_debug_facet() -> dict[str, AirflowDebugRunFacet]:
410
444
  if not conf.debug_mode():
411
445
  return {}
@@ -21,14 +21,13 @@
21
21
 
22
22
  # IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE
23
23
  # `pyproject_TEMPLATE.toml.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
24
- #
25
24
  [build-system]
26
- requires = ["flit_core >=3.2,<4"]
25
+ requires = ["flit_core==3.10.1"]
27
26
  build-backend = "flit_core.buildapi"
28
27
 
29
28
  [project]
30
29
  name = "apache-airflow-providers-openlineage"
31
- version = "1.13.0.rc1"
30
+ version = "1.14.0.rc1"
32
31
  description = "Provider package apache-airflow-providers-openlineage for Apache Airflow"
33
32
  readme = "README.rst"
34
33
  authors = [
@@ -56,16 +55,16 @@ classifiers = [
56
55
  requires-python = "~=3.9"
57
56
  dependencies = [
58
57
  "apache-airflow-providers-common-compat>=1.2.1rc0",
59
- "apache-airflow-providers-common-sql>=1.6.0rc0",
58
+ "apache-airflow-providers-common-sql>=1.20.0rc0",
60
59
  "apache-airflow>=2.8.0rc0",
61
60
  "attrs>=22.2",
62
- "openlineage-integration-common>=1.22.0",
63
- "openlineage-python>=1.22.0",
61
+ "openlineage-integration-common>=1.24.2",
62
+ "openlineage-python>=1.24.2",
64
63
  ]
65
64
 
66
65
  [project.urls]
67
- "Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0"
68
- "Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.13.0/changelog.html"
66
+ "Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.0"
67
+ "Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-openlineage/1.14.0/changelog.html"
69
68
  "Bug Tracker" = "https://github.com/apache/airflow/issues"
70
69
  "Source Code" = "https://github.com/apache/airflow"
71
70
  "Slack Chat" = "https://s.apache.org/airflow-slack"