From 64b524e4a6e897162462ddfe1bb358223ebca311 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 26 Mar 2021 21:13:55 +0100 Subject: [PATCH 01/25] chore(deps): update dependency google-cloud-storage to v1.37.0 (#104) --- samples/snippets/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/requirements.txt b/samples/snippets/requirements.txt index ce6670de..f9c89ad8 100644 --- a/samples/snippets/requirements.txt +++ b/samples/snippets/requirements.txt @@ -1,2 +1,2 @@ google-cloud-documentai==0.3.0 -google-cloud-storage==1.36.2 +google-cloud-storage==1.37.0 From 2ad6f7a2b9a3509d50fc037f00c0376f896020b1 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Tue, 30 Mar 2021 08:42:13 -0700 Subject: [PATCH 02/25] chore: track generated files (#106) --- documentai-v1-py.tar.gz | 0 synth.metadata | 143 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 documentai-v1-py.tar.gz diff --git a/documentai-v1-py.tar.gz b/documentai-v1-py.tar.gz new file mode 100644 index 00000000..e69de29b diff --git a/synth.metadata b/synth.metadata index 1d63eab3..41efba36 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,8 +3,8 @@ { "git": { "name": ".", - "remote": "git@github.com:googleapis/python-documentai", - "sha": "9fd02a6b9ba34a6762a762f12de9948daf1ea9bb" + "remote": "https://github.com/googleapis/python-documentai.git", + "sha": "64b524e4a6e897162462ddfe1bb358223ebca311" } }, { @@ -58,5 +58,144 @@ "generator": "bazel" } } + ], + "generatedFiles": [ + ".coveragerc", + ".flake8", + ".github/CONTRIBUTING.md", + ".github/ISSUE_TEMPLATE/bug_report.md", + ".github/ISSUE_TEMPLATE/feature_request.md", + ".github/ISSUE_TEMPLATE/support_request.md", + ".github/PULL_REQUEST_TEMPLATE.md", + ".github/header-checker-lint.yml", + ".github/release-please.yml", + ".github/snippet-bot.yml", + ".gitignore", + ".kokoro/build.sh", + ".kokoro/continuous/common.cfg", + ".kokoro/continuous/continuous.cfg", + ".kokoro/docker/docs/Dockerfile", + ".kokoro/docker/docs/fetch_gpg_keys.sh", + ".kokoro/docs/common.cfg", + ".kokoro/docs/docs-presubmit.cfg", + ".kokoro/docs/docs.cfg", + ".kokoro/populate-secrets.sh", + ".kokoro/presubmit/common.cfg", + ".kokoro/presubmit/presubmit.cfg", + ".kokoro/publish-docs.sh", + ".kokoro/release.sh", + ".kokoro/release/common.cfg", + ".kokoro/release/release.cfg", + ".kokoro/samples/lint/common.cfg", + ".kokoro/samples/lint/continuous.cfg", + ".kokoro/samples/lint/periodic.cfg", + ".kokoro/samples/lint/presubmit.cfg", + ".kokoro/samples/python3.6/common.cfg", + ".kokoro/samples/python3.6/continuous.cfg", + ".kokoro/samples/python3.6/periodic-head.cfg", + ".kokoro/samples/python3.6/periodic.cfg", + ".kokoro/samples/python3.6/presubmit.cfg", + ".kokoro/samples/python3.7/common.cfg", + ".kokoro/samples/python3.7/continuous.cfg", + ".kokoro/samples/python3.7/periodic-head.cfg", + ".kokoro/samples/python3.7/periodic.cfg", + ".kokoro/samples/python3.7/presubmit.cfg", + ".kokoro/samples/python3.8/common.cfg", + ".kokoro/samples/python3.8/continuous.cfg", + ".kokoro/samples/python3.8/periodic-head.cfg", + ".kokoro/samples/python3.8/periodic.cfg", + ".kokoro/samples/python3.8/presubmit.cfg", + ".kokoro/test-samples-against-head.sh", + ".kokoro/test-samples-impl.sh", + ".kokoro/test-samples.sh", + ".kokoro/trampoline.sh", + ".kokoro/trampoline_v2.sh", + ".pre-commit-config.yaml", + ".trampolinerc", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.rst", + "LICENSE", + "MANIFEST.in", + "docs/_static/custom.css", + "docs/_templates/layout.html", + "docs/conf.py", + "docs/documentai_v1/document_processor_service.rst", + "docs/documentai_v1/services.rst", + "docs/documentai_v1/types.rst", + "docs/documentai_v1beta2/document_understanding_service.rst", + "docs/documentai_v1beta2/services.rst", + "docs/documentai_v1beta2/types.rst", + "docs/documentai_v1beta3/document_processor_service.rst", + "docs/documentai_v1beta3/services.rst", + "docs/documentai_v1beta3/types.rst", + "docs/multiprocessing.rst", + "documentai-v1-py.tar.gz", + "google/cloud/documentai/__init__.py", + "google/cloud/documentai/py.typed", + "google/cloud/documentai_v1/__init__.py", + "google/cloud/documentai_v1/py.typed", + "google/cloud/documentai_v1/services/__init__.py", + "google/cloud/documentai_v1/services/document_processor_service/__init__.py", + "google/cloud/documentai_v1/services/document_processor_service/async_client.py", + "google/cloud/documentai_v1/services/document_processor_service/client.py", + "google/cloud/documentai_v1/services/document_processor_service/transports/__init__.py", + "google/cloud/documentai_v1/services/document_processor_service/transports/base.py", + "google/cloud/documentai_v1/services/document_processor_service/transports/grpc.py", + "google/cloud/documentai_v1/services/document_processor_service/transports/grpc_asyncio.py", + "google/cloud/documentai_v1/types/__init__.py", + "google/cloud/documentai_v1/types/document.py", + "google/cloud/documentai_v1/types/document_io.py", + "google/cloud/documentai_v1/types/document_processor_service.py", + "google/cloud/documentai_v1/types/geometry.py", + "google/cloud/documentai_v1beta2/__init__.py", + "google/cloud/documentai_v1beta2/py.typed", + "google/cloud/documentai_v1beta2/services/__init__.py", + "google/cloud/documentai_v1beta2/services/document_understanding_service/__init__.py", + "google/cloud/documentai_v1beta2/services/document_understanding_service/async_client.py", + "google/cloud/documentai_v1beta2/services/document_understanding_service/client.py", + "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/__init__.py", + "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/base.py", + "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc.py", + "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc_asyncio.py", + "google/cloud/documentai_v1beta2/types/__init__.py", + "google/cloud/documentai_v1beta2/types/document.py", + "google/cloud/documentai_v1beta2/types/document_understanding.py", + "google/cloud/documentai_v1beta2/types/geometry.py", + "google/cloud/documentai_v1beta3/__init__.py", + "google/cloud/documentai_v1beta3/py.typed", + "google/cloud/documentai_v1beta3/services/__init__.py", + "google/cloud/documentai_v1beta3/services/document_processor_service/__init__.py", + "google/cloud/documentai_v1beta3/services/document_processor_service/async_client.py", + "google/cloud/documentai_v1beta3/services/document_processor_service/client.py", + "google/cloud/documentai_v1beta3/services/document_processor_service/transports/__init__.py", + "google/cloud/documentai_v1beta3/services/document_processor_service/transports/base.py", + "google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc.py", + "google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc_asyncio.py", + "google/cloud/documentai_v1beta3/types/__init__.py", + "google/cloud/documentai_v1beta3/types/document.py", + "google/cloud/documentai_v1beta3/types/document_io.py", + "google/cloud/documentai_v1beta3/types/document_processor_service.py", + "google/cloud/documentai_v1beta3/types/geometry.py", + "mypy.ini", + "noxfile.py", + "renovate.json", + "samples/AUTHORING_GUIDE.md", + "samples/CONTRIBUTING.md", + "samples/snippets/noxfile.py", + "scripts/decrypt-secrets.sh", + "scripts/readme-gen/readme_gen.py", + "scripts/readme-gen/templates/README.tmpl.rst", + "scripts/readme-gen/templates/auth.tmpl.rst", + "scripts/readme-gen/templates/auth_api_key.tmpl.rst", + "scripts/readme-gen/templates/install_deps.tmpl.rst", + "scripts/readme-gen/templates/install_portaudio.tmpl.rst", + "setup.cfg", + "testing/.gitignore", + "tests/unit/gapic/documentai_v1/__init__.py", + "tests/unit/gapic/documentai_v1/test_document_processor_service.py", + "tests/unit/gapic/documentai_v1beta2/__init__.py", + "tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py", + "tests/unit/gapic/documentai_v1beta3/__init__.py", + "tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py" ] } \ No newline at end of file From be4e3cb380335cf74a478f6806335dc9e5c05b0f Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 30 Mar 2021 17:42:32 +0200 Subject: [PATCH 03/25] chore(deps): update dependency google-cloud-documentai to v0.4.0 (#103) --- samples/snippets/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/requirements.txt b/samples/snippets/requirements.txt index f9c89ad8..f5e55e70 100644 --- a/samples/snippets/requirements.txt +++ b/samples/snippets/requirements.txt @@ -1,2 +1,2 @@ -google-cloud-documentai==0.3.0 +google-cloud-documentai==0.4.0 google-cloud-storage==1.37.0 From 30fc65be748c5a7aee3d6c34cb18e040666e49b3 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Wed, 31 Mar 2021 12:36:22 -0700 Subject: [PATCH 04/25] build(python): update docfx job to use new plugin (#112) * changes without context * build(python): update docfx job to use new plugin Source-Author: Dan Lee <71398022+dandhlee@users.noreply.github.com> Source-Date: Tue Mar 30 19:36:37 2021 -0400 Source-Repo: googleapis/synthtool Source-Sha: 4501974ad08b5d693311457e2ea4ce845676e329 Source-Link: https://github.com/googleapis/synthtool/commit/4501974ad08b5d693311457e2ea4ce845676e329 --- documentai-v1-py.tar.gz | 0 noxfile.py | 4 +--- synth.metadata | 7 +++---- 3 files changed, 4 insertions(+), 7 deletions(-) delete mode 100644 documentai-v1-py.tar.gz diff --git a/documentai-v1-py.tar.gz b/documentai-v1-py.tar.gz deleted file mode 100644 index e69de29b..00000000 diff --git a/noxfile.py b/noxfile.py index ae8392be..af50a606 100644 --- a/noxfile.py +++ b/noxfile.py @@ -211,9 +211,7 @@ def docfx(session): """Build the docfx yaml files for this library.""" session.install("-e", ".") - # sphinx-docfx-yaml supports up to sphinx version 1.5.5. - # https://github.com/docascode/sphinx-docfx-yaml/issues/97 - session.install("sphinx==1.5.5", "alabaster", "recommonmark", "sphinx-docfx-yaml") + session.install("sphinx", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml") shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( diff --git a/synth.metadata b/synth.metadata index 41efba36..95033970 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/python-documentai.git", - "sha": "64b524e4a6e897162462ddfe1bb358223ebca311" + "sha": "be4e3cb380335cf74a478f6806335dc9e5c05b0f" } }, { @@ -19,14 +19,14 @@ "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "7a3df8832c7c64c482874c5dbebfd0a732b4938b" + "sha": "4501974ad08b5d693311457e2ea4ce845676e329" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "7a3df8832c7c64c482874c5dbebfd0a732b4938b" + "sha": "4501974ad08b5d693311457e2ea4ce845676e329" } } ], @@ -129,7 +129,6 @@ "docs/documentai_v1beta3/services.rst", "docs/documentai_v1beta3/types.rst", "docs/multiprocessing.rst", - "documentai-v1-py.tar.gz", "google/cloud/documentai/__init__.py", "google/cloud/documentai/py.typed", "google/cloud/documentai_v1/__init__.py", From 85c74a6fc58560389a29ef65e02f918c2170474b Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Mon, 5 Apr 2021 11:58:06 -0700 Subject: [PATCH 05/25] chore: add tarfile (#113) --- documentai-v1beta3-py.tar.gz | 0 synth.metadata | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 documentai-v1beta3-py.tar.gz diff --git a/documentai-v1beta3-py.tar.gz b/documentai-v1beta3-py.tar.gz new file mode 100644 index 00000000..e69de29b diff --git a/synth.metadata b/synth.metadata index 95033970..ceac078e 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/python-documentai.git", - "sha": "be4e3cb380335cf74a478f6806335dc9e5c05b0f" + "sha": "30fc65be748c5a7aee3d6c34cb18e040666e49b3" } }, { @@ -129,6 +129,7 @@ "docs/documentai_v1beta3/services.rst", "docs/documentai_v1beta3/types.rst", "docs/multiprocessing.rst", + "documentai-v1beta3-py.tar.gz", "google/cloud/documentai/__init__.py", "google/cloud/documentai/py.typed", "google/cloud/documentai_v1/__init__.py", From bcef3b8b8e3c107ed7ba8528e901731fc185b582 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Wed, 7 Apr 2021 13:12:01 -0700 Subject: [PATCH 06/25] chore: add license headers (#116) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/c5b4f9fb-cbef-4107-b15c-6f8df463f921/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/5b5bf6d519b2d658d9f2e483d9f6f3d0ba8ee6bc --- .pre-commit-config.yaml | 14 ++++++++++++++ docs/conf.py | 13 +++++++++++++ ...beta3-py.tar.gz => documentai-v1beta2-py.tar.gz | 0 synth.metadata | 8 ++++---- 4 files changed, 31 insertions(+), 4 deletions(-) rename documentai-v1beta3-py.tar.gz => documentai-v1beta2-py.tar.gz (100%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 32302e48..8912e9b5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,17 @@ +# Copyright 2021 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. +# # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: diff --git a/docs/conf.py b/docs/conf.py index 4982dd92..a5040f2a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,17 @@ # -*- coding: utf-8 -*- +# Copyright 2021 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. # # google-cloud-documentai documentation build configuration file # diff --git a/documentai-v1beta3-py.tar.gz b/documentai-v1beta2-py.tar.gz similarity index 100% rename from documentai-v1beta3-py.tar.gz rename to documentai-v1beta2-py.tar.gz diff --git a/synth.metadata b/synth.metadata index ceac078e..fa3cdb80 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/python-documentai.git", - "sha": "30fc65be748c5a7aee3d6c34cb18e040666e49b3" + "sha": "85c74a6fc58560389a29ef65e02f918c2170474b" } }, { @@ -19,14 +19,14 @@ "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "4501974ad08b5d693311457e2ea4ce845676e329" + "sha": "5b5bf6d519b2d658d9f2e483d9f6f3d0ba8ee6bc" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "4501974ad08b5d693311457e2ea4ce845676e329" + "sha": "5b5bf6d519b2d658d9f2e483d9f6f3d0ba8ee6bc" } } ], @@ -129,7 +129,7 @@ "docs/documentai_v1beta3/services.rst", "docs/documentai_v1beta3/types.rst", "docs/multiprocessing.rst", - "documentai-v1beta3-py.tar.gz", + "documentai-v1beta2-py.tar.gz", "google/cloud/documentai/__init__.py", "google/cloud/documentai/py.typed", "google/cloud/documentai_v1/__init__.py", From 9878a282d7a8180157d398e52a4b91be61a63e77 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Thu, 8 Apr 2021 07:50:14 -0700 Subject: [PATCH 07/25] chore: delete tarfile (#117) --- documentai-v1beta2-py.tar.gz | 0 synth.metadata | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 documentai-v1beta2-py.tar.gz diff --git a/documentai-v1beta2-py.tar.gz b/documentai-v1beta2-py.tar.gz deleted file mode 100644 index e69de29b..00000000 diff --git a/synth.metadata b/synth.metadata index fa3cdb80..8a689c24 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/python-documentai.git", - "sha": "85c74a6fc58560389a29ef65e02f918c2170474b" + "sha": "bcef3b8b8e3c107ed7ba8528e901731fc185b582" } }, { @@ -129,7 +129,6 @@ "docs/documentai_v1beta3/services.rst", "docs/documentai_v1beta3/types.rst", "docs/multiprocessing.rst", - "documentai-v1beta2-py.tar.gz", "google/cloud/documentai/__init__.py", "google/cloud/documentai/py.typed", "google/cloud/documentai_v1/__init__.py", From ef5930df704a2a84fb93926349b0d6818c4a5a82 Mon Sep 17 00:00:00 2001 From: Eric Schmidt Date: Mon, 12 Apr 2021 14:05:13 -0700 Subject: [PATCH 08/25] samples: updates Document AI samples to v1 version of service (#108) --- .../batch_process_documents_sample_v1beta3.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/samples/snippets/batch_process_documents_sample_v1beta3.py b/samples/snippets/batch_process_documents_sample_v1beta3.py index b1ed3226..a66ff441 100644 --- a/samples/snippets/batch_process_documents_sample_v1beta3.py +++ b/samples/snippets/batch_process_documents_sample_v1beta3.py @@ -16,7 +16,7 @@ # [START documentai_batch_process_document] import re -from google.cloud import documentai_v1beta3 as documentai +from google.cloud import documentai_v1 as documentai from google.cloud import storage # TODO(developer): Uncomment these variables before running the sample. @@ -47,23 +47,25 @@ def batch_process_documents( destination_uri = f"{gcs_output_uri}/{gcs_output_uri_prefix}/" + gcs_documents = documentai.GcsDocuments( + documents=[{"gcs_uri": gcs_input_uri, "mime_type": "application/pdf"}] + ) + # 'mime_type' can be 'application/pdf', 'image/tiff', # and 'image/gif', or 'application/json' - input_config = documentai.types.document_processor_service.BatchProcessRequest.BatchInputConfig( - gcs_source=gcs_input_uri, mime_type="application/pdf" - ) + input_config = documentai.BatchDocumentsInputConfig(gcs_documents=gcs_documents) # Where to write results - output_config = documentai.types.document_processor_service.BatchProcessRequest.BatchOutputConfig( - gcs_destination=destination_uri + output_config = documentai.DocumentOutputConfig( + gcs_output_config={"gcs_uri": destination_uri} ) # Location can be 'us' or 'eu' name = f"projects/{project_id}/locations/{location}/processors/{processor_id}" request = documentai.types.document_processor_service.BatchProcessRequest( name=name, - input_configs=[input_config], - output_config=output_config, + input_documents=input_config, + document_output_config=output_config, ) operation = client.batch_process_documents(request) From af97afc048b2583b5ff3f15d3d254eafc7e7afbf Mon Sep 17 00:00:00 2001 From: Eric Schmidt Date: Wed, 14 Apr 2021 10:13:15 -0700 Subject: [PATCH 09/25] samples: more updates for v1 (#121) * samples: more updates for v1 * fix: lint * fix: tests * fix: tests * fix: tests --- samples/snippets/batch_parse_form_v1beta2.py | 2 +- .../snippets/batch_parse_form_v1beta2_test.py | 4 +- samples/snippets/batch_parse_table_v1beta2.py | 2 +- .../batch_parse_table_v1beta2_test.py | 4 +- ...3.py => batch_process_documents_sample.py} | 0 ...rocess_documents_sample_bad_input_test.py} | 4 +- ...=> batch_process_documents_sample_test.py} | 4 +- samples/snippets/noxfile.py | 38 ++++++++++--------- ..._v1beta3.py => process_document_sample.py} | 4 +- ...est.py => process_document_sample_test.py} | 4 +- ...sample_v1beta3.py => quickstart_sample.py} | 4 +- ...eta3_test.py => quickstart_sample_test.py} | 4 +- 12 files changed, 40 insertions(+), 34 deletions(-) rename samples/snippets/{batch_process_documents_sample_v1beta3.py => batch_process_documents_sample.py} (100%) rename samples/snippets/{batch_process_documents_sample_bad_input_v1beta3_test.py => batch_process_documents_sample_bad_input_test.py} (91%) rename samples/snippets/{batch_process_documents_sample_v1beta3_test.py => batch_process_documents_sample_test.py} (92%) rename samples/snippets/{process_document_sample_v1beta3.py => process_document_sample.py} (96%) rename samples/snippets/{process_document_sample_v1beta3_test.py => process_document_sample_test.py} (88%) rename samples/snippets/{quickstart_sample_v1beta3.py => quickstart_sample.py} (96%) rename samples/snippets/{quickstart_sample_v1beta3_test.py => quickstart_sample_test.py} (90%) diff --git a/samples/snippets/batch_parse_form_v1beta2.py b/samples/snippets/batch_parse_form_v1beta2.py index ae60fd63..a3220b4a 100644 --- a/samples/snippets/batch_parse_form_v1beta2.py +++ b/samples/snippets/batch_parse_form_v1beta2.py @@ -24,7 +24,7 @@ def batch_parse_form( project_id="YOUR_PROJECT_ID", input_uri="gs://cloud-samples-data/documentai/form.pdf", destination_uri="gs://your-bucket-id/path/to/save/results/", - timeout=90 + timeout=90, ): """Parse a form""" diff --git a/samples/snippets/batch_parse_form_v1beta2_test.py b/samples/snippets/batch_parse_form_v1beta2_test.py index 6abd19a2..f42cb249 100644 --- a/samples/snippets/batch_parse_form_v1beta2_test.py +++ b/samples/snippets/batch_parse_form_v1beta2_test.py @@ -41,6 +41,8 @@ def setup_teardown(): def test_batch_parse_form(capsys): - batch_parse_form_v1beta2.batch_parse_form(PROJECT_ID, INPUT_URI, BATCH_OUTPUT_URI, 120) + batch_parse_form_v1beta2.batch_parse_form( + PROJECT_ID, INPUT_URI, BATCH_OUTPUT_URI, 120 + ) out, _ = capsys.readouterr() assert "Output files" in out diff --git a/samples/snippets/batch_parse_table_v1beta2.py b/samples/snippets/batch_parse_table_v1beta2.py index f62495b4..16851437 100644 --- a/samples/snippets/batch_parse_table_v1beta2.py +++ b/samples/snippets/batch_parse_table_v1beta2.py @@ -24,7 +24,7 @@ def batch_parse_table( project_id="YOUR_PROJECT_ID", input_uri="gs://cloud-samples-data/documentai/form.pdf", destination_uri="gs://your-bucket-id/path/to/save/results/", - timeout=90 + timeout=90, ): """Parse a form""" diff --git a/samples/snippets/batch_parse_table_v1beta2_test.py b/samples/snippets/batch_parse_table_v1beta2_test.py index aa890520..0818d8c0 100644 --- a/samples/snippets/batch_parse_table_v1beta2_test.py +++ b/samples/snippets/batch_parse_table_v1beta2_test.py @@ -41,6 +41,8 @@ def setup_teardown(): def test_batch_parse_table(capsys): - batch_parse_table_v1beta2.batch_parse_table(PROJECT_ID, INPUT_URI, BATCH_OUTPUT_URI, 120) + batch_parse_table_v1beta2.batch_parse_table( + PROJECT_ID, INPUT_URI, BATCH_OUTPUT_URI, 120 + ) out, _ = capsys.readouterr() assert "Output files:" in out diff --git a/samples/snippets/batch_process_documents_sample_v1beta3.py b/samples/snippets/batch_process_documents_sample.py similarity index 100% rename from samples/snippets/batch_process_documents_sample_v1beta3.py rename to samples/snippets/batch_process_documents_sample.py diff --git a/samples/snippets/batch_process_documents_sample_bad_input_v1beta3_test.py b/samples/snippets/batch_process_documents_sample_bad_input_test.py similarity index 91% rename from samples/snippets/batch_process_documents_sample_bad_input_v1beta3_test.py rename to samples/snippets/batch_process_documents_sample_bad_input_test.py index e0a7e468..77440c9c 100644 --- a/samples/snippets/batch_process_documents_sample_bad_input_v1beta3_test.py +++ b/samples/snippets/batch_process_documents_sample_bad_input_test.py @@ -16,7 +16,7 @@ import os from uuid import uuid4 -from samples.snippets import batch_process_documents_sample_v1beta3 +from samples.snippets import batch_process_documents_sample location = "us" project_id = os.getenv("GOOGLE_CLOUD_PROJECT") @@ -29,7 +29,7 @@ def test_batch_process_documents_with_bad_input(capsys): try: - batch_process_documents_sample_v1beta3.batch_process_documents( + batch_process_documents_sample.batch_process_documents( project_id=project_id, location=location, processor_id=processor_id, diff --git a/samples/snippets/batch_process_documents_sample_v1beta3_test.py b/samples/snippets/batch_process_documents_sample_test.py similarity index 92% rename from samples/snippets/batch_process_documents_sample_v1beta3_test.py rename to samples/snippets/batch_process_documents_sample_test.py index dcb63567..7168d5a7 100644 --- a/samples/snippets/batch_process_documents_sample_v1beta3_test.py +++ b/samples/snippets/batch_process_documents_sample_test.py @@ -21,7 +21,7 @@ import pytest -from samples.snippets import batch_process_documents_sample_v1beta3 +from samples.snippets import batch_process_documents_sample location = "us" project_id = os.environ["GOOGLE_CLOUD_PROJECT"] @@ -47,7 +47,7 @@ def test_bucket(): def test_batch_process_documents(capsys, test_bucket): - batch_process_documents_sample_v1beta3.batch_process_documents( + batch_process_documents_sample.batch_process_documents( project_id=project_id, location=location, processor_id=processor_id, diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index 97bf7da8..f2320ea0 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -38,28 +38,25 @@ TEST_CONFIG = { # You can opt out from the test for specific Python versions. - 'ignored_versions': ["2.7"], - + "ignored_versions": ["2.7"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them - 'enforce_type_hints': False, - + "enforce_type_hints": False, # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string # to use your own Cloud project. - 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', - # A dictionary you want to inject into your test. Don't put any # secrets here. These values will override predefined values. - 'envs': {}, + "envs": {}, } try: # Ensure we can import noxfile_config in the project's directory. - sys.path.append('.') + sys.path.append(".") from noxfile_config import TEST_CONFIG_OVERRIDE except ImportError as e: print("No user noxfile_config found: detail: {}".format(e)) @@ -74,12 +71,12 @@ def get_pytest_env_vars() -> Dict[str, str]: ret = {} # Override the GCLOUD_PROJECT and the alias. - env_key = TEST_CONFIG['gcloud_project_env'] + env_key = TEST_CONFIG["gcloud_project_env"] # This should error out if not set. - ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] # Apply user supplied envs. - ret.update(TEST_CONFIG['envs']) + ret.update(TEST_CONFIG["envs"]) return ret @@ -88,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. -IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) @@ -137,7 +134,7 @@ def _determine_local_import_names(start_dir: str) -> List[str]: @nox.session def lint(session: nox.sessions.Session) -> None: - if not TEST_CONFIG['enforce_type_hints']: + if not TEST_CONFIG["enforce_type_hints"]: session.install("flake8", "flake8-import-order") else: session.install("flake8", "flake8-import-order", "flake8-annotations") @@ -146,9 +143,11 @@ def lint(session: nox.sessions.Session) -> None: args = FLAKE8_COMMON_ARGS + [ "--application-import-names", ",".join(local_names), - "." + ".", ] session.run("flake8", *args) + + # # Black # @@ -161,6 +160,7 @@ def blacken(session: nox.sessions.Session) -> None: session.run("black", *python_files) + # # Sample Tests # @@ -169,7 +169,9 @@ def blacken(session: nox.sessions.Session) -> None: PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] -def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: """Runs py.test for a particular project.""" if os.path.exists("requirements.txt"): session.install("-r", "requirements.txt") @@ -200,9 +202,9 @@ def py(session: nox.sessions.Session) -> None: if session.python in TESTED_VERSIONS: _session_tests(session) else: - session.skip("SKIPPED: {} tests are disabled for this sample.".format( - session.python - )) + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) # diff --git a/samples/snippets/process_document_sample_v1beta3.py b/samples/snippets/process_document_sample.py similarity index 96% rename from samples/snippets/process_document_sample_v1beta3.py rename to samples/snippets/process_document_sample.py index ab69d073..b9fbe87b 100644 --- a/samples/snippets/process_document_sample_v1beta3.py +++ b/samples/snippets/process_document_sample.py @@ -25,7 +25,7 @@ def process_document_sample( project_id: str, location: str, processor_id: str, file_path: str ): - from google.cloud import documentai_v1beta3 as documentai + from google.cloud import documentai_v1 as documentai # You must set the api_endpoint if you use a location other than 'us', e.g.: opts = {} @@ -46,7 +46,7 @@ def process_document_sample( document = {"content": image_content, "mime_type": "application/pdf"} # Configure the process request - request = {"name": name, "document": document} + request = {"name": name, "raw_document": document} # Recognizes text entities in the PDF document result = client.process_document(request=request) diff --git a/samples/snippets/process_document_sample_v1beta3_test.py b/samples/snippets/process_document_sample_test.py similarity index 88% rename from samples/snippets/process_document_sample_v1beta3_test.py rename to samples/snippets/process_document_sample_test.py index 58b11b22..8fe188d8 100644 --- a/samples/snippets/process_document_sample_v1beta3_test.py +++ b/samples/snippets/process_document_sample_test.py @@ -15,7 +15,7 @@ import os -from samples.snippets import process_document_sample_v1beta3 +from samples.snippets import process_document_sample location = "us" @@ -25,7 +25,7 @@ def test_process_documents(capsys): - process_document_sample_v1beta3.process_document_sample( + process_document_sample.process_document_sample( project_id=project_id, location=location, processor_id=processor_id, diff --git a/samples/snippets/quickstart_sample_v1beta3.py b/samples/snippets/quickstart_sample.py similarity index 96% rename from samples/snippets/quickstart_sample_v1beta3.py rename to samples/snippets/quickstart_sample.py index 884b412c..2e4ef103 100644 --- a/samples/snippets/quickstart_sample_v1beta3.py +++ b/samples/snippets/quickstart_sample.py @@ -13,7 +13,7 @@ # limitations under the License. # -from google.cloud import documentai_v1beta3 as documentai +from google.cloud import documentai_v1 as documentai # [START documentai_quickstart] @@ -45,7 +45,7 @@ def quickstart(project_id: str, location: str, processor_id: str, file_path: str document = {"content": image_content, "mime_type": "application/pdf"} # Configure the process request - request = {"name": name, "document": document} + request = {"name": name, "raw_document": document} result = client.process_document(request=request) document = result.document diff --git a/samples/snippets/quickstart_sample_v1beta3_test.py b/samples/snippets/quickstart_sample_test.py similarity index 90% rename from samples/snippets/quickstart_sample_v1beta3_test.py rename to samples/snippets/quickstart_sample_test.py index 4badc1f7..afeeface 100644 --- a/samples/snippets/quickstart_sample_v1beta3_test.py +++ b/samples/snippets/quickstart_sample_test.py @@ -15,7 +15,7 @@ import os -from samples.snippets import quickstart_sample_v1beta3 +from samples.snippets import quickstart_sample location = "us" project_id = os.environ["GOOGLE_CLOUD_PROJECT"] @@ -24,7 +24,7 @@ def test_quickstart(capsys): - quickstart_sample_v1beta3.quickstart( + quickstart_sample.quickstart( project_id=project_id, location=location, processor_id=processor_id, From c65cc9d66692e05227535acc211424dbf179f555 Mon Sep 17 00:00:00 2001 From: Dan Lee <71398022+dandhlee@users.noreply.github.com> Date: Mon, 19 Apr 2021 11:32:19 -0400 Subject: [PATCH 10/25] chore: prevent normalization of semver versioning (#122) When there is a patch version added to semver versioning, setuptools.setup(version) will normalize the versioning from `-patch` to `.patch` which is not correct SEMVER versioning. The added feature with setuptools.sic(version) will prevent this from happening. --- setup.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4cba6749..968d4c86 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,21 @@ import os import setuptools # type: ignore +# Disable version normalization performed by setuptools.setup() +try: + # Try the approach of using sic(), added in setuptools 46.1.0 + from setuptools import sic +except ImportError: + # Try the approach of replacing packaging.version.Version + sic = lambda v: v + try: + # setuptools >=39.0.0 uses packaging from setuptools.extern + from setuptools.extern import packaging + except ImportError: + # setuptools <39.0.0 uses packaging from pkg_resources.extern + from pkg_resources.extern import packaging + packaging.version.Version = packaging.version.LegacyVersion + version = "0.4.0" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -30,7 +45,7 @@ setuptools.setup( name="google-cloud-documentai", - version=version, + version=sic(version), long_description=readme, author="Google LLC", author_email="googleapis-packages@google.com", From 324aa9dcae6797dc8a25e61e396f86eef15e0aee Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Mon, 19 Apr 2021 08:34:17 -0700 Subject: [PATCH 11/25] chore: template updates (#120) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/60d94463-5a7c-4c76-829d-2ff8e6f3696f/targets - [ ] To automatically regenerate this PR, check this box. (May take up to 24 hours.) Source-Link: https://github.com/googleapis/synthtool/commit/0a071b3460344886297a304253bf924aa68ddb7e --- .github/header-checker-lint.yml | 2 +- documentai-v1-py.tar.gz | 0 renovate.json | 5 ++++- samples/snippets/noxfile.py | 10 ++++++++-- synth.metadata | 7 ++++--- 5 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 documentai-v1-py.tar.gz diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml index fc281c05..6fe78aa7 100644 --- a/.github/header-checker-lint.yml +++ b/.github/header-checker-lint.yml @@ -1,6 +1,6 @@ {"allowedCopyrightHolders": ["Google LLC"], "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"], - "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt"], + "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt", "**/__init__.py", "samples/**/constraints.txt", "samples/**/constraints-test.txt"], "sourceFileExtensions": [ "ts", "js", diff --git a/documentai-v1-py.tar.gz b/documentai-v1-py.tar.gz new file mode 100644 index 00000000..e69de29b diff --git a/renovate.json b/renovate.json index f08bc22c..c0489556 100644 --- a/renovate.json +++ b/renovate.json @@ -2,5 +2,8 @@ "extends": [ "config:base", ":preserveSemverRanges" ], - "ignorePaths": [".pre-commit-config.yaml"] + "ignorePaths": [".pre-commit-config.yaml"], + "pip_requirements": { + "fileMatch": ["requirements-test.txt", "samples/[\\S/]*constraints.txt", "samples/[\\S/]*constraints-test.txt"] + } } diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index f2320ea0..be1a3f25 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -174,10 +174,16 @@ def _session_tests( ) -> None: """Runs py.test for a particular project.""" if os.path.exists("requirements.txt"): - session.install("-r", "requirements.txt") + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") if os.path.exists("requirements-test.txt"): - session.install("-r", "requirements-test.txt") + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") if INSTALL_LIBRARY_FROM_SOURCE: session.install("-e", _get_repo_root()) diff --git a/synth.metadata b/synth.metadata index 8a689c24..d7458525 100644 --- a/synth.metadata +++ b/synth.metadata @@ -4,7 +4,7 @@ "git": { "name": ".", "remote": "https://github.com/googleapis/python-documentai.git", - "sha": "bcef3b8b8e3c107ed7ba8528e901731fc185b582" + "sha": "9878a282d7a8180157d398e52a4b91be61a63e77" } }, { @@ -19,14 +19,14 @@ "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "5b5bf6d519b2d658d9f2e483d9f6f3d0ba8ee6bc" + "sha": "0a071b3460344886297a304253bf924aa68ddb7e" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "5b5bf6d519b2d658d9f2e483d9f6f3d0ba8ee6bc" + "sha": "0a071b3460344886297a304253bf924aa68ddb7e" } } ], @@ -129,6 +129,7 @@ "docs/documentai_v1beta3/services.rst", "docs/documentai_v1beta3/types.rst", "docs/multiprocessing.rst", + "documentai-v1-py.tar.gz", "google/cloud/documentai/__init__.py", "google/cloud/documentai/py.typed", "google/cloud/documentai_v1/__init__.py", From 18abae5a896625acbff664a279198f88d5f85ca7 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 19 Apr 2021 17:34:20 +0200 Subject: [PATCH 12/25] chore(deps): update dependency google-cloud-storage to v1.37.1 (#114) [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [google-cloud-storage](https://togithub.com/googleapis/python-storage) | `==1.37.0` -> `==1.37.1` | [![age](https://badges.renovateapi.com/packages/pypi/google-cloud-storage/1.37.1/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/pypi/google-cloud-storage/1.37.1/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/pypi/google-cloud-storage/1.37.1/compatibility-slim/1.37.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/pypi/google-cloud-storage/1.37.1/confidence-slim/1.37.0)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
googleapis/python-storage ### [`v1.37.1`](https://togithub.com/googleapis/python-storage/blob/master/CHANGELOG.md#​1371-httpswwwgithubcomgoogleapispython-storagecomparev1370v1371-2021-04-02) [Compare Source](https://togithub.com/googleapis/python-storage/compare/v1.37.0...v1.37.1)
--- ### Configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/python-documentai). --- samples/snippets/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/requirements.txt b/samples/snippets/requirements.txt index f5e55e70..a7822ea3 100644 --- a/samples/snippets/requirements.txt +++ b/samples/snippets/requirements.txt @@ -1,2 +1,2 @@ google-cloud-documentai==0.4.0 -google-cloud-storage==1.37.0 +google-cloud-storage==1.37.1 From 0dca635ae7ddd26e1a2c31ccc4177318413668b4 Mon Sep 17 00:00:00 2001 From: Eric Schmidt Date: Tue, 20 Apr 2021 08:06:01 -0700 Subject: [PATCH 13/25] chore: add ml-apis to CODEOWNERS (#125) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 30c3973a..ac72fed3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,4 +8,4 @@ * @googleapis/yoshi-python # The python-samples-reviewers team is the default owner for samples changes -/samples/ @googleapis/python-samples-owners \ No newline at end of file +/samples/ @googleapis/python-samples-owners @googleapis/ml-apis From 30008b45ecc536ecdd47adc04b37cf9881ca0033 Mon Sep 17 00:00:00 2001 From: Dan Lee <71398022+dandhlee@users.noreply.github.com> Date: Mon, 26 Apr 2021 13:12:08 -0400 Subject: [PATCH 14/25] chore(revert): revert preventing normalization (#129) --- setup.py | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/setup.py b/setup.py index 968d4c86..4cba6749 100644 --- a/setup.py +++ b/setup.py @@ -19,21 +19,6 @@ import os import setuptools # type: ignore -# Disable version normalization performed by setuptools.setup() -try: - # Try the approach of using sic(), added in setuptools 46.1.0 - from setuptools import sic -except ImportError: - # Try the approach of replacing packaging.version.Version - sic = lambda v: v - try: - # setuptools >=39.0.0 uses packaging from setuptools.extern - from setuptools.extern import packaging - except ImportError: - # setuptools <39.0.0 uses packaging from pkg_resources.extern - from pkg_resources.extern import packaging - packaging.version.Version = packaging.version.LegacyVersion - version = "0.4.0" package_root = os.path.abspath(os.path.dirname(__file__)) @@ -45,7 +30,7 @@ setuptools.setup( name="google-cloud-documentai", - version=sic(version), + version=version, long_description=readme, author="Google LLC", author_email="googleapis-packages@google.com", From 2c7894e205b95984e01290216ca7d62711385743 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Sun, 9 May 2021 21:12:02 -0400 Subject: [PATCH 15/25] chore: migrate to owl bot (#130) --- .github/.OwlBot.lock.yaml | 4 + .github/.OwlBot.yaml | 29 ++++++ .kokoro/release.sh | 4 +- .kokoro/release/common.cfg | 14 +-- docs/_static/custom.css | 13 ++- synth.py => owlbot.py | 16 +-- samples/snippets/noxfile.py | 38 ++++--- synth.metadata | 201 ------------------------------------ 8 files changed, 71 insertions(+), 248 deletions(-) create mode 100644 .github/.OwlBot.lock.yaml create mode 100644 .github/.OwlBot.yaml rename synth.py => owlbot.py (75%) delete mode 100644 synth.metadata diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml new file mode 100644 index 00000000..29084e8a --- /dev/null +++ b/.github/.OwlBot.lock.yaml @@ -0,0 +1,4 @@ +docker: + digest: sha256:cfc0e802701262c211703c468874d767f65dabe6a1a71d0e07bfc8a3d5175f32 + image: gcr.io/repo-automation-bots/owlbot-python:latest + diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml new file mode 100644 index 00000000..149b734d --- /dev/null +++ b/.github/.OwlBot.yaml @@ -0,0 +1,29 @@ +# Copyright 2021 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. + +docker: + image: gcr.io/repo-automation-bots/owlbot-python:latest + +deep-remove-regex: + - /owl-bot-staging + +deep-preserve-regex: + - /owl-bot-staging/v1beta1 + +deep-copy-regex: + - source: /google/cloud/documentai/(v.*)/.*-py/(.*) + dest: /owl-bot-staging/$1/$2 + +begin-after-commit-hash: 19c469f0eefe7735eb3d6438773f12dd88060da1 + diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 2c110a14..4b5e99f5 100755 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -26,7 +26,7 @@ python3 -m pip install --upgrade twine wheel setuptools export PYTHONUNBUFFERED=1 # Move into the package, build the distribution and upload. -TWINE_PASSWORD=$(cat "${KOKORO_KEYSTORE_DIR}/73713_google_cloud_pypi_password") +TWINE_PASSWORD=$(cat "${KOKORO_GFILE_DIR}/secret_manager/google-cloud-pypi-token") cd github/python-documentai python3 setup.py sdist bdist_wheel -twine upload --username gcloudpypi --password "${TWINE_PASSWORD}" dist/* +twine upload --username __token__ --password "${TWINE_PASSWORD}" dist/* diff --git a/.kokoro/release/common.cfg b/.kokoro/release/common.cfg index 2d80fa2e..8f7706a3 100644 --- a/.kokoro/release/common.cfg +++ b/.kokoro/release/common.cfg @@ -23,18 +23,8 @@ env_vars: { value: "github/python-documentai/.kokoro/release.sh" } -# Fetch PyPI password -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "google_cloud_pypi_password" - } - } -} - # Tokens needed to report release status back to GitHub env_vars: { key: "SECRET_MANAGER_KEYS" - value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" -} \ No newline at end of file + value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem,google-cloud-pypi-token" +} diff --git a/docs/_static/custom.css b/docs/_static/custom.css index bcd37bbd..b0a29546 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -1,9 +1,20 @@ div#python2-eol { border-color: red; border-width: medium; -} +} /* Ensure minimum width for 'Parameters' / 'Returns' column */ dl.field-list > dt { min-width: 100px } + +/* Insert space between methods for readability */ +dl.method { + padding-top: 10px; + padding-bottom: 10px +} + +/* Insert empty space between classes */ +dl.class { + padding-bottom: 50px +} diff --git a/synth.py b/owlbot.py similarity index 75% rename from synth.py rename to owlbot.py index 34c054d6..b3763809 100644 --- a/synth.py +++ b/owlbot.py @@ -22,21 +22,11 @@ logging.basicConfig(level=logging.DEBUG) -gapic = gcp.GAPICBazel() common = gcp.CommonTemplates() -# add the highest stable version to the end -versions = ["v1beta2", "v1beta3", "v1"] -# ---------------------------------------------------------------------------- -# Generate document AI GAPIC layer -# ---------------------------------------------------------------------------- -for version in versions: - library = gapic.py_library( - service="documentai", - version=version, - bazel_target=f"//google/cloud/documentai/{version}:documentai-{version}-py", - ) +default_version = "v1" +for library in s.get_staging_dirs(default_version): excludes = [ "README.rst", "nox.py", @@ -46,6 +36,8 @@ ] s.move(library, excludes=excludes) +s.remove_staging_dirs() + # ---------------------------------------------------------------------------- # Add templated files # ---------------------------------------------------------------------------- diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index be1a3f25..956cdf4f 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -38,25 +38,28 @@ TEST_CONFIG = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + 'ignored_versions': ["2.7"], + # Old samples are opted out of enforcing Python type hints # All new samples should feature them - "enforce_type_hints": False, + 'enforce_type_hints': False, + # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string # to use your own Cloud project. - "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # A dictionary you want to inject into your test. Don't put any # secrets here. These values will override predefined values. - "envs": {}, + 'envs': {}, } try: # Ensure we can import noxfile_config in the project's directory. - sys.path.append(".") + sys.path.append('.') from noxfile_config import TEST_CONFIG_OVERRIDE except ImportError as e: print("No user noxfile_config found: detail: {}".format(e)) @@ -71,12 +74,12 @@ def get_pytest_env_vars() -> Dict[str, str]: ret = {} # Override the GCLOUD_PROJECT and the alias. - env_key = TEST_CONFIG["gcloud_project_env"] + env_key = TEST_CONFIG['gcloud_project_env'] # This should error out if not set. - ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] # Apply user supplied envs. - ret.update(TEST_CONFIG["envs"]) + ret.update(TEST_CONFIG['envs']) return ret @@ -85,7 +88,7 @@ def get_pytest_env_vars() -> Dict[str, str]: ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. -IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) @@ -134,7 +137,7 @@ def _determine_local_import_names(start_dir: str) -> List[str]: @nox.session def lint(session: nox.sessions.Session) -> None: - if not TEST_CONFIG["enforce_type_hints"]: + if not TEST_CONFIG['enforce_type_hints']: session.install("flake8", "flake8-import-order") else: session.install("flake8", "flake8-import-order", "flake8-annotations") @@ -143,11 +146,9 @@ def lint(session: nox.sessions.Session) -> None: args = FLAKE8_COMMON_ARGS + [ "--application-import-names", ",".join(local_names), - ".", + "." ] session.run("flake8", *args) - - # # Black # @@ -160,7 +161,6 @@ def blacken(session: nox.sessions.Session) -> None: session.run("black", *python_files) - # # Sample Tests # @@ -169,9 +169,7 @@ def blacken(session: nox.sessions.Session) -> None: PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] -def _session_tests( - session: nox.sessions.Session, post_install: Callable = None -) -> None: +def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: """Runs py.test for a particular project.""" if os.path.exists("requirements.txt"): if os.path.exists("constraints.txt"): @@ -208,9 +206,9 @@ def py(session: nox.sessions.Session) -> None: if session.python in TESTED_VERSIONS: _session_tests(session) else: - session.skip( - "SKIPPED: {} tests are disabled for this sample.".format(session.python) - ) + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) # diff --git a/synth.metadata b/synth.metadata deleted file mode 100644 index d7458525..00000000 --- a/synth.metadata +++ /dev/null @@ -1,201 +0,0 @@ -{ - "sources": [ - { - "git": { - "name": ".", - "remote": "https://github.com/googleapis/python-documentai.git", - "sha": "9878a282d7a8180157d398e52a4b91be61a63e77" - } - }, - { - "git": { - "name": "googleapis", - "remote": "https://github.com/googleapis/googleapis.git", - "sha": "551ddbb55b96147012c00b66250dd5907556807c", - "internalRef": "364734171" - } - }, - { - "git": { - "name": "synthtool", - "remote": "https://github.com/googleapis/synthtool.git", - "sha": "0a071b3460344886297a304253bf924aa68ddb7e" - } - }, - { - "git": { - "name": "synthtool", - "remote": "https://github.com/googleapis/synthtool.git", - "sha": "0a071b3460344886297a304253bf924aa68ddb7e" - } - } - ], - "destinations": [ - { - "client": { - "source": "googleapis", - "apiName": "documentai", - "apiVersion": "v1beta2", - "language": "python", - "generator": "bazel" - } - }, - { - "client": { - "source": "googleapis", - "apiName": "documentai", - "apiVersion": "v1beta3", - "language": "python", - "generator": "bazel" - } - }, - { - "client": { - "source": "googleapis", - "apiName": "documentai", - "apiVersion": "v1", - "language": "python", - "generator": "bazel" - } - } - ], - "generatedFiles": [ - ".coveragerc", - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/header-checker-lint.yml", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic-head.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic-head.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic-head.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples-against-head.sh", - ".kokoro/test-samples-impl.sh", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".pre-commit-config.yaml", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/conf.py", - "docs/documentai_v1/document_processor_service.rst", - "docs/documentai_v1/services.rst", - "docs/documentai_v1/types.rst", - "docs/documentai_v1beta2/document_understanding_service.rst", - "docs/documentai_v1beta2/services.rst", - "docs/documentai_v1beta2/types.rst", - "docs/documentai_v1beta3/document_processor_service.rst", - "docs/documentai_v1beta3/services.rst", - "docs/documentai_v1beta3/types.rst", - "docs/multiprocessing.rst", - "documentai-v1-py.tar.gz", - "google/cloud/documentai/__init__.py", - "google/cloud/documentai/py.typed", - "google/cloud/documentai_v1/__init__.py", - "google/cloud/documentai_v1/py.typed", - "google/cloud/documentai_v1/services/__init__.py", - "google/cloud/documentai_v1/services/document_processor_service/__init__.py", - "google/cloud/documentai_v1/services/document_processor_service/async_client.py", - "google/cloud/documentai_v1/services/document_processor_service/client.py", - "google/cloud/documentai_v1/services/document_processor_service/transports/__init__.py", - "google/cloud/documentai_v1/services/document_processor_service/transports/base.py", - "google/cloud/documentai_v1/services/document_processor_service/transports/grpc.py", - "google/cloud/documentai_v1/services/document_processor_service/transports/grpc_asyncio.py", - "google/cloud/documentai_v1/types/__init__.py", - "google/cloud/documentai_v1/types/document.py", - "google/cloud/documentai_v1/types/document_io.py", - "google/cloud/documentai_v1/types/document_processor_service.py", - "google/cloud/documentai_v1/types/geometry.py", - "google/cloud/documentai_v1beta2/__init__.py", - "google/cloud/documentai_v1beta2/py.typed", - "google/cloud/documentai_v1beta2/services/__init__.py", - "google/cloud/documentai_v1beta2/services/document_understanding_service/__init__.py", - "google/cloud/documentai_v1beta2/services/document_understanding_service/async_client.py", - "google/cloud/documentai_v1beta2/services/document_understanding_service/client.py", - "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/__init__.py", - "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/base.py", - "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc.py", - "google/cloud/documentai_v1beta2/services/document_understanding_service/transports/grpc_asyncio.py", - "google/cloud/documentai_v1beta2/types/__init__.py", - "google/cloud/documentai_v1beta2/types/document.py", - "google/cloud/documentai_v1beta2/types/document_understanding.py", - "google/cloud/documentai_v1beta2/types/geometry.py", - "google/cloud/documentai_v1beta3/__init__.py", - "google/cloud/documentai_v1beta3/py.typed", - "google/cloud/documentai_v1beta3/services/__init__.py", - "google/cloud/documentai_v1beta3/services/document_processor_service/__init__.py", - "google/cloud/documentai_v1beta3/services/document_processor_service/async_client.py", - "google/cloud/documentai_v1beta3/services/document_processor_service/client.py", - "google/cloud/documentai_v1beta3/services/document_processor_service/transports/__init__.py", - "google/cloud/documentai_v1beta3/services/document_processor_service/transports/base.py", - "google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc.py", - "google/cloud/documentai_v1beta3/services/document_processor_service/transports/grpc_asyncio.py", - "google/cloud/documentai_v1beta3/types/__init__.py", - "google/cloud/documentai_v1beta3/types/document.py", - "google/cloud/documentai_v1beta3/types/document_io.py", - "google/cloud/documentai_v1beta3/types/document_processor_service.py", - "google/cloud/documentai_v1beta3/types/geometry.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/snippets/noxfile.py", - "scripts/decrypt-secrets.sh", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/documentai_v1/__init__.py", - "tests/unit/gapic/documentai_v1/test_document_processor_service.py", - "tests/unit/gapic/documentai_v1beta2/__init__.py", - "tests/unit/gapic/documentai_v1beta2/test_document_understanding_service.py", - "tests/unit/gapic/documentai_v1beta3/__init__.py", - "tests/unit/gapic/documentai_v1beta3/test_document_processor_service.py" - ] -} \ No newline at end of file From c5609b63d8dda0f50485a50f74c3f638aa35d7a5 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Wed, 12 May 2021 13:39:35 -0400 Subject: [PATCH 16/25] chore: add library type to .repo-metadata.json (#137) --- .repo-metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.repo-metadata.json b/.repo-metadata.json index 44c100cb..d88123a4 100644 --- a/.repo-metadata.json +++ b/.repo-metadata.json @@ -6,6 +6,7 @@ "issue_tracker": "", "release_level": "beta", "language": "python", + "library_type": "GAPIC_AUTO", "repo": "googleapis/python-documentai", "distribution_name": "google-cloud-documentai", "api_id": "documentai.googleapis.com", 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 17/25] 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) From 57d09e1d7929d8db2616fa089160d7e8308e7fd8 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Sun, 16 May 2021 12:04:02 +0200 Subject: [PATCH 18/25] chore(deps): update dependency pytest to v6.2.4 (#124) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [pytest](https://docs.pytest.org/en/latest/) ([source](https://togithub.com/pytest-dev/pytest), [changelog](https://docs.pytest.org/en/stable/changelog.html)) | `==6.1.1` -> `==6.2.4` | [![age](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/compatibility-slim/6.1.1)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/confidence-slim/6.1.1)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
pytest-dev/pytest ### [`v6.2.4`](https://togithub.com/pytest-dev/pytest/releases/6.2.4) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.3...6.2.4) # pytest 6.2.4 (2021-05-04) ## Bug Fixes - [#​8539](https://togithub.com/pytest-dev/pytest/issues/8539): Fixed assertion rewriting on Python 3.10. ### [`v6.2.3`](https://togithub.com/pytest-dev/pytest/releases/6.2.3) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.2...6.2.3) # pytest 6.2.3 (2021-04-03) ## Bug Fixes - [#​8414](https://togithub.com/pytest-dev/pytest/issues/8414): pytest used to create directories under `/tmp` with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the `tmp_path`/`tmpdir` fixture). Now the directories are created with private permissions. pytest used silenty use a pre-existing `/tmp/pytest-of-` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user\\'s temporary directory. Now such a condition results in an error. ### [`v6.2.2`](https://togithub.com/pytest-dev/pytest/releases/6.2.2) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.1...6.2.2) # pytest 6.2.2 (2021-01-25) ## Bug Fixes - [#​8152](https://togithub.com/pytest-dev/pytest/issues/8152): Fixed "(<Skipped instance>)" being shown as a skip reason in the verbose test summary line when the reason is empty. - [#​8249](https://togithub.com/pytest-dev/pytest/issues/8249): Fix the `faulthandler` plugin for occasions when running with `twisted.logger` and using `pytest --capture=no`. ### [`v6.2.1`](https://togithub.com/pytest-dev/pytest/releases/6.2.1) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.0...6.2.1) # pytest 6.2.1 (2020-12-15) ## Bug Fixes - [#​7678](https://togithub.com/pytest-dev/pytest/issues/7678): Fixed bug where `ImportPathMismatchError` would be raised for files compiled in the host and loaded later from an UNC mounted path (Windows). - [#​8132](https://togithub.com/pytest-dev/pytest/issues/8132): Fixed regression in `approx`: in 6.2.0 `approx` no longer raises `TypeError` when dealing with non-numeric types, falling back to normal comparison. Before 6.2.0, array types like tf.DeviceArray fell through to the scalar case, and happened to compare correctly to a scalar if they had only one element. After 6.2.0, these types began failing, because they inherited neither from standard Python number hierarchy nor from `numpy.ndarray`. `approx` now converts arguments to `numpy.ndarray` if they expose the array protocol and are not scalars. This treats array-like objects like numpy arrays, regardless of size. ### [`v6.2.0`](https://togithub.com/pytest-dev/pytest/releases/6.2.0) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.1.2...6.2.0) # pytest 6.2.0 (2020-12-12) ## Breaking Changes - [#​7808](https://togithub.com/pytest-dev/pytest/issues/7808): pytest now supports python3.6+ only. ## Deprecations - [#​7469](https://togithub.com/pytest-dev/pytest/issues/7469): Directly constructing/calling the following classes/functions is now deprecated: - `_pytest.cacheprovider.Cache` - `_pytest.cacheprovider.Cache.for_config()` - `_pytest.cacheprovider.Cache.clear_cache()` - `_pytest.cacheprovider.Cache.cache_dir_from_config()` - `_pytest.capture.CaptureFixture` - `_pytest.fixtures.FixtureRequest` - `_pytest.fixtures.SubRequest` - `_pytest.logging.LogCaptureFixture` - `_pytest.pytester.Pytester` - `_pytest.pytester.Testdir` - `_pytest.recwarn.WarningsRecorder` - `_pytest.recwarn.WarningsChecker` - `_pytest.tmpdir.TempPathFactory` - `_pytest.tmpdir.TempdirFactory` These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0. - [#​7530](https://togithub.com/pytest-dev/pytest/issues/7530): The `--strict` command-line option has been deprecated, use `--strict-markers` instead. We have plans to maybe in the future to reintroduce `--strict` and make it an encompassing flag for all strictness related options (`--strict-markers` and `--strict-config` at the moment, more might be introduced in the future). - [#​7988](https://togithub.com/pytest-dev/pytest/issues/7988): The `@pytest.yield_fixture` decorator/function is now deprecated. Use pytest.fixture instead. `yield_fixture` has been an alias for `fixture` for a very long time, so can be search/replaced safely. ## Features - [#​5299](https://togithub.com/pytest-dev/pytest/issues/5299): pytest now warns about unraisable exceptions and unhandled thread exceptions that occur in tests on Python>=3.8. See unraisable for more information. - [#​7425](https://togithub.com/pytest-dev/pytest/issues/7425): New pytester fixture, which is identical to testdir but its methods return pathlib.Path when appropriate instead of `py.path.local`. This is part of the movement to use pathlib.Path objects internally, in order to remove the dependency to `py` in the future. Internally, the old Testdir <\_pytest.pytester.Testdir> is now a thin wrapper around Pytester <\_pytest.pytester.Pytester>, preserving the old interface. - [#​7695](https://togithub.com/pytest-dev/pytest/issues/7695): A new hook was added, pytest_markeval_namespace which should return a dictionary. This dictionary will be used to augment the "global" variables available to evaluate skipif/xfail/xpass markers. Pseudo example `conftest.py`: ```{.sourceCode .python} def pytest_markeval_namespace(): return {"color": "red"} ``` `test_func.py`: ```{.sourceCode .python} @​pytest.mark.skipif("color == 'blue'", reason="Color is not red") def test_func(): assert False ``` - [#​8006](https://togithub.com/pytest-dev/pytest/issues/8006): It is now possible to construct a ~pytest.MonkeyPatch object directly as `pytest.MonkeyPatch()`, in cases when the monkeypatch fixture cannot be used. Previously some users imported it from the private \_pytest.monkeypatch.MonkeyPatch namespace. Additionally, MonkeyPatch.context <pytest.MonkeyPatch.context> is now a classmethod, and can be used as `with MonkeyPatch.context() as mp: ...`. This is the recommended way to use `MonkeyPatch` directly, since unlike the `monkeypatch` fixture, an instance created directly is not `undo()`-ed automatically. ## Improvements - [#​1265](https://togithub.com/pytest-dev/pytest/issues/1265): Added an `__str__` implementation to the ~pytest.pytester.LineMatcher class which is returned from `pytester.run_pytest().stdout` and similar. It returns the entire output, like the existing `str()` method. - [#​2044](https://togithub.com/pytest-dev/pytest/issues/2044): Verbose mode now shows the reason that a test was skipped in the test's terminal line after the "SKIPPED", "XFAIL" or "XPASS". - [#​7469](https://togithub.com/pytest-dev/pytest/issues/7469) The types of builtin pytest fixtures are now exported so they may be used in type annotations of test functions. The newly-exported types are: - `pytest.FixtureRequest` for the request fixture. - `pytest.Cache` for the cache fixture. - `pytest.CaptureFixture[str]` for the capfd and capsys fixtures. - `pytest.CaptureFixture[bytes]` for the capfdbinary and capsysbinary fixtures. - `pytest.LogCaptureFixture` for the caplog fixture. - `pytest.Pytester` for the pytester fixture. - `pytest.Testdir` for the testdir fixture. - `pytest.TempdirFactory` for the tmpdir_factory fixture. - `pytest.TempPathFactory` for the tmp_path_factory fixture. - `pytest.MonkeyPatch` for the monkeypatch fixture. - `pytest.WarningsRecorder` for the recwarn fixture. Constructing them is not supported (except for MonkeyPatch); they are only meant for use in type annotations. Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0. Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy. - [#​7527](https://togithub.com/pytest-dev/pytest/issues/7527): When a comparison between namedtuple <collections.namedtuple> instances of the same type fails, pytest now shows the differing field names (possibly nested) instead of their indexes. - [#​7615](https://togithub.com/pytest-dev/pytest/issues/7615): Node.warn <\_pytest.nodes.Node.warn> now permits any subclass of Warning, not just PytestWarning <pytest.PytestWarning>. - [#​7701](https://togithub.com/pytest-dev/pytest/issues/7701): Improved reporting when using `--collected-only`. It will now show the number of collected tests in the summary stats. - [#​7710](https://togithub.com/pytest-dev/pytest/issues/7710): Use strict equality comparison for non-numeric types in pytest.approx instead of raising TypeError. This was the undocumented behavior before 3.7, but is now officially a supported feature. - [#​7938](https://togithub.com/pytest-dev/pytest/issues/7938): New `--sw-skip` argument which is a shorthand for `--stepwise-skip`. - [#​8023](https://togithub.com/pytest-dev/pytest/issues/8023): Added `'node_modules'` to default value for norecursedirs. - [#​8032](https://togithub.com/pytest-dev/pytest/issues/8032): doClassCleanups <unittest.TestCase.doClassCleanups> (introduced in unittest in Python and 3.8) is now called appropriately. ## Bug Fixes - [#​4824](https://togithub.com/pytest-dev/pytest/issues/4824): Fixed quadratic behavior and improved performance of collection of items using autouse fixtures and xunit fixtures. - [#​7758](https://togithub.com/pytest-dev/pytest/issues/7758): Fixed an issue where some files in packages are getting lost from `--lf` even though they contain tests that failed. Regressed in pytest 5.4.0. - [#​7911](https://togithub.com/pytest-dev/pytest/issues/7911): Directories created by by tmp_path and tmpdir are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites. - [#​7913](https://togithub.com/pytest-dev/pytest/issues/7913): Fixed a crash or hang in pytester.spawn <\_pytest.pytester.Pytester.spawn> when the readline module is involved. - [#​7951](https://togithub.com/pytest-dev/pytest/issues/7951): Fixed handling of recursive symlinks when collecting tests. - [#​7981](https://togithub.com/pytest-dev/pytest/issues/7981): Fixed symlinked directories not being followed during collection. Regressed in pytest 6.1.0. - [#​8016](https://togithub.com/pytest-dev/pytest/issues/8016): Fixed only one doctest being collected when using `pytest --doctest-modules path/to/an/__init__.py`. ## Improved Documentation - [#​7429](https://togithub.com/pytest-dev/pytest/issues/7429): Add more information and use cases about skipping doctests. - [#​7780](https://togithub.com/pytest-dev/pytest/issues/7780): Classes which should not be inherited from are now marked `final class` in the API reference. - [#​7872](https://togithub.com/pytest-dev/pytest/issues/7872): `_pytest.config.argparsing.Parser.addini()` accepts explicit `None` and `"string"`. - [#​7878](https://togithub.com/pytest-dev/pytest/issues/7878): In pull request section, ask to commit after editing changelog and authors file. ## Trivial/Internal Changes - [#​7802](https://togithub.com/pytest-dev/pytest/issues/7802): The `attrs` dependency requirement is now >=19.2.0 instead of >=17.4.0. - [#​8014](https://togithub.com/pytest-dev/pytest/issues/8014): .pyc files created by pytest's assertion rewriting now conform to the newer PEP-552 format on Python>=3.7. (These files are internal and only interpreted by pytest itself.) ### [`v6.1.2`](https://togithub.com/pytest-dev/pytest/releases/6.1.2) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.1.1...6.1.2) # pytest 6.1.2 (2020-10-28) ## Bug Fixes - [#​7758](https://togithub.com/pytest-dev/pytest/issues/7758): Fixed an issue where some files in packages are getting lost from `--lf` even though they contain tests that failed. Regressed in pytest 5.4.0. - [#​7911](https://togithub.com/pytest-dev/pytest/issues/7911): Directories created by tmpdir are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites. ## Improved Documentation - [#​7815](https://togithub.com/pytest-dev/pytest/issues/7815): Improve deprecation warning message for `pytest._fillfuncargs()`.
--- ### Configuration 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/python-documentai). --- samples/snippets/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/requirements-test.txt b/samples/snippets/requirements-test.txt index be53becf..95ea1e6a 100644 --- a/samples/snippets/requirements-test.txt +++ b/samples/snippets/requirements-test.txt @@ -1 +1 @@ -pytest==6.1.1 +pytest==6.2.4 From a344ca5a4b8ad7e9afdbafd45c4c77c9b02f829a 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 11:24:02 +0000 Subject: [PATCH 19/25] chore: new owl bot post processor docker image (#149) gcr.io/repo-automation-bots/owlbot-python:latest@sha256:4c981a6b6f2b8914a448d7b3a01688365be03e3ed26dfee399a6aa77fb112eaa --- .github/.OwlBot.lock.yaml | 5 ++--- .pre-commit-config.yaml | 2 +- CONTRIBUTING.rst | 16 +--------------- noxfile.py | 14 ++------------ 4 files changed, 6 insertions(+), 31 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 29084e8a..864c1765 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,4 +1,3 @@ docker: - digest: sha256:cfc0e802701262c211703c468874d767f65dabe6a1a71d0e07bfc8a3d5175f32 - image: gcr.io/repo-automation-bots/owlbot-python:latest - + image: gcr.io/repo-automation-bots/owlbot-python:latest + digest: sha256:4c981a6b6f2b8914a448d7b3a01688365be03e3ed26dfee399a6aa77fb112eaa diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8912e9b5..4f00c7cf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,6 +26,6 @@ repos: hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.0 + rev: 3.9.2 hooks: - id: flake8 diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 7307ccad..3c208d13 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -160,21 +160,7 @@ Running System Tests auth settings and change some configuration in your project to run all the tests. -- System tests will be run against an actual project and - so you'll need to provide some environment variables to facilitate - authentication to your project: - - - ``GOOGLE_APPLICATION_CREDENTIALS``: The path to a JSON key file; - Such a file can be downloaded directly from the developer's console by clicking - "Generate new JSON key". See private key - `docs `__ - for more details. - -- Once you have downloaded your json keys, set the environment variable - ``GOOGLE_APPLICATION_CREDENTIALS`` to the absolute path of the json file:: - - $ export GOOGLE_APPLICATION_CREDENTIALS="/Users//path/to/app_credentials.json" - +- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. ************* Test Coverage diff --git a/noxfile.py b/noxfile.py index af50a606..1d45cadc 100644 --- a/noxfile.py +++ b/noxfile.py @@ -62,16 +62,9 @@ def lint(session): session.run("flake8", "google", "tests") -@nox.session(python="3.6") +@nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): - """Run black. - - Format code to uniform standard. - - This currently uses Python 3.6 due to the automated Kokoro run of synthtool. - That run uses an image that doesn't have 3.6 installed. Before updating this - check the state of the `gcp_ubuntu_config` we use for that Kokoro run. - """ + """Run black. Format code to uniform standard.""" session.install(BLACK_VERSION) session.run( "black", *BLACK_PATHS, @@ -131,9 +124,6 @@ def system(session): # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": session.skip("RUN_SYSTEM_TESTS is set to false, skipping") - # Sanity check: Only run tests if the environment variable is set. - if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): - session.skip("Credentials must be set via environment variable") # Install pyopenssl for mTLS testing. if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": session.install("pyopenssl") From b9c541ad7098ac5b822c086fd10b0346aff5a417 Mon Sep 17 00:00:00 2001 From: "google-cloud-policy-bot[bot]" <80869356+google-cloud-policy-bot[bot]@users.noreply.github.com> Date: Tue, 18 May 2021 01:34:04 +0000 Subject: [PATCH 20/25] chore: add SECURITY.md (#135) chore: add SECURITY.md --- SECURITY.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..8b58ae9c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). + +The Google Security Team will respond within 5 working days of your report on g.co/vulnz. + +We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. From 7e9abd72d58ffedba8f303fe5f6e32296178343f Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Sat, 22 May 2021 09:28:02 +0000 Subject: [PATCH 21/25] chore: new owl bot post processor docker image (#152) gcr.io/repo-automation-bots/owlbot-python:latest@sha256:3c3a445b3ddc99ccd5d31edc4b4519729635d20693900db32c4f587ed51f7479 --- .github/.OwlBot.lock.yaml | 2 +- noxfile.py | 6 ++++-- samples/snippets/noxfile.py | 8 +++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 864c1765..46e3f021 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/repo-automation-bots/owlbot-python:latest - digest: sha256:4c981a6b6f2b8914a448d7b3a01688365be03e3ed26dfee399a6aa77fb112eaa + digest: sha256:3c3a445b3ddc99ccd5d31edc4b4519729635d20693900db32c4f587ed51f7479 diff --git a/noxfile.py b/noxfile.py index 1d45cadc..94ee6a8f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -179,7 +179,7 @@ def docs(session): """Build the docs for this library.""" session.install("-e", ".") - session.install("sphinx", "alabaster", "recommonmark") + session.install("sphinx==4.0.1", "alabaster", "recommonmark") shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( @@ -201,7 +201,9 @@ def docfx(session): """Build the docfx yaml files for this library.""" session.install("-e", ".") - session.install("sphinx", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml") + session.install( + "sphinx==4.0.1", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml" + ) shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index 956cdf4f..5ff9e1db 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -50,7 +50,10 @@ # to use your own Cloud project. 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', - + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, # A dictionary you want to inject into your test. Don't put any # secrets here. These values will override predefined values. 'envs': {}, @@ -170,6 +173,9 @@ def blacken(session: nox.sessions.Session) -> None: def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") """Runs py.test for a particular project.""" if os.path.exists("requirements.txt"): if os.path.exists("constraints.txt"): From c4aca1bc1c01b3e1fdcc644eaf8922552c6c99a7 Mon Sep 17 00:00:00 2001 From: dgallegos Date: Tue, 25 May 2021 14:35:36 -0500 Subject: [PATCH 22/25] fix: Parsing pages, but should be paragraphs (#147) The code intends to be parsing paragraphs from a page, but was instead parsing pages from a document. --- samples/snippets/batch_process_documents_sample.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/snippets/batch_process_documents_sample.py b/samples/snippets/batch_process_documents_sample.py index a66ff441..88217093 100644 --- a/samples/snippets/batch_process_documents_sample.py +++ b/samples/snippets/batch_process_documents_sample.py @@ -102,7 +102,7 @@ def batch_process_documents( field_value = get_text(form_field.field_value, document) print("Extracted key value pair:") print(f"\t{field_name}, {field_value}") - for paragraph in document.pages: + for paragraph in page.paragraphs: paragraph_text = get_text(paragraph.layout, document) print(f"Paragraph text:\n{paragraph_text}") else: From df900d458a496fbf131e92e9212d2f82af7d1985 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 28 May 2021 15:42:03 +0000 Subject: [PATCH 23/25] chore: new owl bot post processor docker image (#153) gcr.io/repo-automation-bots/owlbot-python:latest@sha256:0856ca711da1fd5ec9d6d7da6c50aa0bbf550fb94acb47b55159a640791987bf --- .github/.OwlBot.lock.yaml | 2 +- docs/multiprocessing.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 46e3f021..127c2cdf 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/repo-automation-bots/owlbot-python:latest - digest: sha256:3c3a445b3ddc99ccd5d31edc4b4519729635d20693900db32c4f587ed51f7479 + digest: sha256:0856ca711da1fd5ec9d6d7da6c50aa0bbf550fb94acb47b55159a640791987bf diff --git a/docs/multiprocessing.rst b/docs/multiprocessing.rst index 1cb29d4c..536d17b2 100644 --- a/docs/multiprocessing.rst +++ b/docs/multiprocessing.rst @@ -1,7 +1,7 @@ .. note:: - Because this client uses :mod:`grpcio` library, it is safe to + Because this client uses :mod:`grpc` library, it is safe to share instances across threads. In multiprocessing scenarios, the best practice is to create client instances *after* the invocation of - :func:`os.fork` by :class:`multiprocessing.Pool` or + :func:`os.fork` by :class:`multiprocessing.pool.Pool` or :class:`multiprocessing.Process`. From 7c8f9494879e87465879bb2d098900ff270698a6 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 28 May 2021 16:00:04 +0000 Subject: [PATCH 24/25] chore: new owl bot post processor docker image (#154) Post-Processor: gcr.io/repo-automation-bots/owlbot-python:latest@sha256:c66ba3c8d7bc8566f47df841f98cd0097b28fff0b1864c86f5817f4c8c3e8600 --- .github/.OwlBot.lock.yaml | 2 +- docs/conf.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 127c2cdf..da616c91 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,3 @@ docker: image: gcr.io/repo-automation-bots/owlbot-python:latest - digest: sha256:0856ca711da1fd5ec9d6d7da6c50aa0bbf550fb94acb47b55159a640791987bf + digest: sha256:c66ba3c8d7bc8566f47df841f98cd0097b28fff0b1864c86f5817f4c8c3e8600 diff --git a/docs/conf.py b/docs/conf.py index a5040f2a..21303740 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -363,6 +363,7 @@ "google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None,), "grpc": ("https://grpc.github.io/grpc/python/", None), "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None), + "protobuf": ("https://googleapis.dev/python/protobuf/latest/", None), } From e1bdfab207fe774f7db10a9a5182bad4a870e63e Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 31 May 2021 21:06:13 +0000 Subject: [PATCH 25/25] chore: release 0.5.0 (#148) :robot: I have created a release \*beep\* \*boop\* --- ## [0.5.0](https://www.github.com/googleapis/python-documentai/compare/v0.4.0...v0.5.0) (2021-05-28) ### Features * add confidence field to the PageAnchor.PageRef in document.proto. ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) * support self-signed JWT flow for service accounts ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) * Use non-regionalized default host name for documentai.googleapis.com ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) ### Bug Fixes * add async client to %name_%version/init.py ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) * Parsing pages, but should be paragraphs ([#147](https://www.github.com/googleapis/python-documentai/issues/147)) ([c4aca1b](https://www.github.com/googleapis/python-documentai/commit/c4aca1bc1c01b3e1fdcc644eaf8922552c6c99a7)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- CHANGELOG.md | 15 +++++++++++++++ setup.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa0af008..8e61d478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [0.5.0](https://www.github.com/googleapis/python-documentai/compare/v0.4.0...v0.5.0) (2021-05-28) + + +### Features + +* add confidence field to the PageAnchor.PageRef in document.proto. ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) +* support self-signed JWT flow for service accounts ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) +* Use non-regionalized default host name for documentai.googleapis.com ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) + + +### Bug Fixes + +* add async client to %name_%version/init.py ([be671a8](https://www.github.com/googleapis/python-documentai/commit/be671a832839d6efeae76d168b7913a9408572b4)) +* Parsing pages, but should be paragraphs ([#147](https://www.github.com/googleapis/python-documentai/issues/147)) ([c4aca1b](https://www.github.com/googleapis/python-documentai/commit/c4aca1bc1c01b3e1fdcc644eaf8922552c6c99a7)) + ## [0.4.0](https://www.github.com/googleapis/python-documentai/compare/v0.3.0...v0.4.0) (2021-03-25) diff --git a/setup.py b/setup.py index 4cba6749..794001e9 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ import os import setuptools # type: ignore -version = "0.4.0" +version = "0.5.0" package_root = os.path.abspath(os.path.dirname(__file__))