openlineage-python 1.34.0__tar.gz → 1.36.0__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.
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/PKG-INFO +6 -2
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/__init__.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/client.py +53 -27
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/constants.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/filter.py +5 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/base.py +3 -3
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/catalog_dataset.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/column_lineage_dataset.py +4 -4
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/data_quality_metrics_input_dataset.py +4 -4
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/ownership_dataset.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/ownership_job.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/parent_run.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/schema_dataset.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/source_code_location_job.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/sql_job.py +2 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/symlinks_dataset.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/cli.py +2 -2
- openlineage_python-1.36.0/openlineage/client/naming/dataset.py +512 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/run.py +5 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/serde.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/__init__.py +9 -5
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/amazon_datazone.py +7 -1
- openlineage_python-1.36.0/openlineage/client/transport/async_http.py +617 -0
- openlineage_python-1.36.0/openlineage/client/transport/composite.py +170 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/factory.py +8 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/http.py +35 -30
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/kafka.py +27 -7
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/transform/transform.py +3 -0
- openlineage_python-1.36.0/openlineage/client/transport/transport.py +70 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/utils.py +2 -2
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/pyproject.toml +42 -3
- openlineage_python-1.36.0/tests/config/test-transport.yaml +7 -0
- openlineage_python-1.36.0/tests/conftest.py +364 -0
- openlineage_python-1.36.0/tests/fixtures/events.py +134 -0
- openlineage_python-1.36.0/tests/fixtures/mock_responses.py +92 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/generator/test_base.py +1 -1
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/generator/test_cli.py +1 -1
- openlineage_python-1.36.0/tests/integration/docker-compose.yml +21 -0
- openlineage_python-1.36.0/tests/integration/test_server/Dockerfile +25 -0
- openlineage_python-1.36.0/tests/integration/test_server/requirements.txt +3 -0
- openlineage_python-1.36.0/tests/integration/test_server/test_server.py +642 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_amazon_datazone.py +16 -4
- openlineage_python-1.36.0/tests/test_async_http.py +971 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_client.py +402 -35
- openlineage_python-1.36.0/tests/test_composite.py +330 -0
- openlineage_python-1.36.0/tests/test_dataset.py +276 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_facet.py +65 -34
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_facet_v2.py +31 -23
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_factory.py +93 -0
- openlineage_python-1.36.0/tests/test_http.py +510 -0
- openlineage_python-1.36.0/tests/test_http_integration.py +503 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_kafka.py +123 -40
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_msk_iam.py +9 -2
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/transform/test_transform.py +19 -1
- openlineage_python-1.36.0/tests/transform/transformers/__init__.py +2 -0
- openlineage_python-1.34.0/openlineage/client/transport/composite.py +0 -92
- openlineage_python-1.34.0/openlineage/client/transport/transport.py +0 -53
- openlineage_python-1.34.0/tests/conftest.py +0 -54
- openlineage_python-1.34.0/tests/test_composite.py +0 -140
- openlineage_python-1.34.0/tests/test_http.py +0 -350
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/.gitignore +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/README.md +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/Makefile +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/conf.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/convert.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/index.rst +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/make.bat +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/source/openlineage.client.rst +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/event_v2.py +6 -6
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/facet.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/facet_v2.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/facets.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/data_quality_assertions_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/dataset_type_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/dataset_version_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/datasource_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/documentation_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/documentation_job.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/environment_variables_run.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/error_message_run.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/external_query_run.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/extraction_error_run.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/input_statistics_input_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/job_type_job.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/lifecycle_state_change_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/nominal_time_run.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/output_statistics_output_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/processing_engine_run.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/source_code_job.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/storage_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/tags_dataset.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/tags_job.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/tags_run.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/base.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/generate.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/header.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/Enum.jinja2 +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/dataclass.jinja2 +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/facet_v2.jinja2 +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/root.jinja2 +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/validators.jinja2 +0 -0
- {openlineage_python-1.34.0/openlineage/client/transport/transform/transformers → openlineage_python-1.36.0/openlineage/client/naming}/__init__.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/py.typed +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/tags.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/console.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/file.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/msk_iam.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/noop.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/transform/__init__.py +1 -1
- {openlineage_python-1.34.0/tests → openlineage_python-1.36.0/openlineage/client/transport/transform/transformers}/__init__.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/transform/transformers/job_namespace_replace_transformer.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/uuid.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/redact_fields.yml +0 -0
- {openlineage_python-1.34.0/tests/generator → openlineage_python-1.36.0/tests}/__init__.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/config.yml +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/exact_filter.yml +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/http.yml +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/openlineage.yml +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/regex_filter.yml +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/example_full_event.json +0 -0
- {openlineage_python-1.34.0/tests/transform → openlineage_python-1.36.0/tests/generator}/__init__.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/nominal_time_without_end.json +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/serde_example_dataset_event.json +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/serde_example_job_event.json +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/serde_example_run_event.json +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_events.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_file.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_utils.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_uuid.py +0 -0
- {openlineage_python-1.34.0/tests/transform/transformers → openlineage_python-1.36.0/tests/transform}/__init__.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/transform/transformers/test_job_namespace_replace_transformer.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/transport.py +0 -0
- {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openlineage-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.36.0
|
|
4
4
|
Summary: OpenLineage Python Client
|
|
5
5
|
Author-email: OpenLineage <info@openlineage.io>
|
|
6
6
|
Keywords: openlineage
|
|
@@ -14,10 +14,12 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Requires-Python: >=3.9
|
|
16
16
|
Requires-Dist: attrs>=20.0
|
|
17
|
+
Requires-Dist: build>=1.2.2
|
|
18
|
+
Requires-Dist: httpx>=0.27.0
|
|
17
19
|
Requires-Dist: packaging>=21.0
|
|
18
20
|
Requires-Dist: python-dateutil>=2.8.2
|
|
19
21
|
Requires-Dist: pyyaml>=5.4
|
|
20
|
-
Requires-Dist: requests>=2.32.
|
|
22
|
+
Requires-Dist: requests>=2.32.4
|
|
21
23
|
Provides-Extra: datazone
|
|
22
24
|
Requires-Dist: boto3>=1.34.134; extra == 'datazone'
|
|
23
25
|
Provides-Extra: docs
|
|
@@ -36,10 +38,12 @@ Requires-Dist: aws-msk-iam-sasl-signer-python>=1.0.1; extra == 'msk-iam'
|
|
|
36
38
|
Requires-Dist: confluent-kafka>=2.1.1; extra == 'msk-iam'
|
|
37
39
|
Provides-Extra: test
|
|
38
40
|
Requires-Dist: covdefaults>=2.3; extra == 'test'
|
|
41
|
+
Requires-Dist: fastapi>=0.100.0; extra == 'test'
|
|
39
42
|
Requires-Dist: pytest-cov>=4.1; extra == 'test'
|
|
40
43
|
Requires-Dist: pytest-mock>=3.10; extra == 'test'
|
|
41
44
|
Requires-Dist: pytest>=7.3.1; extra == 'test'
|
|
42
45
|
Requires-Dist: pyyaml>=5.4; extra == 'test'
|
|
46
|
+
Requires-Dist: uvicorn>=0.20.0; extra == 'test'
|
|
43
47
|
Description-Content-Type: text/markdown
|
|
44
48
|
|
|
45
49
|
# OpenLineage Python Client
|
|
@@ -8,7 +8,7 @@ from openlineage.client.client import OpenLineageClient, OpenLineageClientOption
|
|
|
8
8
|
|
|
9
9
|
with warnings.catch_warnings():
|
|
10
10
|
warnings.simplefilter("ignore", DeprecationWarning)
|
|
11
|
-
from openlineage.client.facet import set_producer as set_producer_v1
|
|
11
|
+
from openlineage.client.facet import set_producer as set_producer_v1
|
|
12
12
|
from openlineage.client.facet_v2 import set_producer as set_producer_v2
|
|
13
13
|
|
|
14
14
|
|
|
@@ -28,7 +28,7 @@ from openlineage.client.transport import (
|
|
|
28
28
|
TransportFactory,
|
|
29
29
|
get_default_factory,
|
|
30
30
|
)
|
|
31
|
-
from openlineage.client.transport.http import HttpConfig, HttpTransport
|
|
31
|
+
from openlineage.client.transport.http import HttpConfig, HttpTransport
|
|
32
32
|
from openlineage.client.transport.noop import NoopConfig, NoopTransport
|
|
33
33
|
from openlineage.client.utils import deep_merge_dicts
|
|
34
34
|
|
|
@@ -183,6 +183,15 @@ class OpenLineageClient:
|
|
|
183
183
|
self.transport.emit(event)
|
|
184
184
|
log.debug("OpenLineage event successfully emitted.")
|
|
185
185
|
|
|
186
|
+
def close(self, timeout: float = -1.0) -> bool:
|
|
187
|
+
"""
|
|
188
|
+
Closes down the transport until all events are processed or timeout is reached.
|
|
189
|
+
Params:
|
|
190
|
+
timeout: Timeout in seconds. `-1` means to block until last event is processed, 0 means no timeout.
|
|
191
|
+
|
|
192
|
+
"""
|
|
193
|
+
return self.transport.close(timeout)
|
|
194
|
+
|
|
186
195
|
@property
|
|
187
196
|
def config(self) -> OpenLineageConfig:
|
|
188
197
|
"""
|
|
@@ -223,9 +232,9 @@ class OpenLineageClient:
|
|
|
223
232
|
This method determines the appropriate transport by executing a sequence of checks:
|
|
224
233
|
1. Verifies if OpenLineage is disabled through environment variable.
|
|
225
234
|
2. Looks for a transport object provided in the arguments.
|
|
226
|
-
3. Attempts to configure the transport from
|
|
235
|
+
3. Attempts to configure the transport from user config, config file or env vars.
|
|
227
236
|
4. Tries to initialize HTTP transport with an url argument (deprecated).
|
|
228
|
-
5. Tries to set up HTTP transport using environment variables.
|
|
237
|
+
5. Tries to set up HTTP transport using simple environment variables.
|
|
229
238
|
6. If no configuration is found, defaults to a console transport and logs a warning message.
|
|
230
239
|
|
|
231
240
|
Returns:
|
|
@@ -236,11 +245,11 @@ class OpenLineageClient:
|
|
|
236
245
|
log.info("OpenLineage is disabled. No events will be emitted.")
|
|
237
246
|
return NoopTransport(NoopConfig())
|
|
238
247
|
|
|
239
|
-
# 2. Check if transport is provided explicitly
|
|
248
|
+
# 2. Check if transport is provided explicitly as argument
|
|
240
249
|
if kwargs.get("transport"):
|
|
241
|
-
return cast(Transport, kwargs["transport"])
|
|
250
|
+
return cast("Transport", kwargs["transport"])
|
|
242
251
|
|
|
243
|
-
# 3. Check if transport configuration is provided
|
|
252
|
+
# 3. Check if transport configuration is provided as config (explicit, file or env vars)
|
|
244
253
|
if self.config.transport and self.config.transport.get("type"):
|
|
245
254
|
factory = kwargs.get("factory") or get_default_factory()
|
|
246
255
|
return factory.create(self.config.transport)
|
|
@@ -251,7 +260,7 @@ class OpenLineageClient:
|
|
|
251
260
|
url=kwargs["url"], options=kwargs.get("options"), session=kwargs.get("session")
|
|
252
261
|
)
|
|
253
262
|
|
|
254
|
-
# 5. Check HTTP transport initialization with env variables
|
|
263
|
+
# 5. Check HTTP transport initialization with simple env variables
|
|
255
264
|
if os.environ.get("OPENLINEAGE_URL"):
|
|
256
265
|
return self._http_transport_from_env_variables()
|
|
257
266
|
|
|
@@ -292,7 +301,7 @@ class OpenLineageClient:
|
|
|
292
301
|
return path
|
|
293
302
|
if path and verbose:
|
|
294
303
|
log.debug("OpenLineage config file is missing or not readable: `%s`.", path)
|
|
295
|
-
except Exception:
|
|
304
|
+
except Exception:
|
|
296
305
|
# We can get different errors depending on system
|
|
297
306
|
if verbose:
|
|
298
307
|
log.exception("Couldn't check if OpenLineage config file is readable: `%s`", path)
|
|
@@ -300,20 +309,19 @@ class OpenLineageClient:
|
|
|
300
309
|
|
|
301
310
|
@staticmethod
|
|
302
311
|
def _http_transport_from_env_variables() -> HttpTransport:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
return HttpTransport(config)
|
|
312
|
+
"""
|
|
313
|
+
Create HTTP transport from legacy environment variables
|
|
314
|
+
"""
|
|
315
|
+
# Start with basic config from legacy environment variables
|
|
316
|
+
config_dict = {
|
|
317
|
+
"url": os.environ["OPENLINEAGE_URL"],
|
|
318
|
+
"auth": {
|
|
319
|
+
"type": "api_key",
|
|
320
|
+
"apiKey": os.environ.get("OPENLINEAGE_API_KEY", ""),
|
|
321
|
+
},
|
|
322
|
+
"endpoint": os.environ.get("OPENLINEAGE_ENDPOINT", "api/v1/lineage"),
|
|
323
|
+
}
|
|
324
|
+
return HttpTransport(HttpConfig.from_dict(config_dict))
|
|
317
325
|
|
|
318
326
|
@staticmethod
|
|
319
327
|
def _http_transport_from_url(
|
|
@@ -338,14 +346,18 @@ class OpenLineageClient:
|
|
|
338
346
|
k.startswith(f"OPENLINEAGE__TRANSPORT__TRANSPORTS__{default_transport_name}")
|
|
339
347
|
for k in os.environ
|
|
340
348
|
):
|
|
341
|
-
log.
|
|
349
|
+
log.info(
|
|
342
350
|
"%s already found in environment variables, skipping aliasing OPENLINEAGE_URL",
|
|
343
351
|
default_transport_name,
|
|
344
352
|
)
|
|
345
353
|
return
|
|
354
|
+
|
|
355
|
+
api_key = os.environ.get("OPENLINEAGE_API_KEY")
|
|
356
|
+
endpoint = os.environ.get("OPENLINEAGE_ENDPOINT")
|
|
357
|
+
|
|
346
358
|
os.environ[f"OPENLINEAGE__TRANSPORT__TRANSPORTS__{default_transport_name}__TYPE"] = "http"
|
|
347
359
|
os.environ[f"OPENLINEAGE__TRANSPORT__TRANSPORTS__{default_transport_name}__URL"] = url
|
|
348
|
-
if api_key
|
|
360
|
+
if api_key:
|
|
349
361
|
os.environ[
|
|
350
362
|
f"OPENLINEAGE__TRANSPORT__TRANSPORTS__{default_transport_name}__AUTH"
|
|
351
363
|
] = json.dumps(
|
|
@@ -354,16 +366,30 @@ class OpenLineageClient:
|
|
|
354
366
|
"apiKey": api_key,
|
|
355
367
|
}
|
|
356
368
|
)
|
|
357
|
-
if endpoint
|
|
369
|
+
if endpoint:
|
|
358
370
|
os.environ[
|
|
359
371
|
f"OPENLINEAGE__TRANSPORT__TRANSPORTS__{default_transport_name}__ENDPOINT"
|
|
360
372
|
] = endpoint
|
|
361
373
|
|
|
374
|
+
if os.environ.get("OPENLINEAGE__TRANSPORT__TYPE") == "async_http":
|
|
375
|
+
# Special case - for seamless switch to async transport
|
|
376
|
+
if not os.getenv("OPENLINEAGE__TRANSPORT__URL"):
|
|
377
|
+
os.environ["OPENLINEAGE__TRANSPORT__URL"] = url
|
|
378
|
+
if api_key and not os.getenv("OPENLINEAGE__TRANSPORT__AUTH"):
|
|
379
|
+
os.environ["OPENLINEAGE__TRANSPORT__AUTH"] = json.dumps(
|
|
380
|
+
{
|
|
381
|
+
"type": "api_key",
|
|
382
|
+
"apiKey": api_key,
|
|
383
|
+
}
|
|
384
|
+
)
|
|
385
|
+
if endpoint and not os.getenv("OPENLINEAGE__TRANSPORT__ENDPOINT"):
|
|
386
|
+
os.environ["OPENLINEAGE__TRANSPORT__ENDPOINT"] = endpoint
|
|
387
|
+
|
|
362
388
|
@classmethod
|
|
363
389
|
def _load_config_from_env_variables(cls) -> dict[str, Any] | None:
|
|
364
390
|
config: dict[str, Any] = {}
|
|
365
391
|
|
|
366
|
-
# get os.environ.items only starting with
|
|
392
|
+
# get os.environ.items only starting with OPENLINEAGE__ prefix and reverse sort
|
|
367
393
|
# to make sure that top-level keys have precedence
|
|
368
394
|
env_vars = sorted(
|
|
369
395
|
filter(lambda k: k[0].startswith(cls.DYNAMIC_ENV_VARS_PREFIX), os.environ.items()), reverse=True
|
|
@@ -442,8 +468,8 @@ class OpenLineageClient:
|
|
|
442
468
|
|
|
443
469
|
return event
|
|
444
470
|
|
|
471
|
+
@staticmethod
|
|
445
472
|
def _update_tag_facet(
|
|
446
|
-
self,
|
|
447
473
|
tags_facet: TagsJobFacet | TagsRunFacet,
|
|
448
474
|
user_tags: list[TagsJobFacetFields | TagsRunFacetFields],
|
|
449
475
|
) -> TagsJobFacet | TagsRunFacet:
|
|
@@ -5,10 +5,14 @@ from __future__ import annotations
|
|
|
5
5
|
import logging
|
|
6
6
|
import re
|
|
7
7
|
import typing
|
|
8
|
+
import warnings
|
|
8
9
|
|
|
9
10
|
import attr
|
|
10
11
|
from openlineage.client.event_v2 import RunEvent as RunEvent_v2
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
with warnings.catch_warnings():
|
|
14
|
+
warnings.simplefilter("ignore", DeprecationWarning)
|
|
15
|
+
from openlineage.client.run import RunEvent
|
|
12
16
|
|
|
13
17
|
log = logging.getLogger(__name__)
|
|
14
18
|
RunEventType = typing.Union[RunEvent, RunEvent_v2]
|
{openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/base.py
RENAMED
|
@@ -23,7 +23,7 @@ class BaseEvent(RedactMixin):
|
|
|
23
23
|
eventTime: str = attr.field() # noqa: N815
|
|
24
24
|
"""the time the event occurred at"""
|
|
25
25
|
|
|
26
|
-
producer: str = attr.field(default="", kw_only=True)
|
|
26
|
+
producer: str = attr.field(default="", kw_only=True) # noqa: N815
|
|
27
27
|
schemaURL: str = attr.field( # noqa: N815
|
|
28
28
|
default="https://openlineage.io/spec/2-0-2/OpenLineage.json#/$defs/BaseEvent", init=False
|
|
29
29
|
)
|
|
@@ -70,7 +70,7 @@ class BaseEvent(RedactMixin):
|
|
|
70
70
|
class BaseFacet(RedactMixin):
|
|
71
71
|
"""all fields of the base facet are prefixed with _ to avoid name conflicts in facets"""
|
|
72
72
|
|
|
73
|
-
_producer: str = attr.field(default="", kw_only=True)
|
|
73
|
+
_producer: str = attr.field(default="", kw_only=True) # noqa: N815
|
|
74
74
|
_schemaURL: str = attr.field( # noqa: N815
|
|
75
75
|
default="https://openlineage.io/spec/2-0-2/OpenLineage.json#/$defs/BaseFacet", init=False
|
|
76
76
|
)
|
|
@@ -86,7 +86,7 @@ class BaseFacet(RedactMixin):
|
|
|
86
86
|
def skip_redact(self) -> list[str]:
|
|
87
87
|
return self._base_skip_redact + self._additional_skip_redact
|
|
88
88
|
|
|
89
|
-
def with_additional_properties(self, **kwargs: dict[str, Any]) -> BaseFacet:
|
|
89
|
+
def with_additional_properties(self, **kwargs: dict[str, Any]) -> "BaseFacet":
|
|
90
90
|
"""Add additional properties to updated class instance."""
|
|
91
91
|
current_attrs = [a.name for a in attr.fields(self.__class__)]
|
|
92
92
|
|
|
@@ -38,7 +38,7 @@ class Fields(RedactMixin):
|
|
|
38
38
|
original data available (like a hash of PII for example)
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
def with_additional_properties(self, **kwargs: dict[str, Any]) -> Fields:
|
|
41
|
+
def with_additional_properties(self, **kwargs: dict[str, Any]) -> "Fields":
|
|
42
42
|
"""Add additional properties to updated class instance."""
|
|
43
43
|
current_attrs = [a.name for a in attr.fields(self.__class__)]
|
|
44
44
|
|
|
@@ -75,7 +75,7 @@ class InputField(RedactMixin):
|
|
|
75
75
|
transformations: list[Transformation] | None = attr.field(factory=list)
|
|
76
76
|
_skip_redact: ClassVar[list[str]] = ["namespace", "name", "field"]
|
|
77
77
|
|
|
78
|
-
def with_additional_properties(self, **kwargs: dict[str, Any]) -> InputField:
|
|
78
|
+
def with_additional_properties(self, **kwargs: dict[str, Any]) -> "InputField":
|
|
79
79
|
"""Add additional properties to updated class instance."""
|
|
80
80
|
current_attrs = [a.name for a in attr.fields(self.__class__)]
|
|
81
81
|
|
|
@@ -102,7 +102,7 @@ class InputField(RedactMixin):
|
|
|
102
102
|
|
|
103
103
|
@attr.define
|
|
104
104
|
class Transformation(RedactMixin):
|
|
105
|
-
type: str
|
|
105
|
+
type: str # noqa: A003
|
|
106
106
|
"""The type of the transformation. Allowed values are: DIRECT, INDIRECT"""
|
|
107
107
|
|
|
108
108
|
subtype: str | None = attr.field(default=None)
|
|
@@ -116,7 +116,7 @@ class Transformation(RedactMixin):
|
|
|
116
116
|
|
|
117
117
|
_skip_redact: ClassVar[list[str]] = ["type", "subtype", "masking"]
|
|
118
118
|
|
|
119
|
-
def with_additional_properties(self, **kwargs: dict[str, Any]) -> Transformation:
|
|
119
|
+
def with_additional_properties(self, **kwargs: dict[str, Any]) -> "Transformation":
|
|
120
120
|
"""Add additional properties to updated class instance."""
|
|
121
121
|
current_attrs = [a.name for a in attr.fields(self.__class__)]
|
|
122
122
|
|
|
@@ -16,14 +16,14 @@ class ColumnMetrics(RedactMixin):
|
|
|
16
16
|
distinctCount: int | None = attr.field(default=None) # noqa: N815
|
|
17
17
|
"""The number of distinct values in this column for the rows evaluated"""
|
|
18
18
|
|
|
19
|
-
sum: float | None = attr.field(default=None)
|
|
19
|
+
sum: float | None = attr.field(default=None) # noqa: A003
|
|
20
20
|
"""The total sum of values in this column for the rows evaluated"""
|
|
21
21
|
|
|
22
22
|
count: float | None = attr.field(default=None)
|
|
23
23
|
"""The number of values in this column"""
|
|
24
24
|
|
|
25
|
-
min: float | None = attr.field(default=None)
|
|
26
|
-
max: float | None = attr.field(default=None)
|
|
25
|
+
min: float | None = attr.field(default=None) # noqa: A003
|
|
26
|
+
max: float | None = attr.field(default=None) # noqa: A003
|
|
27
27
|
quantiles: dict[str, float] | None = attr.field(factory=dict)
|
|
28
28
|
"""The property key is the quantile. Examples: 0.1 0.25 0.5 0.75 1"""
|
|
29
29
|
|
|
@@ -36,7 +36,7 @@ class DataQualityMetricsInputDatasetFacet(InputDatasetFacet):
|
|
|
36
36
|
rowCount: int | None = attr.field(default=None) # noqa: N815
|
|
37
37
|
"""The number of rows evaluated"""
|
|
38
38
|
|
|
39
|
-
bytes: int | None = attr.field(default=None)
|
|
39
|
+
bytes: int | None = attr.field(default=None) # noqa: A003
|
|
40
40
|
"""The size in bytes"""
|
|
41
41
|
|
|
42
42
|
fileCount: int | None = attr.field(default=None) # noqa: N815
|
|
@@ -15,7 +15,7 @@ class Owner(RedactMixin):
|
|
|
15
15
|
the identifier of the owner of the Dataset. It is recommended to define this as a URN. For example
|
|
16
16
|
application:foo, user:jdoe, team:data
|
|
17
17
|
"""
|
|
18
|
-
type: str | None = attr.field(default=None)
|
|
18
|
+
type: str | None = attr.field(default=None) # noqa: A003
|
|
19
19
|
"""The type of ownership (optional)"""
|
|
20
20
|
|
|
21
21
|
|
|
@@ -15,7 +15,7 @@ class Owner(RedactMixin):
|
|
|
15
15
|
the identifier of the owner of the Job. It is recommended to define this as a URN. For example
|
|
16
16
|
application:foo, user:jdoe, team:data
|
|
17
17
|
"""
|
|
18
|
-
type: str | None = attr.field(default=None)
|
|
18
|
+
type: str | None = attr.field(default=None) # noqa: A003
|
|
19
19
|
"""The type of ownership (optional)"""
|
|
20
20
|
|
|
21
21
|
|
{openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/parent_run.py
RENAMED
|
@@ -36,7 +36,7 @@ class ParentRunFacet(RunFacet):
|
|
|
36
36
|
return "https://openlineage.io/spec/facets/1-1-0/ParentRunFacet.json#/$defs/ParentRunFacet"
|
|
37
37
|
|
|
38
38
|
@classmethod
|
|
39
|
-
def create(cls, runId: str, namespace: str, name: str) -> ParentRunFacet: # noqa: N803
|
|
39
|
+
def create(cls, runId: str, namespace: str, name: str) -> "ParentRunFacet": # noqa: N803
|
|
40
40
|
import warnings
|
|
41
41
|
|
|
42
42
|
warnings.warn(
|
|
@@ -23,7 +23,7 @@ class SchemaDatasetFacetFields(RedactMixin):
|
|
|
23
23
|
name: str
|
|
24
24
|
"""The name of the field."""
|
|
25
25
|
|
|
26
|
-
type: str | None = attr.field(default=None)
|
|
26
|
+
type: str | None = attr.field(default=None) # noqa: A003
|
|
27
27
|
"""The type of the field."""
|
|
28
28
|
|
|
29
29
|
description: str | None = attr.field(default=None)
|
{openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/sql_job.py
RENAMED
|
@@ -10,7 +10,8 @@ from openlineage.client.generated.base import JobFacet
|
|
|
10
10
|
@attr.define
|
|
11
11
|
class SQLJobFacet(JobFacet):
|
|
12
12
|
query: str
|
|
13
|
+
dialect: str | None = attr.field(default=None)
|
|
13
14
|
|
|
14
15
|
@staticmethod
|
|
15
16
|
def _get_schema() -> str:
|
|
16
|
-
return "https://openlineage.io/spec/facets/1-0
|
|
17
|
+
return "https://openlineage.io/spec/facets/1-1-0/SQLJobFacet.json#/$defs/SQLJobFacet"
|
|
@@ -6,7 +6,7 @@ import pathlib
|
|
|
6
6
|
import tempfile
|
|
7
7
|
|
|
8
8
|
import click
|
|
9
|
-
import
|
|
9
|
+
import httpx
|
|
10
10
|
from openlineage.client.generator.base import (
|
|
11
11
|
camel_to_snake,
|
|
12
12
|
format_and_save_output,
|
|
@@ -19,7 +19,7 @@ BASE_SPEC_URL = "https://openlineage.io/spec/2-0-2/OpenLineage.json"
|
|
|
19
19
|
|
|
20
20
|
def get_base_spec() -> pathlib.Path:
|
|
21
21
|
"""Get the base spec from the OpenLineage repository."""
|
|
22
|
-
response =
|
|
22
|
+
response = httpx.get(BASE_SPEC_URL, timeout=10)
|
|
23
23
|
response.raise_for_status() # Raise an HTTPError for bad responses
|
|
24
24
|
tmpfile = pathlib.Path(tempfile.mkdtemp()) / "OpenLineage.json"
|
|
25
25
|
tmpfile.write_text(response.text)
|