From 8b6565236ec9c8f598efb55bd85937789c70fe3f Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 8 Oct 2021 14:20:42 +0000 Subject: [PATCH] feat: add context manager support in client (#224) - [ ] Regenerate this pull request now. chore: fix docstring for first attribute of protos committer: @busunkim96 PiperOrigin-RevId: 401271153 Source-Link: https://github.com/googleapis/googleapis/commit/787f8c9a731f44e74a90b9847d48659ca9462d10 Source-Link: https://github.com/googleapis/googleapis-gen/commit/81decffe9fc72396a8153e756d1d67a6eecfd620 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiODFkZWNmZmU5ZmM3MjM5NmE4MTUzZTc1NmQxZDY3YTZlZWNmZDYyMCJ9 --- .../async_client.py | 6 +++ .../document_processor_service/client.py | 18 +++++-- .../transports/base.py | 9 ++++ .../transports/grpc.py | 3 ++ .../transports/grpc_asyncio.py | 3 ++ google/cloud/documentai_v1/types/document.py | 15 ++++++ .../cloud/documentai_v1/types/document_io.py | 4 ++ .../types/document_processor_service.py | 10 +++- google/cloud/documentai_v1/types/geometry.py | 1 + .../documentai_v1/types/operation_metadata.py | 1 + .../async_client.py | 6 +++ .../document_understanding_service/client.py | 18 +++++-- .../transports/base.py | 9 ++++ .../transports/grpc.py | 3 ++ .../transports/grpc_asyncio.py | 3 ++ .../documentai_v1beta2/types/document.py | 10 ++++ .../types/document_understanding.py | 10 ++++ .../documentai_v1beta2/types/geometry.py | 1 + .../async_client.py | 6 +++ .../document_processor_service/client.py | 18 +++++-- .../transports/base.py | 9 ++++ .../transports/grpc.py | 3 ++ .../transports/grpc_asyncio.py | 3 ++ .../documentai_v1beta3/types/document.py | 15 ++++++ .../documentai_v1beta3/types/document_io.py | 4 ++ .../types/document_processor_service.py | 24 +++++++-- .../documentai_v1beta3/types/geometry.py | 1 + .../types/operation_metadata.py | 1 + .../test_document_processor_service.py | 50 +++++++++++++++++++ .../test_document_understanding_service.py | 50 +++++++++++++++++++ .../test_document_processor_service.py | 50 +++++++++++++++++++ 31 files changed, 348 insertions(+), 16 deletions(-) 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 e5cadf4d..b4cfb8cd 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 @@ -451,6 +451,12 @@ async def review_document( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 4e41ca3b..f094486e 100644 --- a/google/cloud/documentai_v1/services/document_processor_service/client.py +++ b/google/cloud/documentai_v1/services/document_processor_service/client.py @@ -369,10 +369,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def process_document( @@ -615,6 +612,19 @@ def review_document( # Done; return the response. return response + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 d6e2dc9e..c01879dc 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 @@ -203,6 +203,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def operations_client(self) -> operations_v1.OperationsClient: """Return the client designed to process long-running operations.""" 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 ec2b7097..ea350b19 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 @@ -333,5 +333,8 @@ def review_document( ) return self._stubs["review_document"] + def close(self): + self.grpc_channel.close() + __all__ = ("DocumentProcessorServiceGrpcTransport",) 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 ccbd53a1..bfb639af 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 @@ -340,5 +340,8 @@ def review_document( ) return self._stubs["review_document"] + def close(self): + return self.grpc_channel.close() + __all__ = ("DocumentProcessorServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/documentai_v1/types/document.py b/google/cloud/documentai_v1/types/document.py index 3e2726e1..711f7410 100644 --- a/google/cloud/documentai_v1/types/document.py +++ b/google/cloud/documentai_v1/types/document.py @@ -135,6 +135,7 @@ class Style(proto.Message): class FontSize(proto.Message): r"""Font size with unit. + Attributes: size (float): Font size for the text. @@ -162,6 +163,7 @@ class FontSize(proto.Message): class Page(proto.Message): r"""A page in a [Document][google.cloud.documentai.v1.Document]. + Attributes: page_number (int): 1-based index for current @@ -218,6 +220,7 @@ class Page(proto.Message): class Dimension(proto.Message): r"""Dimension for the page. + Attributes: width (float): Page width. @@ -233,6 +236,7 @@ class Dimension(proto.Message): class Image(proto.Message): r"""Rendered image contents for this page. + Attributes: content (bytes): Raw byte content of the image. @@ -275,6 +279,7 @@ class Matrix(proto.Message): 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 @@ -391,6 +396,7 @@ class Line(proto.Message): 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] @@ -465,6 +471,7 @@ class VisualElement(proto.Message): 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] @@ -480,6 +487,7 @@ 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. @@ -491,6 +499,7 @@ 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] @@ -529,6 +538,7 @@ class TableCell(proto.Message): 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] @@ -577,6 +587,7 @@ class FormField(proto.Message): 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 @@ -671,6 +682,7 @@ 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: @@ -934,6 +946,7 @@ class Parent(proto.Message): 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 @@ -956,6 +969,7 @@ 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``, @@ -982,6 +996,7 @@ class HumanReview(proto.Message): 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 diff --git a/google/cloud/documentai_v1/types/document_io.py b/google/cloud/documentai_v1/types/document_io.py index 4e5db8fe..4692f6d9 100644 --- a/google/cloud/documentai_v1/types/document_io.py +++ b/google/cloud/documentai_v1/types/document_io.py @@ -31,6 +31,7 @@ class RawDocument(proto.Message): r"""Payload message of raw document content (bytes). + Attributes: content (bytes): Inline document content. @@ -45,6 +46,7 @@ class RawDocument(proto.Message): class GcsDocument(proto.Message): r"""Specifies a document stored on Cloud Storage. + Attributes: gcs_uri (str): The Cloud Storage object uri. @@ -58,6 +60,7 @@ class GcsDocument(proto.Message): 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. @@ -111,6 +114,7 @@ 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 diff --git a/google/cloud/documentai_v1/types/document_processor_service.py b/google/cloud/documentai_v1/types/document_processor_service.py index 45ed8089..8955dfe2 100644 --- a/google/cloud/documentai_v1/types/document_processor_service.py +++ b/google/cloud/documentai_v1/types/document_processor_service.py @@ -40,6 +40,7 @@ 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. @@ -64,6 +65,7 @@ class ProcessRequest(proto.Message): 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 @@ -94,6 +96,7 @@ class State(proto.Enum): 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 @@ -111,6 +114,7 @@ class ProcessResponse(proto.Message): class BatchProcessRequest(proto.Message): r"""Request message for batch process document method. + Attributes: name (str): Required. The processor resource name. @@ -134,11 +138,13 @@ class BatchProcessRequest(proto.Message): 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. @@ -205,6 +211,7 @@ 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. @@ -234,6 +241,7 @@ class Priority(proto.Enum): class ReviewDocumentResponse(proto.Message): r"""Response message for review document method. + Attributes: gcs_destination (str): The Cloud Storage uri for the human reviewed diff --git a/google/cloud/documentai_v1/types/geometry.py b/google/cloud/documentai_v1/types/geometry.py index 6d755641..50d01649 100644 --- a/google/cloud/documentai_v1/types/geometry.py +++ b/google/cloud/documentai_v1/types/geometry.py @@ -58,6 +58,7 @@ class NormalizedVertex(proto.Message): 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. diff --git a/google/cloud/documentai_v1/types/operation_metadata.py b/google/cloud/documentai_v1/types/operation_metadata.py index ae78340e..9b8429fe 100644 --- a/google/cloud/documentai_v1/types/operation_metadata.py +++ b/google/cloud/documentai_v1/types/operation_metadata.py @@ -25,6 +25,7 @@ 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. 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 563f56f4..206ccd6e 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 @@ -328,6 +328,12 @@ async def process_document( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 b7186056..a35bd037 100644 --- a/google/cloud/documentai_v1beta2/services/document_understanding_service/client.py +++ b/google/cloud/documentai_v1beta2/services/document_understanding_service/client.py @@ -340,10 +340,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def batch_process_documents( @@ -485,6 +482,19 @@ def process_document( # Done; return the response. return response + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 eea3885d..bd478c7b 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 @@ -189,6 +189,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def operations_client(self) -> operations_v1.OperationsClient: """Return the client designed to process long-running operations.""" 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 465788f6..6c42f801 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 @@ -300,5 +300,8 @@ def process_document( ) return self._stubs["process_document"] + def close(self): + self.grpc_channel.close() + __all__ = ("DocumentUnderstandingServiceGrpcTransport",) 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 7899ad93..fabd9696 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 @@ -310,5 +310,8 @@ def process_document( ) return self._stubs["process_document"] + def close(self): + return self.grpc_channel.close() + __all__ = ("DocumentUnderstandingServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/documentai_v1beta2/types/document.py b/google/cloud/documentai_v1beta2/types/document.py index 5fbbb4c6..5b421477 100644 --- a/google/cloud/documentai_v1beta2/types/document.py +++ b/google/cloud/documentai_v1beta2/types/document.py @@ -155,6 +155,7 @@ class Style(proto.Message): class FontSize(proto.Message): r"""Font size with unit. + Attributes: size (float): Font size for the text. @@ -182,6 +183,7 @@ class FontSize(proto.Message): class Page(proto.Message): r"""A page in a [Document][google.cloud.documentai.v1beta2.Document]. + Attributes: page_number (int): 1-based index for current @@ -227,6 +229,7 @@ class Page(proto.Message): class Dimension(proto.Message): r"""Dimension for the page. + Attributes: width (float): Page width. @@ -242,6 +245,7 @@ class Dimension(proto.Message): 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 @@ -349,6 +353,7 @@ class Line(proto.Message): 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] @@ -419,6 +424,7 @@ class VisualElement(proto.Message): 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] @@ -435,6 +441,7 @@ 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. @@ -446,6 +453,7 @@ 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] @@ -484,6 +492,7 @@ class TableCell(proto.Message): 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] @@ -535,6 +544,7 @@ class FormField(proto.Message): 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 diff --git a/google/cloud/documentai_v1beta2/types/document_understanding.py b/google/cloud/documentai_v1beta2/types/document_understanding.py index 6eec6686..f36ad3b5 100644 --- a/google/cloud/documentai_v1beta2/types/document_understanding.py +++ b/google/cloud/documentai_v1beta2/types/document_understanding.py @@ -67,6 +67,7 @@ class BatchProcessDocumentsRequest(proto.Message): class ProcessDocumentRequest(proto.Message): r"""Request to process one document. + Attributes: parent (str): Target project and location to make a call. @@ -142,6 +143,7 @@ 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 @@ -179,6 +181,7 @@ class OcrParams(proto.Message): class TableExtractionParams(proto.Message): r"""Parameters to control table extraction behavior. + Attributes: enabled (bool): Whether to enable table extraction. @@ -226,6 +229,7 @@ class TableBoundHint(proto.Message): class FormExtractionParams(proto.Message): r"""Parameters to control form extraction behavior. + Attributes: enabled (bool): Whether to enable form extraction. @@ -262,6 +266,7 @@ class FormExtractionParams(proto.Message): class KeyValuePairHint(proto.Message): r"""User-provided hint for key value pair. + Attributes: key (str): The key text for the hint. @@ -278,6 +283,7 @@ class KeyValuePairHint(proto.Message): class EntityExtractionParams(proto.Message): r"""Parameters to control entity extraction behavior. + Attributes: enabled (bool): Whether to enable entity extraction. @@ -293,6 +299,7 @@ class EntityExtractionParams(proto.Message): class AutoMlParams(proto.Message): r"""Parameters to control AutoML model prediction behavior. + Attributes: model (str): Resource name of the AutoML model. @@ -306,6 +313,7 @@ class AutoMlParams(proto.Message): 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 @@ -336,6 +344,7 @@ class InputConfig(proto.Message): 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 @@ -392,6 +401,7 @@ class GcsDestination(proto.Message): 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. diff --git a/google/cloud/documentai_v1beta2/types/geometry.py b/google/cloud/documentai_v1beta2/types/geometry.py index f8a03e7f..2c695733 100644 --- a/google/cloud/documentai_v1beta2/types/geometry.py +++ b/google/cloud/documentai_v1beta2/types/geometry.py @@ -56,6 +56,7 @@ class NormalizedVertex(proto.Message): 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. 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 4e190a5a..ea5a8ffa 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 @@ -920,6 +920,12 @@ async def review_document( # Done; return the response. return response + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 df27b514..958223dc 100644 --- a/google/cloud/documentai_v1beta3/services/document_processor_service/client.py +++ b/google/cloud/documentai_v1beta3/services/document_processor_service/client.py @@ -391,10 +391,7 @@ def __init__( client_cert_source_for_mtls=client_cert_source_func, quota_project_id=client_options.quota_project_id, client_info=client_info, - always_use_jwt_access=( - Transport == type(self).get_transport_class("grpc") - or Transport == type(self).get_transport_class("grpc_asyncio") - ), + always_use_jwt_access=True, ) def process_document( @@ -1100,6 +1097,19 @@ def review_document( # Done; return the response. return response + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + try: DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 3dd2e2ac..fa1b23f2 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 @@ -224,6 +224,15 @@ def _prep_wrapped_messages(self, client_info): ), } + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + @property def operations_client(self) -> operations_v1.OperationsClient: """Return the client designed to process long-running operations.""" 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 f40eb9f2..8382c9d5 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 @@ -508,5 +508,8 @@ def review_document( ) return self._stubs["review_document"] + def close(self): + self.grpc_channel.close() + __all__ = ("DocumentProcessorServiceGrpcTransport",) 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 73b3a37c..fd19a769 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 @@ -519,5 +519,8 @@ def review_document( ) return self._stubs["review_document"] + def close(self): + return self.grpc_channel.close() + __all__ = ("DocumentProcessorServiceGrpcAsyncIOTransport",) diff --git a/google/cloud/documentai_v1beta3/types/document.py b/google/cloud/documentai_v1beta3/types/document.py index ef3fc26d..6c428279 100644 --- a/google/cloud/documentai_v1beta3/types/document.py +++ b/google/cloud/documentai_v1beta3/types/document.py @@ -135,6 +135,7 @@ class Style(proto.Message): class FontSize(proto.Message): r"""Font size with unit. + Attributes: size (float): Font size for the text. @@ -162,6 +163,7 @@ class FontSize(proto.Message): class Page(proto.Message): r"""A page in a [Document][google.cloud.documentai.v1beta3.Document]. + Attributes: page_number (int): 1-based index for current @@ -218,6 +220,7 @@ class Page(proto.Message): class Dimension(proto.Message): r"""Dimension for the page. + Attributes: width (float): Page width. @@ -233,6 +236,7 @@ class Dimension(proto.Message): class Image(proto.Message): r"""Rendered image contents for this page. + Attributes: content (bytes): Raw byte content of the image. @@ -275,6 +279,7 @@ class Matrix(proto.Message): 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 @@ -393,6 +398,7 @@ class Line(proto.Message): 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] @@ -468,6 +474,7 @@ class VisualElement(proto.Message): 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] @@ -484,6 +491,7 @@ 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. @@ -495,6 +503,7 @@ 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] @@ -533,6 +542,7 @@ class TableCell(proto.Message): 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] @@ -581,6 +591,7 @@ class FormField(proto.Message): 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 @@ -675,6 +686,7 @@ 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: @@ -938,6 +950,7 @@ class Parent(proto.Message): 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 @@ -960,6 +973,7 @@ 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``, @@ -986,6 +1000,7 @@ class HumanReview(proto.Message): 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 diff --git a/google/cloud/documentai_v1beta3/types/document_io.py b/google/cloud/documentai_v1beta3/types/document_io.py index cf61f907..71831439 100644 --- a/google/cloud/documentai_v1beta3/types/document_io.py +++ b/google/cloud/documentai_v1beta3/types/document_io.py @@ -31,6 +31,7 @@ class RawDocument(proto.Message): r"""Payload message of raw document content (bytes). + Attributes: content (bytes): Inline document content. @@ -45,6 +46,7 @@ class RawDocument(proto.Message): class GcsDocument(proto.Message): r"""Specifies a document stored on Cloud Storage. + Attributes: gcs_uri (str): The Cloud Storage object uri. @@ -58,6 +60,7 @@ class GcsDocument(proto.Message): 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. @@ -111,6 +114,7 @@ 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 diff --git a/google/cloud/documentai_v1beta3/types/document_processor_service.py b/google/cloud/documentai_v1beta3/types/document_processor_service.py index 157f7676..7a26d2bc 100644 --- a/google/cloud/documentai_v1beta3/types/document_processor_service.py +++ b/google/cloud/documentai_v1beta3/types/document_processor_service.py @@ -55,6 +55,7 @@ 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. @@ -83,6 +84,7 @@ class ProcessRequest(proto.Message): 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 @@ -113,6 +115,7 @@ class State(proto.Enum): 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 @@ -138,6 +141,7 @@ 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,6 +161,7 @@ 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 @@ -173,6 +178,7 @@ class BatchInputConfig(proto.Message): 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 @@ -196,11 +202,13 @@ class BatchOutputConfig(proto.Message): 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. @@ -275,6 +283,7 @@ class IndividualProcessStatus(proto.Message): class FetchProcessorTypesRequest(proto.Message): r"""Request message for fetch processor types. + Attributes: parent (str): Required. The project of processor type to @@ -287,6 +296,7 @@ class FetchProcessorTypesRequest(proto.Message): class FetchProcessorTypesResponse(proto.Message): r"""Response message for fetch processor types. + Attributes: processor_types (Sequence[google.cloud.documentai_v1beta3.types.ProcessorType]): The list of processor types. @@ -299,6 +309,7 @@ class FetchProcessorTypesResponse(proto.Message): class ListProcessorsRequest(proto.Message): r"""Request message for list all processors belongs to a project. + Attributes: parent (str): Required. The parent (project and location) @@ -322,6 +333,7 @@ class ListProcessorsRequest(proto.Message): class ListProcessorsResponse(proto.Message): r"""Response message for list processors. + Attributes: processors (Sequence[google.cloud.documentai_v1beta3.types.Processor]): The list of processors. @@ -362,6 +374,7 @@ class CreateProcessorRequest(proto.Message): class DeleteProcessorRequest(proto.Message): r"""Request message for the delete processor method. + Attributes: name (str): Required. The processor resource name to be @@ -388,6 +401,7 @@ class DeleteProcessorMetadata(proto.Message): class EnableProcessorRequest(proto.Message): r"""Request message for the enable processor method. + Attributes: name (str): Required. The processor resource name to be @@ -398,7 +412,8 @@ class EnableProcessorRequest(proto.Message): class EnableProcessorResponse(proto.Message): - r"""Response message for the enable processor method. """ + r"""Response message for the enable processor method. + """ class EnableProcessorMetadata(proto.Message): @@ -418,6 +433,7 @@ class EnableProcessorMetadata(proto.Message): class DisableProcessorRequest(proto.Message): r"""Request message for the disable processor method. + Attributes: name (str): Required. The processor resource name to be @@ -428,7 +444,8 @@ class DisableProcessorRequest(proto.Message): class DisableProcessorResponse(proto.Message): - r"""Response message for the disable processor method. """ + r"""Response message for the disable processor method. + """ class DisableProcessorMetadata(proto.Message): @@ -482,6 +499,7 @@ class Priority(proto.Enum): class ReviewDocumentResponse(proto.Message): r"""Response message for review document method. + Attributes: gcs_destination (str): The Cloud Storage uri for the human reviewed diff --git a/google/cloud/documentai_v1beta3/types/geometry.py b/google/cloud/documentai_v1beta3/types/geometry.py index 8fa89041..b00e3b1c 100644 --- a/google/cloud/documentai_v1beta3/types/geometry.py +++ b/google/cloud/documentai_v1beta3/types/geometry.py @@ -58,6 +58,7 @@ class NormalizedVertex(proto.Message): 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. diff --git a/google/cloud/documentai_v1beta3/types/operation_metadata.py b/google/cloud/documentai_v1beta3/types/operation_metadata.py index 8c79a171..05c1e07e 100644 --- a/google/cloud/documentai_v1beta3/types/operation_metadata.py +++ b/google/cloud/documentai_v1beta3/types/operation_metadata.py @@ -25,6 +25,7 @@ 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. 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 dfc013e7..14c874fa 100644 --- a/tests/unit/gapic/documentai_v1/test_document_processor_service.py +++ b/tests/unit/gapic/documentai_v1/test_document_processor_service.py @@ -32,6 +32,7 @@ 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.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.documentai_v1.services.document_processor_service import ( @@ -1298,6 +1299,9 @@ def test_document_processor_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + # Additionally, the LRO client (a property) should # also raise NotImplementedError with pytest.raises(NotImplementedError): @@ -1841,3 +1845,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = DocumentProcessorServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = DocumentProcessorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = DocumentProcessorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() 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 d2edb50c..6aa3f59c 100644 --- a/tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py +++ b/tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py @@ -32,6 +32,7 @@ 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.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.documentai_v1beta2.services.document_understanding_service import ( @@ -1024,6 +1025,9 @@ def test_document_understanding_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + # Additionally, the LRO client (a property) should # also raise NotImplementedError with pytest.raises(NotImplementedError): @@ -1526,3 +1530,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = DocumentUnderstandingServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = DocumentUnderstandingServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = DocumentUnderstandingServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() 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 f31879d8..45746ed3 100644 --- a/tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py +++ b/tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py @@ -32,6 +32,7 @@ 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.api_core import path_template from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError from google.cloud.documentai_v1beta3.services.document_processor_service import ( @@ -2646,6 +2647,9 @@ def test_document_processor_service_base_transport(): with pytest.raises(NotImplementedError): getattr(transport, method)(request=object()) + with pytest.raises(NotImplementedError): + transport.close() + # Additionally, the LRO client (a property) should # also raise NotImplementedError with pytest.raises(NotImplementedError): @@ -3215,3 +3219,49 @@ def test_client_withDEFAULT_CLIENT_INFO(): credentials=ga_credentials.AnonymousCredentials(), client_info=client_info, ) prep.assert_called_once_with(client_info) + + +@pytest.mark.asyncio +async def test_transport_close_async(): + client = DocumentProcessorServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio", + ) + with mock.patch.object( + type(getattr(client.transport, "grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close(): + transports = { + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = DocumentProcessorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + with mock.patch.object( + type(getattr(client.transport, close_name)), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "grpc", + ] + for transport in transports: + client = DocumentProcessorServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called()