From 63d7ed854bf115152b49442bb97996a8c82178a1 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Fri, 15 May 2026 07:24:47 +0000 Subject: [PATCH] feat: regenerate google-cloud-datacatalog-lineage --- librarian.yaml | 1 - .../google-cloud-datacatalog-lineage/.flake8 | 2 +- .../.repo-metadata.json | 1 + .../MANIFEST.in | 2 +- .../docs/conf.py | 4 +- .../cloud/datacatalog_lineage/__init__.py | 14 +- .../datacatalog_lineage/gapic_version.py | 2 +- .../cloud/datacatalog_lineage_v1/__init__.py | 37 +- .../gapic_metadata.json | 15 + .../datacatalog_lineage_v1/gapic_version.py | 2 +- .../services/__init__.py | 2 +- .../services/lineage/__init__.py | 2 +- .../services/lineage/async_client.py | 194 +++- .../services/lineage/client.py | 183 +++- .../services/lineage/pagers.py | 2 +- .../services/lineage/transports/__init__.py | 2 +- .../services/lineage/transports/base.py | 19 +- .../services/lineage/transports/grpc.py | 57 +- .../lineage/transports/grpc_asyncio.py | 63 +- .../services/lineage/transports/rest.py | 258 ++++- .../services/lineage/transports/rest_base.py | 59 +- .../datacatalog_lineage_v1/types/__init__.py | 14 +- .../datacatalog_lineage_v1/types/lineage.py | 594 +++++++++-- .../noxfile.py | 4 +- ...neage_batch_search_link_processes_async.py | 2 +- ...ineage_batch_search_link_processes_sync.py | 2 +- ...ated_lineage_create_lineage_event_async.py | 2 +- ...rated_lineage_create_lineage_event_sync.py | 2 +- ..._generated_lineage_create_process_async.py | 2 +- ...1_generated_lineage_create_process_sync.py | 2 +- ...e_v1_generated_lineage_create_run_async.py | 2 +- ...ge_v1_generated_lineage_create_run_sync.py | 2 +- ...ated_lineage_delete_lineage_event_async.py | 2 +- ...rated_lineage_delete_lineage_event_sync.py | 2 +- ..._generated_lineage_delete_process_async.py | 6 +- ...1_generated_lineage_delete_process_sync.py | 2 +- ...e_v1_generated_lineage_delete_run_async.py | 6 +- ...ge_v1_generated_lineage_delete_run_sync.py | 2 +- ...nerated_lineage_get_lineage_event_async.py | 2 +- ...enerated_lineage_get_lineage_event_sync.py | 2 +- ..._v1_generated_lineage_get_process_async.py | 2 +- ...e_v1_generated_lineage_get_process_sync.py | 2 +- ...eage_v1_generated_lineage_get_run_async.py | 2 +- ...neage_v1_generated_lineage_get_run_sync.py | 2 +- ...rated_lineage_list_lineage_events_async.py | 2 +- ...erated_lineage_list_lineage_events_sync.py | 2 +- ..._generated_lineage_list_processes_async.py | 2 +- ...1_generated_lineage_list_processes_sync.py | 2 +- ...ge_v1_generated_lineage_list_runs_async.py | 2 +- ...age_v1_generated_lineage_list_runs_sync.py | 2 +- ...ge_process_open_lineage_run_event_async.py | 2 +- ...age_process_open_lineage_run_event_sync.py | 2 +- ..._lineage_search_lineage_streaming_async.py | 56 + ...d_lineage_search_lineage_streaming_sync.py | 56 + ...v1_generated_lineage_search_links_async.py | 2 +- ..._v1_generated_lineage_search_links_sync.py | 2 +- ..._generated_lineage_update_process_async.py | 2 +- ...1_generated_lineage_update_process_sync.py | 2 +- ...e_v1_generated_lineage_update_run_async.py | 2 +- ...ge_v1_generated_lineage_update_run_sync.py | 2 +- ...a_google.cloud.datacatalog.lineage.v1.json | 153 +++ .../google-cloud-datacatalog-lineage/setup.py | 11 +- .../testing/constraints-3.10.txt | 21 +- .../testing/constraints-3.9.txt | 13 - .../tests/__init__.py | 2 +- .../tests/unit/__init__.py | 2 +- .../tests/unit/gapic/__init__.py | 2 +- .../gapic/datacatalog_lineage_v1/__init__.py | 2 +- .../datacatalog_lineage_v1/test_lineage.py | 986 ++++++++++++++++-- 69 files changed, 2572 insertions(+), 341 deletions(-) create mode 100644 packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_async.py create mode 100644 packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_sync.py delete mode 100644 packages/google-cloud-datacatalog-lineage/testing/constraints-3.9.txt diff --git a/librarian.yaml b/librarian.yaml index 21f0ff9eddcb..4275f8f04477 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -853,7 +853,6 @@ libraries: version: 0.6.0 apis: - path: google/cloud/datacatalog/lineage/v1 - skip_generate: true python: metadata_name_override: lineage default_version: v1 diff --git a/packages/google-cloud-datacatalog-lineage/.flake8 b/packages/google-cloud-datacatalog-lineage/.flake8 index 90316de21489..f9069a84687b 100644 --- a/packages/google-cloud-datacatalog-lineage/.flake8 +++ b/packages/google-cloud-datacatalog-lineage/.flake8 @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/.repo-metadata.json b/packages/google-cloud-datacatalog-lineage/.repo-metadata.json index aac1a7e4b2c4..1b0650b107fb 100644 --- a/packages/google-cloud-datacatalog-lineage/.repo-metadata.json +++ b/packages/google-cloud-datacatalog-lineage/.repo-metadata.json @@ -5,6 +5,7 @@ "client_documentation": "https://cloud.google.com/python/docs/reference/lineage/latest", "default_version": "v1", "distribution_name": "google-cloud-datacatalog-lineage", + "issue_tracker": "https://issuetracker.google.com/issues/new?component=1530027", "language": "python", "library_type": "GAPIC_AUTO", "name": "lineage", diff --git a/packages/google-cloud-datacatalog-lineage/MANIFEST.in b/packages/google-cloud-datacatalog-lineage/MANIFEST.in index dae249ec8976..f932577add9d 100644 --- a/packages/google-cloud-datacatalog-lineage/MANIFEST.in +++ b/packages/google-cloud-datacatalog-lineage/MANIFEST.in @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/docs/conf.py b/packages/google-cloud-datacatalog-lineage/docs/conf.py index af506b60bef9..d3998e53ab70 100644 --- a/packages/google-cloud-datacatalog-lineage/docs/conf.py +++ b/packages/google-cloud-datacatalog-lineage/docs/conf.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -83,7 +83,7 @@ # General information about the project. project = "google-cloud-datacatalog-lineage" -copyright = "2025, Google, LLC" +copyright = "2026, Google, LLC" author = "Google APIs" # The version info for the project you're documenting, acts as replacement for diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/__init__.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/__init__.py index 866c1c8d6e8c..4c846808a5d6 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,12 +31,15 @@ DeleteLineageEventRequest, DeleteProcessRequest, DeleteRunRequest, + DependencyInfo, + DependencyType, EntityReference, EventLink, GetLineageEventRequest, GetProcessRequest, GetRunRequest, LineageEvent, + LineageLink, Link, ListLineageEventsRequest, ListLineageEventsResponse, @@ -44,6 +47,7 @@ ListProcessesResponse, ListRunsRequest, ListRunsResponse, + MultipleEntityReference, OperationMetadata, Origin, Process, @@ -52,6 +56,8 @@ ProcessOpenLineageRunEventRequest, ProcessOpenLineageRunEventResponse, Run, + SearchLineageStreamingRequest, + SearchLineageStreamingResponse, SearchLinksRequest, SearchLinksResponse, UpdateProcessRequest, @@ -69,12 +75,14 @@ "DeleteLineageEventRequest", "DeleteProcessRequest", "DeleteRunRequest", + "DependencyInfo", "EntityReference", "EventLink", "GetLineageEventRequest", "GetProcessRequest", "GetRunRequest", "LineageEvent", + "LineageLink", "Link", "ListLineageEventsRequest", "ListLineageEventsResponse", @@ -82,6 +90,7 @@ "ListProcessesResponse", "ListRunsRequest", "ListRunsResponse", + "MultipleEntityReference", "OperationMetadata", "Origin", "Process", @@ -90,8 +99,11 @@ "ProcessOpenLineageRunEventRequest", "ProcessOpenLineageRunEventResponse", "Run", + "SearchLineageStreamingRequest", + "SearchLineageStreamingResponse", "SearchLinksRequest", "SearchLinksResponse", "UpdateProcessRequest", "UpdateRunRequest", + "DependencyType", ) diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py index 2673bd4bca01..916d95dd4eda 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py index d805d31185ab..a3c913d09c18 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,13 +21,7 @@ __version__ = package_version.__version__ -if sys.version_info >= (3, 8): # pragma: NO COVER - from importlib import metadata -else: # pragma: NO COVER - # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove - # this code path once we drop support for Python 3.7 - import importlib_metadata as metadata - +from importlib import metadata from .services.lineage import LineageAsyncClient, LineageClient from .types.lineage import ( @@ -39,12 +33,15 @@ DeleteLineageEventRequest, DeleteProcessRequest, DeleteRunRequest, + DependencyInfo, + DependencyType, EntityReference, EventLink, GetLineageEventRequest, GetProcessRequest, GetRunRequest, LineageEvent, + LineageLink, Link, ListLineageEventsRequest, ListLineageEventsResponse, @@ -52,6 +49,7 @@ ListProcessesResponse, ListRunsRequest, ListRunsResponse, + MultipleEntityReference, OperationMetadata, Origin, Process, @@ -60,6 +58,8 @@ ProcessOpenLineageRunEventRequest, ProcessOpenLineageRunEventResponse, Run, + SearchLineageStreamingRequest, + SearchLineageStreamingResponse, SearchLinksRequest, SearchLinksResponse, UpdateProcessRequest, @@ -75,28 +75,17 @@ # An older version of api_core is installed which does not define the # functions above. We do equivalent checks manually. try: - import sys import warnings _py_version_str = sys.version.split()[0] _package_label = "google.cloud.datacatalog_lineage_v1" - if sys.version_info < (3, 9): + if sys.version_info < (3, 10): warnings.warn( "You are using a non-supported Python version " + f"({_py_version_str}). Google will not post any further " + f"updates to {_package_label} supporting this Python version. " + "Please upgrade to the latest Python version, or at " - + f"least to Python 3.9, and then update {_package_label}.", - FutureWarning, - ) - if sys.version_info[:2] == (3, 9): - warnings.warn( - f"You are using a Python version ({_py_version_str}) " - + f"which Google will stop supporting in {_package_label} in " - + "January 2026. Please " - + "upgrade to the latest Python version, or at " - + "least to Python 3.10, before then, and " - + f"then update {_package_label}.", + + f"least to Python 3.10, and then update {_package_label}.", FutureWarning, ) @@ -170,6 +159,8 @@ def _get_version(dependency_name): "DeleteLineageEventRequest", "DeleteProcessRequest", "DeleteRunRequest", + "DependencyInfo", + "DependencyType", "EntityReference", "EventLink", "GetLineageEventRequest", @@ -177,6 +168,7 @@ def _get_version(dependency_name): "GetRunRequest", "LineageClient", "LineageEvent", + "LineageLink", "Link", "ListLineageEventsRequest", "ListLineageEventsResponse", @@ -184,6 +176,7 @@ def _get_version(dependency_name): "ListProcessesResponse", "ListRunsRequest", "ListRunsResponse", + "MultipleEntityReference", "OperationMetadata", "Origin", "Process", @@ -192,6 +185,8 @@ def _get_version(dependency_name): "ProcessOpenLineageRunEventRequest", "ProcessOpenLineageRunEventResponse", "Run", + "SearchLineageStreamingRequest", + "SearchLineageStreamingResponse", "SearchLinksRequest", "SearchLinksResponse", "UpdateProcessRequest", diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_metadata.json b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_metadata.json index f4f773f9d6ba..543a19828847 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_metadata.json +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_metadata.json @@ -80,6 +80,11 @@ "process_open_lineage_run_event" ] }, + "SearchLineageStreaming": { + "methods": [ + "search_lineage_streaming" + ] + }, "SearchLinks": { "methods": [ "search_links" @@ -170,6 +175,11 @@ "process_open_lineage_run_event" ] }, + "SearchLineageStreaming": { + "methods": [ + "search_lineage_streaming" + ] + }, "SearchLinks": { "methods": [ "search_links" @@ -260,6 +270,11 @@ "process_open_lineage_run_event" ] }, + "SearchLineageStreaming": { + "methods": [ + "search_lineage_streaming" + ] + }, "SearchLinks": { "methods": [ "search_links" diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py index 2673bd4bca01..916d95dd4eda 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/__init__.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/__init__.py index cbf94b283c70..32b36c5c4fe0 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/__init__.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/__init__.py index 55e7cdc32c9f..8c11effd310d 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/async_client.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/async_client.py index c5879f287f5b..c9197163556a 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/async_client.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/async_client.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,8 +15,11 @@ # import logging as std_logging import re +import uuid from collections import OrderedDict from typing import ( + AsyncIterable, + Awaitable, Callable, Dict, Mapping, @@ -350,7 +353,7 @@ async def sample_process_open_lineage_run_event(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.ProcessOpenLineageRunEventRequest, dict]]): The request object. Request message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. parent (:class:`str`): Required. The name of the project and its location that should own the @@ -378,7 +381,7 @@ async def sample_process_open_lineage_run_event(): Returns: google.cloud.datacatalog_lineage_v1.types.ProcessOpenLineageRunEventResponse: Response message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. """ # Create or coerce a protobuf request object. @@ -418,6 +421,9 @@ async def sample_process_open_lineage_run_event(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._client._validate_universe_domain() @@ -473,7 +479,7 @@ async def sample_create_process(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.CreateProcessRequest, dict]]): The request object. Request message for - [CreateProcess][google.cloud.datacatalog.lineage.v1.CreateProcess]. + [CreateProcess][google.cloud.datacatalog.lineage.v1.Lineage.CreateProcess]. parent (:class:`str`): Required. The name of the project and its location that should own the @@ -538,6 +544,9 @@ async def sample_create_process(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._client._validate_universe_domain() @@ -592,7 +601,7 @@ async def sample_update_process(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.UpdateProcessRequest, dict]]): The request object. Request message for - [UpdateProcess][google.cloud.datacatalog.lineage.v1.UpdateProcess]. + [UpdateProcess][google.cloud.datacatalog.lineage.v1.Lineage.UpdateProcess]. process (:class:`google.cloud.datacatalog_lineage_v1.types.Process`): Required. The lineage process to update. @@ -603,9 +612,9 @@ async def sample_update_process(): on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - The list of fields to update. - Currently not used. The whole message is - updated. + Optional. The list of fields to + update. Currently not used. The whole + message is updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -663,6 +672,9 @@ async def sample_update_process(): ), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._client._validate_universe_domain() @@ -717,7 +729,7 @@ async def sample_get_process(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.GetProcessRequest, dict]]): The request object. Request message for - [GetProcess][google.cloud.datacatalog.lineage.v1.GetProcess]. + [GetProcess][google.cloud.datacatalog.lineage.v1.Lineage.GetProcess]. name (:class:`str`): Required. The name of the process to get. @@ -830,7 +842,7 @@ async def sample_list_processes(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.ListProcessesRequest, dict]]): The request object. Request message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. parent (:class:`str`): Required. The name of the project and its location that owns this collection @@ -850,7 +862,7 @@ async def sample_list_processes(): Returns: google.cloud.datacatalog_lineage_v1.services.lineage.pagers.ListProcessesAsyncPager: Response message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. Iterating over this object will yield results and resolve additional pages automatically. @@ -948,11 +960,11 @@ async def sample_delete_process(): ) # Make the request - operation = client.delete_process(request=request) + operation = await client.delete_process(request=request) print("Waiting for operation to complete...") - response = (await operation).result() + response = await operation.result() # Handle the response print(response) @@ -960,7 +972,7 @@ async def sample_delete_process(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.DeleteProcessRequest, dict]]): The request object. Request message for - [DeleteProcess][google.cloud.datacatalog.lineage.v1.DeleteProcess]. + [DeleteProcess][google.cloud.datacatalog.lineage.v1.Lineage.DeleteProcess]. name (:class:`str`): Required. The name of the process to delete. @@ -1094,7 +1106,7 @@ async def sample_create_run(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.CreateRunRequest, dict]]): The request object. Request message for - [CreateRun][google.cloud.datacatalog.lineage.v1.CreateRun]. + [CreateRun][google.cloud.datacatalog.lineage.v1.Lineage.CreateRun]. parent (:class:`str`): Required. The name of the process that should own the run. @@ -1159,6 +1171,9 @@ async def sample_create_run(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._client._validate_universe_domain() @@ -1217,7 +1232,7 @@ async def sample_update_run(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.UpdateRunRequest, dict]]): The request object. Request message for - [UpdateRun][google.cloud.datacatalog.lineage.v1.UpdateRun]. + [UpdateRun][google.cloud.datacatalog.lineage.v1.Lineage.UpdateRun]. run (:class:`google.cloud.datacatalog_lineage_v1.types.Run`): Required. The lineage run to update. @@ -1231,9 +1246,9 @@ async def sample_update_run(): on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): - The list of fields to update. - Currently not used. The whole message is - updated. + Optional. The list of fields to + update. Currently not used. The whole + message is updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1344,7 +1359,7 @@ async def sample_get_run(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.GetRunRequest, dict]]): The request object. Request message for - [GetRun][google.cloud.datacatalog.lineage.v1.GetRun]. + [GetRun][google.cloud.datacatalog.lineage.v1.Lineage.GetRun]. name (:class:`str`): Required. The name of the run to get. This corresponds to the ``name`` field @@ -1454,7 +1469,7 @@ async def sample_list_runs(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.ListRunsRequest, dict]]): The request object. Request message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. parent (:class:`str`): Required. The name of process that owns this collection of runs. @@ -1473,7 +1488,7 @@ async def sample_list_runs(): Returns: google.cloud.datacatalog_lineage_v1.services.lineage.pagers.ListRunsAsyncPager: Response message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1571,11 +1586,11 @@ async def sample_delete_run(): ) # Make the request - operation = client.delete_run(request=request) + operation = await client.delete_run(request=request) print("Waiting for operation to complete...") - response = (await operation).result() + response = await operation.result() # Handle the response print(response) @@ -1583,7 +1598,7 @@ async def sample_delete_run(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.DeleteRunRequest, dict]]): The request object. Request message for - [DeleteRun][google.cloud.datacatalog.lineage.v1.DeleteRun]. + [DeleteRun][google.cloud.datacatalog.lineage.v1.Lineage.DeleteRun]. name (:class:`str`): Required. The name of the run to delete. @@ -1713,7 +1728,7 @@ async def sample_create_lineage_event(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.CreateLineageEventRequest, dict]]): The request object. Request message for - [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.CreateLineageEvent]. + [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.CreateLineageEvent]. parent (:class:`str`): Required. The name of the run that should own the lineage event. @@ -1782,6 +1797,9 @@ async def sample_create_lineage_event(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._client._validate_universe_domain() @@ -1836,7 +1854,7 @@ async def sample_get_lineage_event(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.GetLineageEventRequest, dict]]): The request object. Request message for - [GetLineageEvent][google.cloud.datacatalog.lineage.v1.GetLineageEvent]. + [GetLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.GetLineageEvent]. name (:class:`str`): Required. The name of the lineage event to get. @@ -1952,7 +1970,7 @@ async def sample_list_lineage_events(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.ListLineageEventsRequest, dict]]): The request object. Request message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. parent (:class:`str`): Required. The name of the run that owns the collection of lineage events to @@ -1972,7 +1990,7 @@ async def sample_list_lineage_events(): Returns: google.cloud.datacatalog_lineage_v1.services.lineage.pagers.ListLineageEventsAsyncPager: Response message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. Iterating over this object will yield results and resolve additional pages automatically. @@ -2075,7 +2093,7 @@ async def sample_delete_lineage_event(): Args: request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.DeleteLineageEventRequest, dict]]): The request object. Request message for - [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.DeleteLineageEvent]. + [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.DeleteLineageEvent]. name (:class:`str`): Required. The name of the lineage event to delete. @@ -2365,6 +2383,122 @@ async def sample_batch_search_link_processes(): # Done; return the response. return response + def search_lineage_streaming( + self, + request: Optional[Union[lineage.SearchLineageStreamingRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Awaitable[AsyncIterable[lineage.SearchLineageStreamingResponse]]: + r"""Retrieves a streaming response of lineage links connected to the + requested assets by performing a breadth-first search in the + given direction. Links represent the data flow between + **source** (upstream) and **target** (downstream) assets in + transformation pipelines. Links are stored in the same project + as the Lineage Events that create them. This method retrieves + links from all valid locations provided in the request. This + method supports Column-Level Lineage (CLL) along with wildcard + support to retrieve all CLL for an Entity FQN. + + Following permissions are required to retrieve links: + + - ``datalineage.events.get`` permission for the project where + the link is stored for entity-level lineage. + - ``datalineage.events.getFields`` permission for the project + where the link is stored for column-level lineage. + + This method also returns processes that created the links if + explicitly requested by setting + `max_process_per_link `__ + is non-zero and full process details are requested via + ``links.processes.process`` in the + `FieldMask `__. + + Permission required to retrieve processes: + + - ``datalineage.processes.get`` permission for the project where + the process is stored. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import datacatalog_lineage_v1 + + async def sample_search_lineage_streaming(): + # Create a client + client = datacatalog_lineage_v1.LineageAsyncClient() + + # Initialize request argument(s) + request = datacatalog_lineage_v1.SearchLineageStreamingRequest( + parent="parent_value", + locations=['locations_value1', 'locations_value2'], + direction="UPSTREAM", + ) + + # Make the request + stream = await client.search_lineage_streaming(request=request) + + # Handle the response + async for response in stream: + print(response) + + Args: + request (Optional[Union[google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest, dict]]): + The request object. Request message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + AsyncIterable[google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingResponse]: + Response message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, lineage.SearchLineageStreamingRequest): + request = lineage.SearchLineageStreamingRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.search_lineage_streaming + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def list_operations( self, request: Optional[Union[operations_pb2.ListOperationsRequest, dict]] = None, diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py index c0a168340b71..7674cc0e4ec8 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,12 +17,14 @@ import logging as std_logging import os import re +import uuid import warnings from collections import OrderedDict from http import HTTPStatus from typing import ( Callable, Dict, + Iterable, Mapping, MutableMapping, MutableSequence, @@ -835,7 +837,7 @@ def sample_process_open_lineage_run_event(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.ProcessOpenLineageRunEventRequest, dict]): The request object. Request message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. parent (str): Required. The name of the project and its location that should own the @@ -863,7 +865,7 @@ def sample_process_open_lineage_run_event(): Returns: google.cloud.datacatalog_lineage_v1.types.ProcessOpenLineageRunEventResponse: Response message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. """ # Create or coerce a protobuf request object. @@ -902,6 +904,9 @@ def sample_process_open_lineage_run_event(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._validate_universe_domain() @@ -957,7 +962,7 @@ def sample_create_process(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.CreateProcessRequest, dict]): The request object. Request message for - [CreateProcess][google.cloud.datacatalog.lineage.v1.CreateProcess]. + [CreateProcess][google.cloud.datacatalog.lineage.v1.Lineage.CreateProcess]. parent (str): Required. The name of the project and its location that should own the @@ -1019,6 +1024,9 @@ def sample_create_process(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._validate_universe_domain() @@ -1073,7 +1081,7 @@ def sample_update_process(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.UpdateProcessRequest, dict]): The request object. Request message for - [UpdateProcess][google.cloud.datacatalog.lineage.v1.UpdateProcess]. + [UpdateProcess][google.cloud.datacatalog.lineage.v1.Lineage.UpdateProcess]. process (google.cloud.datacatalog_lineage_v1.types.Process): Required. The lineage process to update. @@ -1084,9 +1092,9 @@ def sample_update_process(): on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (google.protobuf.field_mask_pb2.FieldMask): - The list of fields to update. - Currently not used. The whole message is - updated. + Optional. The list of fields to + update. Currently not used. The whole + message is updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1141,6 +1149,9 @@ def sample_update_process(): ), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._validate_universe_domain() @@ -1195,7 +1206,7 @@ def sample_get_process(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.GetProcessRequest, dict]): The request object. Request message for - [GetProcess][google.cloud.datacatalog.lineage.v1.GetProcess]. + [GetProcess][google.cloud.datacatalog.lineage.v1.Lineage.GetProcess]. name (str): Required. The name of the process to get. @@ -1305,7 +1316,7 @@ def sample_list_processes(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.ListProcessesRequest, dict]): The request object. Request message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. parent (str): Required. The name of the project and its location that owns this collection @@ -1325,7 +1336,7 @@ def sample_list_processes(): Returns: google.cloud.datacatalog_lineage_v1.services.lineage.pagers.ListProcessesPager: Response message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. Iterating over this object will yield results and resolve additional pages automatically. @@ -1432,7 +1443,7 @@ def sample_delete_process(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.DeleteProcessRequest, dict]): The request object. Request message for - [DeleteProcess][google.cloud.datacatalog.lineage.v1.DeleteProcess]. + [DeleteProcess][google.cloud.datacatalog.lineage.v1.Lineage.DeleteProcess]. name (str): Required. The name of the process to delete. @@ -1563,7 +1574,7 @@ def sample_create_run(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.CreateRunRequest, dict]): The request object. Request message for - [CreateRun][google.cloud.datacatalog.lineage.v1.CreateRun]. + [CreateRun][google.cloud.datacatalog.lineage.v1.Lineage.CreateRun]. parent (str): Required. The name of the process that should own the run. @@ -1625,6 +1636,9 @@ def sample_create_run(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._validate_universe_domain() @@ -1683,7 +1697,7 @@ def sample_update_run(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.UpdateRunRequest, dict]): The request object. Request message for - [UpdateRun][google.cloud.datacatalog.lineage.v1.UpdateRun]. + [UpdateRun][google.cloud.datacatalog.lineage.v1.Lineage.UpdateRun]. run (google.cloud.datacatalog_lineage_v1.types.Run): Required. The lineage run to update. @@ -1697,9 +1711,9 @@ def sample_update_run(): on the ``request`` instance; if ``request`` is provided, this should not be set. update_mask (google.protobuf.field_mask_pb2.FieldMask): - The list of fields to update. - Currently not used. The whole message is - updated. + Optional. The list of fields to + update. Currently not used. The whole + message is updated. This corresponds to the ``update_mask`` field on the ``request`` instance; if ``request`` is provided, this @@ -1807,7 +1821,7 @@ def sample_get_run(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.GetRunRequest, dict]): The request object. Request message for - [GetRun][google.cloud.datacatalog.lineage.v1.GetRun]. + [GetRun][google.cloud.datacatalog.lineage.v1.Lineage.GetRun]. name (str): Required. The name of the run to get. This corresponds to the ``name`` field @@ -1916,7 +1930,7 @@ def sample_list_runs(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.ListRunsRequest, dict]): The request object. Request message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. parent (str): Required. The name of process that owns this collection of runs. @@ -1935,7 +1949,7 @@ def sample_list_runs(): Returns: google.cloud.datacatalog_lineage_v1.services.lineage.pagers.ListRunsPager: Response message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. Iterating over this object will yield results and resolve additional pages automatically. @@ -2042,7 +2056,7 @@ def sample_delete_run(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.DeleteRunRequest, dict]): The request object. Request message for - [DeleteRun][google.cloud.datacatalog.lineage.v1.DeleteRun]. + [DeleteRun][google.cloud.datacatalog.lineage.v1.Lineage.DeleteRun]. name (str): Required. The name of the run to delete. @@ -2169,7 +2183,7 @@ def sample_create_lineage_event(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.CreateLineageEventRequest, dict]): The request object. Request message for - [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.CreateLineageEvent]. + [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.CreateLineageEvent]. parent (str): Required. The name of the run that should own the lineage event. @@ -2235,6 +2249,9 @@ def sample_create_lineage_event(): gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), ) + if not request.request_id: + request.request_id = str(uuid.uuid4()) + # Validate the universe domain. self._validate_universe_domain() @@ -2289,7 +2306,7 @@ def sample_get_lineage_event(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.GetLineageEventRequest, dict]): The request object. Request message for - [GetLineageEvent][google.cloud.datacatalog.lineage.v1.GetLineageEvent]. + [GetLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.GetLineageEvent]. name (str): Required. The name of the lineage event to get. @@ -2402,7 +2419,7 @@ def sample_list_lineage_events(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.ListLineageEventsRequest, dict]): The request object. Request message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. parent (str): Required. The name of the run that owns the collection of lineage events to @@ -2422,7 +2439,7 @@ def sample_list_lineage_events(): Returns: google.cloud.datacatalog_lineage_v1.services.lineage.pagers.ListLineageEventsPager: Response message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. Iterating over this object will yield results and resolve additional pages automatically. @@ -2522,7 +2539,7 @@ def sample_delete_lineage_event(): Args: request (Union[google.cloud.datacatalog_lineage_v1.types.DeleteLineageEventRequest, dict]): The request object. Request message for - [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.DeleteLineageEvent]. + [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.DeleteLineageEvent]. name (str): Required. The name of the lineage event to delete. @@ -2807,6 +2824,120 @@ def sample_batch_search_link_processes(): # Done; return the response. return response + def search_lineage_streaming( + self, + request: Optional[Union[lineage.SearchLineageStreamingRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Iterable[lineage.SearchLineageStreamingResponse]: + r"""Retrieves a streaming response of lineage links connected to the + requested assets by performing a breadth-first search in the + given direction. Links represent the data flow between + **source** (upstream) and **target** (downstream) assets in + transformation pipelines. Links are stored in the same project + as the Lineage Events that create them. This method retrieves + links from all valid locations provided in the request. This + method supports Column-Level Lineage (CLL) along with wildcard + support to retrieve all CLL for an Entity FQN. + + Following permissions are required to retrieve links: + + - ``datalineage.events.get`` permission for the project where + the link is stored for entity-level lineage. + - ``datalineage.events.getFields`` permission for the project + where the link is stored for column-level lineage. + + This method also returns processes that created the links if + explicitly requested by setting + `max_process_per_link `__ + is non-zero and full process details are requested via + ``links.processes.process`` in the + `FieldMask `__. + + Permission required to retrieve processes: + + - ``datalineage.processes.get`` permission for the project where + the process is stored. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import datacatalog_lineage_v1 + + def sample_search_lineage_streaming(): + # Create a client + client = datacatalog_lineage_v1.LineageClient() + + # Initialize request argument(s) + request = datacatalog_lineage_v1.SearchLineageStreamingRequest( + parent="parent_value", + locations=['locations_value1', 'locations_value2'], + direction="UPSTREAM", + ) + + # Make the request + stream = client.search_lineage_streaming(request=request) + + # Handle the response + for response in stream: + print(response) + + Args: + request (Union[google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest, dict]): + The request object. Request message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + Iterable[google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingResponse]: + Response message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, lineage.SearchLineageStreamingRequest): + request = lineage.SearchLineageStreamingRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search_lineage_streaming] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "LineageClient": return self diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/pagers.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/pagers.py index ad88d0c761ce..436d36706c41 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/pagers.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/pagers.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/__init__.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/__init__.py index 4cb426a1e22d..dd97aec0836c 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/base.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/base.py index 7b79ca946ce8..c1eeb4fb10a9 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/base.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -229,6 +229,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.search_lineage_streaming: gapic_v1.method.wrap_method( + self.search_lineage_streaming, + default_timeout=None, + client_info=client_info, + ), self.cancel_operation: gapic_v1.method.wrap_method( self.cancel_operation, default_timeout=None, @@ -421,6 +426,18 @@ def batch_search_link_processes( ]: raise NotImplementedError() + @property + def search_lineage_streaming( + self, + ) -> Callable[ + [lineage.SearchLineageStreamingRequest], + Union[ + lineage.SearchLineageStreamingResponse, + Awaitable[lineage.SearchLineageStreamingResponse], + ], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc.py index e64835376797..7206108eaa44 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -823,6 +823,61 @@ def batch_search_link_processes( ) return self._stubs["batch_search_link_processes"] + @property + def search_lineage_streaming( + self, + ) -> Callable[ + [lineage.SearchLineageStreamingRequest], lineage.SearchLineageStreamingResponse + ]: + r"""Return a callable for the search lineage streaming method over gRPC. + + Retrieves a streaming response of lineage links connected to the + requested assets by performing a breadth-first search in the + given direction. Links represent the data flow between + **source** (upstream) and **target** (downstream) assets in + transformation pipelines. Links are stored in the same project + as the Lineage Events that create them. This method retrieves + links from all valid locations provided in the request. This + method supports Column-Level Lineage (CLL) along with wildcard + support to retrieve all CLL for an Entity FQN. + + Following permissions are required to retrieve links: + + - ``datalineage.events.get`` permission for the project where + the link is stored for entity-level lineage. + - ``datalineage.events.getFields`` permission for the project + where the link is stored for column-level lineage. + + This method also returns processes that created the links if + explicitly requested by setting + `max_process_per_link `__ + is non-zero and full process details are requested via + ``links.processes.process`` in the + `FieldMask `__. + + Permission required to retrieve processes: + + - ``datalineage.processes.get`` permission for the project where + the process is stored. + + Returns: + Callable[[~.SearchLineageStreamingRequest], + ~.SearchLineageStreamingResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_lineage_streaming" not in self._stubs: + self._stubs["search_lineage_streaming"] = self._logged_channel.unary_stream( + "/google.cloud.datacatalog.lineage.v1.Lineage/SearchLineageStreaming", + request_serializer=lineage.SearchLineageStreamingRequest.serialize, + response_deserializer=lineage.SearchLineageStreamingResponse.deserialize, + ) + return self._stubs["search_lineage_streaming"] + def close(self): self._logged_channel.close() diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc_asyncio.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc_asyncio.py index 3f5ac970b08e..171c54c48e35 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc_asyncio.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/grpc_asyncio.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -839,6 +839,62 @@ def batch_search_link_processes( ) return self._stubs["batch_search_link_processes"] + @property + def search_lineage_streaming( + self, + ) -> Callable[ + [lineage.SearchLineageStreamingRequest], + Awaitable[lineage.SearchLineageStreamingResponse], + ]: + r"""Return a callable for the search lineage streaming method over gRPC. + + Retrieves a streaming response of lineage links connected to the + requested assets by performing a breadth-first search in the + given direction. Links represent the data flow between + **source** (upstream) and **target** (downstream) assets in + transformation pipelines. Links are stored in the same project + as the Lineage Events that create them. This method retrieves + links from all valid locations provided in the request. This + method supports Column-Level Lineage (CLL) along with wildcard + support to retrieve all CLL for an Entity FQN. + + Following permissions are required to retrieve links: + + - ``datalineage.events.get`` permission for the project where + the link is stored for entity-level lineage. + - ``datalineage.events.getFields`` permission for the project + where the link is stored for column-level lineage. + + This method also returns processes that created the links if + explicitly requested by setting + `max_process_per_link `__ + is non-zero and full process details are requested via + ``links.processes.process`` in the + `FieldMask `__. + + Permission required to retrieve processes: + + - ``datalineage.processes.get`` permission for the project where + the process is stored. + + Returns: + Callable[[~.SearchLineageStreamingRequest], + Awaitable[~.SearchLineageStreamingResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_lineage_streaming" not in self._stubs: + self._stubs["search_lineage_streaming"] = self._logged_channel.unary_stream( + "/google.cloud.datacatalog.lineage.v1.Lineage/SearchLineageStreaming", + request_serializer=lineage.SearchLineageStreamingRequest.serialize, + response_deserializer=lineage.SearchLineageStreamingResponse.deserialize, + ) + return self._stubs["search_lineage_streaming"] + def _prep_wrapped_messages(self, client_info): """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" self._wrapped_methods = { @@ -927,6 +983,11 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.search_lineage_streaming: self._wrap_method( + self.search_lineage_streaming, + default_timeout=None, + client_info=client_info, + ), self.cancel_operation: self._wrap_method( self.cancel_operation, default_timeout=None, diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py index 7263c9637005..9bb1be773d53 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -182,6 +182,14 @@ def post_process_open_lineage_run_event(self, response): logging.log(f"Received response: {response}") return response + def pre_search_lineage_streaming(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_search_lineage_streaming(self, response): + logging.log(f"Received response: {response}") + return response + def pre_search_links(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -829,6 +837,56 @@ def post_process_open_lineage_run_event_with_metadata( """ return response, metadata + def pre_search_lineage_streaming( + self, + request: lineage.SearchLineageStreamingRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + lineage.SearchLineageStreamingRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for search_lineage_streaming + + Override in a subclass to manipulate the request or metadata + before they are sent to the Lineage server. + """ + return request, metadata + + def post_search_lineage_streaming( + self, response: rest_streaming.ResponseIterator + ) -> rest_streaming.ResponseIterator: + """Post-rpc interceptor for search_lineage_streaming + + DEPRECATED. Please use the `post_search_lineage_streaming_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Lineage server but before + it is returned to user code. This `post_search_lineage_streaming` interceptor runs + before the `post_search_lineage_streaming_with_metadata` interceptor. + """ + return response + + def post_search_lineage_streaming_with_metadata( + self, + response: rest_streaming.ResponseIterator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for search_lineage_streaming + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_search_lineage_streaming_with_metadata` + interceptor in new development instead of the `post_search_lineage_streaming` interceptor. + When both interceptors are used, this `post_search_lineage_streaming_with_metadata` interceptor runs after the + `post_search_lineage_streaming` interceptor. The (possibly modified) response returned by + `post_search_lineage_streaming` will be passed to + `post_search_lineage_streaming_with_metadata`. + """ + return response, metadata + def pre_search_links( self, request: lineage.SearchLinksRequest, @@ -1407,7 +1465,7 @@ def __call__( Args: request (~.lineage.CreateLineageEventRequest): The request object. Request message for - [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.CreateLineageEvent]. + [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.CreateLineageEvent]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1563,7 +1621,7 @@ def __call__( Args: request (~.lineage.CreateProcessRequest): The request object. Request message for - [CreateProcess][google.cloud.datacatalog.lineage.v1.CreateProcess]. + [CreateProcess][google.cloud.datacatalog.lineage.v1.Lineage.CreateProcess]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1718,7 +1776,7 @@ def __call__( Args: request (~.lineage.CreateRunRequest): The request object. Request message for - [CreateRun][google.cloud.datacatalog.lineage.v1.CreateRun]. + [CreateRun][google.cloud.datacatalog.lineage.v1.Lineage.CreateRun]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1873,7 +1931,7 @@ def __call__( Args: request (~.lineage.DeleteLineageEventRequest): The request object. Request message for - [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.DeleteLineageEvent]. + [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.DeleteLineageEvent]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1980,7 +2038,7 @@ def __call__( Args: request (~.lineage.DeleteProcessRequest): The request object. Request message for - [DeleteProcess][google.cloud.datacatalog.lineage.v1.DeleteProcess]. + [DeleteProcess][google.cloud.datacatalog.lineage.v1.Lineage.DeleteProcess]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2128,7 +2186,7 @@ def __call__( Args: request (~.lineage.DeleteRunRequest): The request object. Request message for - [DeleteRun][google.cloud.datacatalog.lineage.v1.DeleteRun]. + [DeleteRun][google.cloud.datacatalog.lineage.v1.Lineage.DeleteRun]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2276,7 +2334,7 @@ def __call__( Args: request (~.lineage.GetLineageEventRequest): The request object. Request message for - [GetLineageEvent][google.cloud.datacatalog.lineage.v1.GetLineageEvent]. + [GetLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.GetLineageEvent]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2430,7 +2488,7 @@ def __call__( Args: request (~.lineage.GetProcessRequest): The request object. Request message for - [GetProcess][google.cloud.datacatalog.lineage.v1.GetProcess]. + [GetProcess][google.cloud.datacatalog.lineage.v1.Lineage.GetProcess]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2577,7 +2635,7 @@ def __call__( Args: request (~.lineage.GetRunRequest): The request object. Request message for - [GetRun][google.cloud.datacatalog.lineage.v1.GetRun]. + [GetRun][google.cloud.datacatalog.lineage.v1.Lineage.GetRun]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2725,7 +2783,7 @@ def __call__( Args: request (~.lineage.ListLineageEventsRequest): The request object. Request message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2737,7 +2795,7 @@ def __call__( Returns: ~.lineage.ListLineageEventsResponse: Response message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. """ @@ -2876,7 +2934,7 @@ def __call__( Args: request (~.lineage.ListProcessesRequest): The request object. Request message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -2888,7 +2946,7 @@ def __call__( Returns: ~.lineage.ListProcessesResponse: Response message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. """ @@ -3025,7 +3083,7 @@ def __call__( Args: request (~.lineage.ListRunsRequest): The request object. Request message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -3037,7 +3095,7 @@ def __call__( Returns: ~.lineage.ListRunsResponse: Response message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. """ @@ -3176,7 +3234,7 @@ def __call__( Args: request (~.lineage.ProcessOpenLineageRunEventRequest): The request object. Request message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -3188,7 +3246,7 @@ def __call__( Returns: ~.lineage.ProcessOpenLineageRunEventResponse: Response message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. """ @@ -3291,6 +3349,154 @@ def __call__( ) return resp + class _SearchLineageStreaming( + _BaseLineageRestTransport._BaseSearchLineageStreaming, LineageRestStub + ): + def __hash__(self): + return hash("LineageRestTransport.SearchLineageStreaming") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + stream=True, + ) + return response + + def __call__( + self, + request: lineage.SearchLineageStreamingRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rest_streaming.ResponseIterator: + r"""Call the search lineage streaming method over HTTP. + + Args: + request (~.lineage.SearchLineageStreamingRequest): + The request object. Request message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.lineage.SearchLineageStreamingResponse: + Response message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + + """ + + http_options = _BaseLineageRestTransport._BaseSearchLineageStreaming._get_http_options() + + request, metadata = self._interceptor.pre_search_lineage_streaming( + request, metadata + ) + transcoded_request = _BaseLineageRestTransport._BaseSearchLineageStreaming._get_transcoded_request( + http_options, request + ) + + body = _BaseLineageRestTransport._BaseSearchLineageStreaming._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseLineageRestTransport._BaseSearchLineageStreaming._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.datacatalog.lineage_v1.LineageClient.SearchLineageStreaming", + extra={ + "serviceName": "google.cloud.datacatalog.lineage.v1.Lineage", + "rpcName": "SearchLineageStreaming", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = LineageRestTransport._SearchLineageStreaming._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = rest_streaming.ResponseIterator( + response, lineage.SearchLineageStreamingResponse + ) + + resp = self._interceptor.post_search_lineage_streaming(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_lineage_streaming_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + http_response = { + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.datacatalog.lineage_v1.LineageClient.search_lineage_streaming", + extra={ + "serviceName": "google.cloud.datacatalog.lineage.v1.Lineage", + "rpcName": "SearchLineageStreaming", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + class _SearchLinks(_BaseLineageRestTransport._BaseSearchLinks, LineageRestStub): def __hash__(self): return hash("LineageRestTransport.SearchLinks") @@ -3486,7 +3692,7 @@ def __call__( Args: request (~.lineage.UpdateProcessRequest): The request object. Request message for - [UpdateProcess][google.cloud.datacatalog.lineage.v1.UpdateProcess]. + [UpdateProcess][google.cloud.datacatalog.lineage.v1.Lineage.UpdateProcess]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -3641,7 +3847,7 @@ def __call__( Args: request (~.lineage.UpdateRunRequest): The request object. Request message for - [UpdateRun][google.cloud.datacatalog.lineage.v1.UpdateRun]. + [UpdateRun][google.cloud.datacatalog.lineage.v1.Lineage.UpdateRun]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -3873,6 +4079,18 @@ def process_open_lineage_run_event( self._session, self._host, self._interceptor ) # type: ignore + @property + def search_lineage_streaming( + self, + ) -> Callable[ + [lineage.SearchLineageStreamingRequest], lineage.SearchLineageStreamingResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._SearchLineageStreaming( + self._session, self._host, self._interceptor + ) # type: ignore + @property def search_links( self, diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest_base.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest_base.py index 28b53b72c942..39a5e832f83f 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest_base.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest_base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -797,6 +797,63 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseSearchLineageStreaming: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=projects/*/locations/*}:searchLineageStreaming", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = lineage.SearchLineageStreamingRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseLineageRestTransport._BaseSearchLineageStreaming._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseSearchLinks: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/__init__.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/__init__.py index 1dce20cb6383..f910facbc4d8 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,12 +22,15 @@ DeleteLineageEventRequest, DeleteProcessRequest, DeleteRunRequest, + DependencyInfo, + DependencyType, EntityReference, EventLink, GetLineageEventRequest, GetProcessRequest, GetRunRequest, LineageEvent, + LineageLink, Link, ListLineageEventsRequest, ListLineageEventsResponse, @@ -35,6 +38,7 @@ ListProcessesResponse, ListRunsRequest, ListRunsResponse, + MultipleEntityReference, OperationMetadata, Origin, Process, @@ -43,6 +47,8 @@ ProcessOpenLineageRunEventRequest, ProcessOpenLineageRunEventResponse, Run, + SearchLineageStreamingRequest, + SearchLineageStreamingResponse, SearchLinksRequest, SearchLinksResponse, UpdateProcessRequest, @@ -58,12 +64,14 @@ "DeleteLineageEventRequest", "DeleteProcessRequest", "DeleteRunRequest", + "DependencyInfo", "EntityReference", "EventLink", "GetLineageEventRequest", "GetProcessRequest", "GetRunRequest", "LineageEvent", + "LineageLink", "Link", "ListLineageEventsRequest", "ListLineageEventsResponse", @@ -71,6 +79,7 @@ "ListProcessesResponse", "ListRunsRequest", "ListRunsResponse", + "MultipleEntityReference", "OperationMetadata", "Origin", "Process", @@ -79,8 +88,11 @@ "ProcessOpenLineageRunEventRequest", "ProcessOpenLineageRunEventResponse", "Run", + "SearchLineageStreamingRequest", + "SearchLineageStreamingResponse", "SearchLinksRequest", "SearchLinksResponse", "UpdateProcessRequest", "UpdateRunRequest", + "DependencyType", ) diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/lineage.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/lineage.py index 11267870ac60..48983fe97c34 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/lineage.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/types/lineage.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,15 +20,18 @@ import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore import google.protobuf.struct_pb2 as struct_pb2 # type: ignore import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore import proto # type: ignore __protobuf__ = proto.module( package="google.cloud.datacatalog.lineage.v1", manifest={ + "DependencyType", "Process", "Run", "LineageEvent", "EventLink", + "DependencyInfo", "EntityReference", "OperationMetadata", "ProcessOpenLineageRunEventRequest", @@ -51,6 +54,7 @@ "ListLineageEventsResponse", "DeleteLineageEventRequest", "SearchLinksRequest", + "MultipleEntityReference", "SearchLinksResponse", "Link", "BatchSearchLinkProcessesRequest", @@ -58,10 +62,31 @@ "ProcessLinks", "ProcessLinkInfo", "Origin", + "LineageLink", + "SearchLineageStreamingRequest", + "SearchLineageStreamingResponse", }, ) +class DependencyType(proto.Enum): + r"""Type of dependency between entities. + + Values: + DEPENDENCY_TYPE_UNSPECIFIED (0): + Dependency type unspecified. + EXACT_COPY (1): + Exact data copy without any change. + OTHER (3): + Other types of dependencies like filtering or + grouping. + """ + + DEPENDENCY_TYPE_UNSPECIFIED = 0 + EXACT_COPY = 1 + OTHER = 3 + + class Process(proto.Message): r"""A process is the definition of a data transformation operation. @@ -124,7 +149,7 @@ class Run(proto.Message): ``a-zA-Z0-9_-:.`` display_name (str): Optional. A human-readable name you can set to display in a - user interface. Must be not longer than 1024 characters and + user interface. Must be not longer than 200 characters and only contain UTF-8 letters or numbers, spaces or characters like ``_-:&.`` attributes (MutableMapping[str, google.protobuf.struct_pb2.Value]): @@ -256,6 +281,9 @@ class EventLink(proto.Message): Required. Reference to the source entity target (google.cloud.datacatalog_lineage_v1.types.EntityReference): Required. Reference to the target entity + dependency_info (google.cloud.datacatalog_lineage_v1.types.DependencyInfo): + Optional. Describes how the target depends on + the source. """ source: "EntityReference" = proto.Field( @@ -268,6 +296,26 @@ class EventLink(proto.Message): number=2, message="EntityReference", ) + dependency_info: "DependencyInfo" = proto.Field( + proto.MESSAGE, + number=3, + message="DependencyInfo", + ) + + +class DependencyInfo(proto.Message): + r"""Dependency info describes how one entity depends on another. + + Attributes: + dependency_type (google.cloud.datacatalog_lineage_v1.types.DependencyType): + Required. Type of dependency. + """ + + dependency_type: "DependencyType" = proto.Field( + proto.ENUM, + number=1, + enum="DependencyType", + ) class EntityReference(proto.Message): @@ -277,14 +325,30 @@ class EntityReference(proto.Message): Attributes: fully_qualified_name (str): Required. `Fully Qualified Name - (FQN) `__ + (FQN) `__ of the entity. + field (MutableSequence[str]): + Optional. Field path within the entity. Each nesting level + should be a separate value in the repeated field. The order + matters. Must be empty for asset level lineage + + For example to address "salary.net" subfield where "salary" + is a column and "net" is a proto field two values in the + ``field`` should be reported, the first is "salary" and the + second is "net". + + Each field length is limited to 500 characters. Maximum + supported nesting level is 20. """ fully_qualified_name: str = proto.Field( proto.STRING, number=1, ) + field: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) class OperationMetadata(proto.Message): @@ -385,7 +449,7 @@ class Type(proto.Enum): class ProcessOpenLineageRunEventRequest(proto.Message): r"""Request message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. Attributes: parent (str): @@ -397,9 +461,9 @@ class ProcessOpenLineageRunEventRequest(proto.Message): OpenLineage format: https://github.com/OpenLineage/OpenLineage/blob/main/spec/OpenLineage.json request_id (str): - A unique identifier for this request. Restricted to 36 ASCII - characters. A random UUID is recommended. This request is - idempotent only if a ``request_id`` is provided. + Optional. A unique identifier for this request. Restricted + to 36 ASCII characters. A random UUID is recommended. This + request is idempotent only if a ``request_id`` is provided. """ parent: str = proto.Field( @@ -419,7 +483,7 @@ class ProcessOpenLineageRunEventRequest(proto.Message): class ProcessOpenLineageRunEventResponse(proto.Message): r"""Response message for - [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.ProcessOpenLineageRunEvent]. + [ProcessOpenLineageRunEvent][google.cloud.datacatalog.lineage.v1.Lineage.ProcessOpenLineageRunEvent]. Attributes: process (str): @@ -449,7 +513,7 @@ class ProcessOpenLineageRunEventResponse(proto.Message): class CreateProcessRequest(proto.Message): r"""Request message for - [CreateProcess][google.cloud.datacatalog.lineage.v1.CreateProcess]. + [CreateProcess][google.cloud.datacatalog.lineage.v1.Lineage.CreateProcess]. Attributes: parent (str): @@ -458,9 +522,9 @@ class CreateProcessRequest(proto.Message): process (google.cloud.datacatalog_lineage_v1.types.Process): Required. The process to create. request_id (str): - A unique identifier for this request. Restricted to 36 ASCII - characters. A random UUID is recommended. This request is - idempotent only if a ``request_id`` is provided. + Optional. A unique identifier for this request. Restricted + to 36 ASCII characters. A random UUID is recommended. This + request is idempotent only if a ``request_id`` is provided. """ parent: str = proto.Field( @@ -480,7 +544,7 @@ class CreateProcessRequest(proto.Message): class UpdateProcessRequest(proto.Message): r"""Request message for - [UpdateProcess][google.cloud.datacatalog.lineage.v1.UpdateProcess]. + [UpdateProcess][google.cloud.datacatalog.lineage.v1.Lineage.UpdateProcess]. Attributes: process (google.cloud.datacatalog_lineage_v1.types.Process): @@ -489,11 +553,16 @@ class UpdateProcessRequest(proto.Message): The process's ``name`` field is used to identify the process to update. update_mask (google.protobuf.field_mask_pb2.FieldMask): - The list of fields to update. Currently not - used. The whole message is updated. + Optional. The list of fields to update. + Currently not used. The whole message is + updated. allow_missing (bool): - If set to true and the process is not found, - the request inserts it. + Optional. If set to true and the process is + not found, the request inserts it. + request_id (str): + Optional. A unique identifier for this request. Restricted + to 36 ASCII characters. A random UUID is recommended. This + request is idempotent only if a ``request_id`` is provided. """ process: "Process" = proto.Field( @@ -510,11 +579,15 @@ class UpdateProcessRequest(proto.Message): proto.BOOL, number=3, ) + request_id: str = proto.Field( + proto.STRING, + number=4, + ) class GetProcessRequest(proto.Message): r"""Request message for - [GetProcess][google.cloud.datacatalog.lineage.v1.GetProcess]. + [GetProcess][google.cloud.datacatalog.lineage.v1.Lineage.GetProcess]. Attributes: name (str): @@ -529,21 +602,21 @@ class GetProcessRequest(proto.Message): class ListProcessesRequest(proto.Message): r"""Request message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. Attributes: parent (str): Required. The name of the project and its location that owns this collection of processes. page_size (int): - The maximum number of processes to return. - The service may return fewer than this value. If - unspecified, at most 50 processes are returned. - The maximum value is 100; values greater than - 100 are cut to 100. + Optional. The maximum number of processes to + return. The service may return fewer than this + value. If unspecified, at most 50 processes are + returned. The maximum value is 100; values + greater than 100 are cut to 100. page_token (str): - The page token received from a previous ``ListProcesses`` - call. Specify it to get the next page. + Optional. The page token received from a previous + ``ListProcesses`` call. Specify it to get the next page. When paginating, all other parameters specified in this call must match the parameters of the call that provided the page @@ -566,7 +639,7 @@ class ListProcessesRequest(proto.Message): class ListProcessesResponse(proto.Message): r"""Response message for - [ListProcesses][google.cloud.datacatalog.lineage.v1.ListProcesses]. + [ListProcesses][google.cloud.datacatalog.lineage.v1.Lineage.ListProcesses]. Attributes: processes (MutableSequence[google.cloud.datacatalog_lineage_v1.types.Process]): @@ -595,15 +668,15 @@ def raw_page(self): class DeleteProcessRequest(proto.Message): r"""Request message for - [DeleteProcess][google.cloud.datacatalog.lineage.v1.DeleteProcess]. + [DeleteProcess][google.cloud.datacatalog.lineage.v1.Lineage.DeleteProcess]. Attributes: name (str): Required. The name of the process to delete. allow_missing (bool): - If set to true and the process is not found, - the request succeeds but the server doesn't - perform any actions. + Optional. If set to true and the process is + not found, the request succeeds but the server + doesn't perform any actions. """ name: str = proto.Field( @@ -618,7 +691,7 @@ class DeleteProcessRequest(proto.Message): class CreateRunRequest(proto.Message): r"""Request message for - [CreateRun][google.cloud.datacatalog.lineage.v1.CreateRun]. + [CreateRun][google.cloud.datacatalog.lineage.v1.Lineage.CreateRun]. Attributes: parent (str): @@ -627,9 +700,9 @@ class CreateRunRequest(proto.Message): run (google.cloud.datacatalog_lineage_v1.types.Run): Required. The run to create. request_id (str): - A unique identifier for this request. Restricted to 36 ASCII - characters. A random UUID is recommended. This request is - idempotent only if a ``request_id`` is provided. + Optional. A unique identifier for this request. Restricted + to 36 ASCII characters. A random UUID is recommended. This + request is idempotent only if a ``request_id`` is provided. """ parent: str = proto.Field( @@ -649,7 +722,7 @@ class CreateRunRequest(proto.Message): class UpdateRunRequest(proto.Message): r"""Request message for - [UpdateRun][google.cloud.datacatalog.lineage.v1.UpdateRun]. + [UpdateRun][google.cloud.datacatalog.lineage.v1.Lineage.UpdateRun]. Attributes: run (google.cloud.datacatalog_lineage_v1.types.Run): @@ -661,11 +734,12 @@ class UpdateRunRequest(proto.Message): Format: ``projects/{project}/locations/{location}/processes/{process}/runs/{run}``. update_mask (google.protobuf.field_mask_pb2.FieldMask): - The list of fields to update. Currently not - used. The whole message is updated. + Optional. The list of fields to update. + Currently not used. The whole message is + updated. allow_missing (bool): - If set to true and the run is not found, the - request creates it. + Optional. If set to true and the run is not + found, the request creates it. """ run: "Run" = proto.Field( @@ -686,7 +760,7 @@ class UpdateRunRequest(proto.Message): class GetRunRequest(proto.Message): r"""Request message for - [GetRun][google.cloud.datacatalog.lineage.v1.GetRun]. + [GetRun][google.cloud.datacatalog.lineage.v1.Lineage.GetRun]. Attributes: name (str): @@ -701,21 +775,21 @@ class GetRunRequest(proto.Message): class ListRunsRequest(proto.Message): r"""Request message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. Attributes: parent (str): Required. The name of process that owns this collection of runs. page_size (int): - The maximum number of runs to return. The - service may return fewer than this value. If - unspecified, at most 50 runs are returned. The - maximum value is 100; values greater than 100 - are cut to 100. + Optional. The maximum number of runs to + return. The service may return fewer than this + value. If unspecified, at most 50 runs are + returned. The maximum value is 100; values + greater than 100 are cut to 100. page_token (str): - The page token received from a previous ``ListRuns`` call. - Specify it to get the next page. + Optional. The page token received from a previous + ``ListRuns`` call. Specify it to get the next page. When paginating, all other parameters specified in this call must match the parameters of the call that provided the page @@ -738,7 +812,7 @@ class ListRunsRequest(proto.Message): class ListRunsResponse(proto.Message): r"""Response message for - [ListRuns][google.cloud.datacatalog.lineage.v1.ListRuns]. + [ListRuns][google.cloud.datacatalog.lineage.v1.Lineage.ListRuns]. Attributes: runs (MutableSequence[google.cloud.datacatalog_lineage_v1.types.Run]): @@ -767,15 +841,15 @@ def raw_page(self): class DeleteRunRequest(proto.Message): r"""Request message for - [DeleteRun][google.cloud.datacatalog.lineage.v1.DeleteRun]. + [DeleteRun][google.cloud.datacatalog.lineage.v1.Lineage.DeleteRun]. Attributes: name (str): Required. The name of the run to delete. allow_missing (bool): - If set to true and the run is not found, the - request succeeds but the server doesn't perform - any actions. + Optional. If set to true and the run is not + found, the request succeeds but the server + doesn't perform any actions. """ name: str = proto.Field( @@ -790,7 +864,7 @@ class DeleteRunRequest(proto.Message): class CreateLineageEventRequest(proto.Message): r"""Request message for - [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.CreateLineageEvent]. + [CreateLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.CreateLineageEvent]. Attributes: parent (str): @@ -799,9 +873,9 @@ class CreateLineageEventRequest(proto.Message): lineage_event (google.cloud.datacatalog_lineage_v1.types.LineageEvent): Required. The lineage event to create. request_id (str): - A unique identifier for this request. Restricted to 36 ASCII - characters. A random UUID is recommended. This request is - idempotent only if a ``request_id`` is provided. + Optional. A unique identifier for this request. Restricted + to 36 ASCII characters. A random UUID is recommended. This + request is idempotent only if a ``request_id`` is provided. """ parent: str = proto.Field( @@ -821,7 +895,7 @@ class CreateLineageEventRequest(proto.Message): class GetLineageEventRequest(proto.Message): r"""Request message for - [GetLineageEvent][google.cloud.datacatalog.lineage.v1.GetLineageEvent]. + [GetLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.GetLineageEvent]. Attributes: name (str): @@ -837,21 +911,21 @@ class GetLineageEventRequest(proto.Message): class ListLineageEventsRequest(proto.Message): r"""Request message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. Attributes: parent (str): Required. The name of the run that owns the collection of lineage events to get. page_size (int): - The maximum number of lineage events to - return. + Optional. The maximum number of lineage + events to return. The service may return fewer events than this value. If unspecified, at most 50 events are returned. The maximum value is 100; values greater than 100 are cut to 100. page_token (str): - The page token received from a previous + Optional. The page token received from a previous ``ListLineageEvents`` call. Specify it to get the next page. When paginating, all other parameters specified in this call @@ -875,7 +949,7 @@ class ListLineageEventsRequest(proto.Message): class ListLineageEventsResponse(proto.Message): r"""Response message for - [ListLineageEvents][google.cloud.datacatalog.lineage.v1.ListLineageEvents]. + [ListLineageEvents][google.cloud.datacatalog.lineage.v1.Lineage.ListLineageEvents]. Attributes: lineage_events (MutableSequence[google.cloud.datacatalog_lineage_v1.types.LineageEvent]): @@ -904,16 +978,16 @@ def raw_page(self): class DeleteLineageEventRequest(proto.Message): r"""Request message for - [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.DeleteLineageEvent]. + [DeleteLineageEvent][google.cloud.datacatalog.lineage.v1.Lineage.DeleteLineageEvent]. Attributes: name (str): Required. The name of the lineage event to delete. allow_missing (bool): - If set to true and the lineage event is not - found, the request succeeds but the server - doesn't perform any actions. + Optional. If set to true and the lineage + event is not found, the request succeeds but the + server doesn't perform any actions. """ name: str = proto.Field( @@ -952,6 +1026,28 @@ class SearchLinksRequest(proto.Message): retrieve all links that lead from upstream assets to the specified asset. + This field is a member of `oneof`_ ``criteria``. + sources (google.cloud.datacatalog_lineage_v1.types.MultipleEntityReference): + Optional. Send a list of asset information in the + **sources** field to retrieve all links that lead from the + specified assets to downstream assets. This field is similar + to the ``source`` + [source][google.cloud.datacatalog.lineage.v1.SearchLinksRequest.source] + field but allows providing multiple entities. All entities + within the ``MultipleEntityReference`` must have the same + ``fully_qualified_name``. + + This field is a member of `oneof`_ ``criteria``. + targets (google.cloud.datacatalog_lineage_v1.types.MultipleEntityReference): + Optional. Send a list of asset information in the + **targets** field to retrieve all links that lead from + upstream assets to the specified assets. This field is + similar to the ``target`` + [target][google.cloud.datacatalog.lineage.v1.SearchLinksRequest.target] + field but allows providing multiple entities. All entities + within the ``MultipleEntityReference`` must have the same + ``fully_qualified_name``. + This field is a member of `oneof`_ ``criteria``. page_size (int): Optional. The maximum number of links to @@ -986,6 +1082,18 @@ class SearchLinksRequest(proto.Message): oneof="criteria", message="EntityReference", ) + sources: "MultipleEntityReference" = proto.Field( + proto.MESSAGE, + number=6, + oneof="criteria", + message="MultipleEntityReference", + ) + targets: "MultipleEntityReference" = proto.Field( + proto.MESSAGE, + number=7, + oneof="criteria", + message="MultipleEntityReference", + ) page_size: int = proto.Field( proto.INT32, number=2, @@ -996,6 +1104,22 @@ class SearchLinksRequest(proto.Message): ) +class MultipleEntityReference(proto.Message): + r"""Multiple entity reference for SearchLinksRequest. + + Attributes: + entities (MutableSequence[google.cloud.datacatalog_lineage_v1.types.EntityReference]): + Optional. The list of entities to search for + links. The maximum number of entities is 20. + """ + + entities: MutableSequence["EntityReference"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="EntityReference", + ) + + class SearchLinksResponse(proto.Message): r"""Response message for [SearchLinks][google.cloud.datacatalog.lineage.v1.Lineage.SearchLinks]. @@ -1049,8 +1173,25 @@ class Link(proto.Message): end_time (google.protobuf.timestamp_pb2.Timestamp): The end of the last event establishing this link. + dependency_info (MutableSequence[google.cloud.datacatalog_lineage_v1.types.Link.DependencyInfo]): + Optional. The dependency info of the link + (applies only to column level links). """ + class DependencyInfo(proto.Message): + r"""Dependency info describes how one entity depends on another. + + Attributes: + dependency_type (google.cloud.datacatalog_lineage_v1.types.DependencyType): + The type of dependency. + """ + + dependency_type: "DependencyType" = proto.Field( + proto.ENUM, + number=1, + enum="DependencyType", + ) + name: str = proto.Field( proto.STRING, number=1, @@ -1075,6 +1216,11 @@ class Link(proto.Message): number=5, message=timestamp_pb2.Timestamp, ) + dependency_info: MutableSequence[DependencyInfo] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=DependencyInfo, + ) class BatchSearchLinkProcessesRequest(proto.Message): @@ -1096,11 +1242,11 @@ class BatchSearchLinkProcessesRequest(proto.Message): Format: ``projects/{project}/locations/{location}/links/{link}``. page_size (int): - The maximum number of processes to return in - a single page of the response. A page may - contain fewer results than this value. + Optional. The maximum number of processes to + return in a single page of the response. A page + may contain fewer results than this value. page_token (str): - The page token received from a previous + Optional. The page token received from a previous ``BatchSearchLinkProcesses`` call. Use it to get the next page. @@ -1223,14 +1369,16 @@ class Origin(proto.Message): Type of the source. Use of a source_type other than ``CUSTOM`` for process - creation or updating is highly discouraged, and may be - restricted in the future without notice. + creation or updating is highly discouraged. It might be + restricted in the future without notice. There will be + increase in cost if you use any of the source types other + than ``CUSTOM``. name (str): If the source_type isn't CUSTOM, the value of this field - should be a GCP resource name of the system, which reports - lineage. The project and location parts of the resource name - must match the project and location of the lineage resource - being created. Examples: + should be a Google Cloud resource name of the system, which + reports lineage. The project and location parts of the + resource name must match the project and location of the + lineage resource being created. Examples: - ``{source_type: COMPOSER, name: "projects/foo/locations/us/environments/bar"}`` - ``{source_type: BIGQUERY, name: "projects/foo/locations/eu"}`` @@ -1255,6 +1403,12 @@ class SourceType(proto.Enum): Looker Studio DATAPROC (6): Dataproc + VERTEX_AI (7): + Vertex AI + DATAFLOW (8): + Dataflow + LOOKER_CORE (9): + Looker Core """ SOURCE_TYPE_UNSPECIFIED = 0 @@ -1264,6 +1418,9 @@ class SourceType(proto.Enum): COMPOSER = 4 LOOKER_STUDIO = 5 DATAPROC = 6 + VERTEX_AI = 7 + DATAFLOW = 8 + LOOKER_CORE = 9 source_type: SourceType = proto.Field( proto.ENUM, @@ -1276,4 +1433,285 @@ class SourceType(proto.Enum): ) +class LineageLink(proto.Message): + r"""Lineage link between two entities. + + Attributes: + source (google.cloud.datacatalog_lineage_v1.types.EntityReference): + The entity that is the **source** of this link. + target (google.cloud.datacatalog_lineage_v1.types.EntityReference): + The entity that is the **target** of this link. + processes (MutableSequence[google.cloud.datacatalog_lineage_v1.types.LineageLink.LineageProcess]): + Processes metadata associated with the link. + dependency_info (MutableSequence[google.cloud.datacatalog_lineage_v1.types.LineageLink.DependencyInfo]): + Describes how the target entity is dependent + on the source entity. + depth (int): + Depth of the current link in the graph + starting from 1. + location (str): + The location where the LineageEvent that + created the link is stored. + """ + + class LineageProcess(proto.Message): + r"""Process metadata for the link. + + Attributes: + process (google.cloud.datacatalog_lineage_v1.types.Process): + Process that created the link. + """ + + process: "Process" = proto.Field( + proto.MESSAGE, + number=3, + message="Process", + ) + + class DependencyInfo(proto.Message): + r"""Dependency info describes how one entity is dependent on + another. + + Attributes: + dependency_type (google.cloud.datacatalog_lineage_v1.types.DependencyType): + The type of dependency. + """ + + dependency_type: "DependencyType" = proto.Field( + proto.ENUM, + number=1, + enum="DependencyType", + ) + + source: "EntityReference" = proto.Field( + proto.MESSAGE, + number=1, + message="EntityReference", + ) + target: "EntityReference" = proto.Field( + proto.MESSAGE, + number=2, + message="EntityReference", + ) + processes: MutableSequence[LineageProcess] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=LineageProcess, + ) + dependency_info: MutableSequence[DependencyInfo] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=DependencyInfo, + ) + depth: int = proto.Field( + proto.INT32, + number=5, + ) + location: str = proto.Field( + proto.STRING, + number=7, + ) + + +class SearchLineageStreamingRequest(proto.Message): + r"""Request message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + + Attributes: + parent (str): + Required. The project and location to + initiate the search from. + locations (MutableSequence[str]): + Required. The locations to search in. + root_criteria (google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest.RootCriteria): + Required. Criteria for the root of the + search. + direction (google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest.SearchDirection): + Required. Direction of the search. + filters (google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest.SearchFilters): + Optional. Filters for the search. + limits (google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest.SearchLimits): + Optional. Limits for the search. + """ + + class SearchDirection(proto.Enum): + r"""Direction of the search. + + Values: + SEARCH_DIRECTION_UNSPECIFIED (0): + Direction is unspecified. + DOWNSTREAM (1): + Retrieve links that lead from the specified + asset to downstream assets. + UPSTREAM (2): + Retrieve links that lead from upstream assets + to the specified asset. + """ + + SEARCH_DIRECTION_UNSPECIFIED = 0 + DOWNSTREAM = 1 + UPSTREAM = 2 + + class EntitySet(proto.Enum): + r"""Entity set restriction. + + Values: + ENTITY_SET_UNSPECIFIED (0): + The entity set is unspecified. Returns all + the data. + ENTITIES (1): + Returns entities with only FQN specified. For example, + entities with the ``field`` field set are not returned. + """ + + ENTITY_SET_UNSPECIFIED = 0 + ENTITIES = 1 + + class SearchFilters(proto.Message): + r"""Filters for the search. + + Attributes: + dependency_types (MutableSequence[google.cloud.datacatalog_lineage_v1.types.DependencyType]): + Optional. Types of dependencies between + entities to retrieve. If unspecified, all + dependency types are returned. + entity_set (google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest.EntitySet): + Optional. Entity set restriction. If + unspecified, the method returns all entities. + time_range (google.type.interval_pb2.Interval): + Optional. Time interval to search for lineage. If + unspecified, all lineage is returned. Currently, at most one + of ``start_time`` and ``end_time`` can be set. + """ + + dependency_types: MutableSequence["DependencyType"] = proto.RepeatedField( + proto.ENUM, + number=1, + enum="DependencyType", + ) + entity_set: "SearchLineageStreamingRequest.EntitySet" = proto.Field( + proto.ENUM, + number=2, + enum="SearchLineageStreamingRequest.EntitySet", + ) + time_range: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=3, + message=interval_pb2.Interval, + ) + + class SearchLimits(proto.Message): + r"""Limits for the search results. + + Attributes: + max_depth (int): + Optional. The maximum depth of the search. + The default value is 5 and maximum value is 100. + max_results (int): + Optional. The maximum number of links to return in the + response. The default value is 1_000 and the maximum value + is 10_000. + max_process_per_link (int): + Optional. The maximum number of processes to return per + link. The default value is 0 and the maximum value is 100. + If this value is non-zero, the response will contain process + names for the links. To retrieve full process details in the + response, include ``links.processes.process`` in the + `FieldMask `__. + """ + + max_depth: int = proto.Field( + proto.INT32, + number=1, + ) + max_results: int = proto.Field( + proto.INT32, + number=2, + ) + max_process_per_link: int = proto.Field( + proto.INT32, + number=3, + ) + + class RootCriteria(proto.Message): + r"""Criteria for the root of the search. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + entities (google.cloud.datacatalog_lineage_v1.types.MultipleEntityReference): + Optional. The entities to initiate the search from. Entities + can be specified by FQN only, or by FQN and field. To search + by FQN and all available fields for that FQN, use the + wildcard ``*`` as the field value. + + This field is a member of `oneof`_ ``criteria``. + """ + + entities: "MultipleEntityReference" = proto.Field( + proto.MESSAGE, + number=1, + oneof="criteria", + message="MultipleEntityReference", + ) + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + locations: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + root_criteria: RootCriteria = proto.Field( + proto.MESSAGE, + number=3, + message=RootCriteria, + ) + direction: SearchDirection = proto.Field( + proto.ENUM, + number=4, + enum=SearchDirection, + ) + filters: SearchFilters = proto.Field( + proto.MESSAGE, + number=5, + message=SearchFilters, + ) + limits: SearchLimits = proto.Field( + proto.MESSAGE, + number=6, + message=SearchLimits, + ) + + +class SearchLineageStreamingResponse(proto.Message): + r"""Response message for + [SearchLineageStreaming][google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming]. + + Attributes: + links (MutableSequence[google.cloud.datacatalog_lineage_v1.types.LineageLink]): + Output only. The lineage links that match the + search criteria. Can be empty if no links match. + unreachable (MutableSequence[str]): + Unordered list. Unreachable resources. If non-empty, the + result set might be incomplete. + + Currently, only locations are supported. + + Format: ``projects/[PROJECT_NUMBER]/locations/[LOCATION]`` + Example: projects/123456789/locations/us-east1 + """ + + links: MutableSequence["LineageLink"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="LineageLink", + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-datacatalog-lineage/noxfile.py b/packages/google-cloud-datacatalog-lineage/noxfile.py index af54a9b59e51..cad68aabc0ca 100644 --- a/packages/google-cloud-datacatalog-lineage/noxfile.py +++ b/packages/google-cloud-datacatalog-lineage/noxfile.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,7 +31,6 @@ LINT_PATHS.append("samples") ALL_PYTHON = [ - "3.9", "3.10", "3.11", "3.12", @@ -390,7 +389,6 @@ def docs(session): shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( "sphinx-build", - "-W", # warnings as errors "-T", # show full traceback on exception "-N", # no colors "-b", diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_async.py index c8b03c35c37a..fa1ef3220556 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_sync.py index 1554087e4839..91592fd887f2 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_batch_search_link_processes_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_async.py index 23c398f22374..fd3aab623010 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_sync.py index 589a5e389a8c..d7c28711b8be 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_lineage_event_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_async.py index 6071224f4cdf..5479992177f7 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_sync.py index 24f49e9c937d..ad6ce72b8655 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_process_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_async.py index 67766ef01129..3e4a720e83a8 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_sync.py index d9519e9f38d0..6a8580dc460c 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_create_run_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_async.py index 5347dbdb688f..d2d3290db635 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_sync.py index c09f8b4b6055..9bd0e90b5883 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_lineage_event_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_async.py index be702d1a494c..0e8f81179014 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -44,11 +44,11 @@ async def sample_delete_process(): ) # Make the request - operation = client.delete_process(request=request) + operation = await client.delete_process(request=request) print("Waiting for operation to complete...") - response = (await operation).result() + response = await operation.result() # Handle the response print(response) diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_sync.py index ca698f0997ee..e2962c564e4a 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_process_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_async.py index e418d3092ab6..515befc97ac4 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -44,11 +44,11 @@ async def sample_delete_run(): ) # Make the request - operation = client.delete_run(request=request) + operation = await client.delete_run(request=request) print("Waiting for operation to complete...") - response = (await operation).result() + response = await operation.result() # Handle the response print(response) diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_sync.py index ef789892b75a..a14c07beea46 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_delete_run_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_async.py index 55e72f253538..9e7720af55e1 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_sync.py index d99051fee59f..310231a20b60 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_lineage_event_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_async.py index a32aace09fdd..a0b33d8ae817 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_sync.py index a307ea62d6c5..91aae01ffad5 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_process_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_async.py index 0a6fbb72fa92..3552cd90ac02 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_sync.py index 36c6e1110281..49d9f15503f3 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_get_run_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_async.py index 35739ba1096c..10c13a94d395 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_sync.py index 9082021b272e..23b8d4785d30 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_lineage_events_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_async.py index f0bcf2b69429..47e16b1cb32a 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_sync.py index 9c422117a497..f4f1afa8b46a 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_processes_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_async.py index 1b6b97df4e51..8ced93eb0a00 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_sync.py index 100814827ed6..4d36e079a366 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_list_runs_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_async.py index 61f1a9e5216c..7f1befe09d37 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_sync.py index 2ab7eb179475..37499c441aea 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_process_open_lineage_run_event_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_async.py new file mode 100644 index 000000000000..e47f68007a36 --- /dev/null +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_async.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SearchLineageStreaming +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-datacatalog-lineage + + +# [START datalineage_v1_generated_Lineage_SearchLineageStreaming_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import datacatalog_lineage_v1 + + +async def sample_search_lineage_streaming(): + # Create a client + client = datacatalog_lineage_v1.LineageAsyncClient() + + # Initialize request argument(s) + request = datacatalog_lineage_v1.SearchLineageStreamingRequest( + parent="parent_value", + locations=["locations_value1", "locations_value2"], + direction="UPSTREAM", + ) + + # Make the request + stream = await client.search_lineage_streaming(request=request) + + # Handle the response + async for response in stream: + print(response) + + +# [END datalineage_v1_generated_Lineage_SearchLineageStreaming_async] diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_sync.py new file mode 100644 index 000000000000..40eeeda1cf14 --- /dev/null +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_lineage_streaming_sync.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SearchLineageStreaming +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-datacatalog-lineage + + +# [START datalineage_v1_generated_Lineage_SearchLineageStreaming_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import datacatalog_lineage_v1 + + +def sample_search_lineage_streaming(): + # Create a client + client = datacatalog_lineage_v1.LineageClient() + + # Initialize request argument(s) + request = datacatalog_lineage_v1.SearchLineageStreamingRequest( + parent="parent_value", + locations=["locations_value1", "locations_value2"], + direction="UPSTREAM", + ) + + # Make the request + stream = client.search_lineage_streaming(request=request) + + # Handle the response + for response in stream: + print(response) + + +# [END datalineage_v1_generated_Lineage_SearchLineageStreaming_sync] diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_async.py index c5f601465046..f3dc8f7e17cc 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_sync.py index e6ee5677b1c9..3c7a9ae2d180 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_search_links_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_async.py index d07b58dc1ddb..bb388a00a71d 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_sync.py index e2b0a915e463..d936f0456c15 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_process_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_async.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_async.py index a795a5a897b4..09f02cf71406 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_async.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_async.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_sync.py b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_sync.py index cc341361ad3a..4b69816bab69 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_sync.py +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/datalineage_v1_generated_lineage_update_run_sync.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json index ad9eab89d145..fd372f343291 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json @@ -2283,6 +2283,159 @@ ], "title": "datalineage_v1_generated_lineage_process_open_lineage_run_event_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.datacatalog_lineage_v1.LineageAsyncClient", + "shortName": "LineageAsyncClient" + }, + "fullName": "google.cloud.datacatalog_lineage_v1.LineageAsyncClient.search_lineage_streaming", + "method": { + "fullName": "google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming", + "service": { + "fullName": "google.cloud.datacatalog.lineage.v1.Lineage", + "shortName": "Lineage" + }, + "shortName": "SearchLineageStreaming" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingResponse]", + "shortName": "search_lineage_streaming" + }, + "description": "Sample for SearchLineageStreaming", + "file": "datalineage_v1_generated_lineage_search_lineage_streaming_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "datalineage_v1_generated_Lineage_SearchLineageStreaming_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "datalineage_v1_generated_lineage_search_lineage_streaming_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.datacatalog_lineage_v1.LineageClient", + "shortName": "LineageClient" + }, + "fullName": "google.cloud.datacatalog_lineage_v1.LineageClient.search_lineage_streaming", + "method": { + "fullName": "google.cloud.datacatalog.lineage.v1.Lineage.SearchLineageStreaming", + "service": { + "fullName": "google.cloud.datacatalog.lineage.v1.Lineage", + "shortName": "Lineage" + }, + "shortName": "SearchLineageStreaming" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.datacatalog_lineage_v1.types.SearchLineageStreamingResponse]", + "shortName": "search_lineage_streaming" + }, + "description": "Sample for SearchLineageStreaming", + "file": "datalineage_v1_generated_lineage_search_lineage_streaming_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "datalineage_v1_generated_Lineage_SearchLineageStreaming_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "datalineage_v1_generated_lineage_search_lineage_streaming_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-datacatalog-lineage/setup.py b/packages/google-cloud-datacatalog-lineage/setup.py index c32a94431bd7..aef64dce5881 100644 --- a/packages/google-cloud-datacatalog-lineage/setup.py +++ b/packages/google-cloud-datacatalog-lineage/setup.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -41,11 +41,11 @@ release_status = "Development Status :: 5 - Production/Stable" dependencies = [ - "google-api-core[grpc] >= 2.11.0, <3.0.0", + "google-api-core[grpc] >= 2.17.1, <3.0.0", # Exclude incompatible versions of `google-auth` # See https://github.com/googleapis/google-cloud-python/issues/12364 "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", - "grpcio >= 1.33.2, < 2.0.0", + "grpcio >= 1.44.0, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", @@ -73,7 +73,7 @@ long_description=readme, author="Google LLC", author_email="googleapis-packages@google.com", - license="Apache 2.0", + license="Apache-2.0", url=url, classifiers=[ release_status, @@ -81,7 +81,6 @@ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -92,7 +91,7 @@ ], platforms="Posix; MacOS X; Windows", packages=packages, - python_requires=">=3.9", + python_requires=">=3.10", install_requires=dependencies, extras_require=extras, include_package_data=True, diff --git a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt index 7599dea499ed..bac7ba85b4ee 100644 --- a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt +++ b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.10.txt @@ -1,10 +1,11 @@ -# -*- coding: utf-8 -*- -# This constraints file is required for unit tests. -# List all library dependencies and extras in this file. -google-api-core -google-auth -grpcio -proto-plus -protobuf -# cryptography is a direct dependency of google-auth -cryptography +# This constraints file is used to check that lower bounds +# are correct in setup.py +# List all library dependencies and extras in this file, +# pinning their versions to their lower bounds. +# For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# then this file should have google-cloud-foo==1.14.0 +google-api-core==2.17.1 +google-auth==2.14.1 +grpcio==1.44.0 +proto-plus==1.22.3 +protobuf==4.25.8 diff --git a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.9.txt b/packages/google-cloud-datacatalog-lineage/testing/constraints-3.9.txt deleted file mode 100644 index ac3833d41b9a..000000000000 --- a/packages/google-cloud-datacatalog-lineage/testing/constraints-3.9.txt +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -# This constraints file is used to check that lower bounds -# are correct in setup.py -# List all library dependencies and extras in this file, -# pinning their versions to their lower bounds. -# For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", -# then this file should have google-cloud-foo==1.14.0 -google-api-core==2.21.0 -google-auth==2.35.0 -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2453) -# Add the minimum supported version of grpcio to constraints files -proto-plus==1.22.3 -protobuf==4.25.8 diff --git a/packages/google-cloud-datacatalog-lineage/tests/__init__.py b/packages/google-cloud-datacatalog-lineage/tests/__init__.py index cbf94b283c70..32b36c5c4fe0 100644 --- a/packages/google-cloud-datacatalog-lineage/tests/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/tests/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/tests/unit/__init__.py b/packages/google-cloud-datacatalog-lineage/tests/unit/__init__.py index cbf94b283c70..32b36c5c4fe0 100644 --- a/packages/google-cloud-datacatalog-lineage/tests/unit/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/tests/unit/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/__init__.py b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/__init__.py index cbf94b283c70..32b36c5c4fe0 100644 --- a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/__init__.py b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/__init__.py index cbf94b283c70..32b36c5c4fe0 100644 --- a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/__init__.py +++ b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py index 50365b1d8f32..59676e45a2e0 100644 --- a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py +++ b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2025 Google LLC +# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,18 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import os - -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock - from unittest.mock import AsyncMock # pragma: NO COVER -except ImportError: # pragma: NO COVER - import mock - import json import math +import os +import re from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from unittest import mock +from unittest.mock import AsyncMock import grpc import pytest @@ -49,6 +44,7 @@ import google.protobuf.field_mask_pb2 as field_mask_pb2 # type: ignore import google.protobuf.struct_pb2 as struct_pb2 # type: ignore import google.protobuf.timestamp_pb2 as timestamp_pb2 # type: ignore +import google.type.interval_pb2 as interval_pb2 # type: ignore from google.api_core import ( client_options, future, @@ -1268,6 +1264,10 @@ def test_process_open_lineage_run_event(request_type, transport: str = "grpc"): # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1285,6 +1285,7 @@ def test_process_open_lineage_run_event(request_type, transport: str = "grpc"): assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] request = lineage.ProcessOpenLineageRunEventRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -1307,7 +1308,6 @@ def test_process_open_lineage_run_event_non_empty_request_with_auto_populated_fi # if they meet the requirements of AIP 4235. request = lineage.ProcessOpenLineageRunEventRequest( parent="parent_value", - request_id="request_id_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1320,9 +1320,15 @@ def test_process_open_lineage_run_event_non_empty_request_with_auto_populated_fi client.process_open_lineage_run_event(request=request) call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None assert args[0] == lineage.ProcessOpenLineageRunEventRequest( parent="parent_value", - request_id="request_id_value", ) @@ -1421,6 +1427,10 @@ async def test_process_open_lineage_run_event_async( # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -1440,6 +1450,7 @@ async def test_process_open_lineage_run_event_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] request = lineage.ProcessOpenLineageRunEventRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -1667,6 +1678,10 @@ def test_create_process(request_type, transport: str = "grpc"): # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.create_process), "__call__") as call: @@ -1681,6 +1696,7 @@ def test_create_process(request_type, transport: str = "grpc"): assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] request = lineage.CreateProcessRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -1702,7 +1718,6 @@ def test_create_process_non_empty_request_with_auto_populated_field(): # if they meet the requirements of AIP 4235. request = lineage.CreateProcessRequest( parent="parent_value", - request_id="request_id_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1713,9 +1728,15 @@ def test_create_process_non_empty_request_with_auto_populated_field(): client.create_process(request=request) call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None assert args[0] == lineage.CreateProcessRequest( parent="parent_value", - request_id="request_id_value", ) @@ -1808,6 +1829,10 @@ async def test_create_process_async( # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.create_process), "__call__") as call: @@ -1824,6 +1849,7 @@ async def test_create_process_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] request = lineage.CreateProcessRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -2002,6 +2028,10 @@ def test_update_process(request_type, transport: str = "grpc"): # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.update_process), "__call__") as call: @@ -2016,6 +2046,7 @@ def test_update_process(request_type, transport: str = "grpc"): assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] request = lineage.UpdateProcessRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -2045,6 +2076,13 @@ def test_update_process_non_empty_request_with_auto_populated_field(): client.update_process(request=request) call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None assert args[0] == lineage.UpdateProcessRequest() @@ -2137,6 +2175,10 @@ async def test_update_process_async( # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.update_process), "__call__") as call: @@ -2153,6 +2195,7 @@ async def test_update_process_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] request = lineage.UpdateProcessRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -3147,11 +3190,7 @@ async def test_list_processes_async_pages(): RuntimeError, ) pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_processes(request={}) - ).pages: + async for page_ in (await client.list_processes(request={})).pages: pages.append(page_) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token @@ -3500,6 +3539,10 @@ def test_create_run(request_type, transport: str = "grpc"): # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.create_run), "__call__") as call: @@ -3515,6 +3558,7 @@ def test_create_run(request_type, transport: str = "grpc"): assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] request = lineage.CreateRunRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -3537,7 +3581,6 @@ def test_create_run_non_empty_request_with_auto_populated_field(): # if they meet the requirements of AIP 4235. request = lineage.CreateRunRequest( parent="parent_value", - request_id="request_id_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -3548,9 +3591,15 @@ def test_create_run_non_empty_request_with_auto_populated_field(): client.create_run(request=request) call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None assert args[0] == lineage.CreateRunRequest( parent="parent_value", - request_id="request_id_value", ) @@ -3641,6 +3690,10 @@ async def test_create_run_async( # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.create_run), "__call__") as call: @@ -3658,6 +3711,7 @@ async def test_create_run_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] request = lineage.CreateRunRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -4984,11 +5038,7 @@ async def test_list_runs_async_pages(): RuntimeError, ) pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_runs(request={}) - ).pages: + async for page_ in (await client.list_runs(request={})).pages: pages.append(page_) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token @@ -5335,6 +5385,10 @@ def test_create_lineage_event(request_type, transport: str = "grpc"): # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -5350,6 +5404,7 @@ def test_create_lineage_event(request_type, transport: str = "grpc"): assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] request = lineage.CreateLineageEventRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -5370,7 +5425,6 @@ def test_create_lineage_event_non_empty_request_with_auto_populated_field(): # if they meet the requirements of AIP 4235. request = lineage.CreateLineageEventRequest( parent="parent_value", - request_id="request_id_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -5383,9 +5437,15 @@ def test_create_lineage_event_non_empty_request_with_auto_populated_field(): client.create_lineage_event(request=request) call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None assert args[0] == lineage.CreateLineageEventRequest( parent="parent_value", - request_id="request_id_value", ) @@ -5482,6 +5542,10 @@ async def test_create_lineage_event_async( # Everything is optional in proto3 as far as the runtime is concerned, # and we are mocking out the actual API, so just send an empty request. request = request_type() + if isinstance(request, dict): + request["request_id"] = "explicit value for autopopulate-able field" + else: + request.request_id = "explicit value for autopopulate-able field" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object( @@ -5499,6 +5563,7 @@ async def test_create_lineage_event_async( assert len(call.mock_calls) _, args, _ = call.mock_calls[0] request = lineage.CreateLineageEventRequest() + request.request_id = "explicit value for autopopulate-able field" assert args[0] == request # Establish that the response is the type that we expect. @@ -6546,11 +6611,7 @@ async def test_list_lineage_events_async_pages(): RuntimeError, ) pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.list_lineage_events(request={}) - ).pages: + async for page_ in (await client.list_lineage_events(request={})).pages: pages.append(page_) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token @@ -7312,11 +7373,7 @@ async def test_search_links_async_pages(): RuntimeError, ) pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.search_links(request={}) - ).pages: + async for page_ in (await client.search_links(request={})).pages: pages.append(page_) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token @@ -7775,16 +7832,266 @@ async def test_batch_search_link_processes_async_pages(): RuntimeError, ) pages = [] - # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` - # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 - async for page_ in ( # pragma: no branch - await client.batch_search_link_processes(request={}) - ).pages: + async for page_ in (await client.batch_search_link_processes(request={})).pages: pages.append(page_) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): assert page_.raw_page.next_page_token == token +@pytest.mark.parametrize( + "request_type", + [ + lineage.SearchLineageStreamingRequest, + dict, + ], +) +def test_search_lineage_streaming(request_type, transport: str = "grpc"): + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = iter([lineage.SearchLineageStreamingResponse()]) + response = client.search_lineage_streaming(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = lineage.SearchLineageStreamingRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + for message in response: + assert isinstance(message, lineage.SearchLineageStreamingResponse) + + +def test_search_lineage_streaming_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = lineage.SearchLineageStreamingRequest( + parent="parent_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.search_lineage_streaming(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == lineage.SearchLineageStreamingRequest( + parent="parent_value", + ) + + +def test_search_lineage_streaming_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.search_lineage_streaming + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.search_lineage_streaming + ] = mock_rpc + request = {} + client.search_lineage_streaming(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.search_lineage_streaming(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_search_lineage_streaming_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = LineageAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.search_lineage_streaming + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.search_lineage_streaming + ] = mock_rpc + + request = {} + await client.search_lineage_streaming(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.search_lineage_streaming(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_search_lineage_streaming_async( + transport: str = "grpc_asyncio", request_type=lineage.SearchLineageStreamingRequest +): + client = LineageAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[lineage.SearchLineageStreamingResponse()] + ) + response = await client.search_lineage_streaming(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = lineage.SearchLineageStreamingRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + message = await response.read() + assert isinstance(message, lineage.SearchLineageStreamingResponse) + + +@pytest.mark.asyncio +async def test_search_lineage_streaming_async_from_dict(): + await test_search_lineage_streaming_async(request_type=dict) + + +def test_search_lineage_streaming_field_headers(): + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = lineage.SearchLineageStreamingRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + call.return_value = iter([lineage.SearchLineageStreamingResponse()]) + client.search_lineage_streaming(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_search_lineage_streaming_field_headers_async(): + client = LineageAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = lineage.SearchLineageStreamingRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[lineage.SearchLineageStreamingResponse()] + ) + await client.search_lineage_streaming(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + def test_process_open_lineage_run_event_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -7900,8 +8207,20 @@ def test_process_open_lineage_run_event_rest_required_fields( response = client.process_open_lineage_run_event(request) expected_params = [("$alt", "json;enum-encoding=int")] + # Ensure that the uuid4 field is set according to AIP 4235 + for i, (key, value) in enumerate(req.call_args.kwargs["params"]): + if key == "requestId": + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + value, + ) + break + + # Include requestId within expected_params with value mock.ANY + expected_params = [p for p in expected_params if p[0] != "requestId"] + expected_params.append(("requestId", mock.ANY)) actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_process_open_lineage_run_event_rest_unset_required_fields(): @@ -8103,8 +8422,20 @@ def test_create_process_rest_required_fields(request_type=lineage.CreateProcessR response = client.create_process(request) expected_params = [("$alt", "json;enum-encoding=int")] + # Ensure that the uuid4 field is set according to AIP 4235 + for i, (key, value) in enumerate(req.call_args.kwargs["params"]): + if key == "requestId": + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + value, + ) + break + + # Include requestId within expected_params with value mock.ANY + expected_params = [p for p in expected_params if p[0] != "requestId"] + expected_params.append(("requestId", mock.ANY)) actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_create_process_rest_unset_required_fields(): @@ -8245,6 +8576,7 @@ def test_update_process_rest_required_fields(request_type=lineage.UpdateProcessR assert not set(unset_fields) - set( ( "allow_missing", + "request_id", "update_mask", ) ) @@ -8291,8 +8623,20 @@ def test_update_process_rest_required_fields(request_type=lineage.UpdateProcessR response = client.update_process(request) expected_params = [("$alt", "json;enum-encoding=int")] + # Ensure that the uuid4 field is set according to AIP 4235 + for i, (key, value) in enumerate(req.call_args.kwargs["params"]): + if key == "requestId": + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + value, + ) + break + + # Include requestId within expected_params with value mock.ANY + expected_params = [p for p in expected_params if p[0] != "requestId"] + expected_params.append(("requestId", mock.ANY)) actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_update_process_rest_unset_required_fields(): @@ -8305,6 +8649,7 @@ def test_update_process_rest_unset_required_fields(): set( ( "allowMissing", + "requestId", "updateMask", ) ) @@ -8480,7 +8825,7 @@ def test_get_process_rest_required_fields(request_type=lineage.GetProcessRequest expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_get_process_rest_unset_required_fields(): @@ -8664,7 +9009,7 @@ def test_list_processes_rest_required_fields(request_type=lineage.ListProcessesR expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_list_processes_rest_unset_required_fields(): @@ -8911,7 +9256,7 @@ def test_delete_process_rest_required_fields(request_type=lineage.DeleteProcessR expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_delete_process_rest_unset_required_fields(): @@ -9088,8 +9433,20 @@ def test_create_run_rest_required_fields(request_type=lineage.CreateRunRequest): response = client.create_run(request) expected_params = [("$alt", "json;enum-encoding=int")] + # Ensure that the uuid4 field is set according to AIP 4235 + for i, (key, value) in enumerate(req.call_args.kwargs["params"]): + if key == "requestId": + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + value, + ) + break + + # Include requestId within expected_params with value mock.ANY + expected_params = [p for p in expected_params if p[0] != "requestId"] + expected_params.append(("requestId", mock.ANY)) actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_create_run_rest_unset_required_fields(): @@ -9280,7 +9637,7 @@ def test_update_run_rest_required_fields(request_type=lineage.UpdateRunRequest): expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_update_run_rest_unset_required_fields(): @@ -9470,7 +9827,7 @@ def test_get_run_rest_required_fields(request_type=lineage.GetRunRequest): expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_get_run_rest_unset_required_fields(): @@ -9655,7 +10012,7 @@ def test_list_runs_rest_required_fields(request_type=lineage.ListRunsRequest): expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_list_runs_rest_unset_required_fields(): @@ -9907,7 +10264,7 @@ def test_delete_run_rest_required_fields(request_type=lineage.DeleteRunRequest): expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_delete_run_rest_unset_required_fields(): @@ -10091,8 +10448,20 @@ def test_create_lineage_event_rest_required_fields( response = client.create_lineage_event(request) expected_params = [("$alt", "json;enum-encoding=int")] + # Ensure that the uuid4 field is set according to AIP 4235 + for i, (key, value) in enumerate(req.call_args.kwargs["params"]): + if key == "requestId": + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + value, + ) + break + + # Include requestId within expected_params with value mock.ANY + expected_params = [p for p in expected_params if p[0] != "requestId"] + expected_params.append(("requestId", mock.ANY)) actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_create_lineage_event_rest_unset_required_fields(): @@ -10284,7 +10653,7 @@ def test_get_lineage_event_rest_required_fields( expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_get_lineage_event_rest_unset_required_fields(): @@ -10475,7 +10844,7 @@ def test_list_lineage_events_rest_required_fields( expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_list_lineage_events_rest_unset_required_fields(): @@ -10729,7 +11098,7 @@ def test_delete_lineage_event_rest_required_fields( expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_delete_lineage_event_rest_unset_required_fields(): @@ -10906,7 +11275,7 @@ def test_search_links_rest_required_fields(request_type=lineage.SearchLinksReque expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_search_links_rest_unset_required_fields(): @@ -11097,7 +11466,7 @@ def test_batch_search_link_processes_rest_required_fields( expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] - assert expected_params == actual_params + assert sorted(expected_params) == sorted(actual_params) def test_batch_search_link_processes_rest_unset_required_fields(): @@ -11180,24 +11549,167 @@ def test_batch_search_link_processes_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.LineageGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): +def test_search_lineage_streaming_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = LineageClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.LineageGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = LineageClient( - client_options={"credentials_file": "credentials.json"}, + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.search_lineage_streaming + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.search_lineage_streaming + ] = mock_rpc + + request = {} + client.search_lineage_streaming(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.search_lineage_streaming(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_search_lineage_streaming_rest_required_fields( + request_type=lineage.SearchLineageStreamingRequest, +): + transport_class = transports.LineageRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["locations"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).search_lineage_streaming._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["locations"] = "locations_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).search_lineage_streaming._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "locations" in jsonified_request + assert jsonified_request["locations"] == "locations_value" + + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = lineage.SearchLineageStreamingResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = lineage.SearchLineageStreamingResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + json_return_value = "[{}]".format(json_return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + with mock.patch.object(response_value, "iter_content") as iter_content: + iter_content.return_value = iter(json_return_value) + response = client.search_lineage_streaming(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert sorted(expected_params) == sorted(actual_params) + + +def test_search_lineage_streaming_rest_unset_required_fields(): + transport = transports.LineageRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.search_lineage_streaming._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "locations", + "rootCriteria", + "direction", + ) + ) + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.LineageGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.LineageGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = LineageClient( + client_options={"credentials_file": "credentials.json"}, transport=transport, ) @@ -11304,6 +11816,13 @@ def test_process_open_lineage_run_event_empty_call_grpc(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.ProcessOpenLineageRunEventRequest() assert args[0] == request_msg @@ -11325,6 +11844,13 @@ def test_create_process_empty_call_grpc(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateProcessRequest() assert args[0] == request_msg @@ -11346,6 +11872,13 @@ def test_update_process_empty_call_grpc(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.UpdateProcessRequest() assert args[0] == request_msg @@ -11430,6 +11963,13 @@ def test_create_run_empty_call_grpc(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateRunRequest() assert args[0] == request_msg @@ -11537,6 +12077,13 @@ def test_create_lineage_event_empty_call_grpc(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateLineageEventRequest() assert args[0] == request_msg @@ -11655,6 +12202,29 @@ def test_batch_search_link_processes_empty_call_grpc(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_lineage_streaming_empty_call_grpc(): + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + call.return_value = iter([lineage.SearchLineageStreamingResponse()]) + client.search_lineage_streaming(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lineage.SearchLineageStreamingRequest() + + assert args[0] == request_msg + + def test_transport_kind_grpc_asyncio(): transport = LineageAsyncClient.get_transport_class("grpc_asyncio")( credentials=async_anonymous_credentials() @@ -11695,6 +12265,13 @@ async def test_process_open_lineage_run_event_empty_call_grpc_asyncio(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.ProcessOpenLineageRunEventRequest() assert args[0] == request_msg @@ -11723,6 +12300,13 @@ async def test_create_process_empty_call_grpc_asyncio(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateProcessRequest() assert args[0] == request_msg @@ -11751,6 +12335,13 @@ async def test_update_process_empty_call_grpc_asyncio(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.UpdateProcessRequest() assert args[0] == request_msg @@ -11860,6 +12451,13 @@ async def test_create_run_empty_call_grpc_asyncio(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateRunRequest() assert args[0] == request_msg @@ -11999,6 +12597,13 @@ async def test_create_lineage_event_empty_call_grpc_asyncio(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateLineageEventRequest() assert args[0] == request_msg @@ -12143,6 +12748,34 @@ async def test_batch_search_link_processes_empty_call_grpc_asyncio(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_search_lineage_streaming_empty_call_grpc_asyncio(): + client = LineageAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = mock.Mock(aio.UnaryStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[lineage.SearchLineageStreamingResponse()] + ) + await client.search_lineage_streaming(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lineage.SearchLineageStreamingRequest() + + assert args[0] == request_msg + + def test_transport_kind_rest(): transport = LineageClient.get_transport_class("rest")( credentials=ga_credentials.AnonymousCredentials() @@ -13948,8 +14581,12 @@ def test_create_lineage_event_rest_call_success(request_type): "name": "name_value", "links": [ { - "source": {"fully_qualified_name": "fully_qualified_name_value"}, + "source": { + "fully_qualified_name": "fully_qualified_name_value", + "field": ["field_value1", "field_value2"], + }, "target": {}, + "dependency_info": {"dependency_type": 1}, } ], "start_time": {"seconds": 751, "nanos": 543}, @@ -14744,6 +15381,144 @@ def test_batch_search_link_processes_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() +def test_search_lineage_streaming_rest_bad_request( + request_type=lineage.SearchLineageStreamingRequest, +): + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with ( + mock.patch.object(Session, "request") as req, + pytest.raises(core_exceptions.BadRequest), + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.search_lineage_streaming(request) + + +@pytest.mark.parametrize( + "request_type", + [ + lineage.SearchLineageStreamingRequest, + dict, + ], +) +def test_search_lineage_streaming_rest_call_success(request_type): + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = lineage.SearchLineageStreamingResponse( + unreachable=["unreachable_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = lineage.SearchLineageStreamingResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + json_return_value = "[{}]".format(json_return_value) + response_value.iter_content = mock.Mock(return_value=iter(json_return_value)) + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.search_lineage_streaming(request) + + assert isinstance(response, Iterable) + response = next(response) + + # Establish that the response is the type that we expect. + assert isinstance(response, lineage.SearchLineageStreamingResponse) + assert response.unreachable == ["unreachable_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_lineage_streaming_rest_interceptors(null_interceptor): + transport = transports.LineageRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.LineageRestInterceptor(), + ) + client = LineageClient(transport=transport) + + with ( + mock.patch.object(type(client.transport._session), "request") as req, + mock.patch.object(path_template, "transcode") as transcode, + mock.patch.object( + transports.LineageRestInterceptor, "post_search_lineage_streaming" + ) as post, + mock.patch.object( + transports.LineageRestInterceptor, + "post_search_lineage_streaming_with_metadata", + ) as post_with_metadata, + mock.patch.object( + transports.LineageRestInterceptor, "pre_search_lineage_streaming" + ) as pre, + ): + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = lineage.SearchLineageStreamingRequest.pb( + lineage.SearchLineageStreamingRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = lineage.SearchLineageStreamingResponse.to_json( + lineage.SearchLineageStreamingResponse() + ) + req.return_value.iter_content = mock.Mock(return_value=iter(return_value)) + + request = lineage.SearchLineageStreamingRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = lineage.SearchLineageStreamingResponse() + post_with_metadata.return_value = ( + lineage.SearchLineageStreamingResponse(), + metadata, + ) + + client.search_lineage_streaming( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + def test_cancel_operation_rest_bad_request( request_type=operations_pb2.CancelOperationRequest, ): @@ -15020,6 +15795,13 @@ def test_process_open_lineage_run_event_empty_call_rest(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.ProcessOpenLineageRunEventRequest() assert args[0] == request_msg @@ -15040,6 +15822,13 @@ def test_create_process_empty_call_rest(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateProcessRequest() assert args[0] == request_msg @@ -15060,6 +15849,13 @@ def test_update_process_empty_call_rest(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.UpdateProcessRequest() assert args[0] == request_msg @@ -15140,6 +15936,13 @@ def test_create_run_empty_call_rest(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateRunRequest() assert args[0] == request_msg @@ -15242,6 +16045,13 @@ def test_create_lineage_event_empty_call_rest(): # Establish that the underlying stub method was called. call.assert_called() _, args, _ = call.mock_calls[0] + # Ensure that the uuid4 field is set according to AIP 4235 + assert re.match( + r"[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}", + args[0].request_id, + ) + # clear UUID field so that the check below succeeds + args[0].request_id = None request_msg = lineage.CreateLineageEventRequest() assert args[0] == request_msg @@ -15355,6 +16165,28 @@ def test_batch_search_link_processes_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_lineage_streaming_empty_call_rest(): + client = LineageClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search_lineage_streaming), "__call__" + ) as call: + client.search_lineage_streaming(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = lineage.SearchLineageStreamingRequest() + + assert args[0] == request_msg + + def test_lineage_rest_lro_client(): client = LineageClient( credentials=ga_credentials.AnonymousCredentials(), @@ -15422,6 +16254,7 @@ def test_lineage_base_transport(): "delete_lineage_event", "search_links", "batch_search_link_processes", + "search_lineage_streaming", "get_operation", "cancel_operation", "delete_operation", @@ -15744,6 +16577,9 @@ def test_lineage_client_transport_session_collision(transport_name): session1 = client1.transport.batch_search_link_processes._session session2 = client2.transport.batch_search_link_processes._session assert session1 != session2 + session1 = client1.transport.search_lineage_streaming._session + session2 = client2.transport.search_lineage_streaming._session + assert session1 != session2 def test_lineage_grpc_transport_channel():