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.
Files changed (133) hide show
  1. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/PKG-INFO +6 -2
  2. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/__init__.py +1 -1
  3. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/client.py +53 -27
  4. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/constants.py +1 -1
  5. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/filter.py +5 -1
  6. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/base.py +3 -3
  7. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/catalog_dataset.py +1 -1
  8. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/column_lineage_dataset.py +4 -4
  9. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/data_quality_metrics_input_dataset.py +4 -4
  10. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/ownership_dataset.py +1 -1
  11. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/ownership_job.py +1 -1
  12. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/parent_run.py +1 -1
  13. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/schema_dataset.py +1 -1
  14. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/source_code_location_job.py +1 -1
  15. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/sql_job.py +2 -1
  16. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/symlinks_dataset.py +1 -1
  17. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/cli.py +2 -2
  18. openlineage_python-1.36.0/openlineage/client/naming/dataset.py +512 -0
  19. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/run.py +5 -1
  20. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/serde.py +1 -1
  21. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/__init__.py +9 -5
  22. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/amazon_datazone.py +7 -1
  23. openlineage_python-1.36.0/openlineage/client/transport/async_http.py +617 -0
  24. openlineage_python-1.36.0/openlineage/client/transport/composite.py +170 -0
  25. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/factory.py +8 -0
  26. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/http.py +35 -30
  27. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/kafka.py +27 -7
  28. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/transform/transform.py +3 -0
  29. openlineage_python-1.36.0/openlineage/client/transport/transport.py +70 -0
  30. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/utils.py +2 -2
  31. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/pyproject.toml +42 -3
  32. openlineage_python-1.36.0/tests/config/test-transport.yaml +7 -0
  33. openlineage_python-1.36.0/tests/conftest.py +364 -0
  34. openlineage_python-1.36.0/tests/fixtures/events.py +134 -0
  35. openlineage_python-1.36.0/tests/fixtures/mock_responses.py +92 -0
  36. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/generator/test_base.py +1 -1
  37. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/generator/test_cli.py +1 -1
  38. openlineage_python-1.36.0/tests/integration/docker-compose.yml +21 -0
  39. openlineage_python-1.36.0/tests/integration/test_server/Dockerfile +25 -0
  40. openlineage_python-1.36.0/tests/integration/test_server/requirements.txt +3 -0
  41. openlineage_python-1.36.0/tests/integration/test_server/test_server.py +642 -0
  42. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_amazon_datazone.py +16 -4
  43. openlineage_python-1.36.0/tests/test_async_http.py +971 -0
  44. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_client.py +402 -35
  45. openlineage_python-1.36.0/tests/test_composite.py +330 -0
  46. openlineage_python-1.36.0/tests/test_dataset.py +276 -0
  47. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_facet.py +65 -34
  48. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_facet_v2.py +31 -23
  49. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_factory.py +93 -0
  50. openlineage_python-1.36.0/tests/test_http.py +510 -0
  51. openlineage_python-1.36.0/tests/test_http_integration.py +503 -0
  52. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_kafka.py +123 -40
  53. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_msk_iam.py +9 -2
  54. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/transform/test_transform.py +19 -1
  55. openlineage_python-1.36.0/tests/transform/transformers/__init__.py +2 -0
  56. openlineage_python-1.34.0/openlineage/client/transport/composite.py +0 -92
  57. openlineage_python-1.34.0/openlineage/client/transport/transport.py +0 -53
  58. openlineage_python-1.34.0/tests/conftest.py +0 -54
  59. openlineage_python-1.34.0/tests/test_composite.py +0 -140
  60. openlineage_python-1.34.0/tests/test_http.py +0 -350
  61. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/.gitignore +0 -0
  62. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/README.md +0 -0
  63. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/Makefile +0 -0
  64. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/conf.py +0 -0
  65. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/convert.py +0 -0
  66. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/index.rst +0 -0
  67. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/make.bat +0 -0
  68. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/docs/source/openlineage.client.rst +0 -0
  69. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/event_v2.py +6 -6
  70. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/facet.py +0 -0
  71. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/facet_v2.py +0 -0
  72. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/facets.py +0 -0
  73. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/data_quality_assertions_dataset.py +0 -0
  74. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/dataset_type_dataset.py +0 -0
  75. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/dataset_version_dataset.py +0 -0
  76. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/datasource_dataset.py +0 -0
  77. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/documentation_dataset.py +0 -0
  78. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/documentation_job.py +0 -0
  79. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/environment_variables_run.py +0 -0
  80. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/error_message_run.py +0 -0
  81. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/external_query_run.py +0 -0
  82. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/extraction_error_run.py +0 -0
  83. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/input_statistics_input_dataset.py +0 -0
  84. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/job_type_job.py +0 -0
  85. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/lifecycle_state_change_dataset.py +0 -0
  86. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/nominal_time_run.py +0 -0
  87. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/output_statistics_output_dataset.py +0 -0
  88. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/processing_engine_run.py +0 -0
  89. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/source_code_job.py +0 -0
  90. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/storage_dataset.py +0 -0
  91. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/tags_dataset.py +0 -0
  92. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/tags_job.py +0 -0
  93. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generated/tags_run.py +0 -0
  94. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/base.py +0 -0
  95. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/generate.py +0 -0
  96. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/header.py +0 -0
  97. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/Enum.jinja2 +0 -0
  98. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/dataclass.jinja2 +0 -0
  99. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/facet_v2.jinja2 +0 -0
  100. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/root.jinja2 +0 -0
  101. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/generator/templates/validators.jinja2 +0 -0
  102. {openlineage_python-1.34.0/openlineage/client/transport/transform/transformers → openlineage_python-1.36.0/openlineage/client/naming}/__init__.py +0 -0
  103. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/py.typed +0 -0
  104. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/tags.py +0 -0
  105. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/console.py +0 -0
  106. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/file.py +0 -0
  107. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/msk_iam.py +0 -0
  108. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/noop.py +0 -0
  109. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/transform/__init__.py +1 -1
  110. {openlineage_python-1.34.0/tests → openlineage_python-1.36.0/openlineage/client/transport/transform/transformers}/__init__.py +0 -0
  111. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/transport/transform/transformers/job_namespace_replace_transformer.py +0 -0
  112. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/openlineage/client/uuid.py +0 -0
  113. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/redact_fields.yml +0 -0
  114. {openlineage_python-1.34.0/tests/generator → openlineage_python-1.36.0/tests}/__init__.py +0 -0
  115. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/config.yml +0 -0
  116. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/exact_filter.yml +0 -0
  117. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/http.yml +0 -0
  118. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/openlineage.yml +0 -0
  119. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/config/regex_filter.yml +0 -0
  120. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/example_full_event.json +0 -0
  121. {openlineage_python-1.34.0/tests/transform → openlineage_python-1.36.0/tests/generator}/__init__.py +0 -0
  122. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/nominal_time_without_end.json +0 -0
  123. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/serde_example_dataset_event.json +0 -0
  124. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/serde_example_job_event.json +0 -0
  125. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/serde_example_run_event.json +0 -0
  126. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_events.py +0 -0
  127. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_file.py +0 -0
  128. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_utils.py +0 -0
  129. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/test_uuid.py +0 -0
  130. {openlineage_python-1.34.0/tests/transform/transformers → openlineage_python-1.36.0/tests/transform}/__init__.py +0 -0
  131. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/transform/transformers/test_job_namespace_replace_transformer.py +0 -0
  132. {openlineage_python-1.34.0 → openlineage_python-1.36.0}/tests/transport.py +0 -0
  133. {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.34.0
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.3
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, create_token_provider
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 a YAML config file.
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 in YAML config file
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: # noqa: BLE001
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
- config = HttpConfig(
304
- url=os.environ["OPENLINEAGE_URL"],
305
- auth=create_token_provider(
306
- {
307
- "type": "api_key",
308
- "apiKey": os.environ.get("OPENLINEAGE_API_KEY", ""),
309
- },
310
- ),
311
- )
312
- endpoint = os.environ.get("OPENLINEAGE_ENDPOINT", None)
313
- if endpoint is not None:
314
- config.endpoint = endpoint
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.warning(
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 := os.environ.get("OPENLINEAGE_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 := os.environ.get("OPENLINEAGE_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 OPENLINEAGE_ prefix and reverse sort
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:
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "1.34.0"
5
+ __version__ = "1.36.0"
6
6
 
7
7
  DEFAULT_TIMEOUT_MS = 5000
8
8
  DEFAULT_NAMESPACE_NAME = "default"
@@ -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
- from openlineage.client.run import RunEvent
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]
@@ -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
 
@@ -12,7 +12,7 @@ class CatalogDatasetFacet(DatasetFacet):
12
12
  framework: str
13
13
  """The storage framework for which the catalog is configured"""
14
14
 
15
- type: str
15
+ type: str # noqa: A003
16
16
  """Type of the catalog."""
17
17
 
18
18
  name: str
@@ -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
 
@@ -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)
@@ -11,7 +11,7 @@ from openlineage.client.generated.base import JobFacet
11
11
 
12
12
  @attr.define
13
13
  class SourceCodeLocationJobFacet(JobFacet):
14
- type: str
14
+ type: str # noqa: A003
15
15
  """the source control system"""
16
16
 
17
17
  url: str = attr.field()
@@ -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-1/SQLJobFacet.json#/$defs/SQLJobFacet"
17
+ return "https://openlineage.io/spec/facets/1-1-0/SQLJobFacet.json#/$defs/SQLJobFacet"
@@ -16,7 +16,7 @@ class Identifier(RedactMixin):
16
16
  name: str
17
17
  """The dataset name"""
18
18
 
19
- type: str
19
+ type: str # noqa: A003
20
20
  """Identifier type"""
21
21
 
22
22
 
@@ -6,7 +6,7 @@ import pathlib
6
6
  import tempfile
7
7
 
8
8
  import click
9
- import requests
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 = requests.get(BASE_SPEC_URL, timeout=10)
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)