From be671a832839d6efeae76d168b7913a9408572b4 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Sun, 16 May 2021 10:00:05 +0000 Subject: [PATCH] chore: upgrade gapic-generator-python to 0.46.3 (#146) PiperOrigin-RevId: 373649163 Source-Link: https://github.com/googleapis/googleapis/commit/7e1b14e6c7a9ab96d2db7e4a131981f162446d34 Source-Link: https://github.com/googleapis/googleapis-gen/commit/0a3c7d272d697796db75857bac73905c68e498c3 feat: Use non-regionalized default host name for documentai.googleapis.com feat: add confidence field to the PageAnchor.PageRef in document.proto. fix: add async client to %name_%version/init.py chore: add autogenerated snippets chore: remove auth, policy, and options from the reserved names list feat: support self-signed JWT flow for service accounts chore: enable GAPIC metadata generation chore: sort subpackages in %namespace/%name/init.py --- google/cloud/documentai/__init__.py | 28 +- google/cloud/documentai_v1/__init__.py | 7 +- .../cloud/documentai_v1/gapic_metadata.json | 53 +++ .../cloud/documentai_v1/services/__init__.py | 1 - .../document_processor_service/__init__.py | 2 - .../async_client.py | 39 +- .../document_processor_service/client.py | 76 ++-- .../transports/__init__.py | 2 - .../transports/base.py | 123 ++++-- .../transports/grpc.py | 36 +- .../transports/grpc_asyncio.py | 37 +- google/cloud/documentai_v1/types/__init__.py | 2 - google/cloud/documentai_v1/types/document.py | 277 ++++-------- .../cloud/documentai_v1/types/document_io.py | 21 +- .../types/document_processor_service.py | 71 +-- google/cloud/documentai_v1/types/geometry.py | 14 +- google/cloud/documentai_v1beta2/__init__.py | 9 +- .../documentai_v1beta2/gapic_metadata.json | 43 ++ .../documentai_v1beta2/services/__init__.py | 1 - .../__init__.py | 2 - .../async_client.py | 35 +- .../document_understanding_service/client.py | 64 ++- .../transports/__init__.py | 2 - .../transports/base.py | 114 +++-- .../transports/grpc.py | 28 +- .../transports/grpc_asyncio.py | 29 +- .../documentai_v1beta2/types/__init__.py | 2 - .../documentai_v1beta2/types/document.py | 176 ++------ .../types/document_understanding.py | 85 +--- .../documentai_v1beta2/types/geometry.py | 14 +- google/cloud/documentai_v1beta3/__init__.py | 7 +- .../documentai_v1beta3/gapic_metadata.json | 53 +++ .../documentai_v1beta3/services/__init__.py | 1 - .../document_processor_service/__init__.py | 2 - .../async_client.py | 39 +- .../document_processor_service/client.py | 76 ++-- .../transports/__init__.py | 2 - .../transports/base.py | 123 ++++-- .../transports/grpc.py | 36 +- .../transports/grpc_asyncio.py | 37 +- .../documentai_v1beta3/types/__init__.py | 2 - .../documentai_v1beta3/types/document.py | 277 ++++-------- .../documentai_v1beta3/types/document_io.py | 21 +- .../types/document_processor_service.py | 100 ++--- .../documentai_v1beta3/types/geometry.py | 14 +- tests/__init__.py | 15 + tests/unit/__init__.py | 15 + tests/unit/gapic/__init__.py | 15 + tests/unit/gapic/documentai_v1/__init__.py | 1 - .../test_document_processor_service.py | 415 ++++++++++++----- .../unit/gapic/documentai_v1beta2/__init__.py | 1 - .../test_document_understanding_service.py | 357 +++++++++++---- .../unit/gapic/documentai_v1beta3/__init__.py | 1 - .../test_document_processor_service.py | 417 ++++++++++++------ 54 files changed, 1916 insertions(+), 1504 deletions(-) create mode 100644 google/cloud/documentai_v1/gapic_metadata.json create mode 100644 google/cloud/documentai_v1beta2/gapic_metadata.json create mode 100644 google/cloud/documentai_v1beta3/gapic_metadata.json create mode 100644 tests/__init__.py create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/gapic/__init__.py diff --git a/google/cloud/documentai/__init__.py b/google/cloud/documentai/__init__.py index b488ee65..204c15ca 100644 --- a/google/cloud/documentai/__init__.py +++ b/google/cloud/documentai/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +14,13 @@ # limitations under the License. # -from google.cloud.documentai_v1.services.document_processor_service.async_client import ( - DocumentProcessorServiceAsyncClient, -) from google.cloud.documentai_v1.services.document_processor_service.client import ( DocumentProcessorServiceClient, ) +from google.cloud.documentai_v1.services.document_processor_service.async_client import ( + DocumentProcessorServiceAsyncClient, +) + from google.cloud.documentai_v1.types.document import Document from google.cloud.documentai_v1.types.document_io import BatchDocumentsInputConfig from google.cloud.documentai_v1.types.document_io import DocumentOutputConfig @@ -59,26 +59,26 @@ from google.cloud.documentai_v1.types.geometry import Vertex __all__ = ( - "BatchDocumentsInputConfig", - "BatchProcessMetadata", - "BatchProcessRequest", - "BatchProcessResponse", - "BoundingPoly", - "CommonOperationMetadata", + "DocumentProcessorServiceClient", + "DocumentProcessorServiceAsyncClient", "Document", + "BatchDocumentsInputConfig", "DocumentOutputConfig", - "DocumentProcessorServiceAsyncClient", - "DocumentProcessorServiceClient", "GcsDocument", "GcsDocuments", "GcsPrefix", + "RawDocument", + "BatchProcessMetadata", + "BatchProcessRequest", + "BatchProcessResponse", + "CommonOperationMetadata", "HumanReviewStatus", - "NormalizedVertex", "ProcessRequest", "ProcessResponse", - "RawDocument", "ReviewDocumentOperationMetadata", "ReviewDocumentRequest", "ReviewDocumentResponse", + "BoundingPoly", + "NormalizedVertex", "Vertex", ) diff --git a/google/cloud/documentai_v1/__init__.py b/google/cloud/documentai_v1/__init__.py index 84d917be..c6cd3be9 100644 --- a/google/cloud/documentai_v1/__init__.py +++ b/google/cloud/documentai_v1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # from .services.document_processor_service import DocumentProcessorServiceClient +from .services.document_processor_service import DocumentProcessorServiceAsyncClient + from .types.document import Document from .types.document_io import BatchDocumentsInputConfig from .types.document_io import DocumentOutputConfig @@ -37,8 +38,8 @@ from .types.geometry import NormalizedVertex from .types.geometry import Vertex - __all__ = ( + "DocumentProcessorServiceAsyncClient", "BatchDocumentsInputConfig", "BatchProcessMetadata", "BatchProcessRequest", @@ -47,6 +48,7 @@ "CommonOperationMetadata", "Document", "DocumentOutputConfig", + "DocumentProcessorServiceClient", "GcsDocument", "GcsDocuments", "GcsPrefix", @@ -59,5 +61,4 @@ "ReviewDocumentRequest", "ReviewDocumentResponse", "Vertex", - "DocumentProcessorServiceClient", ) diff --git a/google/cloud/documentai_v1/gapic_metadata.json b/google/cloud/documentai_v1/gapic_metadata.json new file mode 100644 index 00000000..0013c0aa --- /dev/null +++ b/google/cloud/documentai_v1/gapic_metadata.json @@ -0,0 +1,53 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.documentai_v1", + "protoPackage": "google.cloud.documentai.v1", + "schema": "1.0", + "services": { + "DocumentProcessorService": { + "clients": { + "grpc": { + "libraryClient": "DocumentProcessorServiceClient", + "rpcs": { + "BatchProcessDocuments": { + "methods": [ + "batch_process_documents" + ] + }, + "ProcessDocument": { + "methods": [ + "process_document" + ] + }, + "ReviewDocument": { + "methods": [ + "review_document" + ] + } + } + }, + "grpc-async": { + "libraryClient": "DocumentProcessorServiceAsyncClient", + "rpcs": { + "BatchProcessDocuments": { + "methods": [ + "batch_process_documents" + ] + }, + "ProcessDocument": { + "methods": [ + "process_document" + ] + }, + "ReviewDocument": { + "methods": [ + "review_document" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/documentai_v1/services/__init__.py b/google/cloud/documentai_v1/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/documentai_v1/services/__init__.py +++ b/google/cloud/documentai_v1/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/documentai_v1/services/document_processor_service/__init__.py b/google/cloud/documentai_v1/services/document_processor_service/__init__.py index 9f87d9f4..900ba543 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/__init__.py +++ b/google/cloud/documentai_v1/services/document_processor_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import DocumentProcessorServiceClient from .async_client import DocumentProcessorServiceAsyncClient diff --git a/google/cloud/documentai_v1/services/document_processor_service/async_client.py b/google/cloud/documentai_v1/services/document_processor_service/async_client.py index 42cf58a4..e5cadf4d 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/async_client.py +++ b/google/cloud/documentai_v1/services/document_processor_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,17 +20,16 @@ import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.documentai_v1.types import document from google.cloud.documentai_v1.types import document_processor_service - from .transports.base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import DocumentProcessorServiceGrpcAsyncIOTransport from .client import DocumentProcessorServiceClient @@ -61,33 +58,28 @@ class DocumentProcessorServiceAsyncClient: parse_processor_path = staticmethod( DocumentProcessorServiceClient.parse_processor_path ) - common_billing_account_path = staticmethod( DocumentProcessorServiceClient.common_billing_account_path ) parse_common_billing_account_path = staticmethod( DocumentProcessorServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(DocumentProcessorServiceClient.common_folder_path) parse_common_folder_path = staticmethod( DocumentProcessorServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( DocumentProcessorServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( DocumentProcessorServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( DocumentProcessorServiceClient.common_project_path ) parse_common_project_path = staticmethod( DocumentProcessorServiceClient.parse_common_project_path ) - common_location_path = staticmethod( DocumentProcessorServiceClient.common_location_path ) @@ -97,7 +89,8 @@ class DocumentProcessorServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -112,7 +105,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -129,7 +122,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> DocumentProcessorServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: DocumentProcessorServiceTransport: The transport used by the client instance. @@ -144,12 +137,12 @@ def transport(self) -> DocumentProcessorServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, DocumentProcessorServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the document processor service client. + """Instantiates the document processor service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -181,7 +174,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = DocumentProcessorServiceClient( credentials=credentials, transport=transport, @@ -211,7 +203,6 @@ async def process_document( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -238,7 +229,6 @@ async def process_document( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -251,7 +241,8 @@ async def process_document( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -294,7 +285,6 @@ async def batch_process_documents( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -324,7 +314,6 @@ async def batch_process_documents( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -337,7 +326,8 @@ async def batch_process_documents( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -389,7 +379,6 @@ async def review_document( This corresponds to the ``human_review_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -419,7 +408,6 @@ async def review_document( # If we have keyword arguments corresponding to fields on the # request, apply these. - if human_review_config is not None: request.human_review_config = human_review_config @@ -432,7 +420,8 @@ async def review_document( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), diff --git a/google/cloud/documentai_v1/services/document_processor_service/client.py b/google/cloud/documentai_v1/services/document_processor_service/client.py index 46160b76..f598710c 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/client.py +++ b/google/cloud/documentai_v1/services/document_processor_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore @@ -36,7 +34,6 @@ from google.api_core import operation_async # type: ignore from google.cloud.documentai_v1.types import document from google.cloud.documentai_v1.types import document_processor_service - from .transports.base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import DocumentProcessorServiceGrpcTransport from .transports.grpc_asyncio import DocumentProcessorServiceGrpcAsyncIOTransport @@ -59,7 +56,7 @@ class DocumentProcessorServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[DocumentProcessorServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -87,7 +84,8 @@ class DocumentProcessorServiceClient(metaclass=DocumentProcessorServiceClientMet @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -114,14 +112,15 @@ def _get_default_mtls_endpoint(api_endpoint): return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - DEFAULT_ENDPOINT = "us-documentai.googleapis.com" + DEFAULT_ENDPOINT = "documentai.googleapis.com" DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore DEFAULT_ENDPOINT ) @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -138,7 +137,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -157,23 +156,24 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> DocumentProcessorServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - DocumentProcessorServiceTransport: The transport used by the client instance. + DocumentProcessorServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def human_review_config_path(project: str, location: str, processor: str,) -> str: - """Return a fully-qualified human_review_config string.""" + """Returns a fully-qualified human_review_config string.""" return "projects/{project}/locations/{location}/processors/{processor}/humanReviewConfig".format( project=project, location=location, processor=processor, ) @staticmethod def parse_human_review_config_path(path: str) -> Dict[str, str]: - """Parse a human_review_config path into its component segments.""" + """Parses a human_review_config path into its component segments.""" m = re.match( r"^projects/(?P.+?)/locations/(?P.+?)/processors/(?P.+?)/humanReviewConfig$", path, @@ -182,14 +182,14 @@ def parse_human_review_config_path(path: str) -> Dict[str, str]: @staticmethod def processor_path(project: str, location: str, processor: str,) -> str: - """Return a fully-qualified processor string.""" + """Returns a fully-qualified processor string.""" return "projects/{project}/locations/{location}/processors/{processor}".format( project=project, location=location, processor=processor, ) @staticmethod def parse_processor_path(path: str) -> Dict[str, str]: - """Parse a processor path into its component segments.""" + """Parses a processor path into its component segments.""" m = re.match( r"^projects/(?P.+?)/locations/(?P.+?)/processors/(?P.+?)$", path, @@ -198,7 +198,7 @@ def parse_processor_path(path: str) -> Dict[str, str]: @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -211,7 +211,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -222,7 +222,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -233,7 +233,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -244,7 +244,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -258,12 +258,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, DocumentProcessorServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the document processor service client. + """Instantiates the document processor service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -318,9 +318,10 @@ def __init__( client_cert_source_func = client_options.client_cert_source else: is_mtls = mtls.has_default_client_cert_source() - client_cert_source_func = ( - mtls.default_client_cert_source() if is_mtls else None - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -332,12 +333,14 @@ def __init__( elif use_mtls_env == "always": api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -352,8 +355,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -390,7 +393,6 @@ def process_document( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -419,10 +421,8 @@ def process_document( # there are no flattened fields. if not isinstance(request, document_processor_service.ProcessRequest): request = document_processor_service.ProcessRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -465,7 +465,6 @@ def batch_process_documents( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -497,10 +496,8 @@ def batch_process_documents( # there are no flattened fields. if not isinstance(request, document_processor_service.BatchProcessRequest): request = document_processor_service.BatchProcessRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -552,7 +549,6 @@ def review_document( This corresponds to the ``human_review_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -584,10 +580,8 @@ def review_document( # there are no flattened fields. if not isinstance(request, document_processor_service.ReviewDocumentRequest): request = document_processor_service.ReviewDocumentRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if human_review_config is not None: request.human_review_config = human_review_config diff --git a/google/cloud/documentai_v1/services/document_processor_service/transports/__init__.py b/google/cloud/documentai_v1/services/document_processor_service/transports/__init__.py index e3e820b3..b9f737af 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/transports/__init__.py +++ b/google/cloud/documentai_v1/services/document_processor_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/documentai_v1/services/document_processor_service/transports/base.py b/google/cloud/documentai_v1/services/document_processor_service/transports/base.py index cb344159..dabbb48a 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/transports/base.py +++ b/google/cloud/documentai_v1/services/document_processor_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.documentai_v1.types import document_processor_service -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -39,27 +38,41 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() +try: + # google.auth.__version__ was added in 1.26.0 + _GOOGLE_AUTH_VERSION = google.auth.__version__ +except AttributeError: + try: # try pkg_resources if it is available + _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version + except pkg_resources.DistributionNotFound: # pragma: NO COVER + _GOOGLE_AUTH_VERSION = None + +_API_CORE_VERSION = google.api_core.__version__ + class DocumentProcessorServiceTransport(abc.ABC): """Abstract transport class for DocumentProcessorService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "documentai.googleapis.com" + def __init__( self, *, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, - credentials_file: typing.Optional[str] = None, - scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES, - quota_project_id: typing.Optional[str] = None, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, **kwargs, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -68,7 +81,7 @@ def __init__( credentials_file (Optional[str]): A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is mutually exclusive with credentials. - scope (Optional[Sequence[str]]): A list of scopes. + scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -82,29 +95,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are increased. + + # TODO: Remove this function once google-auth >= 1.25.0 is required + @classmethod + def _get_scopes_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Optional[Sequence[str]]]: + """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" + + scopes_kwargs = {} + + if _GOOGLE_AUTH_VERSION and ( + packaging.version.parse(_GOOGLE_AUTH_VERSION) + >= packaging.version.parse("1.25.0") + ): + scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} + else: + scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} + + return scopes_kwargs + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,7 +175,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -129,7 +190,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -143,7 +205,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -160,11 +223,11 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def process_document( self, - ) -> typing.Callable[ + ) -> Callable[ [document_processor_service.ProcessRequest], - typing.Union[ + Union[ document_processor_service.ProcessResponse, - typing.Awaitable[document_processor_service.ProcessResponse], + Awaitable[document_processor_service.ProcessResponse], ], ]: raise NotImplementedError() @@ -172,18 +235,18 @@ def process_document( @property def batch_process_documents( self, - ) -> typing.Callable[ + ) -> Callable[ [document_processor_service.BatchProcessRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() @property def review_document( self, - ) -> typing.Callable[ + ) -> Callable[ [document_processor_service.ReviewDocumentRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() diff --git a/google/cloud/documentai_v1/services/document_processor_service/transports/grpc.py b/google/cloud/documentai_v1/services/document_processor_service/transports/grpc.py index 8c55d69c..7063cf35 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/transports/grpc.py +++ b/google/cloud/documentai_v1/services/document_processor_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple +from typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.documentai_v1.types import document_processor_service -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO @@ -55,8 +52,8 @@ class DocumentProcessorServiceGrpcTransport(DocumentProcessorServiceTransport): def __init__( self, *, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -70,7 +67,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -180,8 +178,8 @@ def __init__( @classmethod def create_channel( cls, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -212,13 +210,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -275,7 +275,7 @@ def process_document( def batch_process_documents( self, ) -> Callable[ - [document_processor_service.BatchProcessRequest], operations.Operation + [document_processor_service.BatchProcessRequest], operations_pb2.Operation ]: r"""Return a callable for the batch process documents method over gRPC. @@ -296,7 +296,7 @@ def batch_process_documents( self._stubs["batch_process_documents"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1.DocumentProcessorService/BatchProcessDocuments", request_serializer=document_processor_service.BatchProcessRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["batch_process_documents"] @@ -304,7 +304,7 @@ def batch_process_documents( def review_document( self, ) -> Callable[ - [document_processor_service.ReviewDocumentRequest], operations.Operation + [document_processor_service.ReviewDocumentRequest], operations_pb2.Operation ]: r"""Return a callable for the review document method over gRPC. @@ -325,7 +325,7 @@ def review_document( self._stubs["review_document"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1.DocumentProcessorService/ReviewDocument", request_serializer=document_processor_service.ReviewDocumentRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["review_document"] diff --git a/google/cloud/documentai_v1/services/document_processor_service/transports/grpc_asyncio.py b/google/cloud/documentai_v1/services/document_processor_service/transports/grpc_asyncio.py index 3b172f81..740ceef9 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/transports/grpc_asyncio.py +++ b/google/cloud/documentai_v1/services/document_processor_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore from google.cloud.documentai_v1.types import document_processor_service -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO from .grpc import DocumentProcessorServiceGrpcTransport @@ -58,8 +55,8 @@ class DocumentProcessorServiceGrpcAsyncIOTransport(DocumentProcessorServiceTrans @classmethod def create_channel( cls, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -86,21 +83,23 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) def __init__( self, *, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -114,7 +113,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -173,7 +173,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -282,7 +281,7 @@ def batch_process_documents( self, ) -> Callable[ [document_processor_service.BatchProcessRequest], - Awaitable[operations.Operation], + Awaitable[operations_pb2.Operation], ]: r"""Return a callable for the batch process documents method over gRPC. @@ -303,7 +302,7 @@ def batch_process_documents( self._stubs["batch_process_documents"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1.DocumentProcessorService/BatchProcessDocuments", request_serializer=document_processor_service.BatchProcessRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["batch_process_documents"] @@ -312,7 +311,7 @@ def review_document( self, ) -> Callable[ [document_processor_service.ReviewDocumentRequest], - Awaitable[operations.Operation], + Awaitable[operations_pb2.Operation], ]: r"""Return a callable for the review document method over gRPC. @@ -333,7 +332,7 @@ def review_document( self._stubs["review_document"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1.DocumentProcessorService/ReviewDocument", request_serializer=document_processor_service.ReviewDocumentRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["review_document"] diff --git a/google/cloud/documentai_v1/types/__init__.py b/google/cloud/documentai_v1/types/__init__.py index 0d60bd37..2be40a09 100644 --- a/google/cloud/documentai_v1/types/__init__.py +++ b/google/cloud/documentai_v1/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .document import Document from .document_io import ( BatchDocumentsInputConfig, diff --git a/google/cloud/documentai_v1/types/document.py b/google/cloud/documentai_v1/types/document.py index 781e3c55..b2ba01a0 100644 --- a/google/cloud/documentai_v1/types/document.py +++ b/google/cloud/documentai_v1/types/document.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,18 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.cloud.documentai_v1.types import geometry -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore -from google.type import color_pb2 as gt_color # type: ignore -from google.type import date_pb2 as date # type: ignore -from google.type import datetime_pb2 as datetime # type: ignore -from google.type import money_pb2 as money # type: ignore -from google.type import postal_address_pb2 as postal_address # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import date_pb2 # type: ignore +from google.type import datetime_pb2 # type: ignore +from google.type import money_pb2 # type: ignore +from google.type import postal_address_pb2 # type: ignore __protobuf__ = proto.module( @@ -107,11 +104,9 @@ class ShardInfo(proto.Message): the overall document global text. """ - shard_index = proto.Field(proto.INT64, number=1) - - shard_count = proto.Field(proto.INT64, number=2) - - text_offset = proto.Field(proto.INT64, number=3) + shard_index = proto.Field(proto.INT64, number=1,) + shard_count = proto.Field(proto.INT64, number=2,) + text_offset = proto.Field(proto.INT64, number=3,) class Style(proto.Message): r"""Annotation for common text style attributes. This adheres to @@ -140,7 +135,6 @@ class Style(proto.Message): class FontSize(proto.Message): r"""Font size with unit. - Attributes: size (float): Font size for the text. @@ -149,31 +143,25 @@ class FontSize(proto.Message): (in, px, pt, etc.). """ - size = proto.Field(proto.FLOAT, number=1) - - unit = proto.Field(proto.STRING, number=2) + size = proto.Field(proto.FLOAT, number=1,) + unit = proto.Field(proto.STRING, number=2,) text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - color = proto.Field(proto.MESSAGE, number=2, message=gt_color.Color,) - - background_color = proto.Field(proto.MESSAGE, number=3, message=gt_color.Color,) - - font_weight = proto.Field(proto.STRING, number=4) - - text_style = proto.Field(proto.STRING, number=5) - - text_decoration = proto.Field(proto.STRING, number=6) - + color = proto.Field(proto.MESSAGE, number=2, message=color_pb2.Color,) + background_color = proto.Field( + proto.MESSAGE, number=3, message=color_pb2.Color, + ) + font_weight = proto.Field(proto.STRING, number=4,) + text_style = proto.Field(proto.STRING, number=5,) + text_decoration = proto.Field(proto.STRING, number=6,) font_size = proto.Field( proto.MESSAGE, number=7, message="Document.Style.FontSize", ) class Page(proto.Message): r"""A page in a [Document][google.cloud.documentai.v1.Document]. - Attributes: page_number (int): 1-based index for current @@ -228,7 +216,6 @@ class Page(proto.Message): class Dimension(proto.Message): r"""Dimension for the page. - Attributes: width (float): Page width. @@ -238,15 +225,12 @@ class Dimension(proto.Message): Dimension unit. """ - width = proto.Field(proto.FLOAT, number=1) - - height = proto.Field(proto.FLOAT, number=2) - - unit = proto.Field(proto.STRING, number=3) + width = proto.Field(proto.FLOAT, number=1,) + height = proto.Field(proto.FLOAT, number=2,) + unit = proto.Field(proto.STRING, number=3,) class Image(proto.Message): r"""Rendered image contents for this page. - Attributes: content (bytes): Raw byte content of the image. @@ -258,13 +242,10 @@ class Image(proto.Message): Height of the image in pixels. """ - content = proto.Field(proto.BYTES, number=1) - - mime_type = proto.Field(proto.STRING, number=2) - - width = proto.Field(proto.INT32, number=3) - - height = proto.Field(proto.INT32, number=4) + content = proto.Field(proto.BYTES, number=1,) + mime_type = proto.Field(proto.STRING, number=2,) + width = proto.Field(proto.INT32, number=3,) + height = proto.Field(proto.INT32, number=4,) class Matrix(proto.Message): r"""Representation for transformation matrix, intended to be @@ -285,17 +266,13 @@ class Matrix(proto.Message): The matrix data. """ - rows = proto.Field(proto.INT32, number=1) - - cols = proto.Field(proto.INT32, number=2) - - type_ = proto.Field(proto.INT32, number=3) - - data = proto.Field(proto.BYTES, number=4) + rows = proto.Field(proto.INT32, number=1,) + cols = proto.Field(proto.INT32, number=2,) + type_ = proto.Field(proto.INT32, number=3,) + data = proto.Field(proto.BYTES, number=4,) class Layout(proto.Message): r"""Visual element describing a layout unit on a page. - Attributes: text_anchor (google.cloud.documentai_v1.types.Document.TextAnchor): Text anchor indexing into the @@ -325,13 +302,10 @@ class Orientation(proto.Enum): text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - confidence = proto.Field(proto.FLOAT, number=2) - + confidence = proto.Field(proto.FLOAT, number=2,) bounding_poly = proto.Field( proto.MESSAGE, number=3, message=geometry.BoundingPoly, ) - orientation = proto.Field( proto.ENUM, number=4, enum="Document.Page.Layout.Orientation", ) @@ -354,11 +328,9 @@ class Block(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=3, message="Document.Provenance", ) @@ -382,11 +354,9 @@ class Paragraph(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=3, message="Document.Provenance", ) @@ -410,18 +380,15 @@ class Line(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=3, message="Document.Provenance", ) class Token(proto.Message): r"""A detected token. - Attributes: layout (google.cloud.documentai_v1.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1.Document.Page.Layout] @@ -459,15 +426,12 @@ class Type(proto.Enum): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_break = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Token.DetectedBreak", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=4, message="Document.Provenance", ) @@ -492,16 +456,13 @@ class VisualElement(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - - type_ = proto.Field(proto.STRING, number=2) - + type_ = proto.Field(proto.STRING, number=2,) detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) class Table(proto.Message): r"""A table representation similar to HTML table structure. - Attributes: layout (google.cloud.documentai_v1.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1.Document.Page.Layout] @@ -517,7 +478,6 @@ class Table(proto.Message): class TableRow(proto.Message): r"""A row of table cells. - Attributes: cells (Sequence[google.cloud.documentai_v1.types.Document.Page.Table.TableCell]): Cells that make up this row. @@ -529,7 +489,6 @@ class TableRow(proto.Message): class TableCell(proto.Message): r"""A cell representation inside the table. - Attributes: layout (google.cloud.documentai_v1.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1.Document.Page.Layout] @@ -547,11 +506,8 @@ class TableCell(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - - row_span = proto.Field(proto.INT32, number=2) - - col_span = proto.Field(proto.INT32, number=3) - + row_span = proto.Field(proto.INT32, number=2,) + col_span = proto.Field(proto.INT32, number=3,) detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) @@ -559,22 +515,18 @@ class TableCell(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - header_rows = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.Table.TableRow", ) - body_rows = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.Table.TableRow", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) class FormField(proto.Message): r"""A form field detected on the page. - Attributes: field_name (google.cloud.documentai_v1.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1.Document.Page.Layout] @@ -605,24 +557,19 @@ class FormField(proto.Message): field_name = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - field_value = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Layout", ) - name_detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) - value_detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) - - value_type = proto.Field(proto.STRING, number=5) + value_type = proto.Field(proto.STRING, number=5,) class DetectedLanguage(proto.Message): r"""Detected language for a structural component. - Attributes: language_code (str): The BCP-47 language code, such as "en-US" or "sr-Latn". For @@ -632,52 +579,39 @@ class DetectedLanguage(proto.Message): Confidence of detected language. Range [0, 1]. """ - language_code = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - - page_number = proto.Field(proto.INT32, number=1) + language_code = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) + page_number = proto.Field(proto.INT32, number=1,) image = proto.Field(proto.MESSAGE, number=13, message="Document.Page.Image",) - transforms = proto.RepeatedField( proto.MESSAGE, number=14, message="Document.Page.Matrix", ) - dimension = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Dimension", ) - layout = proto.Field(proto.MESSAGE, number=3, message="Document.Page.Layout",) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) - blocks = proto.RepeatedField( proto.MESSAGE, number=5, message="Document.Page.Block", ) - paragraphs = proto.RepeatedField( proto.MESSAGE, number=6, message="Document.Page.Paragraph", ) - lines = proto.RepeatedField( proto.MESSAGE, number=7, message="Document.Page.Line", ) - tokens = proto.RepeatedField( proto.MESSAGE, number=8, message="Document.Page.Token", ) - visual_elements = proto.RepeatedField( proto.MESSAGE, number=9, message="Document.Page.VisualElement", ) - tables = proto.RepeatedField( proto.MESSAGE, number=10, message="Document.Page.Table", ) - form_fields = proto.RepeatedField( proto.MESSAGE, number=11, message="Document.Page.FormField", ) @@ -727,7 +661,6 @@ class Entity(proto.Message): class NormalizedValue(proto.Message): r"""Parsed and normalized entity value. - Attributes: money_value (google.type.money_pb2.Money): Money value. See also: @@ -761,62 +694,53 @@ class NormalizedValue(proto.Message): """ money_value = proto.Field( - proto.MESSAGE, number=2, oneof="structured_value", message=money.Money, + proto.MESSAGE, + number=2, + oneof="structured_value", + message=money_pb2.Money, ) - date_value = proto.Field( - proto.MESSAGE, number=3, oneof="structured_value", message=date.Date, + proto.MESSAGE, + number=3, + oneof="structured_value", + message=date_pb2.Date, ) - datetime_value = proto.Field( proto.MESSAGE, number=4, oneof="structured_value", - message=datetime.DateTime, + message=datetime_pb2.DateTime, ) - address_value = proto.Field( proto.MESSAGE, number=5, oneof="structured_value", - message=postal_address.PostalAddress, + message=postal_address_pb2.PostalAddress, ) - - boolean_value = proto.Field(proto.BOOL, number=6, oneof="structured_value") - - text = proto.Field(proto.STRING, number=1) + boolean_value = proto.Field(proto.BOOL, number=6, oneof="structured_value",) + text = proto.Field(proto.STRING, number=1,) text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - type_ = proto.Field(proto.STRING, number=2) - - mention_text = proto.Field(proto.STRING, number=3) - - mention_id = proto.Field(proto.STRING, number=4) - - confidence = proto.Field(proto.FLOAT, number=5) - + type_ = proto.Field(proto.STRING, number=2,) + mention_text = proto.Field(proto.STRING, number=3,) + mention_id = proto.Field(proto.STRING, number=4,) + confidence = proto.Field(proto.FLOAT, number=5,) page_anchor = proto.Field( proto.MESSAGE, number=6, message="Document.PageAnchor", ) - - id = proto.Field(proto.STRING, number=7) - + id = proto.Field(proto.STRING, number=7,) normalized_value = proto.Field( proto.MESSAGE, number=9, message="Document.Entity.NormalizedValue", ) - properties = proto.RepeatedField( proto.MESSAGE, number=10, message="Document.Entity", ) - provenance = proto.Field( proto.MESSAGE, number=11, message="Document.Provenance", ) - - redacted = proto.Field(proto.BOOL, number=12) + redacted = proto.Field(proto.BOOL, number=12,) class EntityRelation(proto.Message): r"""Relationship between @@ -831,11 +755,9 @@ class EntityRelation(proto.Message): Relationship description. """ - subject_id = proto.Field(proto.STRING, number=1) - - object_id = proto.Field(proto.STRING, number=2) - - relation = proto.Field(proto.STRING, number=3) + subject_id = proto.Field(proto.STRING, number=1,) + object_id = proto.Field(proto.STRING, number=2,) + relation = proto.Field(proto.STRING, number=3,) class TextAnchor(proto.Message): r"""Text reference indexing into the @@ -868,15 +790,13 @@ class TextSegment(proto.Message): [Document.text][google.cloud.documentai.v1.Document.text]. """ - start_index = proto.Field(proto.INT64, number=1) - - end_index = proto.Field(proto.INT64, number=2) + start_index = proto.Field(proto.INT64, number=1,) + end_index = proto.Field(proto.INT64, number=2,) text_segments = proto.RepeatedField( proto.MESSAGE, number=1, message="Document.TextAnchor.TextSegment", ) - - content = proto.Field(proto.STRING, number=2) + content = proto.Field(proto.STRING, number=2,) class PageAnchor(proto.Message): r"""Referencing the visual context of the entity in the @@ -910,6 +830,9 @@ class PageRef(proto.Message): bounding_poly (google.cloud.documentai_v1.types.BoundingPoly): Optional. Identifies the bounding polygon of a layout element on the page. + confidence (float): + Optional. Confidence of detected page element, if + applicable. Range [0, 1]. """ class LayoutType(proto.Enum): @@ -923,17 +846,15 @@ class LayoutType(proto.Enum): TABLE = 6 FORM_FIELD = 7 - page = proto.Field(proto.INT64, number=1) - + page = proto.Field(proto.INT64, number=1,) layout_type = proto.Field( proto.ENUM, number=2, enum="Document.PageAnchor.PageRef.LayoutType", ) - - layout_id = proto.Field(proto.STRING, number=3) - + layout_id = proto.Field(proto.STRING, number=3,) bounding_poly = proto.Field( proto.MESSAGE, number=4, message=geometry.BoundingPoly, ) + confidence = proto.Field(proto.FLOAT, number=5,) page_refs = proto.RepeatedField( proto.MESSAGE, number=1, message="Document.PageAnchor.PageRef", @@ -982,25 +903,20 @@ class Parent(proto.Message): The id of the parent provenance. """ - revision = proto.Field(proto.INT32, number=1) - - id = proto.Field(proto.INT32, number=2) - - revision = proto.Field(proto.INT32, number=1) - - id = proto.Field(proto.INT32, number=2) + revision = proto.Field(proto.INT32, number=1,) + id = proto.Field(proto.INT32, number=2,) + revision = proto.Field(proto.INT32, number=1,) + id = proto.Field(proto.INT32, number=2,) parents = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Provenance.Parent", ) - type_ = proto.Field( proto.ENUM, number=4, enum="Document.Provenance.OperationType", ) class Revision(proto.Message): r"""Contains past or forward revisions of this document. - Attributes: agent (str): If the change was made by a person specify @@ -1023,7 +939,6 @@ class Revision(proto.Message): class HumanReview(proto.Message): r"""Human Review information of the document. - Attributes: state (str): Human review state. e.g. ``requested``, ``succeeded``, @@ -1034,27 +949,22 @@ class HumanReview(proto.Message): is ``rejected``. """ - state = proto.Field(proto.STRING, number=1) - - state_message = proto.Field(proto.STRING, number=2) - - agent = proto.Field(proto.STRING, number=4, oneof="source") - - processor = proto.Field(proto.STRING, number=5, oneof="source") - - id = proto.Field(proto.STRING, number=1) - - parent = proto.RepeatedField(proto.INT32, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) + state = proto.Field(proto.STRING, number=1,) + state_message = proto.Field(proto.STRING, number=2,) + agent = proto.Field(proto.STRING, number=4, oneof="source",) + processor = proto.Field(proto.STRING, number=5, oneof="source",) + id = proto.Field(proto.STRING, number=1,) + parent = proto.RepeatedField(proto.INT32, number=2,) + create_time = proto.Field( + proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp, + ) human_review = proto.Field( proto.MESSAGE, number=6, message="Document.Revision.HumanReview", ) class TextChange(proto.Message): r"""This message is used for text changes aka. OCR corrections. - Attributes: text_anchor (google.cloud.documentai_v1.types.Document.TextAnchor): Provenance of the correction. Text anchor indexing into the @@ -1072,37 +982,24 @@ class TextChange(proto.Message): text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - changed_text = proto.Field(proto.STRING, number=2) - + changed_text = proto.Field(proto.STRING, number=2,) provenance = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Provenance", ) - uri = proto.Field(proto.STRING, number=1, oneof="source") - - content = proto.Field(proto.BYTES, number=2, oneof="source") - - mime_type = proto.Field(proto.STRING, number=3) - - text = proto.Field(proto.STRING, number=4) - + uri = proto.Field(proto.STRING, number=1, oneof="source",) + content = proto.Field(proto.BYTES, number=2, oneof="source",) + mime_type = proto.Field(proto.STRING, number=3,) + text = proto.Field(proto.STRING, number=4,) text_styles = proto.RepeatedField(proto.MESSAGE, number=5, message=Style,) - pages = proto.RepeatedField(proto.MESSAGE, number=6, message=Page,) - entities = proto.RepeatedField(proto.MESSAGE, number=7, message=Entity,) - entity_relations = proto.RepeatedField( proto.MESSAGE, number=8, message=EntityRelation, ) - text_changes = proto.RepeatedField(proto.MESSAGE, number=14, message=TextChange,) - shard_info = proto.Field(proto.MESSAGE, number=9, message=ShardInfo,) - - error = proto.Field(proto.MESSAGE, number=10, message=status.Status,) - + error = proto.Field(proto.MESSAGE, number=10, message=status_pb2.Status,) revisions = proto.RepeatedField(proto.MESSAGE, number=13, message=Revision,) diff --git a/google/cloud/documentai_v1/types/document_io.py b/google/cloud/documentai_v1/types/document_io.py index 50196830..4e5db8fe 100644 --- a/google/cloud/documentai_v1/types/document_io.py +++ b/google/cloud/documentai_v1/types/document_io.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -33,7 +31,6 @@ class RawDocument(proto.Message): r"""Payload message of raw document content (bytes). - Attributes: content (bytes): Inline document content. @@ -42,14 +39,12 @@ class RawDocument(proto.Message): of the [content]. """ - content = proto.Field(proto.BYTES, number=1) - - mime_type = proto.Field(proto.STRING, number=2) + content = proto.Field(proto.BYTES, number=1,) + mime_type = proto.Field(proto.STRING, number=2,) class GcsDocument(proto.Message): r"""Specifies a document stored on Cloud Storage. - Attributes: gcs_uri (str): The Cloud Storage object uri. @@ -57,14 +52,12 @@ class GcsDocument(proto.Message): An IANA MIME type (RFC6838) of the content. """ - gcs_uri = proto.Field(proto.STRING, number=1) - - mime_type = proto.Field(proto.STRING, number=2) + gcs_uri = proto.Field(proto.STRING, number=1,) + mime_type = proto.Field(proto.STRING, number=2,) class GcsDocuments(proto.Message): r"""Specifies a set of documents on Cloud Storage. - Attributes: documents (Sequence[google.cloud.documentai_v1.types.GcsDocument]): The list of documents. @@ -82,7 +75,7 @@ class GcsPrefix(proto.Message): The URI prefix. """ - gcs_uri_prefix = proto.Field(proto.STRING, number=1) + gcs_uri_prefix = proto.Field(proto.STRING, number=1,) class BatchDocumentsInputConfig(proto.Message): @@ -101,7 +94,6 @@ class BatchDocumentsInputConfig(proto.Message): gcs_prefix = proto.Field( proto.MESSAGE, number=1, oneof="source", message="GcsPrefix", ) - gcs_documents = proto.Field( proto.MESSAGE, number=2, oneof="source", message="GcsDocuments", ) @@ -119,14 +111,13 @@ class DocumentOutputConfig(proto.Message): class GcsOutputConfig(proto.Message): r"""The configuration used when outputting documents. - Attributes: gcs_uri (str): The Cloud Storage uri (a directory) of the output. """ - gcs_uri = proto.Field(proto.STRING, number=1) + gcs_uri = proto.Field(proto.STRING, number=1,) gcs_output_config = proto.Field( proto.MESSAGE, number=1, oneof="destination", message=GcsOutputConfig, diff --git a/google/cloud/documentai_v1/types/document_processor_service.py b/google/cloud/documentai_v1/types/document_processor_service.py index cfdcc7f5..f24ba8c4 100644 --- a/google/cloud/documentai_v1/types/document_processor_service.py +++ b/google/cloud/documentai_v1/types/document_processor_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,14 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.cloud.documentai_v1.types import document as gcd_document from google.cloud.documentai_v1.types import document_io -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as gr_status # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( @@ -43,7 +40,6 @@ class ProcessRequest(proto.Message): r"""Request message for the process document method. - Attributes: inline_document (google.cloud.documentai_v1.types.Document): An inline document proto. @@ -59,19 +55,15 @@ class ProcessRequest(proto.Message): inline_document = proto.Field( proto.MESSAGE, number=4, oneof="source", message=gcd_document.Document, ) - raw_document = proto.Field( proto.MESSAGE, number=5, oneof="source", message=document_io.RawDocument, ) - - name = proto.Field(proto.STRING, number=1) - - skip_human_review = proto.Field(proto.BOOL, number=3) + name = proto.Field(proto.STRING, number=1,) + skip_human_review = proto.Field(proto.BOOL, number=3,) class HumanReviewStatus(proto.Message): r"""The status of human review on a processed document. - Attributes: state (google.cloud.documentai_v1.types.HumanReviewStatus.State): The state of human review on the processing @@ -96,15 +88,12 @@ class State(proto.Enum): ERROR = 4 state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - human_review_operation = proto.Field(proto.STRING, number=3) + state_message = proto.Field(proto.STRING, number=2,) + human_review_operation = proto.Field(proto.STRING, number=3,) class ProcessResponse(proto.Message): r"""Response message for the process document method. - Attributes: document (google.cloud.documentai_v1.types.Document): The document payload, will populate fields @@ -115,7 +104,6 @@ class ProcessResponse(proto.Message): """ document = proto.Field(proto.MESSAGE, number=1, message=gcd_document.Document,) - human_review_status = proto.Field( proto.MESSAGE, number=3, message="HumanReviewStatus", ) @@ -123,7 +111,6 @@ class ProcessResponse(proto.Message): class BatchProcessRequest(proto.Message): r"""Request message for batch process document method. - Attributes: name (str): Required. The processor resource name. @@ -136,26 +123,22 @@ class BatchProcessRequest(proto.Message): skipped for this request. Default to false. """ - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) input_documents = proto.Field( proto.MESSAGE, number=5, message=document_io.BatchDocumentsInputConfig, ) - document_output_config = proto.Field( proto.MESSAGE, number=6, message=document_io.DocumentOutputConfig, ) - - skip_human_review = proto.Field(proto.BOOL, number=4) + skip_human_review = proto.Field(proto.BOOL, number=4,) class BatchProcessResponse(proto.Message): - r"""Response message for batch process document method.""" + r"""Response message for batch process document method. """ class BatchProcessMetadata(proto.Message): r"""The long running operation metadata for batch process method. - Attributes: state (google.cloud.documentai_v1.types.BatchProcessMetadata.State): The state of the current batch processing. @@ -204,24 +187,17 @@ class IndividualProcessStatus(proto.Message): document. """ - input_gcs_source = proto.Field(proto.STRING, number=1) - - status = proto.Field(proto.MESSAGE, number=2, message=gr_status.Status,) - - output_gcs_destination = proto.Field(proto.STRING, number=3) - + input_gcs_source = proto.Field(proto.STRING, number=1,) + status = proto.Field(proto.MESSAGE, number=2, message=status_pb2.Status,) + output_gcs_destination = proto.Field(proto.STRING, number=3,) human_review_status = proto.Field( proto.MESSAGE, number=5, message="HumanReviewStatus", ) state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) - + state_message = proto.Field(proto.STRING, number=2,) + create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) individual_process_statuses = proto.RepeatedField( proto.MESSAGE, number=5, message=IndividualProcessStatus, ) @@ -229,7 +205,6 @@ class IndividualProcessStatus(proto.Message): class ReviewDocumentRequest(proto.Message): r"""Request message for review document method. - Attributes: inline_document (google.cloud.documentai_v1.types.Document): An inline document proto. @@ -242,20 +217,18 @@ class ReviewDocumentRequest(proto.Message): inline_document = proto.Field( proto.MESSAGE, number=4, oneof="source", message=gcd_document.Document, ) - - human_review_config = proto.Field(proto.STRING, number=1) + human_review_config = proto.Field(proto.STRING, number=1,) class ReviewDocumentResponse(proto.Message): r"""Response message for review document method. - Attributes: gcs_destination (str): The Cloud Storage uri for the human reviewed document. """ - gcs_destination = proto.Field(proto.STRING, number=1) + gcs_destination = proto.Field(proto.STRING, number=1,) class ReviewDocumentOperationMetadata(proto.Message): @@ -275,7 +248,6 @@ class ReviewDocumentOperationMetadata(proto.Message): class CommonOperationMetadata(proto.Message): r"""The common metadata for long running operations. - Attributes: state (google.cloud.documentai_v1.types.CommonOperationMetadata.State): The state of the operation. @@ -298,12 +270,9 @@ class State(proto.Enum): CANCELLED = 5 state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) + state_message = proto.Field(proto.STRING, number=2,) + create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/documentai_v1/types/geometry.py b/google/cloud/documentai_v1/types/geometry.py index 3b3258ca..ce8158da 100644 --- a/google/cloud/documentai_v1/types/geometry.py +++ b/google/cloud/documentai_v1/types/geometry.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -36,9 +34,8 @@ class Vertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.INT32, number=1) - - y = proto.Field(proto.INT32, number=2) + x = proto.Field(proto.INT32, number=1,) + y = proto.Field(proto.INT32, number=2,) class NormalizedVertex(proto.Message): @@ -53,14 +50,12 @@ class NormalizedVertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.FLOAT, number=1) - - y = proto.Field(proto.FLOAT, number=2) + x = proto.Field(proto.FLOAT, number=1,) + y = proto.Field(proto.FLOAT, number=2,) class BoundingPoly(proto.Message): r"""A bounding polygon for the detected image annotation. - Attributes: vertices (Sequence[google.cloud.documentai_v1.types.Vertex]): The bounding polygon vertices. @@ -69,7 +64,6 @@ class BoundingPoly(proto.Message): """ vertices = proto.RepeatedField(proto.MESSAGE, number=1, message="Vertex",) - normalized_vertices = proto.RepeatedField( proto.MESSAGE, number=2, message="NormalizedVertex", ) diff --git a/google/cloud/documentai_v1beta2/__init__.py b/google/cloud/documentai_v1beta2/__init__.py index 7a10da73..f5a4882b 100644 --- a/google/cloud/documentai_v1beta2/__init__.py +++ b/google/cloud/documentai_v1beta2/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,10 @@ # from .services.document_understanding_service import DocumentUnderstandingServiceClient +from .services.document_understanding_service import ( + DocumentUnderstandingServiceAsyncClient, +) + from .types.document import Document from .types.document_understanding import AutoMlParams from .types.document_understanding import BatchProcessDocumentsRequest @@ -37,13 +40,14 @@ from .types.geometry import NormalizedVertex from .types.geometry import Vertex - __all__ = ( + "DocumentUnderstandingServiceAsyncClient", "AutoMlParams", "BatchProcessDocumentsRequest", "BatchProcessDocumentsResponse", "BoundingPoly", "Document", + "DocumentUnderstandingServiceClient", "EntityExtractionParams", "FormExtractionParams", "GcsDestination", @@ -59,5 +63,4 @@ "TableBoundHint", "TableExtractionParams", "Vertex", - "DocumentUnderstandingServiceClient", ) diff --git a/google/cloud/documentai_v1beta2/gapic_metadata.json b/google/cloud/documentai_v1beta2/gapic_metadata.json new file mode 100644 index 00000000..633dcc19 --- /dev/null +++ b/google/cloud/documentai_v1beta2/gapic_metadata.json @@ -0,0 +1,43 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.documentai_v1beta2", + "protoPackage": "google.cloud.documentai.v1beta2", + "schema": "1.0", + "services": { + "DocumentUnderstandingService": { + "clients": { + "grpc": { + "libraryClient": "DocumentUnderstandingServiceClient", + "rpcs": { + "BatchProcessDocuments": { + "methods": [ + "batch_process_documents" + ] + }, + "ProcessDocument": { + "methods": [ + "process_document" + ] + } + } + }, + "grpc-async": { + "libraryClient": "DocumentUnderstandingServiceAsyncClient", + "rpcs": { + "BatchProcessDocuments": { + "methods": [ + "batch_process_documents" + ] + }, + "ProcessDocument": { + "methods": [ + "process_document" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/documentai_v1beta2/services/__init__.py b/google/cloud/documentai_v1beta2/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/documentai_v1beta2/services/__init__.py +++ b/google/cloud/documentai_v1beta2/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/documentai_v1beta2/services/document_understanding_service/__init__.py b/google/cloud/documentai_v1beta2/services/document_understanding_service/__init__.py index be18edfd..f8f821ee 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/__init__.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import DocumentUnderstandingServiceClient from .async_client import DocumentUnderstandingServiceAsyncClient diff --git a/google/cloud/documentai_v1beta2/services/document_understanding_service/async_client.py b/google/cloud/documentai_v1beta2/services/document_understanding_service/async_client.py index 05afa3f5..563f56f4 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/async_client.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,18 +20,17 @@ import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.documentai_v1beta2.types import document from google.cloud.documentai_v1beta2.types import document_understanding -from google.rpc import status_pb2 as status # type: ignore - +from google.rpc import status_pb2 # type: ignore from .transports.base import DocumentUnderstandingServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import DocumentUnderstandingServiceGrpcAsyncIOTransport from .client import DocumentUnderstandingServiceClient @@ -56,28 +53,24 @@ class DocumentUnderstandingServiceAsyncClient: parse_common_billing_account_path = staticmethod( DocumentUnderstandingServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod( DocumentUnderstandingServiceClient.common_folder_path ) parse_common_folder_path = staticmethod( DocumentUnderstandingServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( DocumentUnderstandingServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( DocumentUnderstandingServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( DocumentUnderstandingServiceClient.common_project_path ) parse_common_project_path = staticmethod( DocumentUnderstandingServiceClient.parse_common_project_path ) - common_location_path = staticmethod( DocumentUnderstandingServiceClient.common_location_path ) @@ -87,7 +80,8 @@ class DocumentUnderstandingServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -102,7 +96,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -119,7 +113,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> DocumentUnderstandingServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: DocumentUnderstandingServiceTransport: The transport used by the client instance. @@ -134,12 +128,12 @@ def transport(self) -> DocumentUnderstandingServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, DocumentUnderstandingServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the document understanding service client. + """Instantiates the document understanding service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -171,7 +165,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = DocumentUnderstandingServiceClient( credentials=credentials, transport=transport, @@ -203,7 +196,6 @@ async def batch_process_documents( This corresponds to the ``requests`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -232,7 +224,6 @@ async def batch_process_documents( # If we have keyword arguments corresponding to fields on the # request, apply these. - if requests: request.requests.extend(requests) @@ -245,7 +236,8 @@ async def batch_process_documents( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -286,7 +278,6 @@ async def process_document( Args: request (:class:`google.cloud.documentai_v1beta2.types.ProcessDocumentRequest`): The request object. Request to process one document. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -305,7 +296,6 @@ async def process_document( """ # Create or coerce a protobuf request object. - request = document_understanding.ProcessDocumentRequest(request) # Wrap the RPC method; this adds retry and timeout information, @@ -317,7 +307,8 @@ async def process_document( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), diff --git a/google/cloud/documentai_v1beta2/services/document_understanding_service/client.py b/google/cloud/documentai_v1beta2/services/document_understanding_service/client.py index 9b8a6edd..21fc139b 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/client.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore @@ -36,8 +34,7 @@ from google.api_core import operation_async # type: ignore from google.cloud.documentai_v1beta2.types import document from google.cloud.documentai_v1beta2.types import document_understanding -from google.rpc import status_pb2 as status # type: ignore - +from google.rpc import status_pb2 # type: ignore from .transports.base import DocumentUnderstandingServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import DocumentUnderstandingServiceGrpcTransport from .transports.grpc_asyncio import DocumentUnderstandingServiceGrpcAsyncIOTransport @@ -62,7 +59,7 @@ class DocumentUnderstandingServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[DocumentUnderstandingServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -90,7 +87,8 @@ class DocumentUnderstandingServiceClient( @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -124,7 +122,8 @@ def _get_default_mtls_endpoint(api_endpoint): @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -141,7 +140,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -160,16 +159,17 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> DocumentUnderstandingServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - DocumentUnderstandingServiceTransport: The transport used by the client instance. + DocumentUnderstandingServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -182,7 +182,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -193,7 +193,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -204,7 +204,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -215,7 +215,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -229,12 +229,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, DocumentUnderstandingServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the document understanding service client. + """Instantiates the document understanding service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -289,9 +289,10 @@ def __init__( client_cert_source_func = client_options.client_cert_source else: is_mtls = mtls.has_default_client_cert_source() - client_cert_source_func = ( - mtls.default_client_cert_source() if is_mtls else None - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -303,12 +304,14 @@ def __init__( elif use_mtls_env == "always": api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -323,8 +326,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -363,7 +366,6 @@ def batch_process_documents( This corresponds to the ``requests`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -394,10 +396,8 @@ def batch_process_documents( # there are no flattened fields. if not isinstance(request, document_understanding.BatchProcessDocumentsRequest): request = document_understanding.BatchProcessDocumentsRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if requests is not None: request.requests = requests @@ -438,7 +438,6 @@ def process_document( Args: request (google.cloud.documentai_v1beta2.types.ProcessDocumentRequest): The request object. Request to process one document. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -457,7 +456,6 @@ def process_document( """ # Create or coerce a protobuf request object. - # Minor optimization to avoid making a copy if the user passes # in a document_understanding.ProcessDocumentRequest. # There's no risk of modifying the input as we've already verified diff --git a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/__init__.py b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/__init__.py index d296b9d5..0961801d 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/__init__.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/base.py b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/base.py index 38db3690..93cf27a7 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/base.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,22 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.documentai_v1beta2.types import document from google.cloud.documentai_v1beta2.types import document_understanding -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -40,27 +39,41 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() +try: + # google.auth.__version__ was added in 1.26.0 + _GOOGLE_AUTH_VERSION = google.auth.__version__ +except AttributeError: + try: # try pkg_resources if it is available + _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version + except pkg_resources.DistributionNotFound: # pragma: NO COVER + _GOOGLE_AUTH_VERSION = None + +_API_CORE_VERSION = google.api_core.__version__ + class DocumentUnderstandingServiceTransport(abc.ABC): """Abstract transport class for DocumentUnderstandingService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "us-documentai.googleapis.com" + def __init__( self, *, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, - credentials_file: typing.Optional[str] = None, - scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES, - quota_project_id: typing.Optional[str] = None, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, **kwargs, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -69,7 +82,7 @@ def __init__( credentials_file (Optional[str]): A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is mutually exclusive with credentials. - scope (Optional[Sequence[str]]): A list of scopes. + scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -83,29 +96,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are increased. + + # TODO: Remove this function once google-auth >= 1.25.0 is required + @classmethod + def _get_scopes_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Optional[Sequence[str]]]: + """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" + + scopes_kwargs = {} + + if _GOOGLE_AUTH_VERSION and ( + packaging.version.parse(_GOOGLE_AUTH_VERSION) + >= packaging.version.parse("1.25.0") + ): + scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} + else: + scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} + + return scopes_kwargs + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -116,7 +176,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -130,7 +191,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -147,18 +209,18 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def batch_process_documents( self, - ) -> typing.Callable[ + ) -> Callable[ [document_understanding.BatchProcessDocumentsRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() @property def process_document( self, - ) -> typing.Callable[ + ) -> Callable[ [document_understanding.ProcessDocumentRequest], - typing.Union[document.Document, typing.Awaitable[document.Document]], + Union[document.Document, Awaitable[document.Document]], ]: raise NotImplementedError() diff --git a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc.py b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc.py index 391fb597..a75e0e94 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple +from typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.documentai_v1beta2.types import document from google.cloud.documentai_v1beta2.types import document_understanding -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import DocumentUnderstandingServiceTransport, DEFAULT_CLIENT_INFO @@ -55,7 +52,7 @@ def __init__( self, *, host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -69,7 +66,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -180,7 +178,7 @@ def __init__( def create_channel( cls, host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -211,13 +209,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -245,7 +245,7 @@ def operations_client(self) -> operations_v1.OperationsClient: def batch_process_documents( self, ) -> Callable[ - [document_understanding.BatchProcessDocumentsRequest], operations.Operation + [document_understanding.BatchProcessDocumentsRequest], operations_pb2.Operation ]: r"""Return a callable for the batch process documents method over gRPC. @@ -266,7 +266,7 @@ def batch_process_documents( self._stubs["batch_process_documents"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1beta2.DocumentUnderstandingService/BatchProcessDocuments", request_serializer=document_understanding.BatchProcessDocumentsRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["batch_process_documents"] diff --git a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc_asyncio.py b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc_asyncio.py index 76cf0816..bd913f2d 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc_asyncio.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,24 +13,22 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore from google.cloud.documentai_v1beta2.types import document from google.cloud.documentai_v1beta2.types import document_understanding -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import DocumentUnderstandingServiceTransport, DEFAULT_CLIENT_INFO from .grpc import DocumentUnderstandingServiceGrpcTransport @@ -60,7 +57,7 @@ class DocumentUnderstandingServiceGrpcAsyncIOTransport( def create_channel( cls, host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -87,13 +84,15 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -101,7 +100,7 @@ def __init__( self, *, host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -115,7 +114,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -174,7 +174,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -254,7 +253,7 @@ def batch_process_documents( self, ) -> Callable[ [document_understanding.BatchProcessDocumentsRequest], - Awaitable[operations.Operation], + Awaitable[operations_pb2.Operation], ]: r"""Return a callable for the batch process documents method over gRPC. @@ -275,7 +274,7 @@ def batch_process_documents( self._stubs["batch_process_documents"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1beta2.DocumentUnderstandingService/BatchProcessDocuments", request_serializer=document_understanding.BatchProcessDocumentsRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["batch_process_documents"] diff --git a/google/cloud/documentai_v1beta2/types/__init__.py b/google/cloud/documentai_v1beta2/types/__init__.py index e5578fac..be41d52a 100644 --- a/google/cloud/documentai_v1beta2/types/__init__.py +++ b/google/cloud/documentai_v1beta2/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .document import Document from .document_understanding import ( AutoMlParams, diff --git a/google/cloud/documentai_v1beta2/types/document.py b/google/cloud/documentai_v1beta2/types/document.py index e2411002..5fbbb4c6 100644 --- a/google/cloud/documentai_v1beta2/types/document.py +++ b/google/cloud/documentai_v1beta2/types/document.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,13 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.cloud.documentai_v1beta2.types import geometry -from google.rpc import status_pb2 as status # type: ignore -from google.type import color_pb2 as gt_color # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore __protobuf__ = proto.module( @@ -98,11 +95,9 @@ class ShardInfo(proto.Message): in the overall document global text. """ - shard_index = proto.Field(proto.INT64, number=1) - - shard_count = proto.Field(proto.INT64, number=2) - - text_offset = proto.Field(proto.INT64, number=3) + shard_index = proto.Field(proto.INT64, number=1,) + shard_count = proto.Field(proto.INT64, number=2,) + text_offset = proto.Field(proto.INT64, number=3,) class Label(proto.Message): r"""Label attaches schema information and/or other metadata to segments @@ -129,11 +124,9 @@ class Label(proto.Message): assignment. """ - automl_model = proto.Field(proto.STRING, number=2, oneof="source") - - name = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=3) + automl_model = proto.Field(proto.STRING, number=2, oneof="source",) + name = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=3,) class Style(proto.Message): r"""Annotation for common text style attributes. This adheres to @@ -162,7 +155,6 @@ class Style(proto.Message): class FontSize(proto.Message): r"""Font size with unit. - Attributes: size (float): Font size for the text. @@ -171,31 +163,25 @@ class FontSize(proto.Message): (in, px, pt, etc.). """ - size = proto.Field(proto.FLOAT, number=1) - - unit = proto.Field(proto.STRING, number=2) + size = proto.Field(proto.FLOAT, number=1,) + unit = proto.Field(proto.STRING, number=2,) text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - color = proto.Field(proto.MESSAGE, number=2, message=gt_color.Color,) - - background_color = proto.Field(proto.MESSAGE, number=3, message=gt_color.Color,) - - font_weight = proto.Field(proto.STRING, number=4) - - text_style = proto.Field(proto.STRING, number=5) - - text_decoration = proto.Field(proto.STRING, number=6) - + color = proto.Field(proto.MESSAGE, number=2, message=color_pb2.Color,) + background_color = proto.Field( + proto.MESSAGE, number=3, message=color_pb2.Color, + ) + font_weight = proto.Field(proto.STRING, number=4,) + text_style = proto.Field(proto.STRING, number=5,) + text_decoration = proto.Field(proto.STRING, number=6,) font_size = proto.Field( proto.MESSAGE, number=7, message="Document.Style.FontSize", ) class Page(proto.Message): r"""A page in a [Document][google.cloud.documentai.v1beta2.Document]. - Attributes: page_number (int): 1-based index for current @@ -241,7 +227,6 @@ class Page(proto.Message): class Dimension(proto.Message): r"""Dimension for the page. - Attributes: width (float): Page width. @@ -251,15 +236,12 @@ class Dimension(proto.Message): Dimension unit. """ - width = proto.Field(proto.FLOAT, number=1) - - height = proto.Field(proto.FLOAT, number=2) - - unit = proto.Field(proto.STRING, number=3) + width = proto.Field(proto.FLOAT, number=1,) + height = proto.Field(proto.FLOAT, number=2,) + unit = proto.Field(proto.STRING, number=3,) class Layout(proto.Message): r"""Visual element describing a layout unit on a page. - Attributes: text_anchor (google.cloud.documentai_v1beta2.types.Document.TextAnchor): Text anchor indexing into the @@ -292,18 +274,14 @@ class Orientation(proto.Enum): text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - confidence = proto.Field(proto.FLOAT, number=2) - + confidence = proto.Field(proto.FLOAT, number=2,) bounding_poly = proto.Field( proto.MESSAGE, number=3, message=geometry.BoundingPoly, ) - orientation = proto.Field( proto.ENUM, number=4, enum="Document.Page.Layout.Orientation", ) - - id = proto.Field(proto.STRING, number=5) + id = proto.Field(proto.STRING, number=5,) class Block(proto.Message): r"""A block has a set of lines (collected into paragraphs) that @@ -322,7 +300,6 @@ class Block(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) @@ -344,7 +321,6 @@ class Paragraph(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) @@ -367,14 +343,12 @@ class Line(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) class Token(proto.Message): r"""A detected token. - Attributes: layout (google.cloud.documentai_v1beta2.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta2.Document.Page.Layout] @@ -411,11 +385,9 @@ class Type(proto.Enum): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_break = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Token.DetectedBreak", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) @@ -440,16 +412,13 @@ class VisualElement(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - - type_ = proto.Field(proto.STRING, number=2) - + type_ = proto.Field(proto.STRING, number=2,) detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) class Table(proto.Message): r"""A table representation similar to HTML table structure. - Attributes: layout (google.cloud.documentai_v1beta2.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta2.Document.Page.Layout] @@ -466,7 +435,6 @@ class Table(proto.Message): class TableRow(proto.Message): r"""A row of table cells. - Attributes: cells (Sequence[google.cloud.documentai_v1beta2.types.Document.Page.Table.TableCell]): Cells that make up this row. @@ -478,7 +446,6 @@ class TableRow(proto.Message): class TableCell(proto.Message): r"""A cell representation inside the table. - Attributes: layout (google.cloud.documentai_v1beta2.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta2.Document.Page.Layout] @@ -496,11 +463,8 @@ class TableCell(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - - row_span = proto.Field(proto.INT32, number=2) - - col_span = proto.Field(proto.INT32, number=3) - + row_span = proto.Field(proto.INT32, number=2,) + col_span = proto.Field(proto.INT32, number=3,) detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) @@ -508,22 +472,18 @@ class TableCell(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - header_rows = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.Table.TableRow", ) - body_rows = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.Table.TableRow", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) class FormField(proto.Message): r"""A form field detected on the page. - Attributes: field_name (google.cloud.documentai_v1beta2.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta2.Document.Page.Layout] @@ -560,28 +520,21 @@ class FormField(proto.Message): field_name = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - field_value = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Layout", ) - name_detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) - value_detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) - - value_type = proto.Field(proto.STRING, number=5) - - corrected_key_text = proto.Field(proto.STRING, number=6) - - corrected_value_text = proto.Field(proto.STRING, number=7) + value_type = proto.Field(proto.STRING, number=5,) + corrected_key_text = proto.Field(proto.STRING, number=6,) + corrected_value_text = proto.Field(proto.STRING, number=7,) class DetectedLanguage(proto.Message): r"""Detected language for a structural component. - Attributes: language_code (str): The BCP-47 language code, such as "en-US" or "sr-Latn". For @@ -591,46 +544,35 @@ class DetectedLanguage(proto.Message): Confidence of detected language. Range [0, 1]. """ - language_code = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - - page_number = proto.Field(proto.INT32, number=1) + language_code = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) + page_number = proto.Field(proto.INT32, number=1,) dimension = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Dimension", ) - layout = proto.Field(proto.MESSAGE, number=3, message="Document.Page.Layout",) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) - blocks = proto.RepeatedField( proto.MESSAGE, number=5, message="Document.Page.Block", ) - paragraphs = proto.RepeatedField( proto.MESSAGE, number=6, message="Document.Page.Paragraph", ) - lines = proto.RepeatedField( proto.MESSAGE, number=7, message="Document.Page.Line", ) - tokens = proto.RepeatedField( proto.MESSAGE, number=8, message="Document.Page.Token", ) - visual_elements = proto.RepeatedField( proto.MESSAGE, number=9, message="Document.Page.VisualElement", ) - tables = proto.RepeatedField( proto.MESSAGE, number=10, message="Document.Page.Table", ) - form_fields = proto.RepeatedField( proto.MESSAGE, number=11, message="Document.Page.FormField", ) @@ -669,21 +611,14 @@ class Entity(proto.Message): text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - type_ = proto.Field(proto.STRING, number=2) - - mention_text = proto.Field(proto.STRING, number=3) - - mention_id = proto.Field(proto.STRING, number=4) - - confidence = proto.Field(proto.FLOAT, number=5) - + type_ = proto.Field(proto.STRING, number=2,) + mention_text = proto.Field(proto.STRING, number=3,) + mention_id = proto.Field(proto.STRING, number=4,) + confidence = proto.Field(proto.FLOAT, number=5,) page_anchor = proto.Field( proto.MESSAGE, number=6, message="Document.PageAnchor", ) - - id = proto.Field(proto.STRING, number=7) - + id = proto.Field(proto.STRING, number=7,) bounding_poly_for_demo_frontend = proto.Field( proto.MESSAGE, number=8, message=geometry.BoundingPoly, ) @@ -701,11 +636,9 @@ class EntityRelation(proto.Message): Relationship description. """ - subject_id = proto.Field(proto.STRING, number=1) - - object_id = proto.Field(proto.STRING, number=2) - - relation = proto.Field(proto.STRING, number=3) + subject_id = proto.Field(proto.STRING, number=1,) + object_id = proto.Field(proto.STRING, number=2,) + relation = proto.Field(proto.STRING, number=3,) class TextAnchor(proto.Message): r"""Text reference indexing into the @@ -735,9 +668,8 @@ class TextSegment(proto.Message): [Document.text][google.cloud.documentai.v1beta2.Document.text]. """ - start_index = proto.Field(proto.INT64, number=1) - - end_index = proto.Field(proto.INT64, number=2) + start_index = proto.Field(proto.INT64, number=1,) + end_index = proto.Field(proto.INT64, number=2,) text_segments = proto.RepeatedField( proto.MESSAGE, number=1, message="Document.TextAnchor.TextSegment", @@ -785,41 +717,29 @@ class LayoutType(proto.Enum): TABLE = 6 FORM_FIELD = 7 - page = proto.Field(proto.INT64, number=1) - + page = proto.Field(proto.INT64, number=1,) layout_type = proto.Field( proto.ENUM, number=2, enum="Document.PageAnchor.PageRef.LayoutType", ) - - layout_id = proto.Field(proto.STRING, number=3) + layout_id = proto.Field(proto.STRING, number=3,) page_refs = proto.RepeatedField( proto.MESSAGE, number=1, message="Document.PageAnchor.PageRef", ) - uri = proto.Field(proto.STRING, number=1, oneof="source") - - content = proto.Field(proto.BYTES, number=2, oneof="source") - - mime_type = proto.Field(proto.STRING, number=3) - - text = proto.Field(proto.STRING, number=4) - + uri = proto.Field(proto.STRING, number=1, oneof="source",) + content = proto.Field(proto.BYTES, number=2, oneof="source",) + mime_type = proto.Field(proto.STRING, number=3,) + text = proto.Field(proto.STRING, number=4,) text_styles = proto.RepeatedField(proto.MESSAGE, number=5, message=Style,) - pages = proto.RepeatedField(proto.MESSAGE, number=6, message=Page,) - entities = proto.RepeatedField(proto.MESSAGE, number=7, message=Entity,) - entity_relations = proto.RepeatedField( proto.MESSAGE, number=8, message=EntityRelation, ) - shard_info = proto.Field(proto.MESSAGE, number=9, message=ShardInfo,) - labels = proto.RepeatedField(proto.MESSAGE, number=11, message=Label,) - - error = proto.Field(proto.MESSAGE, number=10, message=status.Status,) + error = proto.Field(proto.MESSAGE, number=10, message=status_pb2.Status,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/documentai_v1beta2/types/document_understanding.py b/google/cloud/documentai_v1beta2/types/document_understanding.py index dd80f269..6eec6686 100644 --- a/google/cloud/documentai_v1beta2/types/document_understanding.py +++ b/google/cloud/documentai_v1beta2/types/document_understanding.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.cloud.documentai_v1beta2.types import geometry -from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore __protobuf__ = proto.module( @@ -65,13 +62,11 @@ class BatchProcessDocumentsRequest(proto.Message): requests = proto.RepeatedField( proto.MESSAGE, number=1, message="ProcessDocumentRequest", ) - - parent = proto.Field(proto.STRING, number=2) + parent = proto.Field(proto.STRING, number=2,) class ProcessDocumentRequest(proto.Message): r"""Request to process one document. - Attributes: parent (str): Target project and location to make a call. @@ -114,28 +109,20 @@ class ProcessDocumentRequest(proto.Message): Params. """ - parent = proto.Field(proto.STRING, number=9) - + parent = proto.Field(proto.STRING, number=9,) input_config = proto.Field(proto.MESSAGE, number=1, message="InputConfig",) - output_config = proto.Field(proto.MESSAGE, number=2, message="OutputConfig",) - - document_type = proto.Field(proto.STRING, number=3) - + document_type = proto.Field(proto.STRING, number=3,) table_extraction_params = proto.Field( proto.MESSAGE, number=4, message="TableExtractionParams", ) - form_extraction_params = proto.Field( proto.MESSAGE, number=5, message="FormExtractionParams", ) - entity_extraction_params = proto.Field( proto.MESSAGE, number=6, message="EntityExtractionParams", ) - ocr_params = proto.Field(proto.MESSAGE, number=7, message="OcrParams",) - automl_params = proto.Field(proto.MESSAGE, number=8, message="AutoMlParams",) @@ -155,7 +142,6 @@ class BatchProcessDocumentsResponse(proto.Message): class ProcessDocumentResponse(proto.Message): r"""Response to a single document processing request. - Attributes: input_config (google.cloud.documentai_v1beta2.types.InputConfig): Information about the input file. This is the @@ -168,7 +154,6 @@ class ProcessDocumentResponse(proto.Message): """ input_config = proto.Field(proto.MESSAGE, number=1, message="InputConfig",) - output_config = proto.Field(proto.MESSAGE, number=2, message="OutputConfig",) @@ -189,12 +174,11 @@ class OcrParams(proto.Message): specified languages is not one of the supported languages. """ - language_hints = proto.RepeatedField(proto.STRING, number=1) + language_hints = proto.RepeatedField(proto.STRING, number=1,) class TableExtractionParams(proto.Message): r"""Parameters to control table extraction behavior. - Attributes: enabled (bool): Whether to enable table extraction. @@ -212,15 +196,12 @@ class TableExtractionParams(proto.Message): "builtin/latest" for the latest model. """ - enabled = proto.Field(proto.BOOL, number=1) - + enabled = proto.Field(proto.BOOL, number=1,) table_bound_hints = proto.RepeatedField( proto.MESSAGE, number=2, message="TableBoundHint", ) - - header_hints = proto.RepeatedField(proto.STRING, number=3) - - model_version = proto.Field(proto.STRING, number=4) + header_hints = proto.RepeatedField(proto.STRING, number=3,) + model_version = proto.Field(proto.STRING, number=4,) class TableBoundHint(proto.Message): @@ -239,14 +220,12 @@ class TableBoundHint(proto.Message): axis-aligned rectangle. """ - page_number = proto.Field(proto.INT32, number=1) - + page_number = proto.Field(proto.INT32, number=1,) bounding_box = proto.Field(proto.MESSAGE, number=2, message=geometry.BoundingPoly,) class FormExtractionParams(proto.Message): r"""Parameters to control form extraction behavior. - Attributes: enabled (bool): Whether to enable form extraction. @@ -274,18 +253,15 @@ class FormExtractionParams(proto.Message): are stored. """ - enabled = proto.Field(proto.BOOL, number=1) - + enabled = proto.Field(proto.BOOL, number=1,) key_value_pair_hints = proto.RepeatedField( proto.MESSAGE, number=2, message="KeyValuePairHint", ) - - model_version = proto.Field(proto.STRING, number=3) + model_version = proto.Field(proto.STRING, number=3,) class KeyValuePairHint(proto.Message): r"""User-provided hint for key value pair. - Attributes: key (str): The key text for the hint. @@ -296,14 +272,12 @@ class KeyValuePairHint(proto.Message): Types not in this list will be ignored. """ - key = proto.Field(proto.STRING, number=1) - - value_types = proto.RepeatedField(proto.STRING, number=2) + key = proto.Field(proto.STRING, number=1,) + value_types = proto.RepeatedField(proto.STRING, number=2,) class EntityExtractionParams(proto.Message): r"""Parameters to control entity extraction behavior. - Attributes: enabled (bool): Whether to enable entity extraction. @@ -313,14 +287,12 @@ class EntityExtractionParams(proto.Message): "builtin/latest" for the latest model. """ - enabled = proto.Field(proto.BOOL, number=1) - - model_version = proto.Field(proto.STRING, number=2) + enabled = proto.Field(proto.BOOL, number=1,) + model_version = proto.Field(proto.STRING, number=2,) class AutoMlParams(proto.Message): r"""Parameters to control AutoML model prediction behavior. - Attributes: model (str): Resource name of the AutoML model. @@ -329,12 +301,11 @@ class AutoMlParams(proto.Message): ``projects/{project-id}/locations/{location-id}/models/{model-id}``. """ - model = proto.Field(proto.STRING, number=1) + model = proto.Field(proto.STRING, number=1,) class InputConfig(proto.Message): r"""The desired input location and metadata. - Attributes: gcs_source (google.cloud.documentai_v1beta2.types.GcsSource): The Google Cloud Storage location to read the @@ -359,15 +330,12 @@ class InputConfig(proto.Message): gcs_source = proto.Field( proto.MESSAGE, number=1, oneof="source", message="GcsSource", ) - - contents = proto.Field(proto.BYTES, number=3, oneof="source") - - mime_type = proto.Field(proto.STRING, number=2) + contents = proto.Field(proto.BYTES, number=3, oneof="source",) + mime_type = proto.Field(proto.STRING, number=2,) class OutputConfig(proto.Message): r"""The desired output location and metadata. - Attributes: gcs_destination (google.cloud.documentai_v1beta2.types.GcsDestination): The Google Cloud Storage location to write @@ -395,8 +363,7 @@ class OutputConfig(proto.Message): gcs_destination = proto.Field( proto.MESSAGE, number=1, oneof="destination", message="GcsDestination", ) - - pages_per_shard = proto.Field(proto.INT32, number=2) + pages_per_shard = proto.Field(proto.INT32, number=2,) class GcsSource(proto.Message): @@ -408,7 +375,7 @@ class GcsSource(proto.Message): """ - uri = proto.Field(proto.STRING, number=1) + uri = proto.Field(proto.STRING, number=1,) class GcsDestination(proto.Message): @@ -420,12 +387,11 @@ class GcsDestination(proto.Message): """ - uri = proto.Field(proto.STRING, number=1) + uri = proto.Field(proto.STRING, number=1,) class OperationMetadata(proto.Message): r"""Contains metadata for the BatchProcessDocuments operation. - Attributes: state (google.cloud.documentai_v1beta2.types.OperationMetadata.State): The state of the current batch processing. @@ -449,12 +415,9 @@ class State(proto.Enum): FAILED = 6 state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) + state_message = proto.Field(proto.STRING, number=2,) + create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/documentai_v1beta2/types/geometry.py b/google/cloud/documentai_v1beta2/types/geometry.py index 38ae138a..f8a03e7f 100644 --- a/google/cloud/documentai_v1beta2/types/geometry.py +++ b/google/cloud/documentai_v1beta2/types/geometry.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -36,9 +34,8 @@ class Vertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.INT32, number=1) - - y = proto.Field(proto.INT32, number=2) + x = proto.Field(proto.INT32, number=1,) + y = proto.Field(proto.INT32, number=2,) class NormalizedVertex(proto.Message): @@ -53,14 +50,12 @@ class NormalizedVertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.FLOAT, number=1) - - y = proto.Field(proto.FLOAT, number=2) + x = proto.Field(proto.FLOAT, number=1,) + y = proto.Field(proto.FLOAT, number=2,) class BoundingPoly(proto.Message): r"""A bounding polygon for the detected image annotation. - Attributes: vertices (Sequence[google.cloud.documentai_v1beta2.types.Vertex]): The bounding polygon vertices. @@ -69,7 +64,6 @@ class BoundingPoly(proto.Message): """ vertices = proto.RepeatedField(proto.MESSAGE, number=1, message="Vertex",) - normalized_vertices = proto.RepeatedField( proto.MESSAGE, number=2, message="NormalizedVertex", ) diff --git a/google/cloud/documentai_v1beta3/__init__.py b/google/cloud/documentai_v1beta3/__init__.py index 84d917be..c6cd3be9 100644 --- a/google/cloud/documentai_v1beta3/__init__.py +++ b/google/cloud/documentai_v1beta3/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +15,8 @@ # from .services.document_processor_service import DocumentProcessorServiceClient +from .services.document_processor_service import DocumentProcessorServiceAsyncClient + from .types.document import Document from .types.document_io import BatchDocumentsInputConfig from .types.document_io import DocumentOutputConfig @@ -37,8 +38,8 @@ from .types.geometry import NormalizedVertex from .types.geometry import Vertex - __all__ = ( + "DocumentProcessorServiceAsyncClient", "BatchDocumentsInputConfig", "BatchProcessMetadata", "BatchProcessRequest", @@ -47,6 +48,7 @@ "CommonOperationMetadata", "Document", "DocumentOutputConfig", + "DocumentProcessorServiceClient", "GcsDocument", "GcsDocuments", "GcsPrefix", @@ -59,5 +61,4 @@ "ReviewDocumentRequest", "ReviewDocumentResponse", "Vertex", - "DocumentProcessorServiceClient", ) diff --git a/google/cloud/documentai_v1beta3/gapic_metadata.json b/google/cloud/documentai_v1beta3/gapic_metadata.json new file mode 100644 index 00000000..61a5b92c --- /dev/null +++ b/google/cloud/documentai_v1beta3/gapic_metadata.json @@ -0,0 +1,53 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.documentai_v1beta3", + "protoPackage": "google.cloud.documentai.v1beta3", + "schema": "1.0", + "services": { + "DocumentProcessorService": { + "clients": { + "grpc": { + "libraryClient": "DocumentProcessorServiceClient", + "rpcs": { + "BatchProcessDocuments": { + "methods": [ + "batch_process_documents" + ] + }, + "ProcessDocument": { + "methods": [ + "process_document" + ] + }, + "ReviewDocument": { + "methods": [ + "review_document" + ] + } + } + }, + "grpc-async": { + "libraryClient": "DocumentProcessorServiceAsyncClient", + "rpcs": { + "BatchProcessDocuments": { + "methods": [ + "batch_process_documents" + ] + }, + "ProcessDocument": { + "methods": [ + "process_document" + ] + }, + "ReviewDocument": { + "methods": [ + "review_document" + ] + } + } + } + } + } + } +} diff --git a/google/cloud/documentai_v1beta3/services/__init__.py b/google/cloud/documentai_v1beta3/services/__init__.py index 42ffdf2b..4de65971 100644 --- a/google/cloud/documentai_v1beta3/services/__init__.py +++ b/google/cloud/documentai_v1beta3/services/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/google/cloud/documentai_v1beta3/services/document_processor_service/__init__.py b/google/cloud/documentai_v1beta3/services/document_processor_service/__init__.py index 9f87d9f4..900ba543 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/__init__.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .client import DocumentProcessorServiceClient from .async_client import DocumentProcessorServiceAsyncClient diff --git a/google/cloud/documentai_v1beta3/services/document_processor_service/async_client.py b/google/cloud/documentai_v1beta3/services/document_processor_service/async_client.py index e6c4f780..ac20ff44 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/async_client.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/async_client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict import functools import re @@ -22,17 +20,16 @@ import pkg_resources import google.api_core.client_options as ClientOptions # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore from google.api_core import operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.documentai_v1beta3.types import document from google.cloud.documentai_v1beta3.types import document_processor_service - from .transports.base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc_asyncio import DocumentProcessorServiceGrpcAsyncIOTransport from .client import DocumentProcessorServiceClient @@ -61,33 +58,28 @@ class DocumentProcessorServiceAsyncClient: parse_processor_path = staticmethod( DocumentProcessorServiceClient.parse_processor_path ) - common_billing_account_path = staticmethod( DocumentProcessorServiceClient.common_billing_account_path ) parse_common_billing_account_path = staticmethod( DocumentProcessorServiceClient.parse_common_billing_account_path ) - common_folder_path = staticmethod(DocumentProcessorServiceClient.common_folder_path) parse_common_folder_path = staticmethod( DocumentProcessorServiceClient.parse_common_folder_path ) - common_organization_path = staticmethod( DocumentProcessorServiceClient.common_organization_path ) parse_common_organization_path = staticmethod( DocumentProcessorServiceClient.parse_common_organization_path ) - common_project_path = staticmethod( DocumentProcessorServiceClient.common_project_path ) parse_common_project_path = staticmethod( DocumentProcessorServiceClient.parse_common_project_path ) - common_location_path = staticmethod( DocumentProcessorServiceClient.common_location_path ) @@ -97,7 +89,8 @@ class DocumentProcessorServiceAsyncClient: @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -112,7 +105,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -129,7 +122,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> DocumentProcessorServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: DocumentProcessorServiceTransport: The transport used by the client instance. @@ -144,12 +137,12 @@ def transport(self) -> DocumentProcessorServiceTransport: def __init__( self, *, - credentials: credentials.Credentials = None, + credentials: ga_credentials.Credentials = None, transport: Union[str, DocumentProcessorServiceTransport] = "grpc_asyncio", client_options: ClientOptions = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the document processor service client. + """Instantiates the document processor service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -181,7 +174,6 @@ def __init__( google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport creation failed for any reason. """ - self._client = DocumentProcessorServiceClient( credentials=credentials, transport=transport, @@ -211,7 +203,6 @@ async def process_document( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -238,7 +229,6 @@ async def process_document( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -251,7 +241,8 @@ async def process_document( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -294,7 +285,6 @@ async def batch_process_documents( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -324,7 +314,6 @@ async def batch_process_documents( # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -337,7 +326,8 @@ async def batch_process_documents( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -389,7 +379,6 @@ async def review_document( This corresponds to the ``human_review_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -419,7 +408,6 @@ async def review_document( # If we have keyword arguments corresponding to fields on the # request, apply these. - if human_review_config is not None: request.human_review_config = human_review_config @@ -432,7 +420,8 @@ async def review_document( maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), diff --git a/google/cloud/documentai_v1beta3/services/document_processor_service/client.py b/google/cloud/documentai_v1beta3/services/document_processor_service/client.py index 9064c7d5..6cbccb9a 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/client.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/client.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from distutils import util import os @@ -23,10 +21,10 @@ import pkg_resources from google.api_core import client_options as client_options_lib # type: ignore -from google.api_core import exceptions # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport import mtls # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.auth.exceptions import MutualTLSChannelError # type: ignore @@ -36,7 +34,6 @@ from google.api_core import operation_async # type: ignore from google.cloud.documentai_v1beta3.types import document from google.cloud.documentai_v1beta3.types import document_processor_service - from .transports.base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO from .transports.grpc import DocumentProcessorServiceGrpcTransport from .transports.grpc_asyncio import DocumentProcessorServiceGrpcAsyncIOTransport @@ -59,7 +56,7 @@ class DocumentProcessorServiceClientMeta(type): def get_transport_class( cls, label: str = None, ) -> Type[DocumentProcessorServiceTransport]: - """Return an appropriate transport class. + """Returns an appropriate transport class. Args: label: The name of the desired transport. If none is @@ -87,7 +84,8 @@ class DocumentProcessorServiceClient(metaclass=DocumentProcessorServiceClientMet @staticmethod def _get_default_mtls_endpoint(api_endpoint): - """Convert api endpoint to mTLS endpoint. + """Converts api endpoint to mTLS endpoint. + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. Args: @@ -114,14 +112,15 @@ def _get_default_mtls_endpoint(api_endpoint): return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - DEFAULT_ENDPOINT = "us-documentai.googleapis.com" + DEFAULT_ENDPOINT = "documentai.googleapis.com" DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore DEFAULT_ENDPOINT ) @classmethod def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials info. + """Creates an instance of this client using the provided credentials + info. Args: info (dict): The service account private key info. @@ -138,7 +137,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): @classmethod def from_service_account_file(cls, filename: str, *args, **kwargs): """Creates an instance of this client using the provided credentials - file. + file. Args: filename (str): The path to the service account private key json @@ -157,23 +156,24 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): @property def transport(self) -> DocumentProcessorServiceTransport: - """Return the transport used by the client instance. + """Returns the transport used by the client instance. Returns: - DocumentProcessorServiceTransport: The transport used by the client instance. + DocumentProcessorServiceTransport: The transport used by the client + instance. """ return self._transport @staticmethod def human_review_config_path(project: str, location: str, processor: str,) -> str: - """Return a fully-qualified human_review_config string.""" + """Returns a fully-qualified human_review_config string.""" return "projects/{project}/locations/{location}/processors/{processor}/humanReviewConfig".format( project=project, location=location, processor=processor, ) @staticmethod def parse_human_review_config_path(path: str) -> Dict[str, str]: - """Parse a human_review_config path into its component segments.""" + """Parses a human_review_config path into its component segments.""" m = re.match( r"^projects/(?P.+?)/locations/(?P.+?)/processors/(?P.+?)/humanReviewConfig$", path, @@ -182,14 +182,14 @@ def parse_human_review_config_path(path: str) -> Dict[str, str]: @staticmethod def processor_path(project: str, location: str, processor: str,) -> str: - """Return a fully-qualified processor string.""" + """Returns a fully-qualified processor string.""" return "projects/{project}/locations/{location}/processors/{processor}".format( project=project, location=location, processor=processor, ) @staticmethod def parse_processor_path(path: str) -> Dict[str, str]: - """Parse a processor path into its component segments.""" + """Parses a processor path into its component segments.""" m = re.match( r"^projects/(?P.+?)/locations/(?P.+?)/processors/(?P.+?)$", path, @@ -198,7 +198,7 @@ def parse_processor_path(path: str) -> Dict[str, str]: @staticmethod def common_billing_account_path(billing_account: str,) -> str: - """Return a fully-qualified billing_account string.""" + """Returns a fully-qualified billing_account string.""" return "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -211,7 +211,7 @@ def parse_common_billing_account_path(path: str) -> Dict[str, str]: @staticmethod def common_folder_path(folder: str,) -> str: - """Return a fully-qualified folder string.""" + """Returns a fully-qualified folder string.""" return "folders/{folder}".format(folder=folder,) @staticmethod @@ -222,7 +222,7 @@ def parse_common_folder_path(path: str) -> Dict[str, str]: @staticmethod def common_organization_path(organization: str,) -> str: - """Return a fully-qualified organization string.""" + """Returns a fully-qualified organization string.""" return "organizations/{organization}".format(organization=organization,) @staticmethod @@ -233,7 +233,7 @@ def parse_common_organization_path(path: str) -> Dict[str, str]: @staticmethod def common_project_path(project: str,) -> str: - """Return a fully-qualified project string.""" + """Returns a fully-qualified project string.""" return "projects/{project}".format(project=project,) @staticmethod @@ -244,7 +244,7 @@ def parse_common_project_path(path: str) -> Dict[str, str]: @staticmethod def common_location_path(project: str, location: str,) -> str: - """Return a fully-qualified location string.""" + """Returns a fully-qualified location string.""" return "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -258,12 +258,12 @@ def parse_common_location_path(path: str) -> Dict[str, str]: def __init__( self, *, - credentials: Optional[credentials.Credentials] = None, + credentials: Optional[ga_credentials.Credentials] = None, transport: Union[str, DocumentProcessorServiceTransport, None] = None, client_options: Optional[client_options_lib.ClientOptions] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, ) -> None: - """Instantiate the document processor service client. + """Instantiates the document processor service client. Args: credentials (Optional[google.auth.credentials.Credentials]): The @@ -318,9 +318,10 @@ def __init__( client_cert_source_func = client_options.client_cert_source else: is_mtls = mtls.has_default_client_cert_source() - client_cert_source_func = ( - mtls.default_client_cert_source() if is_mtls else None - ) + if is_mtls: + client_cert_source_func = mtls.default_client_cert_source() + else: + client_cert_source_func = None # Figure out which api endpoint to use. if client_options.api_endpoint is not None: @@ -332,12 +333,14 @@ def __init__( elif use_mtls_env == "always": api_endpoint = self.DEFAULT_MTLS_ENDPOINT elif use_mtls_env == "auto": - api_endpoint = ( - self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT - ) + if is_mtls: + api_endpoint = self.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = self.DEFAULT_ENDPOINT else: raise MutualTLSChannelError( - "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always" + "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted " + "values: never, auto, always" ) # Save or instantiate the transport. @@ -352,8 +355,8 @@ def __init__( ) if client_options.scopes: raise ValueError( - "When providing a transport instance, " - "provide its scopes directly." + "When providing a transport instance, provide its scopes " + "directly." ) self._transport = transport else: @@ -390,7 +393,6 @@ def process_document( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -419,10 +421,8 @@ def process_document( # there are no flattened fields. if not isinstance(request, document_processor_service.ProcessRequest): request = document_processor_service.ProcessRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -465,7 +465,6 @@ def batch_process_documents( This corresponds to the ``name`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -497,10 +496,8 @@ def batch_process_documents( # there are no flattened fields. if not isinstance(request, document_processor_service.BatchProcessRequest): request = document_processor_service.BatchProcessRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if name is not None: request.name = name @@ -552,7 +549,6 @@ def review_document( This corresponds to the ``human_review_config`` field on the ``request`` instance; if ``request`` is provided, this should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -584,10 +580,8 @@ def review_document( # there are no flattened fields. if not isinstance(request, document_processor_service.ReviewDocumentRequest): request = document_processor_service.ReviewDocumentRequest(request) - # If we have keyword arguments corresponding to fields on the # request, apply these. - if human_review_config is not None: request.human_review_config = human_review_config diff --git a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/__init__.py b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/__init__.py index e3e820b3..b9f737af 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/__init__.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from collections import OrderedDict from typing import Dict, Type diff --git a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/base.py b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/base.py index ebcbc6a9..0d7623ed 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/base.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/base.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,21 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import abc -import typing +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union +import packaging.version import pkg_resources -from google import auth # type: ignore -from google.api_core import exceptions # type: ignore +import google.auth # type: ignore +import google.api_core # type: ignore +from google.api_core import exceptions as core_exceptions # type: ignore from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.api_core import operations_v1 # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.cloud.documentai_v1beta3.types import document_processor_service -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( @@ -39,27 +38,41 @@ except pkg_resources.DistributionNotFound: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo() +try: + # google.auth.__version__ was added in 1.26.0 + _GOOGLE_AUTH_VERSION = google.auth.__version__ +except AttributeError: + try: # try pkg_resources if it is available + _GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version + except pkg_resources.DistributionNotFound: # pragma: NO COVER + _GOOGLE_AUTH_VERSION = None + +_API_CORE_VERSION = google.api_core.__version__ + class DocumentProcessorServiceTransport(abc.ABC): """Abstract transport class for DocumentProcessorService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) + DEFAULT_HOST: str = "documentai.googleapis.com" + def __init__( self, *, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, - credentials_file: typing.Optional[str] = None, - scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES, - quota_project_id: typing.Optional[str] = None, + host: str = DEFAULT_HOST, + credentials: ga_credentials.Credentials = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, **kwargs, ) -> None: """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -68,7 +81,7 @@ def __init__( credentials_file (Optional[str]): A file with credentials that can be loaded with :func:`google.auth.load_credentials_from_file`. This argument is mutually exclusive with credentials. - scope (Optional[Sequence[str]]): A list of scopes. + scopes (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. client_info (google.api_core.gapic_v1.client_info.ClientInfo): @@ -82,29 +95,76 @@ def __init__( host += ":443" self._host = host + scopes_kwargs = self._get_scopes_kwargs(self._host, scopes) + # Save the scopes. self._scopes = scopes or self.AUTH_SCOPES # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: - raise exceptions.DuplicateCredentialArgs( + raise core_exceptions.DuplicateCredentialArgs( "'credentials_file' and 'credentials' are mutually exclusive" ) if credentials_file is not None: - credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, **scopes_kwargs, quota_project_id=quota_project_id ) elif credentials is None: - credentials, _ = auth.default( - scopes=self._scopes, quota_project_id=quota_project_id + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials + # TODO(busunkim): These two class methods are in the base transport + # to avoid duplicating code across the transport classes. These functions + # should be deleted once the minimum required versions of google-api-core + # and google-auth are increased. + + # TODO: Remove this function once google-auth >= 1.25.0 is required + @classmethod + def _get_scopes_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Optional[Sequence[str]]]: + """Returns scopes kwargs to pass to google-auth methods depending on the google-auth version""" + + scopes_kwargs = {} + + if _GOOGLE_AUTH_VERSION and ( + packaging.version.parse(_GOOGLE_AUTH_VERSION) + >= packaging.version.parse("1.25.0") + ): + scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES} + else: + scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES} + + return scopes_kwargs + + # TODO: Remove this function once google-api-core >= 1.26.0 is required + @classmethod + def _get_self_signed_jwt_kwargs( + cls, host: str, scopes: Optional[Sequence[str]] + ) -> Dict[str, Union[Optional[Sequence[str]], str]]: + """Returns kwargs to pass to grpc_helpers.create_channel depending on the google-api-core version""" + + self_signed_jwt_kwargs: Dict[str, Union[Optional[Sequence[str]], str]] = {} + + if _API_CORE_VERSION and ( + packaging.version.parse(_API_CORE_VERSION) + >= packaging.version.parse("1.26.0") + ): + self_signed_jwt_kwargs["default_scopes"] = cls.AUTH_SCOPES + self_signed_jwt_kwargs["scopes"] = scopes + self_signed_jwt_kwargs["default_host"] = cls.DEFAULT_HOST + else: + self_signed_jwt_kwargs["scopes"] = scopes or cls.AUTH_SCOPES + + return self_signed_jwt_kwargs + def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { @@ -115,7 +175,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -129,7 +190,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -143,7 +205,8 @@ def _prep_wrapped_messages(self, client_info): maximum=60.0, multiplier=1.3, predicate=retries.if_exception_type( - exceptions.DeadlineExceeded, exceptions.ServiceUnavailable, + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, ), deadline=120.0, ), @@ -160,11 +223,11 @@ def operations_client(self) -> operations_v1.OperationsClient: @property def process_document( self, - ) -> typing.Callable[ + ) -> Callable[ [document_processor_service.ProcessRequest], - typing.Union[ + Union[ document_processor_service.ProcessResponse, - typing.Awaitable[document_processor_service.ProcessResponse], + Awaitable[document_processor_service.ProcessResponse], ], ]: raise NotImplementedError() @@ -172,18 +235,18 @@ def process_document( @property def batch_process_documents( self, - ) -> typing.Callable[ + ) -> Callable[ [document_processor_service.BatchProcessRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() @property def review_document( self, - ) -> typing.Callable[ + ) -> Callable[ [document_processor_service.ReviewDocumentRequest], - typing.Union[operations.Operation, typing.Awaitable[operations.Operation]], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], ]: raise NotImplementedError() diff --git a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc.py b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc.py index 24a3a7d4..3e00e89f 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,22 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple +from typing import Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import grpc_helpers # type: ignore from google.api_core import operations_v1 # type: ignore from google.api_core import gapic_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore import grpc # type: ignore from google.cloud.documentai_v1beta3.types import document_processor_service -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO @@ -55,8 +52,8 @@ class DocumentProcessorServiceGrpcTransport(DocumentProcessorServiceTransport): def __init__( self, *, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Sequence[str] = None, channel: grpc.Channel = None, @@ -70,7 +67,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -180,8 +178,8 @@ def __init__( @classmethod def create_channel( cls, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: str = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -212,13 +210,15 @@ def create_channel( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) @@ -275,7 +275,7 @@ def process_document( def batch_process_documents( self, ) -> Callable[ - [document_processor_service.BatchProcessRequest], operations.Operation + [document_processor_service.BatchProcessRequest], operations_pb2.Operation ]: r"""Return a callable for the batch process documents method over gRPC. @@ -296,7 +296,7 @@ def batch_process_documents( self._stubs["batch_process_documents"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1beta3.DocumentProcessorService/BatchProcessDocuments", request_serializer=document_processor_service.BatchProcessRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["batch_process_documents"] @@ -304,7 +304,7 @@ def batch_process_documents( def review_document( self, ) -> Callable[ - [document_processor_service.ReviewDocumentRequest], operations.Operation + [document_processor_service.ReviewDocumentRequest], operations_pb2.Operation ]: r"""Return a callable for the review document method over gRPC. @@ -325,7 +325,7 @@ def review_document( self._stubs["review_document"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1beta3.DocumentProcessorService/ReviewDocument", request_serializer=document_processor_service.ReviewDocumentRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["review_document"] diff --git a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc_asyncio.py b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc_asyncio.py index 99249da3..84c7318a 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc_asyncio.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc_asyncio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,23 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union from google.api_core import gapic_v1 # type: ignore from google.api_core import grpc_helpers_async # type: ignore from google.api_core import operations_v1 # type: ignore -from google import auth # type: ignore -from google.auth import credentials # type: ignore +from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore +import packaging.version import grpc # type: ignore from grpc.experimental import aio # type: ignore from google.cloud.documentai_v1beta3.types import document_processor_service -from google.longrunning import operations_pb2 as operations # type: ignore - +from google.longrunning import operations_pb2 # type: ignore from .base import DocumentProcessorServiceTransport, DEFAULT_CLIENT_INFO from .grpc import DocumentProcessorServiceGrpcTransport @@ -58,8 +55,8 @@ class DocumentProcessorServiceGrpcAsyncIOTransport(DocumentProcessorServiceTrans @classmethod def create_channel( cls, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, quota_project_id: Optional[str] = None, @@ -86,21 +83,23 @@ def create_channel( Returns: aio.Channel: A gRPC AsyncIO channel object. """ - scopes = scopes or cls.AUTH_SCOPES + + self_signed_jwt_kwargs = cls._get_self_signed_jwt_kwargs(host, scopes) + return grpc_helpers_async.create_channel( host, credentials=credentials, credentials_file=credentials_file, - scopes=scopes, quota_project_id=quota_project_id, + **self_signed_jwt_kwargs, **kwargs, ) def __init__( self, *, - host: str = "us-documentai.googleapis.com", - credentials: credentials.Credentials = None, + host: str = "documentai.googleapis.com", + credentials: ga_credentials.Credentials = None, credentials_file: Optional[str] = None, scopes: Optional[Sequence[str]] = None, channel: aio.Channel = None, @@ -114,7 +113,8 @@ def __init__( """Instantiate the transport. Args: - host (Optional[str]): The hostname to connect to. + host (Optional[str]): + The hostname to connect to. credentials (Optional[google.auth.credentials.Credentials]): The authorization credentials to attach to requests. These credentials identify the application to the service; if none @@ -173,7 +173,6 @@ def __init__( # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - else: if api_mtls_endpoint: host = api_mtls_endpoint @@ -282,7 +281,7 @@ def batch_process_documents( self, ) -> Callable[ [document_processor_service.BatchProcessRequest], - Awaitable[operations.Operation], + Awaitable[operations_pb2.Operation], ]: r"""Return a callable for the batch process documents method over gRPC. @@ -303,7 +302,7 @@ def batch_process_documents( self._stubs["batch_process_documents"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1beta3.DocumentProcessorService/BatchProcessDocuments", request_serializer=document_processor_service.BatchProcessRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["batch_process_documents"] @@ -312,7 +311,7 @@ def review_document( self, ) -> Callable[ [document_processor_service.ReviewDocumentRequest], - Awaitable[operations.Operation], + Awaitable[operations_pb2.Operation], ]: r"""Return a callable for the review document method over gRPC. @@ -333,7 +332,7 @@ def review_document( self._stubs["review_document"] = self.grpc_channel.unary_unary( "/google.cloud.documentai.v1beta3.DocumentProcessorService/ReviewDocument", request_serializer=document_processor_service.ReviewDocumentRequest.serialize, - response_deserializer=operations.Operation.FromString, + response_deserializer=operations_pb2.Operation.FromString, ) return self._stubs["review_document"] diff --git a/google/cloud/documentai_v1beta3/types/__init__.py b/google/cloud/documentai_v1beta3/types/__init__.py index 0d60bd37..2be40a09 100644 --- a/google/cloud/documentai_v1beta3/types/__init__.py +++ b/google/cloud/documentai_v1beta3/types/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - from .document import Document from .document_io import ( BatchDocumentsInputConfig, diff --git a/google/cloud/documentai_v1beta3/types/document.py b/google/cloud/documentai_v1beta3/types/document.py index 3290e2dc..bb808541 100644 --- a/google/cloud/documentai_v1beta3/types/document.py +++ b/google/cloud/documentai_v1beta3/types/document.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,18 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.cloud.documentai_v1beta3.types import geometry -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as status # type: ignore -from google.type import color_pb2 as gt_color # type: ignore -from google.type import date_pb2 as date # type: ignore -from google.type import datetime_pb2 as datetime # type: ignore -from google.type import money_pb2 as money # type: ignore -from google.type import postal_address_pb2 as postal_address # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import date_pb2 # type: ignore +from google.type import datetime_pb2 # type: ignore +from google.type import money_pb2 # type: ignore +from google.type import postal_address_pb2 # type: ignore __protobuf__ = proto.module( @@ -107,11 +104,9 @@ class ShardInfo(proto.Message): in the overall document global text. """ - shard_index = proto.Field(proto.INT64, number=1) - - shard_count = proto.Field(proto.INT64, number=2) - - text_offset = proto.Field(proto.INT64, number=3) + shard_index = proto.Field(proto.INT64, number=1,) + shard_count = proto.Field(proto.INT64, number=2,) + text_offset = proto.Field(proto.INT64, number=3,) class Style(proto.Message): r"""Annotation for common text style attributes. This adheres to @@ -140,7 +135,6 @@ class Style(proto.Message): class FontSize(proto.Message): r"""Font size with unit. - Attributes: size (float): Font size for the text. @@ -149,31 +143,25 @@ class FontSize(proto.Message): (in, px, pt, etc.). """ - size = proto.Field(proto.FLOAT, number=1) - - unit = proto.Field(proto.STRING, number=2) + size = proto.Field(proto.FLOAT, number=1,) + unit = proto.Field(proto.STRING, number=2,) text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - color = proto.Field(proto.MESSAGE, number=2, message=gt_color.Color,) - - background_color = proto.Field(proto.MESSAGE, number=3, message=gt_color.Color,) - - font_weight = proto.Field(proto.STRING, number=4) - - text_style = proto.Field(proto.STRING, number=5) - - text_decoration = proto.Field(proto.STRING, number=6) - + color = proto.Field(proto.MESSAGE, number=2, message=color_pb2.Color,) + background_color = proto.Field( + proto.MESSAGE, number=3, message=color_pb2.Color, + ) + font_weight = proto.Field(proto.STRING, number=4,) + text_style = proto.Field(proto.STRING, number=5,) + text_decoration = proto.Field(proto.STRING, number=6,) font_size = proto.Field( proto.MESSAGE, number=7, message="Document.Style.FontSize", ) class Page(proto.Message): r"""A page in a [Document][google.cloud.documentai.v1beta3.Document]. - Attributes: page_number (int): 1-based index for current @@ -228,7 +216,6 @@ class Page(proto.Message): class Dimension(proto.Message): r"""Dimension for the page. - Attributes: width (float): Page width. @@ -238,15 +225,12 @@ class Dimension(proto.Message): Dimension unit. """ - width = proto.Field(proto.FLOAT, number=1) - - height = proto.Field(proto.FLOAT, number=2) - - unit = proto.Field(proto.STRING, number=3) + width = proto.Field(proto.FLOAT, number=1,) + height = proto.Field(proto.FLOAT, number=2,) + unit = proto.Field(proto.STRING, number=3,) class Image(proto.Message): r"""Rendered image contents for this page. - Attributes: content (bytes): Raw byte content of the image. @@ -258,13 +242,10 @@ class Image(proto.Message): Height of the image in pixels. """ - content = proto.Field(proto.BYTES, number=1) - - mime_type = proto.Field(proto.STRING, number=2) - - width = proto.Field(proto.INT32, number=3) - - height = proto.Field(proto.INT32, number=4) + content = proto.Field(proto.BYTES, number=1,) + mime_type = proto.Field(proto.STRING, number=2,) + width = proto.Field(proto.INT32, number=3,) + height = proto.Field(proto.INT32, number=4,) class Matrix(proto.Message): r"""Representation for transformation matrix, intended to be @@ -285,17 +266,13 @@ class Matrix(proto.Message): The matrix data. """ - rows = proto.Field(proto.INT32, number=1) - - cols = proto.Field(proto.INT32, number=2) - - type_ = proto.Field(proto.INT32, number=3) - - data = proto.Field(proto.BYTES, number=4) + rows = proto.Field(proto.INT32, number=1,) + cols = proto.Field(proto.INT32, number=2,) + type_ = proto.Field(proto.INT32, number=3,) + data = proto.Field(proto.BYTES, number=4,) class Layout(proto.Message): r"""Visual element describing a layout unit on a page. - Attributes: text_anchor (google.cloud.documentai_v1beta3.types.Document.TextAnchor): Text anchor indexing into the @@ -325,13 +302,10 @@ class Orientation(proto.Enum): text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - confidence = proto.Field(proto.FLOAT, number=2) - + confidence = proto.Field(proto.FLOAT, number=2,) bounding_poly = proto.Field( proto.MESSAGE, number=3, message=geometry.BoundingPoly, ) - orientation = proto.Field( proto.ENUM, number=4, enum="Document.Page.Layout.Orientation", ) @@ -355,11 +329,9 @@ class Block(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=3, message="Document.Provenance", ) @@ -383,11 +355,9 @@ class Paragraph(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=3, message="Document.Provenance", ) @@ -412,18 +382,15 @@ class Line(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=3, message="Document.Provenance", ) class Token(proto.Message): r"""A detected token. - Attributes: layout (google.cloud.documentai_v1beta3.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta3.Document.Page.Layout] @@ -462,15 +429,12 @@ class Type(proto.Enum): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - detected_break = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Token.DetectedBreak", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) - provenance = proto.Field( proto.MESSAGE, number=4, message="Document.Provenance", ) @@ -495,16 +459,13 @@ class VisualElement(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - - type_ = proto.Field(proto.STRING, number=2) - + type_ = proto.Field(proto.STRING, number=2,) detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) class Table(proto.Message): r"""A table representation similar to HTML table structure. - Attributes: layout (google.cloud.documentai_v1beta3.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta3.Document.Page.Layout] @@ -521,7 +482,6 @@ class Table(proto.Message): class TableRow(proto.Message): r"""A row of table cells. - Attributes: cells (Sequence[google.cloud.documentai_v1beta3.types.Document.Page.Table.TableCell]): Cells that make up this row. @@ -533,7 +493,6 @@ class TableRow(proto.Message): class TableCell(proto.Message): r"""A cell representation inside the table. - Attributes: layout (google.cloud.documentai_v1beta3.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta3.Document.Page.Layout] @@ -551,11 +510,8 @@ class TableCell(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - - row_span = proto.Field(proto.INT32, number=2) - - col_span = proto.Field(proto.INT32, number=3) - + row_span = proto.Field(proto.INT32, number=2,) + col_span = proto.Field(proto.INT32, number=3,) detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) @@ -563,22 +519,18 @@ class TableCell(proto.Message): layout = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - header_rows = proto.RepeatedField( proto.MESSAGE, number=2, message="Document.Page.Table.TableRow", ) - body_rows = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.Table.TableRow", ) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) class FormField(proto.Message): r"""A form field detected on the page. - Attributes: field_name (google.cloud.documentai_v1beta3.types.Document.Page.Layout): [Layout][google.cloud.documentai.v1beta3.Document.Page.Layout] @@ -609,24 +561,19 @@ class FormField(proto.Message): field_name = proto.Field( proto.MESSAGE, number=1, message="Document.Page.Layout", ) - field_value = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Layout", ) - name_detected_languages = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Page.DetectedLanguage", ) - value_detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) - - value_type = proto.Field(proto.STRING, number=5) + value_type = proto.Field(proto.STRING, number=5,) class DetectedLanguage(proto.Message): r"""Detected language for a structural component. - Attributes: language_code (str): The BCP-47 language code, such as "en-US" or "sr-Latn". For @@ -636,52 +583,39 @@ class DetectedLanguage(proto.Message): Confidence of detected language. Range [0, 1]. """ - language_code = proto.Field(proto.STRING, number=1) - - confidence = proto.Field(proto.FLOAT, number=2) - - page_number = proto.Field(proto.INT32, number=1) + language_code = proto.Field(proto.STRING, number=1,) + confidence = proto.Field(proto.FLOAT, number=2,) + page_number = proto.Field(proto.INT32, number=1,) image = proto.Field(proto.MESSAGE, number=13, message="Document.Page.Image",) - transforms = proto.RepeatedField( proto.MESSAGE, number=14, message="Document.Page.Matrix", ) - dimension = proto.Field( proto.MESSAGE, number=2, message="Document.Page.Dimension", ) - layout = proto.Field(proto.MESSAGE, number=3, message="Document.Page.Layout",) - detected_languages = proto.RepeatedField( proto.MESSAGE, number=4, message="Document.Page.DetectedLanguage", ) - blocks = proto.RepeatedField( proto.MESSAGE, number=5, message="Document.Page.Block", ) - paragraphs = proto.RepeatedField( proto.MESSAGE, number=6, message="Document.Page.Paragraph", ) - lines = proto.RepeatedField( proto.MESSAGE, number=7, message="Document.Page.Line", ) - tokens = proto.RepeatedField( proto.MESSAGE, number=8, message="Document.Page.Token", ) - visual_elements = proto.RepeatedField( proto.MESSAGE, number=9, message="Document.Page.VisualElement", ) - tables = proto.RepeatedField( proto.MESSAGE, number=10, message="Document.Page.Table", ) - form_fields = proto.RepeatedField( proto.MESSAGE, number=11, message="Document.Page.FormField", ) @@ -731,7 +665,6 @@ class Entity(proto.Message): class NormalizedValue(proto.Message): r"""Parsed and normalized entity value. - Attributes: money_value (google.type.money_pb2.Money): Money value. See also: @@ -765,62 +698,53 @@ class NormalizedValue(proto.Message): """ money_value = proto.Field( - proto.MESSAGE, number=2, oneof="structured_value", message=money.Money, + proto.MESSAGE, + number=2, + oneof="structured_value", + message=money_pb2.Money, ) - date_value = proto.Field( - proto.MESSAGE, number=3, oneof="structured_value", message=date.Date, + proto.MESSAGE, + number=3, + oneof="structured_value", + message=date_pb2.Date, ) - datetime_value = proto.Field( proto.MESSAGE, number=4, oneof="structured_value", - message=datetime.DateTime, + message=datetime_pb2.DateTime, ) - address_value = proto.Field( proto.MESSAGE, number=5, oneof="structured_value", - message=postal_address.PostalAddress, + message=postal_address_pb2.PostalAddress, ) - - boolean_value = proto.Field(proto.BOOL, number=6, oneof="structured_value") - - text = proto.Field(proto.STRING, number=1) + boolean_value = proto.Field(proto.BOOL, number=6, oneof="structured_value",) + text = proto.Field(proto.STRING, number=1,) text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - type_ = proto.Field(proto.STRING, number=2) - - mention_text = proto.Field(proto.STRING, number=3) - - mention_id = proto.Field(proto.STRING, number=4) - - confidence = proto.Field(proto.FLOAT, number=5) - + type_ = proto.Field(proto.STRING, number=2,) + mention_text = proto.Field(proto.STRING, number=3,) + mention_id = proto.Field(proto.STRING, number=4,) + confidence = proto.Field(proto.FLOAT, number=5,) page_anchor = proto.Field( proto.MESSAGE, number=6, message="Document.PageAnchor", ) - - id = proto.Field(proto.STRING, number=7) - + id = proto.Field(proto.STRING, number=7,) normalized_value = proto.Field( proto.MESSAGE, number=9, message="Document.Entity.NormalizedValue", ) - properties = proto.RepeatedField( proto.MESSAGE, number=10, message="Document.Entity", ) - provenance = proto.Field( proto.MESSAGE, number=11, message="Document.Provenance", ) - - redacted = proto.Field(proto.BOOL, number=12) + redacted = proto.Field(proto.BOOL, number=12,) class EntityRelation(proto.Message): r"""Relationship between @@ -835,11 +759,9 @@ class EntityRelation(proto.Message): Relationship description. """ - subject_id = proto.Field(proto.STRING, number=1) - - object_id = proto.Field(proto.STRING, number=2) - - relation = proto.Field(proto.STRING, number=3) + subject_id = proto.Field(proto.STRING, number=1,) + object_id = proto.Field(proto.STRING, number=2,) + relation = proto.Field(proto.STRING, number=3,) class TextAnchor(proto.Message): r"""Text reference indexing into the @@ -872,15 +794,13 @@ class TextSegment(proto.Message): [Document.text][google.cloud.documentai.v1beta3.Document.text]. """ - start_index = proto.Field(proto.INT64, number=1) - - end_index = proto.Field(proto.INT64, number=2) + start_index = proto.Field(proto.INT64, number=1,) + end_index = proto.Field(proto.INT64, number=2,) text_segments = proto.RepeatedField( proto.MESSAGE, number=1, message="Document.TextAnchor.TextSegment", ) - - content = proto.Field(proto.STRING, number=2) + content = proto.Field(proto.STRING, number=2,) class PageAnchor(proto.Message): r"""Referencing the visual context of the entity in the @@ -914,6 +834,9 @@ class PageRef(proto.Message): bounding_poly (google.cloud.documentai_v1beta3.types.BoundingPoly): Optional. Identifies the bounding polygon of a layout element on the page. + confidence (float): + Optional. Confidence of detected page element, if + applicable. Range [0, 1]. """ class LayoutType(proto.Enum): @@ -927,17 +850,15 @@ class LayoutType(proto.Enum): TABLE = 6 FORM_FIELD = 7 - page = proto.Field(proto.INT64, number=1) - + page = proto.Field(proto.INT64, number=1,) layout_type = proto.Field( proto.ENUM, number=2, enum="Document.PageAnchor.PageRef.LayoutType", ) - - layout_id = proto.Field(proto.STRING, number=3) - + layout_id = proto.Field(proto.STRING, number=3,) bounding_poly = proto.Field( proto.MESSAGE, number=4, message=geometry.BoundingPoly, ) + confidence = proto.Field(proto.FLOAT, number=5,) page_refs = proto.RepeatedField( proto.MESSAGE, number=1, message="Document.PageAnchor.PageRef", @@ -986,25 +907,20 @@ class Parent(proto.Message): The id of the parent provenance. """ - revision = proto.Field(proto.INT32, number=1) - - id = proto.Field(proto.INT32, number=2) - - revision = proto.Field(proto.INT32, number=1) - - id = proto.Field(proto.INT32, number=2) + revision = proto.Field(proto.INT32, number=1,) + id = proto.Field(proto.INT32, number=2,) + revision = proto.Field(proto.INT32, number=1,) + id = proto.Field(proto.INT32, number=2,) parents = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Provenance.Parent", ) - type_ = proto.Field( proto.ENUM, number=4, enum="Document.Provenance.OperationType", ) class Revision(proto.Message): r"""Contains past or forward revisions of this document. - Attributes: agent (str): If the change was made by a person specify @@ -1027,7 +943,6 @@ class Revision(proto.Message): class HumanReview(proto.Message): r"""Human Review information of the document. - Attributes: state (str): Human review state. e.g. ``requested``, ``succeeded``, @@ -1038,27 +953,22 @@ class HumanReview(proto.Message): is ``rejected``. """ - state = proto.Field(proto.STRING, number=1) - - state_message = proto.Field(proto.STRING, number=2) - - agent = proto.Field(proto.STRING, number=4, oneof="source") - - processor = proto.Field(proto.STRING, number=5, oneof="source") - - id = proto.Field(proto.STRING, number=1) - - parent = proto.RepeatedField(proto.INT32, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) + state = proto.Field(proto.STRING, number=1,) + state_message = proto.Field(proto.STRING, number=2,) + agent = proto.Field(proto.STRING, number=4, oneof="source",) + processor = proto.Field(proto.STRING, number=5, oneof="source",) + id = proto.Field(proto.STRING, number=1,) + parent = proto.RepeatedField(proto.INT32, number=2,) + create_time = proto.Field( + proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp, + ) human_review = proto.Field( proto.MESSAGE, number=6, message="Document.Revision.HumanReview", ) class TextChange(proto.Message): r"""This message is used for text changes aka. OCR corrections. - Attributes: text_anchor (google.cloud.documentai_v1beta3.types.Document.TextAnchor): Provenance of the correction. Text anchor indexing into the @@ -1076,37 +986,24 @@ class TextChange(proto.Message): text_anchor = proto.Field( proto.MESSAGE, number=1, message="Document.TextAnchor", ) - - changed_text = proto.Field(proto.STRING, number=2) - + changed_text = proto.Field(proto.STRING, number=2,) provenance = proto.RepeatedField( proto.MESSAGE, number=3, message="Document.Provenance", ) - uri = proto.Field(proto.STRING, number=1, oneof="source") - - content = proto.Field(proto.BYTES, number=2, oneof="source") - - mime_type = proto.Field(proto.STRING, number=3) - - text = proto.Field(proto.STRING, number=4) - + uri = proto.Field(proto.STRING, number=1, oneof="source",) + content = proto.Field(proto.BYTES, number=2, oneof="source",) + mime_type = proto.Field(proto.STRING, number=3,) + text = proto.Field(proto.STRING, number=4,) text_styles = proto.RepeatedField(proto.MESSAGE, number=5, message=Style,) - pages = proto.RepeatedField(proto.MESSAGE, number=6, message=Page,) - entities = proto.RepeatedField(proto.MESSAGE, number=7, message=Entity,) - entity_relations = proto.RepeatedField( proto.MESSAGE, number=8, message=EntityRelation, ) - text_changes = proto.RepeatedField(proto.MESSAGE, number=14, message=TextChange,) - shard_info = proto.Field(proto.MESSAGE, number=9, message=ShardInfo,) - - error = proto.Field(proto.MESSAGE, number=10, message=status.Status,) - + error = proto.Field(proto.MESSAGE, number=10, message=status_pb2.Status,) revisions = proto.RepeatedField(proto.MESSAGE, number=13, message=Revision,) diff --git a/google/cloud/documentai_v1beta3/types/document_io.py b/google/cloud/documentai_v1beta3/types/document_io.py index 37928c86..cf61f907 100644 --- a/google/cloud/documentai_v1beta3/types/document_io.py +++ b/google/cloud/documentai_v1beta3/types/document_io.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -33,7 +31,6 @@ class RawDocument(proto.Message): r"""Payload message of raw document content (bytes). - Attributes: content (bytes): Inline document content. @@ -42,14 +39,12 @@ class RawDocument(proto.Message): of the [content]. """ - content = proto.Field(proto.BYTES, number=1) - - mime_type = proto.Field(proto.STRING, number=2) + content = proto.Field(proto.BYTES, number=1,) + mime_type = proto.Field(proto.STRING, number=2,) class GcsDocument(proto.Message): r"""Specifies a document stored on Cloud Storage. - Attributes: gcs_uri (str): The Cloud Storage object uri. @@ -57,14 +52,12 @@ class GcsDocument(proto.Message): An IANA MIME type (RFC6838) of the content. """ - gcs_uri = proto.Field(proto.STRING, number=1) - - mime_type = proto.Field(proto.STRING, number=2) + gcs_uri = proto.Field(proto.STRING, number=1,) + mime_type = proto.Field(proto.STRING, number=2,) class GcsDocuments(proto.Message): r"""Specifies a set of documents on Cloud Storage. - Attributes: documents (Sequence[google.cloud.documentai_v1beta3.types.GcsDocument]): The list of documents. @@ -82,7 +75,7 @@ class GcsPrefix(proto.Message): The URI prefix. """ - gcs_uri_prefix = proto.Field(proto.STRING, number=1) + gcs_uri_prefix = proto.Field(proto.STRING, number=1,) class BatchDocumentsInputConfig(proto.Message): @@ -101,7 +94,6 @@ class BatchDocumentsInputConfig(proto.Message): gcs_prefix = proto.Field( proto.MESSAGE, number=1, oneof="source", message="GcsPrefix", ) - gcs_documents = proto.Field( proto.MESSAGE, number=2, oneof="source", message="GcsDocuments", ) @@ -119,14 +111,13 @@ class DocumentOutputConfig(proto.Message): class GcsOutputConfig(proto.Message): r"""The configuration used when outputting documents. - Attributes: gcs_uri (str): The Cloud Storage uri (a directory) of the output. """ - gcs_uri = proto.Field(proto.STRING, number=1) + gcs_uri = proto.Field(proto.STRING, number=1,) gcs_output_config = proto.Field( proto.MESSAGE, number=1, oneof="destination", message=GcsOutputConfig, diff --git a/google/cloud/documentai_v1beta3/types/document_processor_service.py b/google/cloud/documentai_v1beta3/types/document_processor_service.py index 3e025e8a..98d32cd7 100644 --- a/google/cloud/documentai_v1beta3/types/document_processor_service.py +++ b/google/cloud/documentai_v1beta3/types/document_processor_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,14 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore - from google.cloud.documentai_v1beta3.types import document as gcd_document from google.cloud.documentai_v1beta3.types import document_io -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.rpc import status_pb2 as gr_status # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( @@ -43,7 +40,6 @@ class ProcessRequest(proto.Message): r"""Request message for the process document method. - Attributes: inline_document (google.cloud.documentai_v1beta3.types.Document): An inline document proto. @@ -62,21 +58,16 @@ class ProcessRequest(proto.Message): inline_document = proto.Field( proto.MESSAGE, number=4, oneof="source", message=gcd_document.Document, ) - raw_document = proto.Field( proto.MESSAGE, number=5, oneof="source", message=document_io.RawDocument, ) - - name = proto.Field(proto.STRING, number=1) - + name = proto.Field(proto.STRING, number=1,) document = proto.Field(proto.MESSAGE, number=2, message=gcd_document.Document,) - - skip_human_review = proto.Field(proto.BOOL, number=3) + skip_human_review = proto.Field(proto.BOOL, number=3,) class HumanReviewStatus(proto.Message): r"""The status of human review on a processed document. - Attributes: state (google.cloud.documentai_v1beta3.types.HumanReviewStatus.State): The state of human review on the processing @@ -101,15 +92,12 @@ class State(proto.Enum): ERROR = 4 state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - human_review_operation = proto.Field(proto.STRING, number=3) + state_message = proto.Field(proto.STRING, number=2,) + human_review_operation = proto.Field(proto.STRING, number=3,) class ProcessResponse(proto.Message): r"""Response message for the process document method. - Attributes: document (google.cloud.documentai_v1beta3.types.Document): The document payload, will populate fields @@ -127,9 +115,7 @@ class ProcessResponse(proto.Message): """ document = proto.Field(proto.MESSAGE, number=1, message=gcd_document.Document,) - - human_review_operation = proto.Field(proto.STRING, number=2) - + human_review_operation = proto.Field(proto.STRING, number=2,) human_review_status = proto.Field( proto.MESSAGE, number=3, message="HumanReviewStatus", ) @@ -137,7 +123,6 @@ class ProcessResponse(proto.Message): class BatchProcessRequest(proto.Message): r"""Request message for batch process document method. - Attributes: name (str): Required. The processor resource name. @@ -157,7 +142,6 @@ class BatchProcessRequest(proto.Message): class BatchInputConfig(proto.Message): r"""The message for input config in batch process. - Attributes: gcs_source (str): The Cloud Storage location as the source of @@ -169,47 +153,39 @@ class BatchInputConfig(proto.Message): should be application/json. """ - gcs_source = proto.Field(proto.STRING, number=1) - - mime_type = proto.Field(proto.STRING, number=2) + gcs_source = proto.Field(proto.STRING, number=1,) + mime_type = proto.Field(proto.STRING, number=2,) class BatchOutputConfig(proto.Message): r"""The message for output config in batch process. - Attributes: gcs_destination (str): The output Cloud Storage directory to put the processed documents. """ - gcs_destination = proto.Field(proto.STRING, number=1) - - name = proto.Field(proto.STRING, number=1) + gcs_destination = proto.Field(proto.STRING, number=1,) + name = proto.Field(proto.STRING, number=1,) input_configs = proto.RepeatedField( proto.MESSAGE, number=2, message=BatchInputConfig, ) - output_config = proto.Field(proto.MESSAGE, number=3, message=BatchOutputConfig,) - input_documents = proto.Field( proto.MESSAGE, number=5, message=document_io.BatchDocumentsInputConfig, ) - document_output_config = proto.Field( proto.MESSAGE, number=6, message=document_io.DocumentOutputConfig, ) - - skip_human_review = proto.Field(proto.BOOL, number=4) + skip_human_review = proto.Field(proto.BOOL, number=4,) class BatchProcessResponse(proto.Message): - r"""Response message for batch process document method.""" + r"""Response message for batch process document method. """ class BatchProcessMetadata(proto.Message): r"""The long running operation metadata for batch process method. - Attributes: state (google.cloud.documentai_v1beta3.types.BatchProcessMetadata.State): The state of the current batch processing. @@ -265,26 +241,18 @@ class IndividualProcessStatus(proto.Message): document. """ - input_gcs_source = proto.Field(proto.STRING, number=1) - - status = proto.Field(proto.MESSAGE, number=2, message=gr_status.Status,) - - output_gcs_destination = proto.Field(proto.STRING, number=3) - - human_review_operation = proto.Field(proto.STRING, number=4) - + input_gcs_source = proto.Field(proto.STRING, number=1,) + status = proto.Field(proto.MESSAGE, number=2, message=status_pb2.Status,) + output_gcs_destination = proto.Field(proto.STRING, number=3,) + human_review_operation = proto.Field(proto.STRING, number=4,) human_review_status = proto.Field( proto.MESSAGE, number=5, message="HumanReviewStatus", ) state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) - + state_message = proto.Field(proto.STRING, number=2,) + create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) individual_process_statuses = proto.RepeatedField( proto.MESSAGE, number=5, message=IndividualProcessStatus, ) @@ -292,7 +260,6 @@ class IndividualProcessStatus(proto.Message): class ReviewDocumentRequest(proto.Message): r"""Request message for review document method. - Attributes: inline_document (google.cloud.documentai_v1beta3.types.Document): An inline document proto. @@ -307,22 +274,19 @@ class ReviewDocumentRequest(proto.Message): inline_document = proto.Field( proto.MESSAGE, number=4, oneof="source", message=gcd_document.Document, ) - - human_review_config = proto.Field(proto.STRING, number=1) - + human_review_config = proto.Field(proto.STRING, number=1,) document = proto.Field(proto.MESSAGE, number=2, message=gcd_document.Document,) class ReviewDocumentResponse(proto.Message): r"""Response message for review document method. - Attributes: gcs_destination (str): The Cloud Storage uri for the human reviewed document. """ - gcs_destination = proto.Field(proto.STRING, number=1) + gcs_destination = proto.Field(proto.STRING, number=1,) class ReviewDocumentOperationMetadata(proto.Message): @@ -355,13 +319,9 @@ class State(proto.Enum): CANCELLED = 5 state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) - + state_message = proto.Field(proto.STRING, number=2,) + create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) common_metadata = proto.Field( proto.MESSAGE, number=5, message="CommonOperationMetadata", ) @@ -369,7 +329,6 @@ class State(proto.Enum): class CommonOperationMetadata(proto.Message): r"""The common metadata for long running operations. - Attributes: state (google.cloud.documentai_v1beta3.types.CommonOperationMetadata.State): The state of the operation. @@ -392,12 +351,9 @@ class State(proto.Enum): CANCELLED = 5 state = proto.Field(proto.ENUM, number=1, enum=State,) - - state_message = proto.Field(proto.STRING, number=2) - - create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp.Timestamp,) - - update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,) + state_message = proto.Field(proto.STRING, number=2,) + create_time = proto.Field(proto.MESSAGE, number=3, message=timestamp_pb2.Timestamp,) + update_time = proto.Field(proto.MESSAGE, number=4, message=timestamp_pb2.Timestamp,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/documentai_v1beta3/types/geometry.py b/google/cloud/documentai_v1beta3/types/geometry.py index 53c3b9b0..73418c96 100644 --- a/google/cloud/documentai_v1beta3/types/geometry.py +++ b/google/cloud/documentai_v1beta3/types/geometry.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import proto # type: ignore @@ -36,9 +34,8 @@ class Vertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.INT32, number=1) - - y = proto.Field(proto.INT32, number=2) + x = proto.Field(proto.INT32, number=1,) + y = proto.Field(proto.INT32, number=2,) class NormalizedVertex(proto.Message): @@ -53,14 +50,12 @@ class NormalizedVertex(proto.Message): Y coordinate. """ - x = proto.Field(proto.FLOAT, number=1) - - y = proto.Field(proto.FLOAT, number=2) + x = proto.Field(proto.FLOAT, number=1,) + y = proto.Field(proto.FLOAT, number=2,) class BoundingPoly(proto.Message): r"""A bounding polygon for the detected image annotation. - Attributes: vertices (Sequence[google.cloud.documentai_v1beta3.types.Vertex]): The bounding polygon vertices. @@ -69,7 +64,6 @@ class BoundingPoly(proto.Message): """ vertices = proto.RepeatedField(proto.MESSAGE, number=1, message="Vertex",) - normalized_vertices = proto.RepeatedField( proto.MESSAGE, number=2, message="NormalizedVertex", ) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..4de65971 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 00000000..4de65971 --- /dev/null +++ b/tests/unit/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/gapic/__init__.py b/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..4de65971 --- /dev/null +++ b/tests/unit/gapic/__init__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 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. +# diff --git a/tests/unit/gapic/documentai_v1/__init__.py b/tests/unit/gapic/documentai_v1/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/documentai_v1/__init__.py +++ b/tests/unit/gapic/documentai_v1/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/documentai_v1/test_document_processor_service.py b/tests/unit/gapic/documentai_v1/test_document_processor_service.py index b48bdc60..b68164f2 100644 --- a/tests/unit/gapic/documentai_v1/test_document_processor_service.py +++ b/tests/unit/gapic/documentai_v1/test_document_processor_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule -from google import auth + from google.api_core import client_options -from google.api_core import exceptions +from google.api_core import exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.documentai_v1.services.document_processor_service import ( DocumentProcessorServiceAsyncClient, @@ -42,22 +41,52 @@ DocumentProcessorServiceClient, ) from google.cloud.documentai_v1.services.document_processor_service import transports +from google.cloud.documentai_v1.services.document_processor_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.documentai_v1.services.document_processor_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.documentai_v1.types import document from google.cloud.documentai_v1.types import document_io from google.cloud.documentai_v1.types import document_processor_service from google.cloud.documentai_v1.types import geometry from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.protobuf import any_pb2 as gp_any # type: ignore -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.protobuf import wrappers_pb2 as wrappers # type: ignore -from google.rpc import status_pb2 as status # type: ignore -from google.type import color_pb2 as color # type: ignore -from google.type import date_pb2 as date # type: ignore -from google.type import datetime_pb2 as datetime # type: ignore -from google.type import money_pb2 as money # type: ignore -from google.type import postal_address_pb2 as postal_address # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import date_pb2 # type: ignore +from google.type import datetime_pb2 # type: ignore +from google.type import money_pb2 # type: ignore +from google.type import postal_address_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and auth "less than" test cases +# - Delete these pytest markers (Make the "greater than or equal to" tests the default). +requires_google_auth_lt_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), + reason="This test requires google-auth < 1.25.0", +) +requires_google_auth_gte_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), + reason="This test requires google-auth >= 1.25.0", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -110,7 +139,7 @@ def test__get_default_mtls_endpoint(): [DocumentProcessorServiceClient, DocumentProcessorServiceAsyncClient,], ) def test_document_processor_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -120,7 +149,7 @@ def test_document_processor_service_client_from_service_account_info(client_clas assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == "us-documentai.googleapis.com:443" + assert client.transport._host == "documentai.googleapis.com:443" @pytest.mark.parametrize( @@ -128,7 +157,7 @@ def test_document_processor_service_client_from_service_account_info(client_clas [DocumentProcessorServiceClient, DocumentProcessorServiceAsyncClient,], ) def test_document_processor_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -141,7 +170,7 @@ def test_document_processor_service_client_from_service_account_file(client_clas assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == "us-documentai.googleapis.com:443" + assert client.transport._host == "documentai.googleapis.com:443" def test_document_processor_service_client_get_transport_class(): @@ -187,7 +216,7 @@ def test_document_processor_service_client_client_options( with mock.patch.object( DocumentProcessorServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -495,7 +524,7 @@ def test_process_document( transport: str = "grpc", request_type=document_processor_service.ProcessRequest ): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -506,17 +535,14 @@ def test_process_document( with mock.patch.object(type(client.transport.process_document), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = document_processor_service.ProcessResponse() - response = client.process_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ProcessRequest() # Establish that the response is the type that we expect. - assert isinstance(response, document_processor_service.ProcessResponse) @@ -528,7 +554,7 @@ def test_process_document_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -536,7 +562,6 @@ def test_process_document_empty_call(): client.process_document() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ProcessRequest() @@ -546,7 +571,7 @@ async def test_process_document_async( request_type=document_processor_service.ProcessRequest, ): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -559,13 +584,11 @@ async def test_process_document_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( document_processor_service.ProcessResponse() ) - response = await client.process_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ProcessRequest() # Establish that the response is the type that we expect. @@ -579,18 +602,18 @@ async def test_process_document_async_from_dict(): def test_process_document_field_headers(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.process_document), "__call__") as call: call.return_value = document_processor_service.ProcessResponse() - client.process_document(request) # Establish that the underlying gRPC stub method was called. @@ -606,12 +629,13 @@ def test_process_document_field_headers(): @pytest.mark.asyncio async def test_process_document_field_headers_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -619,7 +643,6 @@ async def test_process_document_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( document_processor_service.ProcessResponse() ) - await client.process_document(request) # Establish that the underlying gRPC stub method was called. @@ -634,14 +657,13 @@ async def test_process_document_field_headers_async(): def test_process_document_flattened(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.process_document), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = document_processor_service.ProcessResponse() - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.process_document(name="name_value",) @@ -650,13 +672,12 @@ def test_process_document_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" def test_process_document_flattened_error(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -670,7 +691,7 @@ def test_process_document_flattened_error(): @pytest.mark.asyncio async def test_process_document_flattened_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -689,14 +710,13 @@ async def test_process_document_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @pytest.mark.asyncio async def test_process_document_flattened_error_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -711,7 +731,7 @@ def test_batch_process_documents( transport: str = "grpc", request_type=document_processor_service.BatchProcessRequest ): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -724,13 +744,11 @@ def test_batch_process_documents( ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.BatchProcessRequest() # Establish that the response is the type that we expect. @@ -745,7 +763,7 @@ def test_batch_process_documents_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -755,7 +773,6 @@ def test_batch_process_documents_empty_call(): client.batch_process_documents() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.BatchProcessRequest() @@ -765,7 +782,7 @@ async def test_batch_process_documents_async( request_type=document_processor_service.BatchProcessRequest, ): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -780,13 +797,11 @@ async def test_batch_process_documents_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.BatchProcessRequest() # Establish that the response is the type that we expect. @@ -800,12 +815,13 @@ async def test_batch_process_documents_async_from_dict(): def test_batch_process_documents_field_headers(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.BatchProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -813,7 +829,6 @@ def test_batch_process_documents_field_headers(): type(client.transport.batch_process_documents), "__call__" ) as call: call.return_value = operations_pb2.Operation(name="operations/op") - client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. @@ -829,12 +844,13 @@ def test_batch_process_documents_field_headers(): @pytest.mark.asyncio async def test_batch_process_documents_field_headers_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.BatchProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -844,7 +860,6 @@ async def test_batch_process_documents_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) - await client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. @@ -859,7 +874,7 @@ async def test_batch_process_documents_field_headers_async(): def test_batch_process_documents_flattened(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -868,7 +883,6 @@ def test_batch_process_documents_flattened(): ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.batch_process_documents(name="name_value",) @@ -877,13 +891,12 @@ def test_batch_process_documents_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" def test_batch_process_documents_flattened_error(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -897,7 +910,7 @@ def test_batch_process_documents_flattened_error(): @pytest.mark.asyncio async def test_batch_process_documents_flattened_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -918,14 +931,13 @@ async def test_batch_process_documents_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @pytest.mark.asyncio async def test_batch_process_documents_flattened_error_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -941,7 +953,7 @@ def test_review_document( request_type=document_processor_service.ReviewDocumentRequest, ): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -952,13 +964,11 @@ def test_review_document( with mock.patch.object(type(client.transport.review_document), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.review_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ReviewDocumentRequest() # Establish that the response is the type that we expect. @@ -973,7 +983,7 @@ def test_review_document_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -981,7 +991,6 @@ def test_review_document_empty_call(): client.review_document() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ReviewDocumentRequest() @@ -991,7 +1000,7 @@ async def test_review_document_async( request_type=document_processor_service.ReviewDocumentRequest, ): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1004,13 +1013,11 @@ async def test_review_document_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.review_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ReviewDocumentRequest() # Establish that the response is the type that we expect. @@ -1024,18 +1031,18 @@ async def test_review_document_async_from_dict(): def test_review_document_field_headers(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ReviewDocumentRequest() + request.human_review_config = "human_review_config/value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.review_document), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") - client.review_document(request) # Establish that the underlying gRPC stub method was called. @@ -1054,12 +1061,13 @@ def test_review_document_field_headers(): @pytest.mark.asyncio async def test_review_document_field_headers_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ReviewDocumentRequest() + request.human_review_config = "human_review_config/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1067,7 +1075,6 @@ async def test_review_document_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) - await client.review_document(request) # Establish that the underlying gRPC stub method was called. @@ -1085,14 +1092,13 @@ async def test_review_document_field_headers_async(): def test_review_document_flattened(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.review_document), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.review_document(human_review_config="human_review_config_value",) @@ -1101,13 +1107,12 @@ def test_review_document_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].human_review_config == "human_review_config_value" def test_review_document_flattened_error(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -1122,7 +1127,7 @@ def test_review_document_flattened_error(): @pytest.mark.asyncio async def test_review_document_flattened_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1143,14 +1148,13 @@ async def test_review_document_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].human_review_config == "human_review_config_value" @pytest.mark.asyncio async def test_review_document_flattened_error_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -1165,16 +1169,16 @@ async def test_review_document_flattened_error_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentProcessorServiceClient( @@ -1184,7 +1188,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentProcessorServiceClient( @@ -1195,7 +1199,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = DocumentProcessorServiceClient(transport=transport) assert client.transport is transport @@ -1204,13 +1208,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.DocumentProcessorServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -1225,8 +1229,8 @@ def test_transport_get_channel(): ) def test_transport_adc(transport_class): # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -1234,7 +1238,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.DocumentProcessorServiceGrpcTransport, @@ -1243,9 +1247,9 @@ def test_transport_grpc_default(): def test_document_processor_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.DocumentProcessorServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -1257,7 +1261,7 @@ def test_document_processor_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.DocumentProcessorServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -1277,15 +1281,37 @@ def test_document_processor_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_document_processor_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.documentai_v1.services.document_processor_service.transports.DocumentProcessorServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DocumentProcessorServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_document_processor_service_base_transport_with_credentials_file_old_google_auth(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True ) as load_creds, mock.patch( "google.cloud.documentai_v1.services.document_processor_service.transports.DocumentProcessorServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.DocumentProcessorServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -1298,19 +1324,33 @@ def test_document_processor_service_base_transport_with_credentials_file(): def test_document_processor_service_base_transport_with_adc(): # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.documentai_v1.services.document_processor_service.transports.DocumentProcessorServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.DocumentProcessorServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_document_processor_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + DocumentProcessorServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_document_processor_service_auth_adc_old_google_auth(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) DocumentProcessorServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -1318,20 +1358,158 @@ def test_document_processor_service_auth_adc(): ) -def test_document_processor_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.DocumentProcessorServiceGrpcTransport, + transports.DocumentProcessorServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_document_processor_service_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transports.DocumentProcessorServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DocumentProcessorServiceGrpcTransport, + transports.DocumentProcessorServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_document_processor_service_transport_auth_adc_old_google_auth(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus") adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentProcessorServiceGrpcTransport, grpc_helpers), + (transports.DocumentProcessorServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_document_processor_service_transport_create_channel( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="documentai.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentProcessorServiceGrpcTransport, grpc_helpers), + (transports.DocumentProcessorServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_document_processor_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentProcessorServiceGrpcTransport, grpc_helpers), + (transports.DocumentProcessorServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_document_processor_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -1342,7 +1520,7 @@ def test_document_processor_service_transport_auth_adc(): def test_document_processor_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -1381,22 +1559,22 @@ def test_document_processor_service_grpc_transport_client_cert_source_for_mtls( def test_document_processor_service_host_no_port(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( - api_endpoint="us-documentai.googleapis.com" + api_endpoint="documentai.googleapis.com" ), ) - assert client.transport._host == "us-documentai.googleapis.com:443" + assert client.transport._host == "documentai.googleapis.com:443" def test_document_processor_service_host_with_port(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( - api_endpoint="us-documentai.googleapis.com:8000" + api_endpoint="documentai.googleapis.com:8000" ), ) - assert client.transport._host == "us-documentai.googleapis.com:8000" + assert client.transport._host == "documentai.googleapis.com:8000" def test_document_processor_service_grpc_transport_channel(): @@ -1447,9 +1625,9 @@ def test_document_processor_service_transport_channel_mtls_with_client_cert_sour mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1525,7 +1703,7 @@ def test_document_processor_service_transport_channel_mtls_with_adc(transport_cl def test_document_processor_service_grpc_lro_client(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1538,7 +1716,7 @@ def test_document_processor_service_grpc_lro_client(): def test_document_processor_service_grpc_lro_async_client(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1553,7 +1731,6 @@ def test_human_review_config_path(): project = "squid" location = "clam" processor = "whelk" - expected = "projects/{project}/locations/{location}/processors/{processor}/humanReviewConfig".format( project=project, location=location, processor=processor, ) @@ -1580,7 +1757,6 @@ def test_processor_path(): project = "cuttlefish" location = "mussel" processor = "winkle" - expected = "projects/{project}/locations/{location}/processors/{processor}".format( project=project, location=location, processor=processor, ) @@ -1603,7 +1779,6 @@ def test_parse_processor_path(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1624,7 +1799,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = DocumentProcessorServiceClient.common_folder_path(folder) assert expected == actual @@ -1643,7 +1817,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = DocumentProcessorServiceClient.common_organization_path(organization) assert expected == actual @@ -1662,7 +1835,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = DocumentProcessorServiceClient.common_project_path(project) assert expected == actual @@ -1682,7 +1854,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1709,7 +1880,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.DocumentProcessorServiceTransport, "_prep_wrapped_messages" ) as prep: client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1718,6 +1889,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = DocumentProcessorServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/documentai_v1beta2/__init__.py b/tests/unit/gapic/documentai_v1beta2/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/documentai_v1beta2/__init__.py +++ b/tests/unit/gapic/documentai_v1beta2/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py b/tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py index ffea17d6..4b80d6e1 100644 --- a/tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py +++ b/tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule -from google import auth + from google.api_core import client_options -from google.api_core import exceptions +from google.api_core import exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.documentai_v1beta2.services.document_understanding_service import ( DocumentUnderstandingServiceAsyncClient, @@ -44,12 +43,42 @@ from google.cloud.documentai_v1beta2.services.document_understanding_service import ( transports, ) +from google.cloud.documentai_v1beta2.services.document_understanding_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.documentai_v1beta2.services.document_understanding_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.documentai_v1beta2.types import document from google.cloud.documentai_v1beta2.types import document_understanding from google.cloud.documentai_v1beta2.types import geometry from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.rpc import status_pb2 as status # type: ignore +from google.rpc import status_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and auth "less than" test cases +# - Delete these pytest markers (Make the "greater than or equal to" tests the default). +requires_google_auth_lt_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), + reason="This test requires google-auth < 1.25.0", +) +requires_google_auth_gte_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), + reason="This test requires google-auth >= 1.25.0", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -104,7 +133,7 @@ def test__get_default_mtls_endpoint(): [DocumentUnderstandingServiceClient, DocumentUnderstandingServiceAsyncClient,], ) def test_document_understanding_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -122,7 +151,7 @@ def test_document_understanding_service_client_from_service_account_info(client_ [DocumentUnderstandingServiceClient, DocumentUnderstandingServiceAsyncClient,], ) def test_document_understanding_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -181,7 +210,7 @@ def test_document_understanding_service_client_client_options( with mock.patch.object( DocumentUnderstandingServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -490,7 +519,7 @@ def test_batch_process_documents( request_type=document_understanding.BatchProcessDocumentsRequest, ): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -503,13 +532,11 @@ def test_batch_process_documents( ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_understanding.BatchProcessDocumentsRequest() # Establish that the response is the type that we expect. @@ -524,7 +551,7 @@ def test_batch_process_documents_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -534,7 +561,6 @@ def test_batch_process_documents_empty_call(): client.batch_process_documents() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_understanding.BatchProcessDocumentsRequest() @@ -544,7 +570,7 @@ async def test_batch_process_documents_async( request_type=document_understanding.BatchProcessDocumentsRequest, ): client = DocumentUnderstandingServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -559,13 +585,11 @@ async def test_batch_process_documents_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_understanding.BatchProcessDocumentsRequest() # Establish that the response is the type that we expect. @@ -579,12 +603,13 @@ async def test_batch_process_documents_async_from_dict(): def test_batch_process_documents_field_headers(): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_understanding.BatchProcessDocumentsRequest() + request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -592,7 +617,6 @@ def test_batch_process_documents_field_headers(): type(client.transport.batch_process_documents), "__call__" ) as call: call.return_value = operations_pb2.Operation(name="operations/op") - client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. @@ -608,12 +632,13 @@ def test_batch_process_documents_field_headers(): @pytest.mark.asyncio async def test_batch_process_documents_field_headers_async(): client = DocumentUnderstandingServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_understanding.BatchProcessDocumentsRequest() + request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -623,7 +648,6 @@ async def test_batch_process_documents_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) - await client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. @@ -638,7 +662,7 @@ async def test_batch_process_documents_field_headers_async(): def test_batch_process_documents_flattened(): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -647,7 +671,6 @@ def test_batch_process_documents_flattened(): ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.batch_process_documents( @@ -660,7 +683,6 @@ def test_batch_process_documents_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].requests == [ document_understanding.ProcessDocumentRequest(parent="parent_value") ] @@ -668,7 +690,7 @@ def test_batch_process_documents_flattened(): def test_batch_process_documents_flattened_error(): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -685,7 +707,7 @@ def test_batch_process_documents_flattened_error(): @pytest.mark.asyncio async def test_batch_process_documents_flattened_async(): client = DocumentUnderstandingServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -710,7 +732,6 @@ async def test_batch_process_documents_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].requests == [ document_understanding.ProcessDocumentRequest(parent="parent_value") ] @@ -719,7 +740,7 @@ async def test_batch_process_documents_flattened_async(): @pytest.mark.asyncio async def test_batch_process_documents_flattened_error_async(): client = DocumentUnderstandingServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -737,7 +758,7 @@ def test_process_document( transport: str = "grpc", request_type=document_understanding.ProcessDocumentRequest ): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -750,21 +771,16 @@ def test_process_document( call.return_value = document.Document( mime_type="mime_type_value", text="text_value", uri="uri_value", ) - response = client.process_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_understanding.ProcessDocumentRequest() # Establish that the response is the type that we expect. - assert isinstance(response, document.Document) - assert response.mime_type == "mime_type_value" - assert response.text == "text_value" @@ -776,7 +792,7 @@ def test_process_document_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -784,7 +800,6 @@ def test_process_document_empty_call(): client.process_document() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_understanding.ProcessDocumentRequest() @@ -794,7 +809,7 @@ async def test_process_document_async( request_type=document_understanding.ProcessDocumentRequest, ): client = DocumentUnderstandingServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -807,20 +822,16 @@ async def test_process_document_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( document.Document(mime_type="mime_type_value", text="text_value",) ) - response = await client.process_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_understanding.ProcessDocumentRequest() # Establish that the response is the type that we expect. assert isinstance(response, document.Document) - assert response.mime_type == "mime_type_value" - assert response.text == "text_value" @@ -831,18 +842,18 @@ async def test_process_document_async_from_dict(): def test_process_document_field_headers(): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_understanding.ProcessDocumentRequest() + request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.process_document), "__call__") as call: call.return_value = document.Document() - client.process_document(request) # Establish that the underlying gRPC stub method was called. @@ -858,18 +869,18 @@ def test_process_document_field_headers(): @pytest.mark.asyncio async def test_process_document_field_headers_async(): client = DocumentUnderstandingServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_understanding.ProcessDocumentRequest() + request.parent = "parent/value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.process_document), "__call__") as call: call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(document.Document()) - await client.process_document(request) # Establish that the underlying gRPC stub method was called. @@ -885,16 +896,16 @@ async def test_process_document_field_headers_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.DocumentUnderstandingServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.DocumentUnderstandingServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentUnderstandingServiceClient( @@ -904,7 +915,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.DocumentUnderstandingServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentUnderstandingServiceClient( @@ -915,7 +926,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.DocumentUnderstandingServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = DocumentUnderstandingServiceClient(transport=transport) assert client.transport is transport @@ -924,13 +935,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.DocumentUnderstandingServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.DocumentUnderstandingServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -945,8 +956,8 @@ def test_transport_get_channel(): ) def test_transport_adc(transport_class): # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -954,7 +965,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.DocumentUnderstandingServiceGrpcTransport, @@ -963,9 +974,9 @@ def test_transport_grpc_default(): def test_document_understanding_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.DocumentUnderstandingServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -977,7 +988,7 @@ def test_document_understanding_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.DocumentUnderstandingServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -996,15 +1007,37 @@ def test_document_understanding_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_document_understanding_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True ) as load_creds, mock.patch( "google.cloud.documentai_v1beta2.services.document_understanding_service.transports.DocumentUnderstandingServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DocumentUnderstandingServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_document_understanding_service_base_transport_with_credentials_file_old_google_auth(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.documentai_v1beta2.services.document_understanding_service.transports.DocumentUnderstandingServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.DocumentUnderstandingServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -1017,19 +1050,33 @@ def test_document_understanding_service_base_transport_with_credentials_file(): def test_document_understanding_service_base_transport_with_adc(): # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.documentai_v1beta2.services.document_understanding_service.transports.DocumentUnderstandingServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.DocumentUnderstandingServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_document_understanding_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + DocumentUnderstandingServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_document_understanding_service_auth_adc_old_google_auth(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) DocumentUnderstandingServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -1037,20 +1084,169 @@ def test_document_understanding_service_auth_adc(): ) -def test_document_understanding_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.DocumentUnderstandingServiceGrpcTransport, + transports.DocumentUnderstandingServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_document_understanding_service_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transports.DocumentUnderstandingServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DocumentUnderstandingServiceGrpcTransport, + transports.DocumentUnderstandingServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_document_understanding_service_transport_auth_adc_old_google_auth( + transport_class, +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus") adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentUnderstandingServiceGrpcTransport, grpc_helpers), + ( + transports.DocumentUnderstandingServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +@requires_api_core_gte_1_26_0 +def test_document_understanding_service_transport_create_channel( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "us-documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="us-documentai.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentUnderstandingServiceGrpcTransport, grpc_helpers), + ( + transports.DocumentUnderstandingServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +@requires_api_core_lt_1_26_0 +def test_document_understanding_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "us-documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentUnderstandingServiceGrpcTransport, grpc_helpers), + ( + transports.DocumentUnderstandingServiceGrpcAsyncIOTransport, + grpc_helpers_async, + ), + ], +) +@requires_api_core_lt_1_26_0 +def test_document_understanding_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "us-documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -1061,7 +1257,7 @@ def test_document_understanding_service_transport_auth_adc(): def test_document_understanding_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -1100,7 +1296,7 @@ def test_document_understanding_service_grpc_transport_client_cert_source_for_mt def test_document_understanding_service_host_no_port(): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="us-documentai.googleapis.com" ), @@ -1110,7 +1306,7 @@ def test_document_understanding_service_host_no_port(): def test_document_understanding_service_host_with_port(): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( api_endpoint="us-documentai.googleapis.com:8000" ), @@ -1166,9 +1362,9 @@ def test_document_understanding_service_transport_channel_mtls_with_client_cert_ mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1246,7 +1442,7 @@ def test_document_understanding_service_transport_channel_mtls_with_adc( def test_document_understanding_service_grpc_lro_client(): client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1259,7 +1455,7 @@ def test_document_understanding_service_grpc_lro_client(): def test_document_understanding_service_grpc_lro_async_client(): client = DocumentUnderstandingServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1272,7 +1468,6 @@ def test_document_understanding_service_grpc_lro_async_client(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1295,7 +1490,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = DocumentUnderstandingServiceClient.common_folder_path(folder) assert expected == actual @@ -1314,7 +1508,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = DocumentUnderstandingServiceClient.common_organization_path(organization) assert expected == actual @@ -1333,7 +1526,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = DocumentUnderstandingServiceClient.common_project_path(project) assert expected == actual @@ -1353,7 +1545,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1380,7 +1571,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.DocumentUnderstandingServiceTransport, "_prep_wrapped_messages" ) as prep: client = DocumentUnderstandingServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1389,6 +1580,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = DocumentUnderstandingServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) diff --git a/tests/unit/gapic/documentai_v1beta3/__init__.py b/tests/unit/gapic/documentai_v1beta3/__init__.py index 42ffdf2b..4de65971 100644 --- a/tests/unit/gapic/documentai_v1beta3/__init__.py +++ b/tests/unit/gapic/documentai_v1beta3/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py b/tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py index 7179689c..7ce09e4e 100644 --- a/tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py +++ b/tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - import os import mock +import packaging.version import grpc from grpc.experimental import aio @@ -24,16 +23,16 @@ import pytest from proto.marshal.rules.dates import DurationRule, TimestampRule -from google import auth + from google.api_core import client_options -from google.api_core import exceptions +from google.api_core import exceptions as core_exceptions from google.api_core import future from google.api_core import gapic_v1 from google.api_core import grpc_helpers from google.api_core import grpc_helpers_async from google.api_core import operation_async # type: ignore from google.api_core import operations_v1 -from google.auth import credentials +from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.documentai_v1beta3.services.document_processor_service import ( DocumentProcessorServiceAsyncClient, @@ -44,22 +43,52 @@ from google.cloud.documentai_v1beta3.services.document_processor_service import ( transports, ) +from google.cloud.documentai_v1beta3.services.document_processor_service.transports.base import ( + _API_CORE_VERSION, +) +from google.cloud.documentai_v1beta3.services.document_processor_service.transports.base import ( + _GOOGLE_AUTH_VERSION, +) from google.cloud.documentai_v1beta3.types import document from google.cloud.documentai_v1beta3.types import document_io from google.cloud.documentai_v1beta3.types import document_processor_service from google.cloud.documentai_v1beta3.types import geometry from google.longrunning import operations_pb2 from google.oauth2 import service_account -from google.protobuf import any_pb2 as gp_any # type: ignore -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.protobuf import wrappers_pb2 as wrappers # type: ignore -from google.rpc import status_pb2 as status # type: ignore -from google.type import color_pb2 as color # type: ignore -from google.type import date_pb2 as date # type: ignore -from google.type import datetime_pb2 as datetime # type: ignore -from google.type import money_pb2 as money # type: ignore -from google.type import postal_address_pb2 as postal_address # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from google.type import color_pb2 # type: ignore +from google.type import date_pb2 # type: ignore +from google.type import datetime_pb2 # type: ignore +from google.type import money_pb2 # type: ignore +from google.type import postal_address_pb2 # type: ignore +import google.auth + + +# TODO(busunkim): Once google-api-core >= 1.26.0 is required: +# - Delete all the api-core and auth "less than" test cases +# - Delete these pytest markers (Make the "greater than or equal to" tests the default). +requires_google_auth_lt_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"), + reason="This test requires google-auth < 1.25.0", +) +requires_google_auth_gte_1_25_0 = pytest.mark.skipif( + packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"), + reason="This test requires google-auth >= 1.25.0", +) + +requires_api_core_lt_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) >= packaging.version.parse("1.26.0"), + reason="This test requires google-api-core < 1.26.0", +) + +requires_api_core_gte_1_26_0 = pytest.mark.skipif( + packaging.version.parse(_API_CORE_VERSION) < packaging.version.parse("1.26.0"), + reason="This test requires google-api-core >= 1.26.0", +) def client_cert_source_callback(): @@ -112,7 +141,7 @@ def test__get_default_mtls_endpoint(): [DocumentProcessorServiceClient, DocumentProcessorServiceAsyncClient,], ) def test_document_processor_service_client_from_service_account_info(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: @@ -122,7 +151,7 @@ def test_document_processor_service_client_from_service_account_info(client_clas assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == "us-documentai.googleapis.com:443" + assert client.transport._host == "documentai.googleapis.com:443" @pytest.mark.parametrize( @@ -130,7 +159,7 @@ def test_document_processor_service_client_from_service_account_info(client_clas [DocumentProcessorServiceClient, DocumentProcessorServiceAsyncClient,], ) def test_document_processor_service_client_from_service_account_file(client_class): - creds = credentials.AnonymousCredentials() + creds = ga_credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_file" ) as factory: @@ -143,7 +172,7 @@ def test_document_processor_service_client_from_service_account_file(client_clas assert client.transport._credentials == creds assert isinstance(client, client_class) - assert client.transport._host == "us-documentai.googleapis.com:443" + assert client.transport._host == "documentai.googleapis.com:443" def test_document_processor_service_client_get_transport_class(): @@ -189,7 +218,7 @@ def test_document_processor_service_client_client_options( with mock.patch.object( DocumentProcessorServiceClient, "get_transport_class" ) as gtc: - transport = transport_class(credentials=credentials.AnonymousCredentials()) + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) client = client_class(transport=transport) gtc.assert_not_called() @@ -497,7 +526,7 @@ def test_process_document( transport: str = "grpc", request_type=document_processor_service.ProcessRequest ): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -510,19 +539,15 @@ def test_process_document( call.return_value = document_processor_service.ProcessResponse( human_review_operation="human_review_operation_value", ) - response = client.process_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ProcessRequest() # Establish that the response is the type that we expect. - assert isinstance(response, document_processor_service.ProcessResponse) - assert response.human_review_operation == "human_review_operation_value" @@ -534,7 +559,7 @@ def test_process_document_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -542,7 +567,6 @@ def test_process_document_empty_call(): client.process_document() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ProcessRequest() @@ -552,7 +576,7 @@ async def test_process_document_async( request_type=document_processor_service.ProcessRequest, ): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -567,18 +591,15 @@ async def test_process_document_async( human_review_operation="human_review_operation_value", ) ) - response = await client.process_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ProcessRequest() # Establish that the response is the type that we expect. assert isinstance(response, document_processor_service.ProcessResponse) - assert response.human_review_operation == "human_review_operation_value" @@ -589,18 +610,18 @@ async def test_process_document_async_from_dict(): def test_process_document_field_headers(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.process_document), "__call__") as call: call.return_value = document_processor_service.ProcessResponse() - client.process_document(request) # Establish that the underlying gRPC stub method was called. @@ -616,12 +637,13 @@ def test_process_document_field_headers(): @pytest.mark.asyncio async def test_process_document_field_headers_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -629,7 +651,6 @@ async def test_process_document_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( document_processor_service.ProcessResponse() ) - await client.process_document(request) # Establish that the underlying gRPC stub method was called. @@ -644,14 +665,13 @@ async def test_process_document_field_headers_async(): def test_process_document_flattened(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.process_document), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = document_processor_service.ProcessResponse() - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.process_document(name="name_value",) @@ -660,13 +680,12 @@ def test_process_document_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" def test_process_document_flattened_error(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -680,7 +699,7 @@ def test_process_document_flattened_error(): @pytest.mark.asyncio async def test_process_document_flattened_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -699,14 +718,13 @@ async def test_process_document_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @pytest.mark.asyncio async def test_process_document_flattened_error_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -721,7 +739,7 @@ def test_batch_process_documents( transport: str = "grpc", request_type=document_processor_service.BatchProcessRequest ): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -734,13 +752,11 @@ def test_batch_process_documents( ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.BatchProcessRequest() # Establish that the response is the type that we expect. @@ -755,7 +771,7 @@ def test_batch_process_documents_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -765,7 +781,6 @@ def test_batch_process_documents_empty_call(): client.batch_process_documents() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.BatchProcessRequest() @@ -775,7 +790,7 @@ async def test_batch_process_documents_async( request_type=document_processor_service.BatchProcessRequest, ): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -790,13 +805,11 @@ async def test_batch_process_documents_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.BatchProcessRequest() # Establish that the response is the type that we expect. @@ -810,12 +823,13 @@ async def test_batch_process_documents_async_from_dict(): def test_batch_process_documents_field_headers(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.BatchProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -823,7 +837,6 @@ def test_batch_process_documents_field_headers(): type(client.transport.batch_process_documents), "__call__" ) as call: call.return_value = operations_pb2.Operation(name="operations/op") - client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. @@ -839,12 +852,13 @@ def test_batch_process_documents_field_headers(): @pytest.mark.asyncio async def test_batch_process_documents_field_headers_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.BatchProcessRequest() + request.name = "name/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -854,7 +868,6 @@ async def test_batch_process_documents_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) - await client.batch_process_documents(request) # Establish that the underlying gRPC stub method was called. @@ -869,7 +882,7 @@ async def test_batch_process_documents_field_headers_async(): def test_batch_process_documents_flattened(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -878,7 +891,6 @@ def test_batch_process_documents_flattened(): ) as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.batch_process_documents(name="name_value",) @@ -887,13 +899,12 @@ def test_batch_process_documents_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" def test_batch_process_documents_flattened_error(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -907,7 +918,7 @@ def test_batch_process_documents_flattened_error(): @pytest.mark.asyncio async def test_batch_process_documents_flattened_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -928,14 +939,13 @@ async def test_batch_process_documents_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" @pytest.mark.asyncio async def test_batch_process_documents_flattened_error_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -951,7 +961,7 @@ def test_review_document( request_type=document_processor_service.ReviewDocumentRequest, ): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -962,13 +972,11 @@ def test_review_document( with mock.patch.object(type(client.transport.review_document), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/spam") - response = client.review_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ReviewDocumentRequest() # Establish that the response is the type that we expect. @@ -983,7 +991,7 @@ def test_review_document_empty_call(): # This test is a coverage failsafe to make sure that totally empty calls, # i.e. request == None and no flattened fields passed, work. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -991,7 +999,6 @@ def test_review_document_empty_call(): client.review_document() call.assert_called() _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ReviewDocumentRequest() @@ -1001,7 +1008,7 @@ async def test_review_document_async( request_type=document_processor_service.ReviewDocumentRequest, ): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # Everything is optional in proto3 as far as the runtime is concerned, @@ -1014,13 +1021,11 @@ async def test_review_document_async( call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/spam") ) - response = await client.review_document(request) # Establish that the underlying gRPC stub method was called. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0] == document_processor_service.ReviewDocumentRequest() # Establish that the response is the type that we expect. @@ -1034,18 +1039,18 @@ async def test_review_document_async_from_dict(): def test_review_document_field_headers(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ReviewDocumentRequest() + request.human_review_config = "human_review_config/value" # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.review_document), "__call__") as call: call.return_value = operations_pb2.Operation(name="operations/op") - client.review_document(request) # Establish that the underlying gRPC stub method was called. @@ -1064,12 +1069,13 @@ def test_review_document_field_headers(): @pytest.mark.asyncio async def test_review_document_field_headers_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + 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 = document_processor_service.ReviewDocumentRequest() + request.human_review_config = "human_review_config/value" # Mock the actual call within the gRPC stub, and fake the request. @@ -1077,7 +1083,6 @@ async def test_review_document_field_headers_async(): call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( operations_pb2.Operation(name="operations/op") ) - await client.review_document(request) # Establish that the underlying gRPC stub method was called. @@ -1095,14 +1100,13 @@ async def test_review_document_field_headers_async(): def test_review_document_flattened(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. with mock.patch.object(type(client.transport.review_document), "__call__") as call: # Designate an appropriate return value for the call. call.return_value = operations_pb2.Operation(name="operations/op") - # Call the method with a truthy value for each flattened field, # using the keyword arguments to the method. client.review_document(human_review_config="human_review_config_value",) @@ -1111,13 +1115,12 @@ def test_review_document_flattened(): # request object values. assert len(call.mock_calls) == 1 _, args, _ = call.mock_calls[0] - assert args[0].human_review_config == "human_review_config_value" def test_review_document_flattened_error(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -1132,7 +1135,7 @@ def test_review_document_flattened_error(): @pytest.mark.asyncio async def test_review_document_flattened_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Mock the actual call within the gRPC stub, and fake the request. @@ -1153,14 +1156,13 @@ async def test_review_document_flattened_async(): # request object values. assert len(call.mock_calls) _, args, _ = call.mock_calls[0] - assert args[0].human_review_config == "human_review_config_value" @pytest.mark.asyncio async def test_review_document_flattened_error_async(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Attempting to call a method with both a request object and flattened @@ -1175,16 +1177,16 @@ async def test_review_document_flattened_error_async(): def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport=transport, ) # It is an error to provide a credentials file and a transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentProcessorServiceClient( @@ -1194,7 +1196,7 @@ def test_credentials_transport_error(): # It is an error to provide scopes and a transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) with pytest.raises(ValueError): client = DocumentProcessorServiceClient( @@ -1205,7 +1207,7 @@ def test_credentials_transport_error(): def test_transport_instance(): # A client may be instantiated with a custom transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) client = DocumentProcessorServiceClient(transport=transport) assert client.transport is transport @@ -1214,13 +1216,13 @@ def test_transport_instance(): def test_transport_get_channel(): # A client may be instantiated with a custom transport instance. transport = transports.DocumentProcessorServiceGrpcTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel transport = transports.DocumentProcessorServiceGrpcAsyncIOTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) channel = transport.grpc_channel assert channel @@ -1235,8 +1237,8 @@ def test_transport_get_channel(): ) def test_transport_adc(transport_class): # Test default credentials are used if not provided. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport_class() adc.assert_called_once() @@ -1244,7 +1246,7 @@ def test_transport_adc(transport_class): def test_transport_grpc_default(): # A client should use the gRPC transport by default. client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) assert isinstance( client.transport, transports.DocumentProcessorServiceGrpcTransport, @@ -1253,9 +1255,9 @@ def test_transport_grpc_default(): def test_document_processor_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error - with pytest.raises(exceptions.DuplicateCredentialArgs): + with pytest.raises(core_exceptions.DuplicateCredentialArgs): transport = transports.DocumentProcessorServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", ) @@ -1267,7 +1269,7 @@ def test_document_processor_service_base_transport(): ) as Transport: Transport.return_value = None transport = transports.DocumentProcessorServiceTransport( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), ) # Every method on the transport should just blindly @@ -1287,15 +1289,37 @@ def test_document_processor_service_base_transport(): transport.operations_client +@requires_google_auth_gte_1_25_0 def test_document_processor_service_base_transport_with_credentials_file(): # Instantiate the base transport with a credentials file with mock.patch.object( - auth, "load_credentials_from_file" + google.auth, "load_credentials_from_file", autospec=True ) as load_creds, mock.patch( "google.cloud.documentai_v1beta3.services.document_processor_service.transports.DocumentProcessorServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - load_creds.return_value = (credentials.AnonymousCredentials(), None) + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DocumentProcessorServiceTransport( + credentials_file="credentials.json", quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", + ) + + +@requires_google_auth_lt_1_25_0 +def test_document_processor_service_base_transport_with_credentials_file_old_google_auth(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.documentai_v1beta3.services.document_processor_service.transports.DocumentProcessorServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.DocumentProcessorServiceTransport( credentials_file="credentials.json", quota_project_id="octopus", ) @@ -1308,19 +1332,33 @@ def test_document_processor_service_base_transport_with_credentials_file(): def test_document_processor_service_base_transport_with_adc(): # Test the default credentials are used if credentials and credentials_file are None. - with mock.patch.object(auth, "default") as adc, mock.patch( + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( "google.cloud.documentai_v1beta3.services.document_processor_service.transports.DocumentProcessorServiceTransport._prep_wrapped_messages" ) as Transport: Transport.return_value = None - adc.return_value = (credentials.AnonymousCredentials(), None) + adc.return_value = (ga_credentials.AnonymousCredentials(), None) transport = transports.DocumentProcessorServiceTransport() adc.assert_called_once() +@requires_google_auth_gte_1_25_0 def test_document_processor_service_auth_adc(): # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + DocumentProcessorServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id=None, + ) + + +@requires_google_auth_lt_1_25_0 +def test_document_processor_service_auth_adc_old_google_auth(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) DocumentProcessorServiceClient() adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), @@ -1328,20 +1366,158 @@ def test_document_processor_service_auth_adc(): ) -def test_document_processor_service_transport_auth_adc(): +@pytest.mark.parametrize( + "transport_class", + [ + transports.DocumentProcessorServiceGrpcTransport, + transports.DocumentProcessorServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_gte_1_25_0 +def test_document_processor_service_transport_auth_adc(transport_class): # If credentials and host are not provided, the transport class should use # ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - transports.DocumentProcessorServiceGrpcTransport( - host="squid.clam.whelk", quota_project_id="octopus" + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + quota_project_id="octopus", ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DocumentProcessorServiceGrpcTransport, + transports.DocumentProcessorServiceGrpcAsyncIOTransport, + ], +) +@requires_google_auth_lt_1_25_0 +def test_document_processor_service_transport_auth_adc_old_google_auth(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus") adc.assert_called_once_with( scopes=("https://www.googleapis.com/auth/cloud-platform",), quota_project_id="octopus", ) +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentProcessorServiceGrpcTransport, grpc_helpers), + (transports.DocumentProcessorServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_gte_1_26_0 +def test_document_processor_service_transport_create_channel( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=("https://www.googleapis.com/auth/cloud-platform",), + scopes=["1", "2"], + default_host="documentai.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentProcessorServiceGrpcTransport, grpc_helpers), + (transports.DocumentProcessorServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_document_processor_service_transport_create_channel_old_api_core( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus") + + create_channel.assert_called_with( + "documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.DocumentProcessorServiceGrpcTransport, grpc_helpers), + (transports.DocumentProcessorServiceGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +@requires_api_core_lt_1_26_0 +def test_document_processor_service_transport_create_channel_user_scopes( + transport_class, grpc_helpers +): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "documentai.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + scopes=["1", "2"], + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + @pytest.mark.parametrize( "transport_class", [ @@ -1352,7 +1528,7 @@ def test_document_processor_service_transport_auth_adc(): def test_document_processor_service_grpc_transport_client_cert_source_for_mtls( transport_class, ): - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() # Check ssl_channel_credentials is used if provided. with mock.patch.object(transport_class, "create_channel") as mock_create_channel: @@ -1391,22 +1567,22 @@ def test_document_processor_service_grpc_transport_client_cert_source_for_mtls( def test_document_processor_service_host_no_port(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( - api_endpoint="us-documentai.googleapis.com" + api_endpoint="documentai.googleapis.com" ), ) - assert client.transport._host == "us-documentai.googleapis.com:443" + assert client.transport._host == "documentai.googleapis.com:443" def test_document_processor_service_host_with_port(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), + credentials=ga_credentials.AnonymousCredentials(), client_options=client_options.ClientOptions( - api_endpoint="us-documentai.googleapis.com:8000" + api_endpoint="documentai.googleapis.com:8000" ), ) - assert client.transport._host == "us-documentai.googleapis.com:8000" + assert client.transport._host == "documentai.googleapis.com:8000" def test_document_processor_service_grpc_transport_channel(): @@ -1457,9 +1633,9 @@ def test_document_processor_service_transport_channel_mtls_with_client_cert_sour mock_grpc_channel = mock.Mock() grpc_create_channel.return_value = mock_grpc_channel - cred = credentials.AnonymousCredentials() + cred = ga_credentials.AnonymousCredentials() with pytest.warns(DeprecationWarning): - with mock.patch.object(auth, "default") as adc: + with mock.patch.object(google.auth, "default") as adc: adc.return_value = (cred, None) transport = transport_class( host="squid.clam.whelk", @@ -1535,7 +1711,7 @@ def test_document_processor_service_transport_channel_mtls_with_adc(transport_cl def test_document_processor_service_grpc_lro_client(): client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), transport="grpc", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc", ) transport = client.transport @@ -1548,7 +1724,7 @@ def test_document_processor_service_grpc_lro_client(): def test_document_processor_service_grpc_lro_async_client(): client = DocumentProcessorServiceAsyncClient( - credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio", + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", ) transport = client.transport @@ -1563,7 +1739,6 @@ def test_human_review_config_path(): project = "squid" location = "clam" processor = "whelk" - expected = "projects/{project}/locations/{location}/processors/{processor}/humanReviewConfig".format( project=project, location=location, processor=processor, ) @@ -1590,7 +1765,6 @@ def test_processor_path(): project = "cuttlefish" location = "mussel" processor = "winkle" - expected = "projects/{project}/locations/{location}/processors/{processor}".format( project=project, location=location, processor=processor, ) @@ -1613,7 +1787,6 @@ def test_parse_processor_path(): def test_common_billing_account_path(): billing_account = "squid" - expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -1634,7 +1807,6 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): folder = "whelk" - expected = "folders/{folder}".format(folder=folder,) actual = DocumentProcessorServiceClient.common_folder_path(folder) assert expected == actual @@ -1653,7 +1825,6 @@ def test_parse_common_folder_path(): def test_common_organization_path(): organization = "oyster" - expected = "organizations/{organization}".format(organization=organization,) actual = DocumentProcessorServiceClient.common_organization_path(organization) assert expected == actual @@ -1672,7 +1843,6 @@ def test_parse_common_organization_path(): def test_common_project_path(): project = "cuttlefish" - expected = "projects/{project}".format(project=project,) actual = DocumentProcessorServiceClient.common_project_path(project) assert expected == actual @@ -1692,7 +1862,6 @@ def test_parse_common_project_path(): def test_common_location_path(): project = "winkle" location = "nautilus" - expected = "projects/{project}/locations/{location}".format( project=project, location=location, ) @@ -1719,7 +1888,7 @@ def test_client_withDEFAULT_CLIENT_INFO(): transports.DocumentProcessorServiceTransport, "_prep_wrapped_messages" ) as prep: client = DocumentProcessorServiceClient( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) @@ -1728,6 +1897,6 @@ def test_client_withDEFAULT_CLIENT_INFO(): ) as prep: transport_class = DocumentProcessorServiceClient.get_transport_class() transport = transport_class( - credentials=credentials.AnonymousCredentials(), client_info=client_info, + credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info)