From 80bef1f07d38785aa1dc32a66e34d54d3ef04591 Mon Sep 17 00:00:00 2001
From: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com>
Date: Mon, 28 Sep 2020 17:05:01 -0600
Subject: [PATCH] feat: add v4 (#29)
---
UPGRADING.md | 54 +-
docs/index.rst | 7 +-
docs/talent_v4/services.rst | 18 +
docs/talent_v4/types.rst | 5 +
google/cloud/talent/__init__.py | 280 +-
google/cloud/talent_v4/__init__.py | 153 +
google/cloud/talent_v4/proto/common.proto | 928 +++++
google/cloud/talent_v4/proto/company.proto | 118 +
.../talent_v4/proto/company_service.proto | 184 +
.../talent_v4/proto/completion_service.proto | 163 +
google/cloud/talent_v4/proto/event.proto | 180 +
.../cloud/talent_v4/proto/event_service.proto | 68 +
google/cloud/talent_v4/proto/filters.proto | 358 ++
google/cloud/talent_v4/proto/histogram.proto | 56 +
google/cloud/talent_v4/proto/job.proto | 370 ++
.../cloud/talent_v4/proto/job_service.proto | 865 +++++
google/cloud/talent_v4/proto/tenant.proto | 53 +
.../talent_v4/proto/tenant_service.proto | 175 +
google/cloud/talent_v4/py.typed | 2 +
google/cloud/talent_v4/services/__init__.py | 16 +
.../services/company_service/__init__.py | 24 +
.../services/company_service/async_client.py | 559 +++
.../services/company_service/client.py | 706 ++++
.../services/company_service/pagers.py | 149 +
.../company_service/transports/__init__.py | 36 +
.../company_service/transports/base.py | 209 ++
.../company_service/transports/grpc.py | 371 ++
.../transports/grpc_asyncio.py | 376 ++
.../talent_v4/services/completion/__init__.py | 24 +
.../services/completion/async_client.py | 169 +
.../talent_v4/services/completion/client.py | 308 ++
.../completion/transports/__init__.py | 36 +
.../services/completion/transports/base.py | 138 +
.../services/completion/transports/grpc.py | 264 ++
.../completion/transports/grpc_asyncio.py | 264 ++
.../services/event_service/__init__.py | 24 +
.../services/event_service/async_client.py | 210 ++
.../services/event_service/client.py | 358 ++
.../event_service/transports/__init__.py | 36 +
.../services/event_service/transports/base.py | 126 +
.../services/event_service/transports/grpc.py | 266 ++
.../event_service/transports/grpc_asyncio.py | 268 ++
.../services/job_service/__init__.py | 24 +
.../services/job_service/async_client.py | 1001 ++++++
.../talent_v4/services/job_service/client.py | 1154 ++++++
.../talent_v4/services/job_service/pagers.py | 149 +
.../job_service/transports/__init__.py | 36 +
.../services/job_service/transports/base.py | 282 ++
.../services/job_service/transports/grpc.py | 533 +++
.../job_service/transports/grpc_asyncio.py | 551 +++
.../services/tenant_service/__init__.py | 24 +
.../services/tenant_service/async_client.py | 555 +++
.../services/tenant_service/client.py | 697 ++++
.../services/tenant_service/pagers.py | 149 +
.../tenant_service/transports/__init__.py | 36 +
.../tenant_service/transports/base.py | 209 ++
.../tenant_service/transports/grpc.py | 367 ++
.../tenant_service/transports/grpc_asyncio.py | 370 ++
google/cloud/talent_v4/types/__init__.py | 137 +
google/cloud/talent_v4/types/common.py | 746 ++++
google/cloud/talent_v4/types/company.py | 144 +
.../cloud/talent_v4/types/company_service.py | 178 +
.../talent_v4/types/completion_service.py | 136 +
google/cloud/talent_v4/types/event.py | 118 +
google/cloud/talent_v4/types/event_service.py | 50 +
google/cloud/talent_v4/types/filters.py | 396 +++
google/cloud/talent_v4/types/histogram.py | 72 +
google/cloud/talent_v4/types/job.py | 479 +++
google/cloud/talent_v4/types/job_service.py | 923 +++++
google/cloud/talent_v4/types/tenant.py | 51 +
.../cloud/talent_v4/types/tenant_service.py | 162 +
.../application_service/async_client.py | 50 +-
.../services/application_service/client.py | 101 +-
.../application_service/transports/base.py | 32 +-
.../application_service/transports/grpc.py | 62 +-
.../transports/grpc_asyncio.py | 61 +-
.../services/company_service/async_client.py | 48 +-
.../services/company_service/client.py | 101 +-
.../company_service/transports/base.py | 32 +-
.../company_service/transports/grpc.py | 62 +-
.../transports/grpc_asyncio.py | 61 +-
.../services/completion/async_client.py | 35 +-
.../services/completion/client.py | 101 +-
.../services/completion/transports/base.py | 20 +-
.../services/completion/transports/grpc.py | 62 +-
.../completion/transports/grpc_asyncio.py | 61 +-
.../services/event_service/async_client.py | 33 +-
.../services/event_service/client.py | 101 +-
.../services/event_service/transports/base.py | 20 +-
.../services/event_service/transports/grpc.py | 62 +-
.../event_service/transports/grpc_asyncio.py | 61 +-
.../services/job_service/async_client.py | 62 +-
.../services/job_service/client.py | 105 +-
.../services/job_service/transports/base.py | 42 +-
.../services/job_service/transports/grpc.py | 62 +-
.../job_service/transports/grpc_asyncio.py | 61 +-
.../services/profile_service/async_client.py | 50 +-
.../services/profile_service/client.py | 101 +-
.../profile_service/transports/base.py | 34 +-
.../profile_service/transports/grpc.py | 62 +-
.../transports/grpc_asyncio.py | 61 +-
.../services/tenant_service/async_client.py | 48 +-
.../services/tenant_service/client.py | 101 +-
.../tenant_service/transports/base.py | 32 +-
.../tenant_service/transports/grpc.py | 62 +-
.../tenant_service/transports/grpc_asyncio.py | 61 +-
google/cloud/talent_v4beta1/types/common.py | 16 +-
.../types/completion_service.py | 8 +-
google/cloud/talent_v4beta1/types/event.py | 8 +-
google/cloud/talent_v4beta1/types/filters.py | 12 +-
google/cloud/talent_v4beta1/types/profile.py | 8 +-
noxfile.py | 2 +-
.../job_search_autocomplete_job_title.py | 2 +-
samples/snippets/job_search_commute_search.py | 2 +-
.../job_search_custom_ranking_search.py | 2 +-
.../snippets/job_search_histogram_search.py | 2 +-
scripts/fixup_talent_v4_keywords.py | 199 ++
synth.metadata | 9 +
synth.py | 6 +-
tests/unit/gapic/talent_v4/__init__.py | 1 +
.../gapic/talent_v4/test_company_service.py | 2111 +++++++++++
tests/unit/gapic/talent_v4/test_completion.py | 851 +++++
.../gapic/talent_v4/test_event_service.py | 958 +++++
.../unit/gapic/talent_v4/test_job_service.py | 3087 +++++++++++++++++
.../gapic/talent_v4/test_tenant_service.py | 1882 ++++++++++
.../test_application_service.py | 549 +--
.../talent_v4beta1/test_company_service.py | 539 +--
.../gapic/talent_v4beta1/test_completion.py | 511 +--
.../talent_v4beta1/test_event_service.py | 513 +--
.../gapic/talent_v4beta1/test_job_service.py | 554 +--
.../talent_v4beta1/test_profile_service.py | 551 +--
.../talent_v4beta1/test_tenant_service.py | 539 +--
132 files changed, 31099 insertions(+), 2636 deletions(-)
create mode 100644 docs/talent_v4/services.rst
create mode 100644 docs/talent_v4/types.rst
create mode 100644 google/cloud/talent_v4/__init__.py
create mode 100644 google/cloud/talent_v4/proto/common.proto
create mode 100644 google/cloud/talent_v4/proto/company.proto
create mode 100644 google/cloud/talent_v4/proto/company_service.proto
create mode 100644 google/cloud/talent_v4/proto/completion_service.proto
create mode 100644 google/cloud/talent_v4/proto/event.proto
create mode 100644 google/cloud/talent_v4/proto/event_service.proto
create mode 100644 google/cloud/talent_v4/proto/filters.proto
create mode 100644 google/cloud/talent_v4/proto/histogram.proto
create mode 100644 google/cloud/talent_v4/proto/job.proto
create mode 100644 google/cloud/talent_v4/proto/job_service.proto
create mode 100644 google/cloud/talent_v4/proto/tenant.proto
create mode 100644 google/cloud/talent_v4/proto/tenant_service.proto
create mode 100644 google/cloud/talent_v4/py.typed
create mode 100644 google/cloud/talent_v4/services/__init__.py
create mode 100644 google/cloud/talent_v4/services/company_service/__init__.py
create mode 100644 google/cloud/talent_v4/services/company_service/async_client.py
create mode 100644 google/cloud/talent_v4/services/company_service/client.py
create mode 100644 google/cloud/talent_v4/services/company_service/pagers.py
create mode 100644 google/cloud/talent_v4/services/company_service/transports/__init__.py
create mode 100644 google/cloud/talent_v4/services/company_service/transports/base.py
create mode 100644 google/cloud/talent_v4/services/company_service/transports/grpc.py
create mode 100644 google/cloud/talent_v4/services/company_service/transports/grpc_asyncio.py
create mode 100644 google/cloud/talent_v4/services/completion/__init__.py
create mode 100644 google/cloud/talent_v4/services/completion/async_client.py
create mode 100644 google/cloud/talent_v4/services/completion/client.py
create mode 100644 google/cloud/talent_v4/services/completion/transports/__init__.py
create mode 100644 google/cloud/talent_v4/services/completion/transports/base.py
create mode 100644 google/cloud/talent_v4/services/completion/transports/grpc.py
create mode 100644 google/cloud/talent_v4/services/completion/transports/grpc_asyncio.py
create mode 100644 google/cloud/talent_v4/services/event_service/__init__.py
create mode 100644 google/cloud/talent_v4/services/event_service/async_client.py
create mode 100644 google/cloud/talent_v4/services/event_service/client.py
create mode 100644 google/cloud/talent_v4/services/event_service/transports/__init__.py
create mode 100644 google/cloud/talent_v4/services/event_service/transports/base.py
create mode 100644 google/cloud/talent_v4/services/event_service/transports/grpc.py
create mode 100644 google/cloud/talent_v4/services/event_service/transports/grpc_asyncio.py
create mode 100644 google/cloud/talent_v4/services/job_service/__init__.py
create mode 100644 google/cloud/talent_v4/services/job_service/async_client.py
create mode 100644 google/cloud/talent_v4/services/job_service/client.py
create mode 100644 google/cloud/talent_v4/services/job_service/pagers.py
create mode 100644 google/cloud/talent_v4/services/job_service/transports/__init__.py
create mode 100644 google/cloud/talent_v4/services/job_service/transports/base.py
create mode 100644 google/cloud/talent_v4/services/job_service/transports/grpc.py
create mode 100644 google/cloud/talent_v4/services/job_service/transports/grpc_asyncio.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/__init__.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/async_client.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/client.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/pagers.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/transports/__init__.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/transports/base.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/transports/grpc.py
create mode 100644 google/cloud/talent_v4/services/tenant_service/transports/grpc_asyncio.py
create mode 100644 google/cloud/talent_v4/types/__init__.py
create mode 100644 google/cloud/talent_v4/types/common.py
create mode 100644 google/cloud/talent_v4/types/company.py
create mode 100644 google/cloud/talent_v4/types/company_service.py
create mode 100644 google/cloud/talent_v4/types/completion_service.py
create mode 100644 google/cloud/talent_v4/types/event.py
create mode 100644 google/cloud/talent_v4/types/event_service.py
create mode 100644 google/cloud/talent_v4/types/filters.py
create mode 100644 google/cloud/talent_v4/types/histogram.py
create mode 100644 google/cloud/talent_v4/types/job.py
create mode 100644 google/cloud/talent_v4/types/job_service.py
create mode 100644 google/cloud/talent_v4/types/tenant.py
create mode 100644 google/cloud/talent_v4/types/tenant_service.py
create mode 100644 scripts/fixup_talent_v4_keywords.py
create mode 100644 tests/unit/gapic/talent_v4/__init__.py
create mode 100644 tests/unit/gapic/talent_v4/test_company_service.py
create mode 100644 tests/unit/gapic/talent_v4/test_completion.py
create mode 100644 tests/unit/gapic/talent_v4/test_event_service.py
create mode 100644 tests/unit/gapic/talent_v4/test_job_service.py
create mode 100644 tests/unit/gapic/talent_v4/test_tenant_service.py
diff --git a/UPGRADING.md b/UPGRADING.md
index cb385ee6..9a5a84b4 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -37,7 +37,7 @@ response = client.batch_create_jobs(parent, jobs)
**After:**
```py
-response = client.batch_create_jobs(request={"parent": "''", "jobs": "[]"})
+response = client.batch_create_jobs(request={"parent": "parent", "jobs": []})
```
### More Details
@@ -103,4 +103,56 @@ response = client.batch_create_jobs(
},
jobs=jobs
)
+```
+
+## v4beta1 -> v4
+
+In addition, this release adds the v4 API surface, which has breaking changes from the v4beta1.
+The `google.cloud.talent` import now resolves to `google.cloud.talent_v4`. To continue
+to use the `v4beta1`, import from it explicitly.
+
+The `v4` surface merges functionalty in the `v3p1beta1` and `v4beta1`.
+
+```py
+from google.cloud import talent_v4beta1
+```
+
+
+### search_jobs
+
+`search_jobs` returns `SearchJobsResponse`. Matching jobs are in `SearchJobsResponse.matching_jobs`.
+
+
+**v4beta1:**
+```py
+from google.cloud import talent_v4beta1
+
+
+client = talent_v4beta1.JobServiceClient()
+
+#...
+request = talent_v4beta1.SearchJobsRequest(
+ parent=parent,
+ request_metadata=request_metadata,
+ job_query=job_query,
+)
+for response_item in client.search_jobs(request=request):
+ # ...
+```
+
+**v4**
+```py
+from google.cloud import talent_v4
+
+
+client = talent_v4.JobServiceClient()
+
+#...
+request = talent_v4.SearchJobsRequest(
+ parent=parent,
+ request_metadata=request_metadata,
+ job_query=job_query,
+)
+for response_item in client.search_jobs(request=request).matching_jobs:
+ # ...
```
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
index d181d6e9..ef884a75 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,19 +2,20 @@
.. include:: multiprocessing.rst
-Api Reference
+API Reference
-------------
.. toctree::
:maxdepth: 2
+ talent_v4/services
+ talent_v4/types
talent_v4beta1/services
talent_v4beta1/types
- changelog
Migration Guide
---------------
-See the guide below for instructions on migrating to the 2.x release of this library.
+See the guide below for instructions on migrating to the 1.x release of this library.
.. toctree::
:maxdepth: 2
diff --git a/docs/talent_v4/services.rst b/docs/talent_v4/services.rst
new file mode 100644
index 00000000..5efed8a2
--- /dev/null
+++ b/docs/talent_v4/services.rst
@@ -0,0 +1,18 @@
+Services for Google Cloud Talent v4 API
+=======================================
+
+.. automodule:: google.cloud.talent_v4.services.company_service
+ :members:
+ :inherited-members:
+.. automodule:: google.cloud.talent_v4.services.completion
+ :members:
+ :inherited-members:
+.. automodule:: google.cloud.talent_v4.services.event_service
+ :members:
+ :inherited-members:
+.. automodule:: google.cloud.talent_v4.services.job_service
+ :members:
+ :inherited-members:
+.. automodule:: google.cloud.talent_v4.services.tenant_service
+ :members:
+ :inherited-members:
diff --git a/docs/talent_v4/types.rst b/docs/talent_v4/types.rst
new file mode 100644
index 00000000..9b5991f6
--- /dev/null
+++ b/docs/talent_v4/types.rst
@@ -0,0 +1,5 @@
+Types for Google Cloud Talent v4 API
+====================================
+
+.. automodule:: google.cloud.talent_v4.types
+ :members:
diff --git a/google/cloud/talent/__init__.py b/google/cloud/talent/__init__.py
index cb19a827..13571c97 100644
--- a/google/cloud/talent/__init__.py
+++ b/google/cloud/talent/__init__.py
@@ -15,183 +15,96 @@
# limitations under the License.
#
-from google.cloud.talent_v4beta1.services.application_service.async_client import (
- ApplicationServiceAsyncClient,
-)
-from google.cloud.talent_v4beta1.services.application_service.client import (
- ApplicationServiceClient,
-)
-from google.cloud.talent_v4beta1.services.company_service.async_client import (
+from google.cloud.talent_v4.services.company_service.async_client import (
CompanyServiceAsyncClient,
)
-from google.cloud.talent_v4beta1.services.company_service.client import (
- CompanyServiceClient,
-)
-from google.cloud.talent_v4beta1.services.completion.async_client import (
+from google.cloud.talent_v4.services.company_service.client import CompanyServiceClient
+from google.cloud.talent_v4.services.completion.async_client import (
CompletionAsyncClient,
)
-from google.cloud.talent_v4beta1.services.completion.client import CompletionClient
-from google.cloud.talent_v4beta1.services.event_service.async_client import (
+from google.cloud.talent_v4.services.completion.client import CompletionClient
+from google.cloud.talent_v4.services.event_service.async_client import (
EventServiceAsyncClient,
)
-from google.cloud.talent_v4beta1.services.event_service.client import EventServiceClient
-from google.cloud.talent_v4beta1.services.job_service.async_client import (
+from google.cloud.talent_v4.services.event_service.client import EventServiceClient
+from google.cloud.talent_v4.services.job_service.async_client import (
JobServiceAsyncClient,
)
-from google.cloud.talent_v4beta1.services.job_service.client import JobServiceClient
-from google.cloud.talent_v4beta1.services.profile_service.async_client import (
- ProfileServiceAsyncClient,
-)
-from google.cloud.talent_v4beta1.services.profile_service.client import (
- ProfileServiceClient,
-)
-from google.cloud.talent_v4beta1.services.tenant_service.async_client import (
+from google.cloud.talent_v4.services.job_service.client import JobServiceClient
+from google.cloud.talent_v4.services.tenant_service.async_client import (
TenantServiceAsyncClient,
)
-from google.cloud.talent_v4beta1.services.tenant_service.client import (
- TenantServiceClient,
-)
-from google.cloud.talent_v4beta1.types.application import Application
-from google.cloud.talent_v4beta1.types.application_service import (
- CreateApplicationRequest,
-)
-from google.cloud.talent_v4beta1.types.application_service import (
- DeleteApplicationRequest,
-)
-from google.cloud.talent_v4beta1.types.application_service import GetApplicationRequest
-from google.cloud.talent_v4beta1.types.application_service import (
- ListApplicationsRequest,
-)
-from google.cloud.talent_v4beta1.types.application_service import (
- ListApplicationsResponse,
-)
-from google.cloud.talent_v4beta1.types.application_service import (
- UpdateApplicationRequest,
-)
-from google.cloud.talent_v4beta1.types.common import AvailabilitySignalType
-from google.cloud.talent_v4beta1.types.common import BatchOperationMetadata
-from google.cloud.talent_v4beta1.types.common import Certification
-from google.cloud.talent_v4beta1.types.common import CommuteMethod
-from google.cloud.talent_v4beta1.types.common import CompanySize
-from google.cloud.talent_v4beta1.types.common import CompensationInfo
-from google.cloud.talent_v4beta1.types.common import ContactInfoUsage
-from google.cloud.talent_v4beta1.types.common import CustomAttribute
-from google.cloud.talent_v4beta1.types.common import DegreeType
-from google.cloud.talent_v4beta1.types.common import DeviceInfo
-from google.cloud.talent_v4beta1.types.common import EmploymentType
-from google.cloud.talent_v4beta1.types.common import HtmlSanitization
-from google.cloud.talent_v4beta1.types.common import Interview
-from google.cloud.talent_v4beta1.types.common import JobBenefit
-from google.cloud.talent_v4beta1.types.common import JobCategory
-from google.cloud.talent_v4beta1.types.common import JobLevel
-from google.cloud.talent_v4beta1.types.common import Location
-from google.cloud.talent_v4beta1.types.common import Outcome
-from google.cloud.talent_v4beta1.types.common import PostingRegion
-from google.cloud.talent_v4beta1.types.common import Rating
-from google.cloud.talent_v4beta1.types.common import RequestMetadata
-from google.cloud.talent_v4beta1.types.common import ResponseMetadata
-from google.cloud.talent_v4beta1.types.common import Skill
-from google.cloud.talent_v4beta1.types.common import SkillProficiencyLevel
-from google.cloud.talent_v4beta1.types.common import SpellingCorrection
-from google.cloud.talent_v4beta1.types.common import TimestampRange
-from google.cloud.talent_v4beta1.types.common import Visibility
-from google.cloud.talent_v4beta1.types.company import Company
-from google.cloud.talent_v4beta1.types.company_service import CreateCompanyRequest
-from google.cloud.talent_v4beta1.types.company_service import DeleteCompanyRequest
-from google.cloud.talent_v4beta1.types.company_service import GetCompanyRequest
-from google.cloud.talent_v4beta1.types.company_service import ListCompaniesRequest
-from google.cloud.talent_v4beta1.types.company_service import ListCompaniesResponse
-from google.cloud.talent_v4beta1.types.company_service import UpdateCompanyRequest
-from google.cloud.talent_v4beta1.types.completion_service import CompleteQueryRequest
-from google.cloud.talent_v4beta1.types.completion_service import CompleteQueryResponse
-from google.cloud.talent_v4beta1.types.event import ClientEvent
-from google.cloud.talent_v4beta1.types.event import JobEvent
-from google.cloud.talent_v4beta1.types.event import ProfileEvent
-from google.cloud.talent_v4beta1.types.event_service import CreateClientEventRequest
-from google.cloud.talent_v4beta1.types.filters import ApplicationDateFilter
-from google.cloud.talent_v4beta1.types.filters import ApplicationJobFilter
-from google.cloud.talent_v4beta1.types.filters import ApplicationOutcomeNotesFilter
-from google.cloud.talent_v4beta1.types.filters import AvailabilityFilter
-from google.cloud.talent_v4beta1.types.filters import CandidateAvailabilityFilter
-from google.cloud.talent_v4beta1.types.filters import CommuteFilter
-from google.cloud.talent_v4beta1.types.filters import CompensationFilter
-from google.cloud.talent_v4beta1.types.filters import EducationFilter
-from google.cloud.talent_v4beta1.types.filters import EmployerFilter
-from google.cloud.talent_v4beta1.types.filters import JobQuery
-from google.cloud.talent_v4beta1.types.filters import JobTitleFilter
-from google.cloud.talent_v4beta1.types.filters import LocationFilter
-from google.cloud.talent_v4beta1.types.filters import PersonNameFilter
-from google.cloud.talent_v4beta1.types.filters import ProfileQuery
-from google.cloud.talent_v4beta1.types.filters import SkillFilter
-from google.cloud.talent_v4beta1.types.filters import TimeFilter
-from google.cloud.talent_v4beta1.types.filters import WorkExperienceFilter
-from google.cloud.talent_v4beta1.types.histogram import HistogramQuery
-from google.cloud.talent_v4beta1.types.histogram import HistogramQueryResult
-from google.cloud.talent_v4beta1.types.job import Job
-from google.cloud.talent_v4beta1.types.job_service import BatchCreateJobsRequest
-from google.cloud.talent_v4beta1.types.job_service import BatchDeleteJobsRequest
-from google.cloud.talent_v4beta1.types.job_service import BatchUpdateJobsRequest
-from google.cloud.talent_v4beta1.types.job_service import CreateJobRequest
-from google.cloud.talent_v4beta1.types.job_service import DeleteJobRequest
-from google.cloud.talent_v4beta1.types.job_service import GetJobRequest
-from google.cloud.talent_v4beta1.types.job_service import JobOperationResult
-from google.cloud.talent_v4beta1.types.job_service import JobView
-from google.cloud.talent_v4beta1.types.job_service import ListJobsRequest
-from google.cloud.talent_v4beta1.types.job_service import ListJobsResponse
-from google.cloud.talent_v4beta1.types.job_service import SearchJobsRequest
-from google.cloud.talent_v4beta1.types.job_service import SearchJobsResponse
-from google.cloud.talent_v4beta1.types.job_service import UpdateJobRequest
-from google.cloud.talent_v4beta1.types.profile import Activity
-from google.cloud.talent_v4beta1.types.profile import AdditionalContactInfo
-from google.cloud.talent_v4beta1.types.profile import Address
-from google.cloud.talent_v4beta1.types.profile import AvailabilitySignal
-from google.cloud.talent_v4beta1.types.profile import Degree
-from google.cloud.talent_v4beta1.types.profile import EducationRecord
-from google.cloud.talent_v4beta1.types.profile import Email
-from google.cloud.talent_v4beta1.types.profile import EmploymentRecord
-from google.cloud.talent_v4beta1.types.profile import Patent
-from google.cloud.talent_v4beta1.types.profile import PersonName
-from google.cloud.talent_v4beta1.types.profile import PersonalUri
-from google.cloud.talent_v4beta1.types.profile import Phone
-from google.cloud.talent_v4beta1.types.profile import Profile
-from google.cloud.talent_v4beta1.types.profile import Publication
-from google.cloud.talent_v4beta1.types.profile import Resume
-from google.cloud.talent_v4beta1.types.profile_service import CreateProfileRequest
-from google.cloud.talent_v4beta1.types.profile_service import DeleteProfileRequest
-from google.cloud.talent_v4beta1.types.profile_service import GetProfileRequest
-from google.cloud.talent_v4beta1.types.profile_service import ListProfilesRequest
-from google.cloud.talent_v4beta1.types.profile_service import ListProfilesResponse
-from google.cloud.talent_v4beta1.types.profile_service import SearchProfilesRequest
-from google.cloud.talent_v4beta1.types.profile_service import SearchProfilesResponse
-from google.cloud.talent_v4beta1.types.profile_service import SummarizedProfile
-from google.cloud.talent_v4beta1.types.profile_service import UpdateProfileRequest
-from google.cloud.talent_v4beta1.types.tenant import Tenant
-from google.cloud.talent_v4beta1.types.tenant_service import CreateTenantRequest
-from google.cloud.talent_v4beta1.types.tenant_service import DeleteTenantRequest
-from google.cloud.talent_v4beta1.types.tenant_service import GetTenantRequest
-from google.cloud.talent_v4beta1.types.tenant_service import ListTenantsRequest
-from google.cloud.talent_v4beta1.types.tenant_service import ListTenantsResponse
-from google.cloud.talent_v4beta1.types.tenant_service import UpdateTenantRequest
+from google.cloud.talent_v4.services.tenant_service.client import TenantServiceClient
+from google.cloud.talent_v4.types.common import BatchOperationMetadata
+from google.cloud.talent_v4.types.common import CommuteMethod
+from google.cloud.talent_v4.types.common import CompanySize
+from google.cloud.talent_v4.types.common import CompensationInfo
+from google.cloud.talent_v4.types.common import CustomAttribute
+from google.cloud.talent_v4.types.common import DegreeType
+from google.cloud.talent_v4.types.common import DeviceInfo
+from google.cloud.talent_v4.types.common import EmploymentType
+from google.cloud.talent_v4.types.common import HtmlSanitization
+from google.cloud.talent_v4.types.common import JobBenefit
+from google.cloud.talent_v4.types.common import JobCategory
+from google.cloud.talent_v4.types.common import JobLevel
+from google.cloud.talent_v4.types.common import Location
+from google.cloud.talent_v4.types.common import PostingRegion
+from google.cloud.talent_v4.types.common import RequestMetadata
+from google.cloud.talent_v4.types.common import ResponseMetadata
+from google.cloud.talent_v4.types.common import SpellingCorrection
+from google.cloud.talent_v4.types.common import TimestampRange
+from google.cloud.talent_v4.types.common import Visibility
+from google.cloud.talent_v4.types.company import Company
+from google.cloud.talent_v4.types.company_service import CreateCompanyRequest
+from google.cloud.talent_v4.types.company_service import DeleteCompanyRequest
+from google.cloud.talent_v4.types.company_service import GetCompanyRequest
+from google.cloud.talent_v4.types.company_service import ListCompaniesRequest
+from google.cloud.talent_v4.types.company_service import ListCompaniesResponse
+from google.cloud.talent_v4.types.company_service import UpdateCompanyRequest
+from google.cloud.talent_v4.types.completion_service import CompleteQueryRequest
+from google.cloud.talent_v4.types.completion_service import CompleteQueryResponse
+from google.cloud.talent_v4.types.event import ClientEvent
+from google.cloud.talent_v4.types.event import JobEvent
+from google.cloud.talent_v4.types.event_service import CreateClientEventRequest
+from google.cloud.talent_v4.types.filters import CommuteFilter
+from google.cloud.talent_v4.types.filters import CompensationFilter
+from google.cloud.talent_v4.types.filters import JobQuery
+from google.cloud.talent_v4.types.filters import LocationFilter
+from google.cloud.talent_v4.types.histogram import HistogramQuery
+from google.cloud.talent_v4.types.histogram import HistogramQueryResult
+from google.cloud.talent_v4.types.job import Job
+from google.cloud.talent_v4.types.job_service import BatchCreateJobsRequest
+from google.cloud.talent_v4.types.job_service import BatchCreateJobsResponse
+from google.cloud.talent_v4.types.job_service import BatchDeleteJobsRequest
+from google.cloud.talent_v4.types.job_service import BatchDeleteJobsResponse
+from google.cloud.talent_v4.types.job_service import BatchUpdateJobsRequest
+from google.cloud.talent_v4.types.job_service import BatchUpdateJobsResponse
+from google.cloud.talent_v4.types.job_service import CreateJobRequest
+from google.cloud.talent_v4.types.job_service import DeleteJobRequest
+from google.cloud.talent_v4.types.job_service import GetJobRequest
+from google.cloud.talent_v4.types.job_service import JobResult
+from google.cloud.talent_v4.types.job_service import JobView
+from google.cloud.talent_v4.types.job_service import ListJobsRequest
+from google.cloud.talent_v4.types.job_service import ListJobsResponse
+from google.cloud.talent_v4.types.job_service import SearchJobsRequest
+from google.cloud.talent_v4.types.job_service import SearchJobsResponse
+from google.cloud.talent_v4.types.job_service import UpdateJobRequest
+from google.cloud.talent_v4.types.tenant import Tenant
+from google.cloud.talent_v4.types.tenant_service import CreateTenantRequest
+from google.cloud.talent_v4.types.tenant_service import DeleteTenantRequest
+from google.cloud.talent_v4.types.tenant_service import GetTenantRequest
+from google.cloud.talent_v4.types.tenant_service import ListTenantsRequest
+from google.cloud.talent_v4.types.tenant_service import ListTenantsResponse
+from google.cloud.talent_v4.types.tenant_service import UpdateTenantRequest
__all__ = (
- "Activity",
- "AdditionalContactInfo",
- "Address",
- "Application",
- "ApplicationDateFilter",
- "ApplicationJobFilter",
- "ApplicationOutcomeNotesFilter",
- "ApplicationServiceAsyncClient",
- "ApplicationServiceClient",
- "AvailabilityFilter",
- "AvailabilitySignal",
- "AvailabilitySignalType",
"BatchCreateJobsRequest",
+ "BatchCreateJobsResponse",
"BatchDeleteJobsRequest",
+ "BatchDeleteJobsResponse",
"BatchOperationMetadata",
"BatchUpdateJobsRequest",
- "CandidateAvailabilityFilter",
- "Certification",
+ "BatchUpdateJobsResponse",
"ClientEvent",
"CommuteFilter",
"CommuteMethod",
@@ -205,98 +118,55 @@
"CompleteQueryResponse",
"CompletionAsyncClient",
"CompletionClient",
- "ContactInfoUsage",
- "CreateApplicationRequest",
"CreateClientEventRequest",
"CreateCompanyRequest",
"CreateJobRequest",
- "CreateProfileRequest",
"CreateTenantRequest",
"CustomAttribute",
- "Degree",
"DegreeType",
- "DeleteApplicationRequest",
"DeleteCompanyRequest",
"DeleteJobRequest",
- "DeleteProfileRequest",
"DeleteTenantRequest",
"DeviceInfo",
- "EducationFilter",
- "EducationRecord",
- "Email",
- "EmployerFilter",
- "EmploymentRecord",
"EmploymentType",
"EventServiceAsyncClient",
"EventServiceClient",
- "GetApplicationRequest",
"GetCompanyRequest",
"GetJobRequest",
- "GetProfileRequest",
"GetTenantRequest",
"HistogramQuery",
"HistogramQueryResult",
"HtmlSanitization",
- "Interview",
"Job",
"JobBenefit",
"JobCategory",
"JobEvent",
"JobLevel",
- "JobOperationResult",
"JobQuery",
+ "JobResult",
"JobServiceAsyncClient",
"JobServiceClient",
- "JobTitleFilter",
"JobView",
- "ListApplicationsRequest",
- "ListApplicationsResponse",
"ListCompaniesRequest",
"ListCompaniesResponse",
"ListJobsRequest",
"ListJobsResponse",
- "ListProfilesRequest",
- "ListProfilesResponse",
"ListTenantsRequest",
"ListTenantsResponse",
"Location",
"LocationFilter",
- "Outcome",
- "Patent",
- "PersonName",
- "PersonNameFilter",
- "PersonalUri",
- "Phone",
"PostingRegion",
- "Profile",
- "ProfileEvent",
- "ProfileQuery",
- "ProfileServiceAsyncClient",
- "ProfileServiceClient",
- "Publication",
- "Rating",
"RequestMetadata",
"ResponseMetadata",
- "Resume",
"SearchJobsRequest",
"SearchJobsResponse",
- "SearchProfilesRequest",
- "SearchProfilesResponse",
- "Skill",
- "SkillFilter",
- "SkillProficiencyLevel",
"SpellingCorrection",
- "SummarizedProfile",
"Tenant",
"TenantServiceAsyncClient",
"TenantServiceClient",
- "TimeFilter",
"TimestampRange",
- "UpdateApplicationRequest",
"UpdateCompanyRequest",
"UpdateJobRequest",
- "UpdateProfileRequest",
"UpdateTenantRequest",
"Visibility",
- "WorkExperienceFilter",
)
diff --git a/google/cloud/talent_v4/__init__.py b/google/cloud/talent_v4/__init__.py
new file mode 100644
index 00000000..b193e4de
--- /dev/null
+++ b/google/cloud/talent_v4/__init__.py
@@ -0,0 +1,153 @@
+# -*- 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.
+#
+
+from .services.company_service import CompanyServiceClient
+from .services.completion import CompletionClient
+from .services.event_service import EventServiceClient
+from .services.job_service import JobServiceClient
+from .services.tenant_service import TenantServiceClient
+from .types.common import BatchOperationMetadata
+from .types.common import CommuteMethod
+from .types.common import CompanySize
+from .types.common import CompensationInfo
+from .types.common import CustomAttribute
+from .types.common import DegreeType
+from .types.common import DeviceInfo
+from .types.common import EmploymentType
+from .types.common import HtmlSanitization
+from .types.common import JobBenefit
+from .types.common import JobCategory
+from .types.common import JobLevel
+from .types.common import Location
+from .types.common import PostingRegion
+from .types.common import RequestMetadata
+from .types.common import ResponseMetadata
+from .types.common import SpellingCorrection
+from .types.common import TimestampRange
+from .types.common import Visibility
+from .types.company import Company
+from .types.company_service import CreateCompanyRequest
+from .types.company_service import DeleteCompanyRequest
+from .types.company_service import GetCompanyRequest
+from .types.company_service import ListCompaniesRequest
+from .types.company_service import ListCompaniesResponse
+from .types.company_service import UpdateCompanyRequest
+from .types.completion_service import CompleteQueryRequest
+from .types.completion_service import CompleteQueryResponse
+from .types.event import ClientEvent
+from .types.event import JobEvent
+from .types.event_service import CreateClientEventRequest
+from .types.filters import CommuteFilter
+from .types.filters import CompensationFilter
+from .types.filters import JobQuery
+from .types.filters import LocationFilter
+from .types.histogram import HistogramQuery
+from .types.histogram import HistogramQueryResult
+from .types.job import Job
+from .types.job_service import BatchCreateJobsRequest
+from .types.job_service import BatchCreateJobsResponse
+from .types.job_service import BatchDeleteJobsRequest
+from .types.job_service import BatchDeleteJobsResponse
+from .types.job_service import BatchUpdateJobsRequest
+from .types.job_service import BatchUpdateJobsResponse
+from .types.job_service import CreateJobRequest
+from .types.job_service import DeleteJobRequest
+from .types.job_service import GetJobRequest
+from .types.job_service import JobResult
+from .types.job_service import JobView
+from .types.job_service import ListJobsRequest
+from .types.job_service import ListJobsResponse
+from .types.job_service import SearchJobsRequest
+from .types.job_service import SearchJobsResponse
+from .types.job_service import UpdateJobRequest
+from .types.tenant import Tenant
+from .types.tenant_service import CreateTenantRequest
+from .types.tenant_service import DeleteTenantRequest
+from .types.tenant_service import GetTenantRequest
+from .types.tenant_service import ListTenantsRequest
+from .types.tenant_service import ListTenantsResponse
+from .types.tenant_service import UpdateTenantRequest
+
+
+__all__ = (
+ "BatchCreateJobsRequest",
+ "BatchCreateJobsResponse",
+ "BatchDeleteJobsRequest",
+ "BatchDeleteJobsResponse",
+ "BatchOperationMetadata",
+ "BatchUpdateJobsRequest",
+ "BatchUpdateJobsResponse",
+ "ClientEvent",
+ "CommuteFilter",
+ "CommuteMethod",
+ "Company",
+ "CompanyServiceClient",
+ "CompanySize",
+ "CompensationFilter",
+ "CompensationInfo",
+ "CompleteQueryRequest",
+ "CompleteQueryResponse",
+ "CompletionClient",
+ "CreateClientEventRequest",
+ "CreateCompanyRequest",
+ "CreateJobRequest",
+ "CreateTenantRequest",
+ "CustomAttribute",
+ "DegreeType",
+ "DeleteCompanyRequest",
+ "DeleteJobRequest",
+ "DeleteTenantRequest",
+ "DeviceInfo",
+ "EmploymentType",
+ "EventServiceClient",
+ "GetCompanyRequest",
+ "GetJobRequest",
+ "GetTenantRequest",
+ "HistogramQuery",
+ "HistogramQueryResult",
+ "HtmlSanitization",
+ "Job",
+ "JobBenefit",
+ "JobCategory",
+ "JobEvent",
+ "JobLevel",
+ "JobQuery",
+ "JobResult",
+ "JobServiceClient",
+ "JobView",
+ "ListCompaniesRequest",
+ "ListCompaniesResponse",
+ "ListJobsRequest",
+ "ListJobsResponse",
+ "ListTenantsRequest",
+ "ListTenantsResponse",
+ "Location",
+ "LocationFilter",
+ "PostingRegion",
+ "RequestMetadata",
+ "ResponseMetadata",
+ "SearchJobsRequest",
+ "SearchJobsResponse",
+ "SpellingCorrection",
+ "Tenant",
+ "TimestampRange",
+ "UpdateCompanyRequest",
+ "UpdateJobRequest",
+ "UpdateTenantRequest",
+ "Visibility",
+ "TenantServiceClient",
+)
diff --git a/google/cloud/talent_v4/proto/common.proto b/google/cloud/talent_v4/proto/common.proto
new file mode 100644
index 00000000..a7daca9e
--- /dev/null
+++ b/google/cloud/talent_v4/proto/common.proto
@@ -0,0 +1,928 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/field_behavior.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+import "google/type/latlng.proto";
+import "google/type/money.proto";
+import "google/type/postal_address.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "CommonProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// Message representing a period of time between two timestamps.
+message TimestampRange {
+ // Begin of the period (inclusive).
+ google.protobuf.Timestamp start_time = 1;
+
+ // End of the period (exclusive).
+ google.protobuf.Timestamp end_time = 2;
+}
+
+// An enum that represents the size of the company.
+enum CompanySize {
+ // Default value if the size isn't specified.
+ COMPANY_SIZE_UNSPECIFIED = 0;
+
+ // The company has less than 50 employees.
+ MINI = 1;
+
+ // The company has between 50 and 99 employees.
+ SMALL = 2;
+
+ // The company has between 100 and 499 employees.
+ SMEDIUM = 3;
+
+ // The company has between 500 and 999 employees.
+ MEDIUM = 4;
+
+ // The company has between 1,000 and 4,999 employees.
+ BIG = 5;
+
+ // The company has between 5,000 and 9,999 employees.
+ BIGGER = 6;
+
+ // The company has 10,000 or more employees.
+ GIANT = 7;
+}
+
+// An enum that represents employee benefits included with the job.
+enum JobBenefit {
+ // Default value if the type isn't specified.
+ JOB_BENEFIT_UNSPECIFIED = 0;
+
+ // The job includes access to programs that support child care, such
+ // as daycare.
+ CHILD_CARE = 1;
+
+ // The job includes dental services covered by a dental
+ // insurance plan.
+ DENTAL = 2;
+
+ // The job offers specific benefits to domestic partners.
+ DOMESTIC_PARTNER = 3;
+
+ // The job allows for a flexible work schedule.
+ FLEXIBLE_HOURS = 4;
+
+ // The job includes health services covered by a medical insurance plan.
+ MEDICAL = 5;
+
+ // The job includes a life insurance plan provided by the employer or
+ // available for purchase by the employee.
+ LIFE_INSURANCE = 6;
+
+ // The job allows for a leave of absence to a parent to care for a newborn
+ // child.
+ PARENTAL_LEAVE = 7;
+
+ // The job includes a workplace retirement plan provided by the
+ // employer or available for purchase by the employee.
+ RETIREMENT_PLAN = 8;
+
+ // The job allows for paid time off due to illness.
+ SICK_DAYS = 9;
+
+ // The job includes paid time off for vacation.
+ VACATION = 10;
+
+ // The job includes vision services covered by a vision
+ // insurance plan.
+ VISION = 11;
+}
+
+// Educational degree level defined in International Standard Classification
+// of Education (ISCED).
+enum DegreeType {
+ // Default value. Represents no degree, or early childhood education.
+ // Maps to ISCED code 0.
+ // Ex) Kindergarten
+ DEGREE_TYPE_UNSPECIFIED = 0;
+
+ // Primary education which is typically the first stage of compulsory
+ // education. ISCED code 1.
+ // Ex) Elementary school
+ PRIMARY_EDUCATION = 1;
+
+ // Lower secondary education; First stage of secondary education building on
+ // primary education, typically with a more subject-oriented curriculum.
+ // ISCED code 2.
+ // Ex) Middle school
+ LOWER_SECONDARY_EDUCATION = 2;
+
+ // Middle education; Second/final stage of secondary education preparing for
+ // tertiary education and/or providing skills relevant to employment.
+ // Usually with an increased range of subject options and streams. ISCED
+ // code 3.
+ // Ex) High school
+ UPPER_SECONDARY_EDUCATION = 3;
+
+ // Adult Remedial Education; Programmes providing learning experiences that
+ // build on secondary education and prepare for labour market entry and/or
+ // tertiary education. The content is broader than secondary but not as
+ // complex as tertiary education. ISCED code 4.
+ ADULT_REMEDIAL_EDUCATION = 4;
+
+ // Associate's or equivalent; Short first tertiary programmes that are
+ // typically practically-based, occupationally-specific and prepare for
+ // labour market entry. These programmes may also provide a pathway to other
+ // tertiary programmes. ISCED code 5.
+ ASSOCIATES_OR_EQUIVALENT = 5;
+
+ // Bachelor's or equivalent; Programmes designed to provide intermediate
+ // academic and/or professional knowledge, skills and competencies leading
+ // to a first tertiary degree or equivalent qualification. ISCED code 6.
+ BACHELORS_OR_EQUIVALENT = 6;
+
+ // Master's or equivalent; Programmes designed to provide advanced academic
+ // and/or professional knowledge, skills and competencies leading to a
+ // second tertiary degree or equivalent qualification. ISCED code 7.
+ MASTERS_OR_EQUIVALENT = 7;
+
+ // Doctoral or equivalent; Programmes designed primarily to lead to an
+ // advanced research qualification, usually concluding with the submission
+ // and defense of a substantive dissertation of publishable quality based on
+ // original research. ISCED code 8.
+ DOCTORAL_OR_EQUIVALENT = 8;
+}
+
+// An enum that represents the employment type of a job.
+enum EmploymentType {
+ // The default value if the employment type isn't specified.
+ EMPLOYMENT_TYPE_UNSPECIFIED = 0;
+
+ // The job requires working a number of hours that constitute full
+ // time employment, typically 40 or more hours per week.
+ FULL_TIME = 1;
+
+ // The job entails working fewer hours than a full time job,
+ // typically less than 40 hours a week.
+ PART_TIME = 2;
+
+ // The job is offered as a contracted, as opposed to a salaried employee,
+ // position.
+ CONTRACTOR = 3;
+
+ // The job is offered as a contracted position with the understanding
+ // that it's converted into a full-time position at the end of the
+ // contract. Jobs of this type are also returned by a search for
+ // [EmploymentType.CONTRACTOR][google.cloud.talent.v4.EmploymentType.CONTRACTOR]
+ // jobs.
+ CONTRACT_TO_HIRE = 4;
+
+ // The job is offered as a temporary employment opportunity, usually
+ // a short-term engagement.
+ TEMPORARY = 5;
+
+ // The job is a fixed-term opportunity for students or entry-level job
+ // seekers to obtain on-the-job training, typically offered as a summer
+ // position.
+ INTERN = 6;
+
+ // The is an opportunity for an individual to volunteer, where there's no
+ // expectation of compensation for the provided services.
+ VOLUNTEER = 7;
+
+ // The job requires an employee to work on an as-needed basis with a
+ // flexible schedule.
+ PER_DIEM = 8;
+
+ // The job involves employing people in remote areas and flying them
+ // temporarily to the work site instead of relocating employees and their
+ // families permanently.
+ FLY_IN_FLY_OUT = 9;
+
+ // The job does not fit any of the other listed types.
+ OTHER_EMPLOYMENT_TYPE = 10;
+}
+
+// An enum that represents the required experience level required for the job.
+enum JobLevel {
+ // The default value if the level isn't specified.
+ JOB_LEVEL_UNSPECIFIED = 0;
+
+ // Entry-level individual contributors, typically with less than 2 years of
+ // experience in a similar role. Includes interns.
+ ENTRY_LEVEL = 1;
+
+ // Experienced individual contributors, typically with 2+ years of
+ // experience in a similar role.
+ EXPERIENCED = 2;
+
+ // Entry- to mid-level managers responsible for managing a team of people.
+ MANAGER = 3;
+
+ // Senior-level managers responsible for managing teams of managers.
+ DIRECTOR = 4;
+
+ // Executive-level managers and above, including C-level positions.
+ EXECUTIVE = 5;
+}
+
+// An enum that represents the categorization or primary focus of specific
+// role. This value is different than the "industry" associated with a role,
+// which is related to the categorization of the company listing the job.
+enum JobCategory {
+ // The default value if the category isn't specified.
+ JOB_CATEGORY_UNSPECIFIED = 0;
+
+ // An accounting and finance job, such as an Accountant.
+ ACCOUNTING_AND_FINANCE = 1;
+
+ // An administrative and office job, such as an Administrative Assistant.
+ ADMINISTRATIVE_AND_OFFICE = 2;
+
+ // An advertising and marketing job, such as Marketing Manager.
+ ADVERTISING_AND_MARKETING = 3;
+
+ // An animal care job, such as Veterinarian.
+ ANIMAL_CARE = 4;
+
+ // An art, fashion, or design job, such as Designer.
+ ART_FASHION_AND_DESIGN = 5;
+
+ // A business operations job, such as Business Operations Manager.
+ BUSINESS_OPERATIONS = 6;
+
+ // A cleaning and facilities job, such as Custodial Staff.
+ CLEANING_AND_FACILITIES = 7;
+
+ // A computer and IT job, such as Systems Administrator.
+ COMPUTER_AND_IT = 8;
+
+ // A construction job, such as General Laborer.
+ CONSTRUCTION = 9;
+
+ // A customer service job, such s Cashier.
+ CUSTOMER_SERVICE = 10;
+
+ // An education job, such as School Teacher.
+ EDUCATION = 11;
+
+ // An entertainment and travel job, such as Flight Attendant.
+ ENTERTAINMENT_AND_TRAVEL = 12;
+
+ // A farming or outdoor job, such as Park Ranger.
+ FARMING_AND_OUTDOORS = 13;
+
+ // A healthcare job, such as Registered Nurse.
+ HEALTHCARE = 14;
+
+ // A human resources job, such as Human Resources Director.
+ HUMAN_RESOURCES = 15;
+
+ // An installation, maintenance, or repair job, such as Electrician.
+ INSTALLATION_MAINTENANCE_AND_REPAIR = 16;
+
+ // A legal job, such as Law Clerk.
+ LEGAL = 17;
+
+ // A management job, often used in conjunction with another category,
+ // such as Store Manager.
+ MANAGEMENT = 18;
+
+ // A manufacturing or warehouse job, such as Assembly Technician.
+ MANUFACTURING_AND_WAREHOUSE = 19;
+
+ // A media, communications, or writing job, such as Media Relations.
+ MEDIA_COMMUNICATIONS_AND_WRITING = 20;
+
+ // An oil, gas or mining job, such as Offshore Driller.
+ OIL_GAS_AND_MINING = 21;
+
+ // A personal care and services job, such as Hair Stylist.
+ PERSONAL_CARE_AND_SERVICES = 22;
+
+ // A protective services job, such as Security Guard.
+ PROTECTIVE_SERVICES = 23;
+
+ // A real estate job, such as Buyer's Agent.
+ REAL_ESTATE = 24;
+
+ // A restaurant and hospitality job, such as Restaurant Server.
+ RESTAURANT_AND_HOSPITALITY = 25;
+
+ // A sales and/or retail job, such Sales Associate.
+ SALES_AND_RETAIL = 26;
+
+ // A science and engineering job, such as Lab Technician.
+ SCIENCE_AND_ENGINEERING = 27;
+
+ // A social services or non-profit job, such as Case Worker.
+ SOCIAL_SERVICES_AND_NON_PROFIT = 28;
+
+ // A sports, fitness, or recreation job, such as Personal Trainer.
+ SPORTS_FITNESS_AND_RECREATION = 29;
+
+ // A transportation or logistics job, such as Truck Driver.
+ TRANSPORTATION_AND_LOGISTICS = 30;
+}
+
+// An enum that represents the job posting region. In most cases, job postings
+// don't need to specify a region. If a region is given, jobs are
+// eligible for searches in the specified region.
+enum PostingRegion {
+ // If the region is unspecified, the job is only returned if it
+ // matches the [LocationFilter][google.cloud.talent.v4.LocationFilter].
+ POSTING_REGION_UNSPECIFIED = 0;
+
+ // In addition to exact location matching, job posting is returned when the
+ // [LocationFilter][google.cloud.talent.v4.LocationFilter] in the search query
+ // is in the same administrative area as the returned job posting. For
+ // example, if a `ADMINISTRATIVE_AREA` job is posted in "CA, USA", it's
+ // returned if [LocationFilter][google.cloud.talent.v4.LocationFilter] has
+ // "Mountain View".
+ //
+ // Administrative area refers to top-level administrative subdivision of this
+ // country. For example, US state, IT region, UK constituent nation and
+ // JP prefecture.
+ ADMINISTRATIVE_AREA = 1;
+
+ // In addition to exact location matching, job is returned when
+ // [LocationFilter][google.cloud.talent.v4.LocationFilter] in search query is
+ // in the same country as this job. For example, if a `NATION_WIDE` job is
+ // posted in "USA", it's returned if
+ // [LocationFilter][google.cloud.talent.v4.LocationFilter] has 'Mountain
+ // View'.
+ NATION = 2;
+
+ // Job allows employees to work remotely (telecommute).
+ // If locations are provided with this value, the job is
+ // considered as having a location, but telecommuting is allowed.
+ TELECOMMUTE = 3;
+}
+
+// Deprecated. All resources are only visible to the owner.
+//
+// An enum that represents who has view access to the resource.
+enum Visibility {
+ option deprecated = true;
+
+ // Default value.
+ VISIBILITY_UNSPECIFIED = 0;
+
+ // The resource is only visible to the GCP account who owns it.
+ ACCOUNT_ONLY = 1;
+
+ // The resource is visible to the owner and may be visible to other
+ // applications and processes at Google.
+ SHARED_WITH_GOOGLE = 2;
+
+ // The resource is visible to the owner and may be visible to all other API
+ // clients.
+ SHARED_WITH_PUBLIC = 3;
+}
+
+// Option for HTML content sanitization on user input fields, for example, job
+// description. By setting this option, user can determine whether and how
+// sanitization is performed on these fields.
+enum HtmlSanitization {
+ // Default value.
+ HTML_SANITIZATION_UNSPECIFIED = 0;
+
+ // Disables sanitization on HTML input.
+ HTML_SANITIZATION_DISABLED = 1;
+
+ // Sanitizes HTML input, only accepts bold, italic, ordered list, and
+ // unordered list markup tags.
+ SIMPLE_FORMATTING_ONLY = 2;
+}
+
+// Method for commute.
+enum CommuteMethod {
+ // Commute method isn't specified.
+ COMMUTE_METHOD_UNSPECIFIED = 0;
+
+ // Commute time is calculated based on driving time.
+ DRIVING = 1;
+
+ // Commute time is calculated based on public transit including bus, metro,
+ // subway, and so on.
+ TRANSIT = 2;
+
+ // Commute time is calculated based on walking time.
+ WALKING = 3;
+
+ // Commute time is calculated based on biking time.
+ CYCLING = 4;
+}
+
+// A resource that represents a location with full geographic information.
+message Location {
+ // An enum which represents the type of a location.
+ enum LocationType {
+ // Default value if the type isn't specified.
+ LOCATION_TYPE_UNSPECIFIED = 0;
+
+ // A country level location.
+ COUNTRY = 1;
+
+ // A state or equivalent level location.
+ ADMINISTRATIVE_AREA = 2;
+
+ // A county or equivalent level location.
+ SUB_ADMINISTRATIVE_AREA = 3;
+
+ // A city or equivalent level location.
+ LOCALITY = 4;
+
+ // A postal code level location.
+ POSTAL_CODE = 5;
+
+ // A sublocality is a subdivision of a locality, for example a city borough,
+ // ward, or arrondissement. Sublocalities are usually recognized by a local
+ // political authority. For example, Manhattan and Brooklyn are recognized
+ // as boroughs by the City of New York, and are therefore modeled as
+ // sublocalities.
+ SUB_LOCALITY = 6;
+
+ // A district or equivalent level location.
+ SUB_LOCALITY_1 = 7;
+
+ // A smaller district or equivalent level display.
+ SUB_LOCALITY_2 = 8;
+
+ // A neighborhood level location.
+ NEIGHBORHOOD = 9;
+
+ // A street address level location.
+ STREET_ADDRESS = 10;
+ }
+
+ // The type of a location, which corresponds to the address lines field of
+ // [google.type.PostalAddress][google.type.PostalAddress]. For example,
+ // "Downtown, Atlanta, GA, USA" has a type of
+ // [LocationType.NEIGHBORHOOD][google.cloud.talent.v4.Location.LocationType.NEIGHBORHOOD],
+ // and "Kansas City, KS, USA" has a type of
+ // [LocationType.LOCALITY][google.cloud.talent.v4.Location.LocationType.LOCALITY].
+ LocationType location_type = 1;
+
+ // Postal address of the location that includes human readable information,
+ // such as postal delivery and payments addresses. Given a postal address,
+ // a postal service can deliver items to a premises, P.O. Box, or other
+ // delivery location.
+ google.type.PostalAddress postal_address = 2;
+
+ // An object representing a latitude/longitude pair.
+ google.type.LatLng lat_lng = 3;
+
+ // Radius in miles of the job location. This value is derived from the
+ // location bounding box in which a circle with the specified radius
+ // centered from [google.type.LatLng][google.type.LatLng] covers the area
+ // associated with the job location. For example, currently, "Mountain View,
+ // CA, USA" has a radius of 6.17 miles.
+ double radius_miles = 4;
+}
+
+// Meta information related to the job searcher or entity
+// conducting the job search. This information is used to improve the
+// performance of the service.
+message RequestMetadata {
+ // Required if
+ // [allow_missing_ids][google.cloud.talent.v4.RequestMetadata.allow_missing_ids]
+ // is unset or `false`.
+ //
+ // The client-defined scope or source of the service call, which typically
+ // is the domain on
+ // which the service has been implemented and is currently being run.
+ //
+ // For example, if the service is being run by client Foo, Inc., on
+ // job board www.foo.com and career site www.bar.com, then this field is
+ // set to "foo.com" for use on the job board, and "bar.com" for use on the
+ // career site.
+ //
+ // Note that any improvements to the model for a particular tenant site rely
+ // on this field being set correctly to a unique domain.
+ //
+ // The maximum number of allowed characters is 255.
+ string domain = 1;
+
+ // Required if
+ // [allow_missing_ids][google.cloud.talent.v4.RequestMetadata.allow_missing_ids]
+ // is unset or `false`.
+ //
+ // A unique session identification string. A session is defined as the
+ // duration of an end user's interaction with the service over a certain
+ // period.
+ // Obfuscate this field for privacy concerns before
+ // providing it to the service.
+ //
+ // Note that any improvements to the model for a particular tenant site rely
+ // on this field being set correctly to a unique session ID.
+ //
+ // The maximum number of allowed characters is 255.
+ string session_id = 2;
+
+ // Required if
+ // [allow_missing_ids][google.cloud.talent.v4.RequestMetadata.allow_missing_ids]
+ // is unset or `false`.
+ //
+ // A unique user identification string, as determined by the client.
+ // To have the strongest positive impact on search quality
+ // make sure the client-level is unique.
+ // Obfuscate this field for privacy concerns before
+ // providing it to the service.
+ //
+ // Note that any improvements to the model for a particular tenant site rely
+ // on this field being set correctly to a unique user ID.
+ //
+ // The maximum number of allowed characters is 255.
+ string user_id = 3;
+
+ // Only set when any of
+ // [domain][google.cloud.talent.v4.RequestMetadata.domain],
+ // [session_id][google.cloud.talent.v4.RequestMetadata.session_id] and
+ // [user_id][google.cloud.talent.v4.RequestMetadata.user_id] isn't available
+ // for some reason. It is highly recommended not to set this field and provide
+ // accurate [domain][google.cloud.talent.v4.RequestMetadata.domain],
+ // [session_id][google.cloud.talent.v4.RequestMetadata.session_id] and
+ // [user_id][google.cloud.talent.v4.RequestMetadata.user_id] for the best
+ // service experience.
+ bool allow_missing_ids = 4;
+
+ // The type of device used by the job seeker at the time of the call to the
+ // service.
+ DeviceInfo device_info = 5;
+}
+
+// Additional information returned to client, such as debugging information.
+message ResponseMetadata {
+ // A unique id associated with this call.
+ // This id is logged for tracking purposes.
+ string request_id = 1;
+}
+
+// Device information collected from the job seeker, candidate, or
+// other entity conducting the job search. Providing this information improves
+// the quality of the search results across devices.
+message DeviceInfo {
+ // An enumeration describing an API access portal and exposure mechanism.
+ enum DeviceType {
+ // The device type isn't specified.
+ DEVICE_TYPE_UNSPECIFIED = 0;
+
+ // A desktop web browser, such as, Chrome, Firefox, Safari, or Internet
+ // Explorer)
+ WEB = 1;
+
+ // A mobile device web browser, such as a phone or tablet with a Chrome
+ // browser.
+ MOBILE_WEB = 2;
+
+ // An Android device native application.
+ ANDROID = 3;
+
+ // An iOS device native application.
+ IOS = 4;
+
+ // A bot, as opposed to a device operated by human beings, such as a web
+ // crawler.
+ BOT = 5;
+
+ // Other devices types.
+ OTHER = 6;
+ }
+
+ // Type of the device.
+ DeviceType device_type = 1;
+
+ // A device-specific ID. The ID must be a unique identifier that
+ // distinguishes the device from other devices.
+ string id = 2;
+}
+
+// Custom attribute values that are either filterable or non-filterable.
+message CustomAttribute {
+ // Exactly one of
+ // [string_values][google.cloud.talent.v4.CustomAttribute.string_values] or
+ // [long_values][google.cloud.talent.v4.CustomAttribute.long_values] must be
+ // specified.
+ //
+ // This field is used to perform a string match (`CASE_SENSITIVE_MATCH` or
+ // `CASE_INSENSITIVE_MATCH`) search.
+ // For filterable `string_value`s, a maximum total number of 200 values
+ // is allowed, with each `string_value` has a byte size of no more than
+ // 500B. For unfilterable `string_values`, the maximum total byte size of
+ // unfilterable `string_values` is 50KB.
+ //
+ // Empty string isn't allowed.
+ repeated string string_values = 1;
+
+ // Exactly one of
+ // [string_values][google.cloud.talent.v4.CustomAttribute.string_values] or
+ // [long_values][google.cloud.talent.v4.CustomAttribute.long_values] must be
+ // specified.
+ //
+ // This field is used to perform number range search.
+ // (`EQ`, `GT`, `GE`, `LE`, `LT`) over filterable `long_value`.
+ //
+ // Currently at most 1
+ // [long_values][google.cloud.talent.v4.CustomAttribute.long_values] is
+ // supported.
+ repeated int64 long_values = 2;
+
+ // If the `filterable` flag is true, the custom field values may be used for
+ // custom attribute filters
+ // [JobQuery.custom_attribute_filter][google.cloud.talent.v4.JobQuery.custom_attribute_filter].
+ // If false, these values may not be used for custom attribute filters.
+ //
+ // Default is false.
+ bool filterable = 3;
+
+ // If the `keyword_searchable` flag is true, the keywords in custom fields are
+ // searchable by keyword match.
+ // If false, the values are not searchable by keyword match.
+ //
+ // Default is false.
+ bool keyword_searchable = 4;
+}
+
+// Spell check result.
+message SpellingCorrection {
+ // Indicates if the query was corrected by the spell checker.
+ bool corrected = 1;
+
+ // Correction output consisting of the corrected keyword string.
+ string corrected_text = 2;
+
+ // Corrected output with html tags to highlight the corrected words.
+ // Corrected words are called out with the "..." html tags.
+ //
+ // For example, the user input query is "software enginear", where the second
+ // word, "enginear," is incorrect. It should be "engineer". When spelling
+ // correction is enabled, this value is
+ // "software engineer".
+ string corrected_html = 3;
+}
+
+// Job compensation details.
+message CompensationInfo {
+ // A compensation entry that represents one component of compensation, such
+ // as base pay, bonus, or other compensation type.
+ //
+ // Annualization: One compensation entry can be annualized if
+ // - it contains valid
+ // [amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ // or
+ // [range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range].
+ // - and its
+ // [expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year]
+ // is set or can be derived. Its annualized range is determined as
+ // ([amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ // or
+ // [range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range])
+ // times
+ // [expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year].
+ message CompensationEntry {
+ // Compensation type.
+ //
+ // Default is
+ // [CompensationType.COMPENSATION_TYPE_UNSPECIFIED][google.cloud.talent.v4.CompensationInfo.CompensationType.COMPENSATION_TYPE_UNSPECIFIED].
+ CompensationType type = 1;
+
+ // Frequency of the specified amount.
+ //
+ // Default is
+ // [CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED][google.cloud.talent.v4.CompensationInfo.CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED].
+ CompensationUnit unit = 2;
+
+ // Compensation amount. It could be a fixed amount or a floating range.
+ oneof compensation_amount {
+ // Compensation amount.
+ google.type.Money amount = 3;
+
+ // Compensation range.
+ CompensationRange range = 4;
+ }
+
+ // Compensation description. For example, could
+ // indicate equity terms or provide additional context to an estimated
+ // bonus.
+ string description = 5;
+
+ // Expected number of units paid each year. If not specified, when
+ // [Job.employment_types][google.cloud.talent.v4.Job.employment_types] is
+ // FULLTIME, a default value is inferred based on
+ // [unit][google.cloud.talent.v4.CompensationInfo.CompensationEntry.unit].
+ // Default values:
+ // - HOURLY: 2080
+ // - DAILY: 260
+ // - WEEKLY: 52
+ // - MONTHLY: 12
+ // - ANNUAL: 1
+ google.protobuf.DoubleValue expected_units_per_year = 6;
+ }
+
+ // Compensation range.
+ message CompensationRange {
+ // The maximum amount of compensation. If left empty, the value is set
+ // to a maximal compensation value and the currency code is set to
+ // match the [currency code][google.type.Money.currency_code] of
+ // min_compensation.
+ google.type.Money max_compensation = 2;
+
+ // The minimum amount of compensation. If left empty, the value is set
+ // to zero and the currency code is set to match the
+ // [currency code][google.type.Money.currency_code] of max_compensation.
+ google.type.Money min_compensation = 1;
+ }
+
+ // The type of compensation.
+ //
+ // For compensation amounts specified in non-monetary amounts,
+ // describe the compensation scheme in the
+ // [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description].
+ //
+ // For example, tipping format is described in
+ // [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description]
+ // (for example, "expect 15-20% tips based on customer bill.") and an estimate
+ // of the tips provided in
+ // [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ // or
+ // [CompensationEntry.range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range]
+ // ($10 per hour).
+ //
+ // For example, equity is described in
+ // [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description]
+ // (for example, "1% - 2% equity vesting over 4 years, 1 year cliff") and
+ // value estimated in
+ // [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ // or
+ // [CompensationEntry.range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range].
+ // If no value estimate is possible, units are
+ // [CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED][google.cloud.talent.v4.CompensationInfo.CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED]
+ // and then further clarified in
+ // [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description]
+ // field.
+ enum CompensationType {
+ // Default value.
+ COMPENSATION_TYPE_UNSPECIFIED = 0;
+
+ // Base compensation: Refers to the fixed amount of money paid to an
+ // employee by an employer in return for work performed. Base compensation
+ // does not include benefits, bonuses or any other potential compensation
+ // from an employer.
+ BASE = 1;
+
+ // Bonus.
+ BONUS = 2;
+
+ // Signing bonus.
+ SIGNING_BONUS = 3;
+
+ // Equity.
+ EQUITY = 4;
+
+ // Profit sharing.
+ PROFIT_SHARING = 5;
+
+ // Commission.
+ COMMISSIONS = 6;
+
+ // Tips.
+ TIPS = 7;
+
+ // Other compensation type.
+ OTHER_COMPENSATION_TYPE = 8;
+ }
+
+ // Pay frequency.
+ enum CompensationUnit {
+ // Default value.
+ COMPENSATION_UNIT_UNSPECIFIED = 0;
+
+ // Hourly.
+ HOURLY = 1;
+
+ // Daily.
+ DAILY = 2;
+
+ // Weekly
+ WEEKLY = 3;
+
+ // Monthly.
+ MONTHLY = 4;
+
+ // Yearly.
+ YEARLY = 5;
+
+ // One time.
+ ONE_TIME = 6;
+
+ // Other compensation units.
+ OTHER_COMPENSATION_UNIT = 7;
+ }
+
+ // Job compensation information.
+ //
+ // At most one entry can be of type
+ // [CompensationInfo.CompensationType.BASE][google.cloud.talent.v4.CompensationInfo.CompensationType.BASE],
+ // which is referred as **base compensation entry** for the job.
+ repeated CompensationEntry entries = 1;
+
+ // Output only. Annualized base compensation range. Computed as base
+ // compensation entry's
+ // [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ // times
+ // [CompensationEntry.expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year].
+ //
+ // See
+ // [CompensationEntry][google.cloud.talent.v4.CompensationInfo.CompensationEntry]
+ // for explanation on compensation annualization.
+ CompensationRange annualized_base_compensation_range = 2
+ [(google.api.field_behavior) = OUTPUT_ONLY];
+
+ // Output only. Annualized total compensation range. Computed as all
+ // compensation entries'
+ // [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ // times
+ // [CompensationEntry.expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year].
+ //
+ // See
+ // [CompensationEntry][google.cloud.talent.v4.CompensationInfo.CompensationEntry]
+ // for explanation on compensation annualization.
+ CompensationRange annualized_total_compensation_range = 3
+ [(google.api.field_behavior) = OUTPUT_ONLY];
+}
+
+// Metadata used for long running operations returned by CTS batch APIs.
+// It's used to replace
+// [google.longrunning.Operation.metadata][google.longrunning.Operation.metadata].
+message BatchOperationMetadata {
+ enum State {
+ // Default value.
+ STATE_UNSPECIFIED = 0;
+
+ // The batch operation is being prepared for processing.
+ INITIALIZING = 1;
+
+ // The batch operation is actively being processed.
+ PROCESSING = 2;
+
+ // The batch operation is processed, and at least one item has been
+ // successfully processed.
+ SUCCEEDED = 3;
+
+ // The batch operation is done and no item has been successfully processed.
+ FAILED = 4;
+
+ // The batch operation is in the process of cancelling after
+ // [google.longrunning.Operations.CancelOperation][google.longrunning.Operations.CancelOperation]
+ // is called.
+ CANCELLING = 5;
+
+ // The batch operation is done after
+ // [google.longrunning.Operations.CancelOperation][google.longrunning.Operations.CancelOperation]
+ // is called. Any items processed before cancelling are returned in the
+ // response.
+ CANCELLED = 6;
+ }
+
+ // The state of a long running operation.
+ State state = 1;
+
+ // More detailed information about operation state.
+ string state_description = 2;
+
+ // Count of successful item(s) inside an operation.
+ int32 success_count = 3;
+
+ // Count of failed item(s) inside an operation.
+ int32 failure_count = 4;
+
+ // Count of total item(s) inside an operation.
+ int32 total_count = 5;
+
+ // The time when the batch operation is created.
+ google.protobuf.Timestamp create_time = 6;
+
+ // The time when the batch operation status is updated. The metadata and the
+ // [update_time][google.cloud.talent.v4.BatchOperationMetadata.update_time] is
+ // refreshed every minute otherwise cached data is returned.
+ google.protobuf.Timestamp update_time = 7;
+
+ // The time when the batch operation is finished and
+ // [google.longrunning.Operation.done][google.longrunning.Operation.done] is
+ // set to `true`.
+ google.protobuf.Timestamp end_time = 8;
+}
diff --git a/google/cloud/talent_v4/proto/company.proto b/google/cloud/talent_v4/proto/company.proto
new file mode 100644
index 00000000..5c1de8f2
--- /dev/null
+++ b/google/cloud/talent_v4/proto/company.proto
@@ -0,0 +1,118 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "google/cloud/talent/v4/common.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "CompanyProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A Company resource represents a company in the service. A company is the
+// entity that owns job postings, that is, the hiring entity responsible for
+// employing applicants for the job position.
+message Company {
+ option (google.api.resource) = {
+ type: "jobs.googleapis.com/Company"
+ pattern: "projects/{project}/tenants/{tenant}/companies/{company}"
+ };
+
+ // Derived details about the company.
+ message DerivedInfo {
+ // A structured headquarters location of the company, resolved from
+ // [Company.headquarters_address][google.cloud.talent.v4.Company.headquarters_address]
+ // if provided.
+ Location headquarters_location = 1;
+ }
+
+ // Required during company update.
+ //
+ // The resource name for a company. This is generated by the service when a
+ // company is created.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}", for
+ // example, "projects/foo/tenants/bar/companies/baz".
+ string name = 1;
+
+ // Required. The display name of the company, for example, "Google LLC".
+ string display_name = 2 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. Client side company identifier, used to uniquely identify the
+ // company.
+ //
+ // The maximum number of allowed characters is 255.
+ string external_id = 3 [(google.api.field_behavior) = REQUIRED];
+
+ // The employer's company size.
+ CompanySize size = 4;
+
+ // The street address of the company's main headquarters, which may be
+ // different from the job location. The service attempts
+ // to geolocate the provided address, and populates a more specific
+ // location wherever possible in
+ // [DerivedInfo.headquarters_location][google.cloud.talent.v4.Company.DerivedInfo.headquarters_location].
+ string headquarters_address = 5;
+
+ // Set to true if it is the hiring agency that post jobs for other
+ // employers.
+ //
+ // Defaults to false if not provided.
+ bool hiring_agency = 6;
+
+ // Equal Employment Opportunity legal disclaimer text to be
+ // associated with all jobs, and typically to be displayed in all
+ // roles.
+ //
+ // The maximum number of allowed characters is 500.
+ string eeo_text = 7;
+
+ // The URI representing the company's primary web site or home page,
+ // for example, "https://www.google.com".
+ //
+ // The maximum number of allowed characters is 255.
+ string website_uri = 8;
+
+ // The URI to employer's career site or careers page on the employer's web
+ // site, for example, "https://careers.google.com".
+ string career_site_uri = 9;
+
+ // A URI that hosts the employer's company logo.
+ string image_uri = 10;
+
+ // A list of keys of filterable
+ // [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes],
+ // whose corresponding `string_values` are used in keyword searches. Jobs with
+ // `string_values` under these specified field keys are returned if any
+ // of the values match the search keyword. Custom field values with
+ // parenthesis, brackets and special symbols are not searchable as-is,
+ // and those keyword queries must be surrounded by quotes.
+ repeated string keyword_searchable_job_custom_attributes = 11;
+
+ // Output only. Derived details about the company.
+ DerivedInfo derived_info = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
+
+ // Output only. Indicates whether a company is flagged to be suspended from
+ // public availability by the service when job content appears suspicious,
+ // abusive, or spammy.
+ bool suspended = 13 [(google.api.field_behavior) = OUTPUT_ONLY];
+}
diff --git a/google/cloud/talent_v4/proto/company_service.proto b/google/cloud/talent_v4/proto/company_service.proto
new file mode 100644
index 00000000..78bba7cc
--- /dev/null
+++ b/google/cloud/talent_v4/proto/company_service.proto
@@ -0,0 +1,184 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/client.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "google/cloud/talent/v4/common.proto";
+import "google/cloud/talent/v4/company.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "CompanyServiceProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A service that handles company management, including CRUD and enumeration.
+service CompanyService {
+ option (google.api.default_host) = "jobs.googleapis.com";
+ option (google.api.oauth_scopes) =
+ "https://www.googleapis.com/auth/cloud-platform,"
+ "https://www.googleapis.com/auth/jobs";
+
+ // Creates a new company entity.
+ rpc CreateCompany(CreateCompanyRequest) returns (Company) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/companies"
+ body: "company"
+ };
+ option (google.api.method_signature) = "parent,company";
+ }
+
+ // Retrieves specified company.
+ rpc GetCompany(GetCompanyRequest) returns (Company) {
+ option (google.api.http) = {
+ get: "/v4/{name=projects/*/tenants/*/companies/*}"
+ };
+ option (google.api.method_signature) = "name";
+ }
+
+ // Updates specified company.
+ rpc UpdateCompany(UpdateCompanyRequest) returns (Company) {
+ option (google.api.http) = {
+ patch: "/v4/{company.name=projects/*/tenants/*/companies/*}"
+ body: "company"
+ };
+ option (google.api.method_signature) = "company,update_mask";
+ }
+
+ // Deletes specified company.
+ // Prerequisite: The company has no jobs associated with it.
+ rpc DeleteCompany(DeleteCompanyRequest) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ delete: "/v4/{name=projects/*/tenants/*/companies/*}"
+ };
+ option (google.api.method_signature) = "name";
+ }
+
+ // Lists all companies associated with the project.
+ rpc ListCompanies(ListCompaniesRequest) returns (ListCompaniesResponse) {
+ option (google.api.http) = {
+ get: "/v4/{parent=projects/*/tenants/*}/companies"
+ };
+ option (google.api.method_signature) = "parent";
+ }
+}
+
+// The Request of the CreateCompany method.
+message CreateCompanyRequest {
+ // Required. Resource name of the tenant under which the company is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}", for example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Tenant" }
+ ];
+
+ // Required. The company to be created.
+ Company company = 2 [(google.api.field_behavior) = REQUIRED];
+}
+
+// Request for getting a company by name.
+message GetCompanyRequest {
+ // Required. The resource name of the company to be retrieved.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}", for
+ // example, "projects/api-test-project/tenants/foo/companies/bar".
+ string name = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Company" }
+ ];
+}
+
+// Request for updating a specified company.
+message UpdateCompanyRequest {
+ // Required. The company resource to replace the current resource in the
+ // system.
+ Company company = 1 [(google.api.field_behavior) = REQUIRED];
+
+ // Strongly recommended for the best service experience.
+ //
+ // If [update_mask][google.cloud.talent.v4.UpdateCompanyRequest.update_mask]
+ // is provided, only the specified fields in
+ // [company][google.cloud.talent.v4.UpdateCompanyRequest.company] are updated.
+ // Otherwise all the fields are updated.
+ //
+ // A field mask to specify the company fields to be updated. Only
+ // top level fields of [Company][google.cloud.talent.v4.Company] are
+ // supported.
+ google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request to delete a company.
+message DeleteCompanyRequest {
+ // Required. The resource name of the company to be deleted.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}", for
+ // example, "projects/foo/tenants/bar/companies/baz".
+ string name = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Company" }
+ ];
+}
+
+// List companies for which the client has ACL visibility.
+message ListCompaniesRequest {
+ // Required. Resource name of the tenant under which the company is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}", for example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Tenant" }
+ ];
+
+ // The starting indicator from which to return results.
+ string page_token = 2;
+
+ // The maximum number of companies to be returned, at most 100.
+ // Default is 100 if a non-positive number is provided.
+ int32 page_size = 3;
+
+ // Set to true if the companies requested must have open jobs.
+ //
+ // Defaults to false.
+ //
+ // If true, at most
+ // [page_size][google.cloud.talent.v4.ListCompaniesRequest.page_size] of
+ // companies are fetched, among which only those with open jobs are returned.
+ bool require_open_jobs = 4;
+}
+
+// The List companies response object.
+message ListCompaniesResponse {
+ // Companies for the current client.
+ repeated Company companies = 1;
+
+ // A token to retrieve the next page of results.
+ string next_page_token = 2;
+
+ // Additional information for the API invocation, such as the request
+ // tracking id.
+ ResponseMetadata metadata = 3;
+}
diff --git a/google/cloud/talent_v4/proto/completion_service.proto b/google/cloud/talent_v4/proto/completion_service.proto
new file mode 100644
index 00000000..e910d580
--- /dev/null
+++ b/google/cloud/talent_v4/proto/completion_service.proto
@@ -0,0 +1,163 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/client.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "google/cloud/talent/v4/common.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "CompletionServiceProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A service handles auto completion.
+service Completion {
+ option (google.api.default_host) = "jobs.googleapis.com";
+ option (google.api.oauth_scopes) =
+ "https://www.googleapis.com/auth/cloud-platform,"
+ "https://www.googleapis.com/auth/jobs";
+
+ // Completes the specified prefix with keyword suggestions.
+ // Intended for use by a job search auto-complete search box.
+ rpc CompleteQuery(CompleteQueryRequest) returns (CompleteQueryResponse) {
+ option (google.api.http) = {
+ get: "/v4/{tenant=projects/*/tenants/*}:completeQuery"
+ };
+ }
+}
+
+// Auto-complete parameters.
+message CompleteQueryRequest {
+ // Enum to specify the scope of completion.
+ enum CompletionScope {
+ // Default value.
+ COMPLETION_SCOPE_UNSPECIFIED = 0;
+
+ // Suggestions are based only on the data provided by the client.
+ TENANT = 1;
+
+ // Suggestions are based on all jobs data in the system that's visible to
+ // the client
+ PUBLIC = 2;
+ }
+
+ // Enum to specify auto-completion topics.
+ enum CompletionType {
+ // Default value.
+ COMPLETION_TYPE_UNSPECIFIED = 0;
+
+ // Suggest job titles for jobs autocomplete.
+ //
+ // For
+ // [CompletionType.JOB_TITLE][google.cloud.talent.v4.CompleteQueryRequest.CompletionType.JOB_TITLE]
+ // type, only open jobs with the same
+ // [language_codes][google.cloud.talent.v4.CompleteQueryRequest.language_codes]
+ // are returned.
+ JOB_TITLE = 1;
+
+ // Suggest company names for jobs autocomplete.
+ //
+ // For
+ // [CompletionType.COMPANY_NAME][google.cloud.talent.v4.CompleteQueryRequest.CompletionType.COMPANY_NAME]
+ // type, only companies having open jobs with the same
+ // [language_codes][google.cloud.talent.v4.CompleteQueryRequest.language_codes]
+ // are returned.
+ COMPANY_NAME = 2;
+
+ // Suggest both job titles and company names for jobs autocomplete.
+ //
+ // For
+ // [CompletionType.COMBINED][google.cloud.talent.v4.CompleteQueryRequest.CompletionType.COMBINED]
+ // type, only open jobs with the same
+ // [language_codes][google.cloud.talent.v4.CompleteQueryRequest.language_codes]
+ // or companies having open jobs with the same
+ // [language_codes][google.cloud.talent.v4.CompleteQueryRequest.language_codes]
+ // are returned.
+ COMBINED = 3;
+ }
+
+ // Required. Resource name of tenant the completion is performed within.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}", for example,
+ // "projects/foo/tenants/bar".
+ string tenant = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Tenant" }
+ ];
+
+ // Required. The query used to generate suggestions.
+ //
+ // The maximum number of allowed characters is 255.
+ string query = 2 [(google.api.field_behavior) = REQUIRED];
+
+ // The list of languages of the query. This is
+ // the BCP-47 language code, such as "en-US" or "sr-Latn".
+ // For more information, see
+ // [Tags for Identifying Languages](https://tools.ietf.org/html/bcp47).
+ //
+ // The maximum number of allowed characters is 255.
+ repeated string language_codes = 3;
+
+ // Required. Completion result count.
+ //
+ // The maximum allowed page size is 10.
+ int32 page_size = 4 [(google.api.field_behavior) = REQUIRED];
+
+ // If provided, restricts completion to specified company.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}", for
+ // example, "projects/foo/tenants/bar/companies/baz".
+ string company = 5 [
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Company" }
+ ];
+
+ // The scope of the completion. The defaults is
+ // [CompletionScope.PUBLIC][google.cloud.talent.v4.CompleteQueryRequest.CompletionScope.PUBLIC].
+ CompletionScope scope = 6;
+
+ // The completion topic. The default is
+ // [CompletionType.COMBINED][google.cloud.talent.v4.CompleteQueryRequest.CompletionType.COMBINED].
+ CompletionType type = 7;
+}
+
+// Response of auto-complete query.
+message CompleteQueryResponse {
+ // Resource that represents completion results.
+ message CompletionResult {
+ // The suggestion for the query.
+ string suggestion = 1;
+
+ // The completion topic.
+ CompleteQueryRequest.CompletionType type = 2;
+
+ // The URI of the company image for
+ // [COMPANY_NAME][google.cloud.talent.v4.CompleteQueryRequest.CompletionType.COMPANY_NAME].
+ string image_uri = 3;
+ }
+
+ // Results of the matching job/company candidates.
+ repeated CompletionResult completion_results = 1;
+
+ // Additional information for the API invocation, such as the request
+ // tracking id.
+ ResponseMetadata metadata = 2;
+}
diff --git a/google/cloud/talent_v4/proto/event.proto b/google/cloud/talent_v4/proto/event.proto
new file mode 100644
index 00000000..862a4b9a
--- /dev/null
+++ b/google/cloud/talent_v4/proto/event.proto
@@ -0,0 +1,180 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/field_behavior.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "EventProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// An event issued when an end user interacts with the application that
+// implements Cloud Talent Solution. Providing this information improves the
+// quality of results for the API clients, enabling the
+// service to perform optimally. The number of events sent must be consistent
+// with other calls, such as job searches, issued to the service by the client.
+message ClientEvent {
+ // Strongly recommended for the best service experience.
+ //
+ // A unique ID generated in the API responses. It can be found in
+ // [ResponseMetadata.request_id][google.cloud.talent.v4.ResponseMetadata.request_id].
+ string request_id = 1;
+
+ // Required. A unique identifier, generated by the client application.
+ string event_id = 2 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. The timestamp of the event.
+ google.protobuf.Timestamp create_time = 4
+ [(google.api.field_behavior) = REQUIRED];
+
+ // Required.
+ //
+ // The detail information of a specific event type.
+ oneof event {
+ // An event issued when a job seeker interacts with the application that
+ // implements Cloud Talent Solution.
+ JobEvent job_event = 5;
+ }
+
+ // Notes about the event provided by recruiters or other users, for example,
+ // feedback on why a job was bookmarked.
+ string event_notes = 9;
+}
+
+// An event issued when a job seeker interacts with the application that
+// implements Cloud Talent Solution.
+message JobEvent {
+ // An enumeration of an event attributed to the behavior of the end user,
+ // such as a job seeker.
+ enum JobEventType {
+ // The event is unspecified by other provided values.
+ JOB_EVENT_TYPE_UNSPECIFIED = 0;
+
+ // The job seeker or other entity interacting with the service has
+ // had a job rendered in their view, such as in a list of search results in
+ // a compressed or clipped format. This event is typically associated with
+ // the viewing of a jobs list on a single page by a job seeker.
+ IMPRESSION = 1;
+
+ // The job seeker, or other entity interacting with the service, has
+ // viewed the details of a job, including the full description. This
+ // event doesn't apply to the viewing a snippet of a job appearing as a
+ // part of the job search results. Viewing a snippet is associated with an
+ // [impression][google.cloud.talent.v4.JobEvent.JobEventType.IMPRESSION]).
+ VIEW = 2;
+
+ // The job seeker or other entity interacting with the service
+ // performed an action to view a job and was redirected to a different
+ // website for job.
+ VIEW_REDIRECT = 3;
+
+ // The job seeker or other entity interacting with the service
+ // began the process or demonstrated the intention of applying for a job.
+ APPLICATION_START = 4;
+
+ // The job seeker or other entity interacting with the service
+ // submitted an application for a job.
+ APPLICATION_FINISH = 5;
+
+ // The job seeker or other entity interacting with the service
+ // submitted an application for a job with a single click without
+ // entering information. If a job seeker performs this action, send only
+ // this event to the service. Do not also send
+ // [JobEventType.APPLICATION_START][google.cloud.talent.v4.JobEvent.JobEventType.APPLICATION_START]
+ // or
+ // [JobEventType.APPLICATION_FINISH][google.cloud.talent.v4.JobEvent.JobEventType.APPLICATION_FINISH]
+ // events.
+ APPLICATION_QUICK_SUBMISSION = 6;
+
+ // The job seeker or other entity interacting with the service
+ // performed an action to apply to a job and was redirected to a different
+ // website to complete the application.
+ APPLICATION_REDIRECT = 7;
+
+ // The job seeker or other entity interacting with the service began the
+ // process or demonstrated the intention of applying for a job from the
+ // search results page without viewing the details of the job posting.
+ // If sending this event, JobEventType.VIEW event shouldn't be sent.
+ APPLICATION_START_FROM_SEARCH = 8;
+
+ // The job seeker, or other entity interacting with the service, performs an
+ // action with a single click from the search results page to apply to a job
+ // (without viewing the details of the job posting), and is redirected
+ // to a different website to complete the application. If a candidate
+ // performs this action, send only this event to the service. Do not also
+ // send
+ // [JobEventType.APPLICATION_START][google.cloud.talent.v4.JobEvent.JobEventType.APPLICATION_START],
+ // [JobEventType.APPLICATION_FINISH][google.cloud.talent.v4.JobEvent.JobEventType.APPLICATION_FINISH]
+ // or [JobEventType.VIEW][google.cloud.talent.v4.JobEvent.JobEventType.VIEW]
+ // events.
+ APPLICATION_REDIRECT_FROM_SEARCH = 9;
+
+ // This event should be used when a company submits an application
+ // on behalf of a job seeker. This event is intended for use by staffing
+ // agencies attempting to place candidates.
+ APPLICATION_COMPANY_SUBMIT = 10;
+
+ // The job seeker or other entity interacting with the service demonstrated
+ // an interest in a job by bookmarking or saving it.
+ BOOKMARK = 11;
+
+ // The job seeker or other entity interacting with the service was
+ // sent a notification, such as an email alert or device notification,
+ // containing one or more jobs listings generated by the service.
+ NOTIFICATION = 12;
+
+ // The job seeker or other entity interacting with the service was
+ // employed by the hiring entity (employer). Send this event
+ // only if the job seeker was hired through an application that was
+ // initiated by a search conducted through the Cloud Talent Solution
+ // service.
+ HIRED = 13;
+
+ // A recruiter or staffing agency submitted an application on behalf of the
+ // candidate after interacting with the service to identify a suitable job
+ // posting.
+ SENT_CV = 14;
+
+ // The entity interacting with the service (for example, the job seeker),
+ // was granted an initial interview by the hiring entity (employer). This
+ // event should only be sent if the job seeker was granted an interview as
+ // part of an application that was initiated by a search conducted through /
+ // recommendation provided by the Cloud Talent Solution service.
+ INTERVIEW_GRANTED = 15;
+ }
+
+ // Required. The type of the event (see
+ // [JobEventType][google.cloud.talent.v4.JobEvent.JobEventType]).
+ JobEventType type = 1 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. The [job name(s)][google.cloud.talent.v4.Job.name] associated
+ // with this event. For example, if this is an
+ // [impression][google.cloud.talent.v4.JobEvent.JobEventType.IMPRESSION]
+ // event, this field contains the identifiers of all jobs shown to the job
+ // seeker. If this was a
+ // [view][google.cloud.talent.v4.JobEvent.JobEventType.VIEW] event, this field
+ // contains the identifier of the viewed job.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}", for
+ // example, "projects/foo/tenants/bar/jobs/baz".
+ repeated string jobs = 2 [(google.api.field_behavior) = REQUIRED];
+}
diff --git a/google/cloud/talent_v4/proto/event_service.proto b/google/cloud/talent_v4/proto/event_service.proto
new file mode 100644
index 00000000..7cd25f11
--- /dev/null
+++ b/google/cloud/talent_v4/proto/event_service.proto
@@ -0,0 +1,68 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/client.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "google/cloud/talent/v4/event.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "EventServiceProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A service handles client event report.
+service EventService {
+ option (google.api.default_host) = "jobs.googleapis.com";
+ option (google.api.oauth_scopes) =
+ "https://www.googleapis.com/auth/cloud-platform,"
+ "https://www.googleapis.com/auth/jobs";
+
+ // Report events issued when end user interacts with customer's application
+ // that uses Cloud Talent Solution. You may inspect the created events in
+ // [self service
+ // tools](https://console.cloud.google.com/talent-solution/overview).
+ // [Learn
+ // more](https://cloud.google.com/talent-solution/docs/management-tools)
+ // about self service tools.
+ rpc CreateClientEvent(CreateClientEventRequest) returns (ClientEvent) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/clientEvents"
+ body: "client_event"
+ };
+ option (google.api.method_signature) = "parent,client_event";
+ }
+}
+
+// The report event request.
+message CreateClientEventRequest {
+ // Required. Resource name of the tenant under which the event is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}", for example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Tenant" }
+ ];
+
+ // Required. Events issued when end user interacts with customer's application
+ // that uses Cloud Talent Solution.
+ ClientEvent client_event = 2 [(google.api.field_behavior) = REQUIRED];
+}
diff --git a/google/cloud/talent_v4/proto/filters.proto b/google/cloud/talent_v4/proto/filters.proto
new file mode 100644
index 00000000..fb3ffc4f
--- /dev/null
+++ b/google/cloud/talent_v4/proto/filters.proto
@@ -0,0 +1,358 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/field_behavior.proto";
+import "google/cloud/talent/v4/common.proto";
+import "google/protobuf/duration.proto";
+import "google/type/latlng.proto";
+import "google/type/timeofday.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "FiltersProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// The query required to perform a search query.
+message JobQuery {
+ // The query string that matches against the job title, description, and
+ // location fields.
+ //
+ // The maximum number of allowed characters is 255.
+ string query = 1;
+
+ // The language code of [query][google.cloud.talent.v4.JobQuery.query]. For
+ // example, "en-US". This field helps to better interpret the query.
+ //
+ // If a value isn't specified, the query language code is automatically
+ // detected, which may not be accurate.
+ //
+ // Language code should be in BCP-47 format, such as "en-US" or "sr-Latn".
+ // For more information, see
+ // [Tags for Identifying Languages](https://tools.ietf.org/html/bcp47).
+ string query_language_code = 14;
+
+ // This filter specifies the company entities to search against.
+ //
+ // If a value isn't specified, jobs are searched for against all
+ // companies.
+ //
+ // If multiple values are specified, jobs are searched against the
+ // companies specified.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}". For
+ // example, "projects/foo/tenants/bar/companies/baz".
+ //
+ // At most 20 company filters are allowed.
+ repeated string companies = 2;
+
+ // The location filter specifies geo-regions containing the jobs to
+ // search against. See [LocationFilter][google.cloud.talent.v4.LocationFilter]
+ // for more information.
+ //
+ // If a location value isn't specified, jobs fitting the other search
+ // criteria are retrieved regardless of where they're located.
+ //
+ // If multiple values are specified, jobs are retrieved from any of the
+ // specified locations. If different values are specified for the
+ // [LocationFilter.distance_in_miles][google.cloud.talent.v4.LocationFilter.distance_in_miles]
+ // parameter, the maximum provided distance is used for all locations.
+ //
+ // At most 5 location filters are allowed.
+ repeated LocationFilter location_filters = 3;
+
+ // The category filter specifies the categories of jobs to search against.
+ // See [JobCategory][google.cloud.talent.v4.JobCategory] for more information.
+ //
+ // If a value isn't specified, jobs from any category are searched against.
+ //
+ // If multiple values are specified, jobs from any of the specified
+ // categories are searched against.
+ repeated JobCategory job_categories = 4;
+
+ // Allows filtering jobs by commute time with different travel methods (for
+ // example, driving or public transit).
+ //
+ // Note: This only works when you specify a
+ // [CommuteMethod][google.cloud.talent.v4.CommuteMethod]. In this case,
+ // [location_filters][google.cloud.talent.v4.JobQuery.location_filters] is
+ // ignored.
+ //
+ // Currently we don't support sorting by commute time.
+ CommuteFilter commute_filter = 5;
+
+ // This filter specifies the exact company
+ // [Company.display_name][google.cloud.talent.v4.Company.display_name] of the
+ // jobs to search against.
+ //
+ // If a value isn't specified, jobs within the search results are
+ // associated with any company.
+ //
+ // If multiple values are specified, jobs within the search results may be
+ // associated with any of the specified companies.
+ //
+ // At most 20 company display name filters are allowed.
+ repeated string company_display_names = 6;
+
+ // This search filter is applied only to
+ // [Job.compensation_info][google.cloud.talent.v4.Job.compensation_info]. For
+ // example, if the filter is specified as "Hourly job with per-hour
+ // compensation > $15", only jobs meeting these criteria are searched. If a
+ // filter isn't defined, all open jobs are searched.
+ CompensationFilter compensation_filter = 7;
+
+ // This filter specifies a structured syntax to match against the
+ // [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes]
+ // marked as `filterable`.
+ //
+ // The syntax for this expression is a subset of SQL syntax.
+ //
+ // Supported operators are: `=`, `!=`, `<`, `<=`, `>`, and `>=` where the
+ // left of the operator is a custom field key and the right of the operator
+ // is a number or a quoted string. You must escape backslash (\\) and
+ // quote (\") characters.
+ //
+ // Supported functions are `LOWER([field_name])` to
+ // perform a case insensitive match and `EMPTY([field_name])` to filter on the
+ // existence of a key.
+ //
+ // Boolean expressions (AND/OR/NOT) are supported up to 3 levels of
+ // nesting (for example, "((A AND B AND C) OR NOT D) AND E"), a maximum of 100
+ // comparisons or functions are allowed in the expression. The expression
+ // must be < 6000 bytes in length.
+ //
+ // Sample Query:
+ // `(LOWER(driving_license)="class \"a\"" OR EMPTY(driving_license)) AND
+ // driving_years > 10`
+ string custom_attribute_filter = 8;
+
+ // This flag controls the spell-check feature. If false, the
+ // service attempts to correct a misspelled query,
+ // for example, "enginee" is corrected to "engineer".
+ //
+ // Defaults to false: a spell check is performed.
+ bool disable_spell_check = 9;
+
+ // The employment type filter specifies the employment type of jobs to
+ // search against, such as
+ // [EmploymentType.FULL_TIME][google.cloud.talent.v4.EmploymentType.FULL_TIME].
+ //
+ // If a value isn't specified, jobs in the search results includes any
+ // employment type.
+ //
+ // If multiple values are specified, jobs in the search results include
+ // any of the specified employment types.
+ repeated EmploymentType employment_types = 10;
+
+ // This filter specifies the locale of jobs to search against,
+ // for example, "en-US".
+ //
+ // If a value isn't specified, the search results can contain jobs in any
+ // locale.
+ //
+ //
+ // Language codes should be in BCP-47 format, such as "en-US" or "sr-Latn".
+ // For more information, see
+ // [Tags for Identifying Languages](https://tools.ietf.org/html/bcp47).
+ //
+ // At most 10 language code filters are allowed.
+ repeated string language_codes = 11;
+
+ // Jobs published within a range specified by this filter are searched
+ // against.
+ TimestampRange publish_time_range = 12;
+
+ // This filter specifies a list of job names to be excluded during search.
+ //
+ // At most 400 excluded job names are allowed.
+ repeated string excluded_jobs = 13;
+}
+
+// Geographic region of the search.
+message LocationFilter {
+ // Specify whether to include telecommute jobs.
+ enum TelecommutePreference {
+ // Default value if the telecommute preference isn't specified.
+ TELECOMMUTE_PREFERENCE_UNSPECIFIED = 0;
+
+ // Exclude telecommute jobs.
+ TELECOMMUTE_EXCLUDED = 1;
+
+ // Allow telecommute jobs.
+ TELECOMMUTE_ALLOWED = 2;
+ }
+
+ // The address name, such as "Mountain View" or "Bay Area".
+ string address = 1;
+
+ // CLDR region code of the country/region of the address. This is used
+ // to address ambiguity of the user-input location, for example, "Liverpool"
+ // against "Liverpool, NY, US" or "Liverpool, UK".
+ //
+ // Set this field to bias location resolution toward a specific country
+ // or territory. If this field is not set, application behavior is biased
+ // toward the United States by default.
+ //
+ // See
+ // https://www.unicode.org/cldr/charts/30/supplemental/territory_information.html
+ // for details. Example: "CH" for Switzerland.
+ string region_code = 2;
+
+ // The latitude and longitude of the geographic center to search from. This
+ // field is ignored if `address` is provided.
+ google.type.LatLng lat_lng = 3;
+
+ // The distance_in_miles is applied when the location being searched for is
+ // identified as a city or smaller. This field is ignored if the location
+ // being searched for is a state or larger.
+ double distance_in_miles = 4;
+
+ // Allows the client to return jobs without a
+ // set location, specifically, telecommuting jobs (telecommuting is considered
+ // by the service as a special location.
+ // [Job.posting_region][google.cloud.talent.v4.Job.posting_region] indicates
+ // if a job permits telecommuting. If this field is set to
+ // [TelecommutePreference.TELECOMMUTE_ALLOWED][google.cloud.talent.v4.LocationFilter.TelecommutePreference.TELECOMMUTE_ALLOWED],
+ // telecommuting jobs are searched, and
+ // [address][google.cloud.talent.v4.LocationFilter.address] and
+ // [lat_lng][google.cloud.talent.v4.LocationFilter.lat_lng] are ignored. If
+ // not set or set to
+ // [TelecommutePreference.TELECOMMUTE_EXCLUDED][google.cloud.talent.v4.LocationFilter.TelecommutePreference.TELECOMMUTE_EXCLUDED],
+ // telecommute job are not searched.
+ //
+ // This filter can be used by itself to search exclusively for telecommuting
+ // jobs, or it can be combined with another location
+ // filter to search for a combination of job locations,
+ // such as "Mountain View" or "telecommuting" jobs. However, when used in
+ // combination with other location filters, telecommuting jobs can be
+ // treated as less relevant than other jobs in the search response.
+ //
+ // This field is only used for job search requests.
+ TelecommutePreference telecommute_preference = 5;
+}
+
+// Filter on job compensation type and amount.
+message CompensationFilter {
+ // Specify the type of filtering.
+ enum FilterType {
+ // Filter type unspecified. Position holder, INVALID, should never be used.
+ FILTER_TYPE_UNSPECIFIED = 0;
+
+ // Filter by `base compensation entry's` unit. A job is a match if and
+ // only if the job contains a base CompensationEntry and the base
+ // CompensationEntry's unit matches provided
+ // [units][google.cloud.talent.v4.CompensationFilter.units]. Populate one or
+ // more [units][google.cloud.talent.v4.CompensationFilter.units].
+ //
+ // See
+ // [CompensationInfo.CompensationEntry][google.cloud.talent.v4.CompensationInfo.CompensationEntry]
+ // for definition of base compensation entry.
+ UNIT_ONLY = 1;
+
+ // Filter by `base compensation entry's` unit and amount / range. A job
+ // is a match if and only if the job contains a base CompensationEntry, and
+ // the base entry's unit matches provided
+ // [CompensationUnit][google.cloud.talent.v4.CompensationInfo.CompensationUnit]
+ // and amount or range overlaps with provided
+ // [CompensationRange][google.cloud.talent.v4.CompensationInfo.CompensationRange].
+ //
+ // See
+ // [CompensationInfo.CompensationEntry][google.cloud.talent.v4.CompensationInfo.CompensationEntry]
+ // for definition of base compensation entry.
+ //
+ // Set exactly one [units][google.cloud.talent.v4.CompensationFilter.units]
+ // and populate [range][google.cloud.talent.v4.CompensationFilter.range].
+ UNIT_AND_AMOUNT = 2;
+
+ // Filter by annualized base compensation amount and `base compensation
+ // entry's` unit. Populate
+ // [range][google.cloud.talent.v4.CompensationFilter.range] and zero or more
+ // [units][google.cloud.talent.v4.CompensationFilter.units].
+ ANNUALIZED_BASE_AMOUNT = 3;
+
+ // Filter by annualized total compensation amount and `base compensation
+ // entry's` unit . Populate
+ // [range][google.cloud.talent.v4.CompensationFilter.range] and zero or more
+ // [units][google.cloud.talent.v4.CompensationFilter.units].
+ ANNUALIZED_TOTAL_AMOUNT = 4;
+ }
+
+ // Required. Type of filter.
+ FilterType type = 1 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. Specify desired `base compensation entry's`
+ // [CompensationInfo.CompensationUnit][google.cloud.talent.v4.CompensationInfo.CompensationUnit].
+ repeated CompensationInfo.CompensationUnit units = 2
+ [(google.api.field_behavior) = REQUIRED];
+
+ // Compensation range.
+ CompensationInfo.CompensationRange range = 3;
+
+ // If set to true, jobs with unspecified compensation range fields are
+ // included.
+ bool include_jobs_with_unspecified_compensation_range = 4;
+}
+
+// Parameters needed for commute search.
+message CommuteFilter {
+ // The traffic density to use when calculating commute time.
+ enum RoadTraffic {
+ // Road traffic situation isn't specified.
+ ROAD_TRAFFIC_UNSPECIFIED = 0;
+
+ // Optimal commute time without considering any traffic impact.
+ TRAFFIC_FREE = 1;
+
+ // Commute time calculation takes in account the peak traffic impact.
+ BUSY_HOUR = 2;
+ }
+
+ // Required. The method of transportation to calculate the commute time for.
+ CommuteMethod commute_method = 1 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. The latitude and longitude of the location to calculate the
+ // commute time from.
+ google.type.LatLng start_coordinates = 2
+ [(google.api.field_behavior) = REQUIRED];
+
+ // Required. The maximum travel time in seconds. The maximum allowed value is
+ // `3600s` (one hour). Format is `123s`.
+ google.protobuf.Duration travel_duration = 3
+ [(google.api.field_behavior) = REQUIRED];
+
+ // If `true`, jobs without street level addresses may also be returned.
+ // For city level addresses, the city center is used. For state and coarser
+ // level addresses, text matching is used.
+ // If this field is set to `false` or isn't specified, only jobs that include
+ // street level addresses will be returned by commute search.
+ bool allow_imprecise_addresses = 4;
+
+ // Traffic factor to take into account while searching by commute.
+ oneof traffic_option {
+ // Specifies the traffic density to use when calculating commute time.
+ RoadTraffic road_traffic = 5;
+
+ // The departure time used to calculate traffic impact, represented as
+ // [google.type.TimeOfDay][google.type.TimeOfDay] in local time zone.
+ //
+ // Currently traffic model is restricted to hour level resolution.
+ google.type.TimeOfDay departure_time = 6;
+ }
+}
diff --git a/google/cloud/talent_v4/proto/histogram.proto b/google/cloud/talent_v4/proto/histogram.proto
new file mode 100644
index 00000000..f58ac1c0
--- /dev/null
+++ b/google/cloud/talent_v4/proto/histogram.proto
@@ -0,0 +1,56 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "HistogramProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// The histogram request.
+message HistogramQuery {
+ // An expression specifies a histogram request against matching jobs for
+ // searches.
+ //
+ // See
+ // [SearchJobsRequest.histogram_queries][google.cloud.talent.v4.SearchJobsRequest.histogram_queries]
+ // for details about syntax.
+ string histogram_query = 1;
+}
+
+// Histogram result that matches
+// [HistogramQuery][google.cloud.talent.v4.HistogramQuery] specified in
+// searches.
+message HistogramQueryResult {
+ // Requested histogram expression.
+ string histogram_query = 1;
+
+ // A map from the values of the facet associated with distinct values to the
+ // number of matching entries with corresponding value.
+ //
+ // The key format is:
+ //
+ // * (for string histogram) string values stored in the field.
+ // * (for named numeric bucket) name specified in `bucket()` function, like
+ // for `bucket(0, MAX, "non-negative")`, the key will be `non-negative`.
+ // * (for anonymous numeric bucket) range formatted as `-`, for
+ // example, `0-1000`, `MIN-0`, and `0-MAX`.
+ map histogram = 2;
+}
diff --git a/google/cloud/talent_v4/proto/job.proto b/google/cloud/talent_v4/proto/job.proto
new file mode 100644
index 00000000..66242e10
--- /dev/null
+++ b/google/cloud/talent_v4/proto/job.proto
@@ -0,0 +1,370 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "google/cloud/talent/v4/common.proto";
+import "google/protobuf/timestamp.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "JobProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A Job resource represents a job posting (also referred to as a "job listing"
+// or "job requisition"). A job belongs to a
+// [Company][google.cloud.talent.v4.Company], which is the hiring entity
+// responsible for the job.
+message Job {
+ option (google.api.resource) = {
+ type: "jobs.googleapis.com/Job"
+ pattern: "projects/{project}/tenants/{tenant}/jobs/{job}"
+ };
+
+ // Application related details of a job posting.
+ message ApplicationInfo {
+ // Use this field to specify email address(es) to which resumes or
+ // applications can be sent.
+ //
+ // The maximum number of allowed characters for each entry is 255.
+ repeated string emails = 1;
+
+ // Use this field to provide instructions, such as "Mail your application
+ // to ...", that a candidate can follow to apply for the job.
+ //
+ // This field accepts and sanitizes HTML input, and also accepts
+ // bold, italic, ordered list, and unordered list markup tags.
+ //
+ // The maximum number of allowed characters is 3,000.
+ string instruction = 2;
+
+ // Use this URI field to direct an applicant to a website, for example to
+ // link to an online application form.
+ //
+ // The maximum number of allowed characters for each entry is 2,000.
+ repeated string uris = 3;
+ }
+
+ // Derived details about the job posting.
+ message DerivedInfo {
+ // Structured locations of the job, resolved from
+ // [Job.addresses][google.cloud.talent.v4.Job.addresses].
+ //
+ // [locations][google.cloud.talent.v4.Job.DerivedInfo.locations] are exactly
+ // matched to [Job.addresses][google.cloud.talent.v4.Job.addresses] in the
+ // same order.
+ repeated Location locations = 1;
+
+ // Job categories derived from [Job.title][google.cloud.talent.v4.Job.title]
+ // and [Job.description][google.cloud.talent.v4.Job.description].
+ repeated JobCategory job_categories = 3;
+ }
+
+ // Options for job processing.
+ message ProcessingOptions {
+ // If set to `true`, the service does not attempt to resolve a
+ // more precise address for the job.
+ bool disable_street_address_resolution = 1;
+
+ // Option for job HTML content sanitization. Applied fields are:
+ //
+ // * description
+ // * applicationInfo.instruction
+ // * incentives
+ // * qualifications
+ // * responsibilities
+ //
+ // HTML tags in these fields may be stripped if sanitiazation isn't
+ // disabled.
+ //
+ // Defaults to
+ // [HtmlSanitization.SIMPLE_FORMATTING_ONLY][google.cloud.talent.v4.HtmlSanitization.SIMPLE_FORMATTING_ONLY].
+ HtmlSanitization html_sanitization = 2;
+ }
+
+ // Required during job update.
+ //
+ // The resource name for the job. This is generated by the service when a
+ // job is created.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}". For
+ // example, "projects/foo/tenants/bar/jobs/baz".
+ //
+ // Use of this field in job queries and API calls is preferred over the use of
+ // [requisition_id][google.cloud.talent.v4.Job.requisition_id] since this
+ // value is unique.
+ string name = 1;
+
+ // Required. The resource name of the company listing the job.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}". For
+ // example, "projects/foo/tenants/bar/companies/baz".
+ string company = 2 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Company" }
+ ];
+
+ // Required. The requisition ID, also referred to as the posting ID, is
+ // assigned by the client to identify a job. This field is intended to be used
+ // by clients for client identification and tracking of postings. A job isn't
+ // allowed to be created if there is another job with the same
+ // [company][google.cloud.talent.v4.Job.name],
+ // [language_code][google.cloud.talent.v4.Job.language_code] and
+ // [requisition_id][google.cloud.talent.v4.Job.requisition_id].
+ //
+ // The maximum number of allowed characters is 255.
+ string requisition_id = 3 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. The title of the job, such as "Software Engineer"
+ //
+ // The maximum number of allowed characters is 500.
+ string title = 4 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. The description of the job, which typically includes a
+ // multi-paragraph description of the company and related information.
+ // Separate fields are provided on the job object for
+ // [responsibilities][google.cloud.talent.v4.Job.responsibilities],
+ // [qualifications][google.cloud.talent.v4.Job.qualifications], and other job
+ // characteristics. Use of these separate job fields is recommended.
+ //
+ // This field accepts and sanitizes HTML input, and also accepts
+ // bold, italic, ordered list, and unordered list markup tags.
+ //
+ // The maximum number of allowed characters is 100,000.
+ string description = 5 [(google.api.field_behavior) = REQUIRED];
+
+ // Strongly recommended for the best service experience.
+ //
+ // Location(s) where the employer is looking to hire for this job posting.
+ //
+ // Specifying the full street address(es) of the hiring location enables
+ // better API results, especially job searches by commute time.
+ //
+ // At most 50 locations are allowed for best search performance. If a job has
+ // more locations, it is suggested to split it into multiple jobs with unique
+ // [requisition_id][google.cloud.talent.v4.Job.requisition_id]s (e.g. 'ReqA'
+ // becomes 'ReqA-1', 'ReqA-2', and so on.) as multiple jobs with the same
+ // [company][google.cloud.talent.v4.Job.company],
+ // [language_code][google.cloud.talent.v4.Job.language_code] and
+ // [requisition_id][google.cloud.talent.v4.Job.requisition_id] are not
+ // allowed. If the original
+ // [requisition_id][google.cloud.talent.v4.Job.requisition_id] must be
+ // preserved, a custom field should be used for storage. It is also suggested
+ // to group the locations that close to each other in the same job for better
+ // search experience.
+ //
+ // The maximum number of allowed characters is 500.
+ repeated string addresses = 6;
+
+ // Job application information.
+ ApplicationInfo application_info = 7;
+
+ // The benefits included with the job.
+ repeated JobBenefit job_benefits = 8;
+
+ // Job compensation information (a.k.a. "pay rate") i.e., the compensation
+ // that will paid to the employee.
+ CompensationInfo compensation_info = 9;
+
+ // A map of fields to hold both filterable and non-filterable custom job
+ // attributes that are not covered by the provided structured fields.
+ //
+ // The keys of the map are strings up to 64 bytes and must match the
+ // pattern: [a-zA-Z][a-zA-Z0-9_]*. For example, key0LikeThis or
+ // KEY_1_LIKE_THIS.
+ //
+ // At most 100 filterable and at most 100 unfilterable keys are supported.
+ // For filterable `string_values`, across all keys at most 200 values are
+ // allowed, with each string no more than 255 characters. For unfilterable
+ // `string_values`, the maximum total size of `string_values` across all keys
+ // is 50KB.
+ map custom_attributes = 10;
+
+ // The desired education degrees for the job, such as Bachelors, Masters.
+ repeated DegreeType degree_types = 11;
+
+ // The department or functional area within the company with the open
+ // position.
+ //
+ // The maximum number of allowed characters is 255.
+ string department = 12;
+
+ // The employment type(s) of a job, for example,
+ // [full time][google.cloud.talent.v4.EmploymentType.FULL_TIME] or
+ // [part time][google.cloud.talent.v4.EmploymentType.PART_TIME].
+ repeated EmploymentType employment_types = 13;
+
+ // A description of bonus, commission, and other compensation
+ // incentives associated with the job not including salary or pay.
+ //
+ // The maximum number of allowed characters is 10,000.
+ string incentives = 14;
+
+ // The language of the posting. This field is distinct from
+ // any requirements for fluency that are associated with the job.
+ //
+ // Language codes must be in BCP-47 format, such as "en-US" or "sr-Latn".
+ // For more information, see
+ // [Tags for Identifying Languages](https://tools.ietf.org/html/bcp47){:
+ // class="external" target="_blank" }.
+ //
+ // If this field is unspecified and
+ // [Job.description][google.cloud.talent.v4.Job.description] is present,
+ // detected language code based on
+ // [Job.description][google.cloud.talent.v4.Job.description] is assigned,
+ // otherwise defaults to 'en_US'.
+ string language_code = 15;
+
+ // The experience level associated with the job, such as "Entry Level".
+ JobLevel job_level = 16;
+
+ // A promotion value of the job, as determined by the client.
+ // The value determines the sort order of the jobs returned when searching for
+ // jobs using the featured jobs search call, with higher promotional values
+ // being returned first and ties being resolved by relevance sort. Only the
+ // jobs with a promotionValue >0 are returned in a FEATURED_JOB_SEARCH.
+ //
+ // Default value is 0, and negative values are treated as 0.
+ int32 promotion_value = 17;
+
+ // A description of the qualifications required to perform the
+ // job. The use of this field is recommended
+ // as an alternative to using the more general
+ // [description][google.cloud.talent.v4.Job.description] field.
+ //
+ // This field accepts and sanitizes HTML input, and also accepts
+ // bold, italic, ordered list, and unordered list markup tags.
+ //
+ // The maximum number of allowed characters is 10,000.
+ string qualifications = 18;
+
+ // A description of job responsibilities. The use of this field is
+ // recommended as an alternative to using the more general
+ // [description][google.cloud.talent.v4.Job.description] field.
+ //
+ // This field accepts and sanitizes HTML input, and also accepts
+ // bold, italic, ordered list, and unordered list markup tags.
+ //
+ // The maximum number of allowed characters is 10,000.
+ string responsibilities = 19;
+
+ // The job [PostingRegion][google.cloud.talent.v4.PostingRegion] (for example,
+ // state, country) throughout which the job is available. If this field is
+ // set, a [LocationFilter][google.cloud.talent.v4.LocationFilter] in a search
+ // query within the job region finds this job posting if an exact location
+ // match isn't specified. If this field is set to
+ // [PostingRegion.NATION][google.cloud.talent.v4.PostingRegion.NATION] or
+ // [PostingRegion.ADMINISTRATIVE_AREA][google.cloud.talent.v4.PostingRegion.ADMINISTRATIVE_AREA],
+ // setting job [Job.addresses][google.cloud.talent.v4.Job.addresses] to the
+ // same location level as this field is strongly recommended.
+ PostingRegion posting_region = 20;
+
+ // Deprecated. The job is only visible to the owner.
+ //
+ // The visibility of the job.
+ //
+ // Defaults to
+ // [Visibility.ACCOUNT_ONLY][google.cloud.talent.v4.Visibility.ACCOUNT_ONLY]
+ // if not specified.
+ Visibility visibility = 21 [deprecated = true];
+
+ // The start timestamp of the job in UTC time zone. Typically this field
+ // is used for contracting engagements. Invalid timestamps are ignored.
+ google.protobuf.Timestamp job_start_time = 22;
+
+ // The end timestamp of the job. Typically this field is used for contracting
+ // engagements. Invalid timestamps are ignored.
+ google.protobuf.Timestamp job_end_time = 23;
+
+ // The timestamp this job posting was most recently published. The default
+ // value is the time the request arrives at the server. Invalid timestamps are
+ // ignored.
+ google.protobuf.Timestamp posting_publish_time = 24;
+
+ // Strongly recommended for the best service experience.
+ //
+ // The expiration timestamp of the job. After this timestamp, the
+ // job is marked as expired, and it no longer appears in search results. The
+ // expired job can't be listed by the
+ // [ListJobs][google.cloud.talent.v4.JobService.ListJobs] API, but it can be
+ // retrieved with the [GetJob][google.cloud.talent.v4.JobService.GetJob] API
+ // or updated with the
+ // [UpdateJob][google.cloud.talent.v4.JobService.UpdateJob] API or deleted
+ // with the [DeleteJob][google.cloud.talent.v4.JobService.DeleteJob] API. An
+ // expired job can be updated and opened again by using a future expiration
+ // timestamp. Updating an expired job fails if there is another existing open
+ // job with same [company][google.cloud.talent.v4.Job.company],
+ // [language_code][google.cloud.talent.v4.Job.language_code] and
+ // [requisition_id][google.cloud.talent.v4.Job.requisition_id].
+ //
+ // The expired jobs are retained in our system for 90 days. However, the
+ // overall expired job count cannot exceed 3 times the maximum number of
+ // open jobs over previous 7 days. If this threshold is exceeded,
+ // expired jobs are cleaned out in order of earliest expire time.
+ // Expired jobs are no longer accessible after they are cleaned
+ // out.
+ //
+ // Invalid timestamps are ignored, and treated as expire time not provided.
+ //
+ // If the timestamp is before the instant request is made, the job
+ // is treated as expired immediately on creation. This kind of job can
+ // not be updated. And when creating a job with past timestamp, the
+ // [posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ // must be set before
+ // [posting_expire_time][google.cloud.talent.v4.Job.posting_expire_time]. The
+ // purpose of this feature is to allow other objects, such as [Application][],
+ // to refer a job that didn't exist in the system prior to becoming expired.
+ // If you want to modify a job that was expired on creation, delete it and
+ // create a new one.
+ //
+ // If this value isn't provided at the time of job creation or is invalid,
+ // the job posting expires after 30 days from the job's creation time. For
+ // example, if the job was created on 2017/01/01 13:00AM UTC with an
+ // unspecified expiration date, the job expires after 2017/01/31 13:00AM UTC.
+ //
+ // If this value isn't provided on job update, it depends on the field masks
+ // set by
+ // [UpdateJobRequest.update_mask][google.cloud.talent.v4.UpdateJobRequest.update_mask].
+ // If the field masks include
+ // [job_end_time][google.cloud.talent.v4.Job.job_end_time], or the masks are
+ // empty meaning that every field is updated, the job posting expires after 30
+ // days from the job's last update time. Otherwise the expiration date isn't
+ // updated.
+ google.protobuf.Timestamp posting_expire_time = 25;
+
+ // Output only. The timestamp when this job posting was created.
+ google.protobuf.Timestamp posting_create_time = 26
+ [(google.api.field_behavior) = OUTPUT_ONLY];
+
+ // Output only. The timestamp when this job posting was last updated.
+ google.protobuf.Timestamp posting_update_time = 27
+ [(google.api.field_behavior) = OUTPUT_ONLY];
+
+ // Output only. Display name of the company listing the job.
+ string company_display_name = 28 [(google.api.field_behavior) = OUTPUT_ONLY];
+
+ // Output only. Derived details about the job posting.
+ DerivedInfo derived_info = 29 [(google.api.field_behavior) = OUTPUT_ONLY];
+
+ // Options for job processing.
+ ProcessingOptions processing_options = 30;
+}
diff --git a/google/cloud/talent_v4/proto/job_service.proto b/google/cloud/talent_v4/proto/job_service.proto
new file mode 100644
index 00000000..37642927
--- /dev/null
+++ b/google/cloud/talent_v4/proto/job_service.proto
@@ -0,0 +1,865 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/client.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "google/cloud/talent/v4/common.proto";
+import "google/cloud/talent/v4/filters.proto";
+import "google/cloud/talent/v4/histogram.proto";
+import "google/cloud/talent/v4/job.proto";
+import "google/longrunning/operations.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+import "google/rpc/status.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "JobServiceProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A service handles job management, including job CRUD, enumeration and search.
+service JobService {
+ option (google.api.default_host) = "jobs.googleapis.com";
+ option (google.api.oauth_scopes) =
+ "https://www.googleapis.com/auth/cloud-platform,"
+ "https://www.googleapis.com/auth/jobs";
+
+ // Creates a new job.
+ //
+ // Typically, the job becomes searchable within 10 seconds, but it may take
+ // up to 5 minutes.
+ rpc CreateJob(CreateJobRequest) returns (Job) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/jobs"
+ body: "job"
+ };
+ option (google.api.method_signature) = "parent,job";
+ }
+
+ // Begins executing a batch create jobs operation.
+ rpc BatchCreateJobs(BatchCreateJobsRequest) returns (google.longrunning.Operation) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/jobs:batchCreate"
+ body: "*"
+ };
+ option (google.api.method_signature) = "parent,jobs";
+ option (google.longrunning.operation_info) = {
+ response_type: "BatchCreateJobsResponse"
+ metadata_type: "BatchOperationMetadata"
+ };
+ }
+
+ // Retrieves the specified job, whose status is OPEN or recently EXPIRED
+ // within the last 90 days.
+ rpc GetJob(GetJobRequest) returns (Job) {
+ option (google.api.http) = {
+ get: "/v4/{name=projects/*/tenants/*/jobs/*}"
+ };
+ option (google.api.method_signature) = "name";
+ }
+
+ // Updates specified job.
+ //
+ // Typically, updated contents become visible in search results within 10
+ // seconds, but it may take up to 5 minutes.
+ rpc UpdateJob(UpdateJobRequest) returns (Job) {
+ option (google.api.http) = {
+ patch: "/v4/{job.name=projects/*/tenants/*/jobs/*}"
+ body: "job"
+ };
+ option (google.api.method_signature) = "job,update_mask";
+ }
+
+ // Begins executing a batch update jobs operation.
+ rpc BatchUpdateJobs(BatchUpdateJobsRequest) returns (google.longrunning.Operation) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/jobs:batchUpdate"
+ body: "*"
+ };
+ option (google.api.method_signature) = "parent,jobs";
+ option (google.longrunning.operation_info) = {
+ response_type: "BatchUpdateJobsResponse"
+ metadata_type: "BatchOperationMetadata"
+ };
+ }
+
+ // Deletes the specified job.
+ //
+ // Typically, the job becomes unsearchable within 10 seconds, but it may take
+ // up to 5 minutes.
+ rpc DeleteJob(DeleteJobRequest) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ delete: "/v4/{name=projects/*/tenants/*/jobs/*}"
+ };
+ option (google.api.method_signature) = "name";
+ }
+
+ // Begins executing a batch delete jobs operation.
+ rpc BatchDeleteJobs(BatchDeleteJobsRequest) returns (google.longrunning.Operation) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/jobs:batchDelete"
+ body: "*"
+ };
+ option (google.api.method_signature) = "parent,names";
+ option (google.longrunning.operation_info) = {
+ response_type: "BatchDeleteJobsResponse"
+ metadata_type: "BatchOperationMetadata"
+ };
+ }
+
+ // Lists jobs by filter.
+ rpc ListJobs(ListJobsRequest) returns (ListJobsResponse) {
+ option (google.api.http) = {
+ get: "/v4/{parent=projects/*/tenants/*}/jobs"
+ };
+ option (google.api.method_signature) = "parent,filter";
+ }
+
+ // Searches for jobs using the provided [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+ //
+ // This call constrains the [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ // present in the database, and only returns jobs that the caller has
+ // permission to search against.
+ rpc SearchJobs(SearchJobsRequest) returns (SearchJobsResponse) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/jobs:search"
+ body: "*"
+ };
+ }
+
+ // Searches for jobs using the provided [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+ //
+ // This API call is intended for the use case of targeting passive job
+ // seekers (for example, job seekers who have signed up to receive email
+ // alerts about potential job opportunities), it has different algorithmic
+ // adjustments that are designed to specifically target passive job seekers.
+ //
+ // This call constrains the [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ // present in the database, and only returns jobs the caller has
+ // permission to search against.
+ rpc SearchJobsForAlert(SearchJobsRequest) returns (SearchJobsResponse) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*/tenants/*}/jobs:searchForAlert"
+ body: "*"
+ };
+ }
+}
+
+// Create job request.
+message CreateJobRequest {
+ // Required. The resource name of the tenant under which the job is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}". For example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ child_type: "jobs.googleapis.com/Job"
+ }
+ ];
+
+ // Required. The Job to be created.
+ Job job = 2 [(google.api.field_behavior) = REQUIRED];
+}
+
+// Get job request.
+message GetJobRequest {
+ // Required. The resource name of the job to retrieve.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}". For
+ // example, "projects/foo/tenants/bar/jobs/baz".
+ string name = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ type: "jobs.googleapis.com/Job"
+ }
+ ];
+}
+
+// Update job request.
+message UpdateJobRequest {
+ // Required. The Job to be updated.
+ Job job = 1 [(google.api.field_behavior) = REQUIRED];
+
+ // Strongly recommended for the best service experience.
+ //
+ // If [update_mask][google.cloud.talent.v4.UpdateJobRequest.update_mask] is provided, only the specified fields in
+ // [job][google.cloud.talent.v4.UpdateJobRequest.job] are updated. Otherwise all the fields are updated.
+ //
+ // A field mask to restrict the fields that are updated. Only
+ // top level fields of [Job][google.cloud.talent.v4.Job] are supported.
+ google.protobuf.FieldMask update_mask = 2;
+}
+
+// Delete job request.
+message DeleteJobRequest {
+ // Required. The resource name of the job to be deleted.
+ //
+ // The format is
+ // "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}". For
+ // example, "projects/foo/tenants/bar/jobs/baz".
+ string name = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ type: "jobs.googleapis.com/Job"
+ }
+ ];
+}
+
+// List jobs request.
+message ListJobsRequest {
+ // Required. The resource name of the tenant under which the job is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}". For example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ child_type: "jobs.googleapis.com/Job"
+ }
+ ];
+
+ // Required. The filter string specifies the jobs to be enumerated.
+ //
+ // Supported operator: =, AND
+ //
+ // The fields eligible for filtering are:
+ //
+ // * `companyName` (Required)
+ // * `requisitionId`
+ // * `status` Available values: OPEN, EXPIRED, ALL. Defaults to
+ // OPEN if no value is specified.
+ //
+ // Sample Query:
+ //
+ // * companyName = "projects/foo/tenants/bar/companies/baz"
+ // * companyName = "projects/foo/tenants/bar/companies/baz" AND
+ // requisitionId = "req-1"
+ // * companyName = "projects/foo/tenants/bar/companies/baz" AND
+ // status = "EXPIRED"
+ string filter = 2 [(google.api.field_behavior) = REQUIRED];
+
+ // The starting point of a query result.
+ string page_token = 3;
+
+ // The maximum number of jobs to be returned per page of results.
+ //
+ // If [job_view][google.cloud.talent.v4.ListJobsRequest.job_view] is set to [JobView.JOB_VIEW_ID_ONLY][google.cloud.talent.v4.JobView.JOB_VIEW_ID_ONLY], the maximum allowed
+ // page size is 1000. Otherwise, the maximum allowed page size is 100.
+ //
+ // Default is 100 if empty or a number < 1 is specified.
+ int32 page_size = 4;
+
+ // The desired job attributes returned for jobs in the
+ // search response. Defaults to [JobView.JOB_VIEW_FULL][google.cloud.talent.v4.JobView.JOB_VIEW_FULL] if no value is
+ // specified.
+ JobView job_view = 5;
+}
+
+// An enum that specifies the job attributes that are returned in the
+// [MatchingJob.job][google.cloud.talent.v4.SearchJobsResponse.MatchingJob.job] or
+// [ListJobsResponse.jobs][google.cloud.talent.v4.ListJobsResponse.jobs] fields.
+enum JobView {
+ // Default value.
+ JOB_VIEW_UNSPECIFIED = 0;
+
+ // A ID only view of job, with following attributes:
+ // [Job.name][google.cloud.talent.v4.Job.name], [Job.requisition_id][google.cloud.talent.v4.Job.requisition_id], [Job.language_code][google.cloud.talent.v4.Job.language_code].
+ JOB_VIEW_ID_ONLY = 1;
+
+ // A minimal view of the job, with the following attributes:
+ // [Job.name][google.cloud.talent.v4.Job.name], [Job.requisition_id][google.cloud.talent.v4.Job.requisition_id], [Job.title][google.cloud.talent.v4.Job.title],
+ // [Job.company][google.cloud.talent.v4.Job.company], [Job.DerivedInfo.locations][google.cloud.talent.v4.Job.DerivedInfo.locations], [Job.language_code][google.cloud.talent.v4.Job.language_code].
+ JOB_VIEW_MINIMAL = 2;
+
+ // A small view of the job, with the following attributes in the search
+ // results: [Job.name][google.cloud.talent.v4.Job.name], [Job.requisition_id][google.cloud.talent.v4.Job.requisition_id], [Job.title][google.cloud.talent.v4.Job.title],
+ // [Job.company][google.cloud.talent.v4.Job.company], [Job.DerivedInfo.locations][google.cloud.talent.v4.Job.DerivedInfo.locations], [Job.visibility][google.cloud.talent.v4.Job.visibility],
+ // [Job.language_code][google.cloud.talent.v4.Job.language_code], [Job.description][google.cloud.talent.v4.Job.description].
+ JOB_VIEW_SMALL = 3;
+
+ // All available attributes are included in the search results.
+ JOB_VIEW_FULL = 4;
+}
+
+// List jobs response.
+message ListJobsResponse {
+ // The Jobs for a given company.
+ //
+ // The maximum number of items returned is based on the limit field
+ // provided in the request.
+ repeated Job jobs = 1;
+
+ // A token to retrieve the next page of results.
+ string next_page_token = 2;
+
+ // Additional information for the API invocation, such as the request
+ // tracking id.
+ ResponseMetadata metadata = 3;
+}
+
+// The Request body of the `SearchJobs` call.
+message SearchJobsRequest {
+ // Custom ranking information for [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+ message CustomRankingInfo {
+ // The importance level for [CustomRankingInfo.ranking_expression][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.ranking_expression].
+ enum ImportanceLevel {
+ // Default value if the importance level isn't specified.
+ IMPORTANCE_LEVEL_UNSPECIFIED = 0;
+
+ // The given ranking expression is of None importance, existing relevance
+ // score (determined by API algorithm) dominates job's final ranking
+ // position.
+ NONE = 1;
+
+ // The given ranking expression is of Low importance in terms of job's
+ // final ranking position compared to existing relevance
+ // score (determined by API algorithm).
+ LOW = 2;
+
+ // The given ranking expression is of Mild importance in terms of job's
+ // final ranking position compared to existing relevance
+ // score (determined by API algorithm).
+ MILD = 3;
+
+ // The given ranking expression is of Medium importance in terms of job's
+ // final ranking position compared to existing relevance
+ // score (determined by API algorithm).
+ MEDIUM = 4;
+
+ // The given ranking expression is of High importance in terms of job's
+ // final ranking position compared to existing relevance
+ // score (determined by API algorithm).
+ HIGH = 5;
+
+ // The given ranking expression is of Extreme importance, and dominates
+ // job's final ranking position with existing relevance
+ // score (determined by API algorithm) ignored.
+ EXTREME = 6;
+ }
+
+ // Required. Controls over how important the score of
+ // [CustomRankingInfo.ranking_expression][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.ranking_expression] gets applied to job's final
+ // ranking position.
+ //
+ // An error is thrown if not specified.
+ ImportanceLevel importance_level = 1 [(google.api.field_behavior) = REQUIRED];
+
+ // Required. Controls over how job documents get ranked on top of existing relevance
+ // score (determined by API algorithm). A combination of the ranking
+ // expression and relevance score is used to determine job's final ranking
+ // position.
+ //
+ // The syntax for this expression is a subset of Google SQL syntax.
+ //
+ // Supported operators are: +, -, *, /, where the left and right side of
+ // the operator is either a numeric [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes] key,
+ // integer/double value or an expression that can be evaluated to a number.
+ //
+ // Parenthesis are supported to adjust calculation precedence. The
+ // expression must be < 100 characters in length.
+ //
+ // The expression is considered invalid for a job if the expression
+ // references custom attributes that are not populated on the job or if the
+ // expression results in a divide by zero. If an expression is invalid for a
+ // job, that job is demoted to the end of the results.
+ //
+ // Sample ranking expression
+ // (year + 25) * 0.25 - (freshness / 0.5)
+ string ranking_expression = 2 [(google.api.field_behavior) = REQUIRED];
+ }
+
+ // A string-represented enumeration of the job search mode. The service
+ // operate differently for different modes of service.
+ enum SearchMode {
+ // The mode of the search method isn't specified. The default search
+ // behavior is identical to JOB_SEARCH search behavior.
+ SEARCH_MODE_UNSPECIFIED = 0;
+
+ // The job search matches against all jobs, and featured jobs
+ // (jobs with promotionValue > 0) are not specially handled.
+ JOB_SEARCH = 1;
+
+ // The job search matches only against featured jobs (jobs with a
+ // promotionValue > 0). This method doesn't return any jobs having a
+ // promotionValue <= 0. The search results order is determined by the
+ // promotionValue (jobs with a higher promotionValue are returned higher up
+ // in the search results), with relevance being used as a tiebreaker.
+ FEATURED_JOB_SEARCH = 2;
+ }
+
+ // Controls whether highly similar jobs are returned next to each other in
+ // the search results. Jobs are identified as highly similar based on
+ // their titles, job categories, and locations. Highly similar results are
+ // clustered so that only one representative job of the cluster is
+ // displayed to the job seeker higher up in the results, with the other jobs
+ // being displayed lower down in the results.
+ enum DiversificationLevel {
+ // The diversification level isn't specified.
+ DIVERSIFICATION_LEVEL_UNSPECIFIED = 0;
+
+ // Disables diversification. Jobs that would normally be pushed to the last
+ // page would not have their positions altered. This may result in highly
+ // similar jobs appearing in sequence in the search results.
+ DISABLED = 1;
+
+ // Default diversifying behavior. The result list is ordered so that
+ // highly similar results are pushed to the end of the last page of search
+ // results. If you are using pageToken to page through the result set,
+ // latency might be lower but we can't guarantee that all results are
+ // returned. If you are using page offset, latency might be higher but all
+ // results are returned.
+ SIMPLE = 2;
+ }
+
+ // Required. The resource name of the tenant to search within.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}". For example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ child_type: "jobs.googleapis.com/Job"
+ }
+ ];
+
+ // Mode of a search.
+ //
+ // Defaults to [SearchMode.JOB_SEARCH][google.cloud.talent.v4.SearchJobsRequest.SearchMode.JOB_SEARCH].
+ SearchMode search_mode = 2;
+
+ // Required. The meta information collected about the job searcher, used to improve the
+ // search quality of the service. The identifiers (such as `user_id`) are
+ // provided by users, and must be unique and consistent.
+ RequestMetadata request_metadata = 3 [(google.api.field_behavior) = REQUIRED];
+
+ // Query used to search against jobs, such as keyword, location filters, etc.
+ JobQuery job_query = 4;
+
+ // Controls whether to broaden the search when it produces sparse results.
+ // Broadened queries append results to the end of the matching results
+ // list.
+ //
+ // Defaults to false.
+ bool enable_broadening = 5;
+
+ // An expression specifies a histogram request against matching jobs.
+ //
+ // Expression syntax is an aggregation function call with histogram facets and
+ // other options.
+ //
+ // Available aggregation function calls are:
+ // * `count(string_histogram_facet)`: Count the number of matching entities,
+ // for each distinct attribute value.
+ // * `count(numeric_histogram_facet, list of buckets)`: Count the number of
+ // matching entities within each bucket.
+ //
+ // Data types:
+ //
+ // * Histogram facet: facet names with format [a-zA-Z][a-zA-Z0-9_]+.
+ // * String: string like "any string with backslash escape for quote(\")."
+ // * Number: whole number and floating point number like 10, -1 and -0.01.
+ // * List: list of elements with comma(,) separator surrounded by square
+ // brackets, for example, [1, 2, 3] and ["one", "two", "three"].
+ //
+ // Built-in constants:
+ //
+ // * MIN (minimum number similar to java Double.MIN_VALUE)
+ // * MAX (maximum number similar to java Double.MAX_VALUE)
+ //
+ // Built-in functions:
+ //
+ // * bucket(start, end[, label]): bucket built-in function creates a bucket
+ // with range of [start, end). Note that the end is exclusive, for example,
+ // bucket(1, MAX, "positive number") or bucket(1, 10).
+ //
+ // Job histogram facets:
+ //
+ // * company_display_name: histogram by [Job.company_display_name][google.cloud.talent.v4.Job.company_display_name].
+ // * employment_type: histogram by [Job.employment_types][google.cloud.talent.v4.Job.employment_types], for example,
+ // "FULL_TIME", "PART_TIME".
+ // * company_size: histogram by [CompanySize][google.cloud.talent.v4.CompanySize], for example, "SMALL",
+ // "MEDIUM", "BIG".
+ // * publish_time_in_month: histogram by the [Job.posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ // in months.
+ // Must specify list of numeric buckets in spec.
+ // * publish_time_in_year: histogram by the [Job.posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ // in years.
+ // Must specify list of numeric buckets in spec.
+ // * degree_types: histogram by the [Job.degree_types][google.cloud.talent.v4.Job.degree_types], for example,
+ // "Bachelors", "Masters".
+ // * job_level: histogram by the [Job.job_level][google.cloud.talent.v4.Job.job_level], for example, "Entry
+ // Level".
+ // * country: histogram by the country code of jobs, for example, "US", "FR".
+ // * admin1: histogram by the admin1 code of jobs, which is a global
+ // placeholder referring to the state, province, or the particular term a
+ // country uses to define the geographic structure below the country level,
+ // for example, "CA", "IL".
+ // * city: histogram by a combination of the "city name, admin1 code". For
+ // example, "Mountain View, CA", "New York, NY".
+ // * admin1_country: histogram by a combination of the "admin1 code, country",
+ // for example, "CA, US", "IL, US".
+ // * city_coordinate: histogram by the city center's GPS coordinates (latitude
+ // and longitude), for example, 37.4038522,-122.0987765. Since the
+ // coordinates of a city center can change, customers may need to refresh
+ // them periodically.
+ // * locale: histogram by the [Job.language_code][google.cloud.talent.v4.Job.language_code], for example, "en-US",
+ // "fr-FR".
+ // * language: histogram by the language subtag of the [Job.language_code][google.cloud.talent.v4.Job.language_code],
+ // for example, "en", "fr".
+ // * category: histogram by the [JobCategory][google.cloud.talent.v4.JobCategory], for example,
+ // "COMPUTER_AND_IT", "HEALTHCARE".
+ // * base_compensation_unit: histogram by the
+ // [CompensationInfo.CompensationUnit][google.cloud.talent.v4.CompensationInfo.CompensationUnit] of base
+ // salary, for example, "WEEKLY", "MONTHLY".
+ // * base_compensation: histogram by the base salary. Must specify list of
+ // numeric buckets to group results by.
+ // * annualized_base_compensation: histogram by the base annualized salary.
+ // Must specify list of numeric buckets to group results by.
+ // * annualized_total_compensation: histogram by the total annualized salary.
+ // Must specify list of numeric buckets to group results by.
+ // * string_custom_attribute: histogram by string [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes].
+ // Values can be accessed via square bracket notations like
+ // string_custom_attribute["key1"].
+ // * numeric_custom_attribute: histogram by numeric [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes].
+ // Values can be accessed via square bracket notations like
+ // numeric_custom_attribute["key1"]. Must specify list of numeric buckets to
+ // group results by.
+ //
+ // Example expressions:
+ //
+ // * `count(admin1)`
+ // * `count(base_compensation, [bucket(1000, 10000), bucket(10000, 100000),
+ // bucket(100000, MAX)])`
+ // * `count(string_custom_attribute["some-string-custom-attribute"])`
+ // * `count(numeric_custom_attribute["some-numeric-custom-attribute"],
+ // [bucket(MIN, 0, "negative"), bucket(0, MAX, "non-negative"])`
+ repeated HistogramQuery histogram_queries = 7;
+
+ // The desired job attributes returned for jobs in the search response.
+ // Defaults to [JobView.JOB_VIEW_SMALL][google.cloud.talent.v4.JobView.JOB_VIEW_SMALL] if no value is specified.
+ JobView job_view = 8;
+
+ // An integer that specifies the current offset (that is, starting result
+ // location, amongst the jobs deemed by the API as relevant) in search
+ // results. This field is only considered if [page_token][google.cloud.talent.v4.SearchJobsRequest.page_token] is unset.
+ //
+ // The maximum allowed value is 5000. Otherwise an error is thrown.
+ //
+ // For example, 0 means to return results starting from the first matching
+ // job, and 10 means to return from the 11th job. This can be used for
+ // pagination, (for example, pageSize = 10 and offset = 10 means to return
+ // from the second page).
+ int32 offset = 9;
+
+ // A limit on the number of jobs returned in the search results.
+ // Increasing this value above the default value of 10 can increase search
+ // response time. The value can be between 1 and 100.
+ int32 max_page_size = 10;
+
+ // The token specifying the current offset within
+ // search results. See [SearchJobsResponse.next_page_token][google.cloud.talent.v4.SearchJobsResponse.next_page_token] for
+ // an explanation of how to obtain the next set of query results.
+ string page_token = 11;
+
+ // The criteria determining how search results are sorted. Default is
+ // `"relevance desc"`.
+ //
+ // Supported options are:
+ //
+ // * `"relevance desc"`: By relevance descending, as determined by the API
+ // algorithms. Relevance thresholding of query results is only available
+ // with this ordering.
+ // * `"posting_publish_time desc"`: By [Job.posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ // descending.
+ // * `"posting_update_time desc"`: By [Job.posting_update_time][google.cloud.talent.v4.Job.posting_update_time]
+ // descending.
+ // * `"title"`: By [Job.title][google.cloud.talent.v4.Job.title] ascending.
+ // * `"title desc"`: By [Job.title][google.cloud.talent.v4.Job.title] descending.
+ // * `"annualized_base_compensation"`: By job's
+ // [CompensationInfo.annualized_base_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_base_compensation_range] ascending. Jobs
+ // whose annualized base compensation is unspecified are put at the end of
+ // search results.
+ // * `"annualized_base_compensation desc"`: By job's
+ // [CompensationInfo.annualized_base_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_base_compensation_range] descending. Jobs
+ // whose annualized base compensation is unspecified are put at the end of
+ // search results.
+ // * `"annualized_total_compensation"`: By job's
+ // [CompensationInfo.annualized_total_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_total_compensation_range] ascending. Jobs
+ // whose annualized base compensation is unspecified are put at the end of
+ // search results.
+ // * `"annualized_total_compensation desc"`: By job's
+ // [CompensationInfo.annualized_total_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_total_compensation_range] descending. Jobs
+ // whose annualized base compensation is unspecified are put at the end of
+ // search results.
+ // * `"custom_ranking desc"`: By the relevance score adjusted to the
+ // [SearchJobsRequest.CustomRankingInfo.ranking_expression][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.ranking_expression] with weight
+ // factor assigned by
+ // [SearchJobsRequest.CustomRankingInfo.importance_level][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.importance_level] in descending
+ // order.
+ // * Location sorting: Use the special syntax to order jobs by distance:
+ // `"distance_from('Hawaii')"`: Order by distance from Hawaii.
+ // `"distance_from(19.89, 155.5)"`: Order by distance from a coordinate.
+ // `"distance_from('Hawaii'), distance_from('Puerto Rico')"`: Order by
+ // multiple locations. See details below.
+ // `"distance_from('Hawaii'), distance_from(19.89, 155.5)"`: Order by
+ // multiple locations. See details below.
+ // The string can have a maximum of 256 characters. When multiple distance
+ // centers are provided, a job that is close to any of the distance centers
+ // would have a high rank. When a job has multiple locations, the job
+ // location closest to one of the distance centers will be used. Jobs that
+ // don't have locations will be ranked at the bottom. Distance is calculated
+ // with a precision of 11.3 meters (37.4 feet). Diversification strategy is
+ // still applied unless explicitly disabled in
+ // [diversification_level][google.cloud.talent.v4.SearchJobsRequest.diversification_level].
+ string order_by = 12;
+
+ // Controls whether highly similar jobs are returned next to each other in
+ // the search results. Jobs are identified as highly similar based on
+ // their titles, job categories, and locations. Highly similar results are
+ // clustered so that only one representative job of the cluster is
+ // displayed to the job seeker higher up in the results, with the other jobs
+ // being displayed lower down in the results.
+ //
+ // Defaults to [DiversificationLevel.SIMPLE][google.cloud.talent.v4.SearchJobsRequest.DiversificationLevel.SIMPLE] if no value
+ // is specified.
+ DiversificationLevel diversification_level = 13;
+
+ // Controls over how job documents get ranked on top of existing relevance
+ // score (determined by API algorithm).
+ CustomRankingInfo custom_ranking_info = 14;
+
+ // Controls whether to disable exact keyword match on [Job.title][google.cloud.talent.v4.Job.title],
+ // [Job.description][google.cloud.talent.v4.Job.description], [Job.company_display_name][google.cloud.talent.v4.Job.company_display_name], [Job.addresses][google.cloud.talent.v4.Job.addresses],
+ // [Job.qualifications][google.cloud.talent.v4.Job.qualifications]. When disable keyword match is turned off, a
+ // keyword match returns jobs that do not match given category filters when
+ // there are matching keywords. For example, for the query "program manager,"
+ // a result is returned even if the job posting has the title "software
+ // developer," which doesn't fall into "program manager" ontology, but does
+ // have "program manager" appearing in its description.
+ //
+ // For queries like "cloud" that don't contain title or
+ // location specific ontology, jobs with "cloud" keyword matches are returned
+ // regardless of this flag's value.
+ //
+ // Use [Company.keyword_searchable_job_custom_attributes][google.cloud.talent.v4.Company.keyword_searchable_job_custom_attributes] if
+ // company-specific globally matched custom field/attribute string values are
+ // needed. Enabling keyword match improves recall of subsequent search
+ // requests.
+ //
+ // Defaults to false.
+ bool disable_keyword_match = 16;
+}
+
+// Response for SearchJob method.
+message SearchJobsResponse {
+ // Job entry with metadata inside [SearchJobsResponse][google.cloud.talent.v4.SearchJobsResponse].
+ message MatchingJob {
+ // Job resource that matches the specified [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+ Job job = 1;
+
+ // A summary of the job with core information that's displayed on the search
+ // results listing page.
+ string job_summary = 2;
+
+ // Contains snippets of text from the [Job.title][google.cloud.talent.v4.Job.title] field most
+ // closely matching a search query's keywords, if available. The matching
+ // query keywords are enclosed in HTML bold tags.
+ string job_title_snippet = 3;
+
+ // Contains snippets of text from the [Job.description][google.cloud.talent.v4.Job.description] and similar
+ // fields that most closely match a search query's keywords, if available.
+ // All HTML tags in the original fields are stripped when returned in this
+ // field, and matching query keywords are enclosed in HTML bold tags.
+ string search_text_snippet = 4;
+
+ // Commute information which is generated based on specified
+ // [CommuteFilter][google.cloud.talent.v4.CommuteFilter].
+ CommuteInfo commute_info = 5;
+ }
+
+ // Commute details related to this job.
+ message CommuteInfo {
+ // Location used as the destination in the commute calculation.
+ Location job_location = 1;
+
+ // The number of seconds required to travel to the job location from the
+ // query location. A duration of 0 seconds indicates that the job isn't
+ // reachable within the requested duration, but was returned as part of an
+ // expanded query.
+ google.protobuf.Duration travel_duration = 2;
+ }
+
+ // The Job entities that match the specified [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+ repeated MatchingJob matching_jobs = 1;
+
+ // The histogram results that match with specified
+ // [SearchJobsRequest.histogram_queries][google.cloud.talent.v4.SearchJobsRequest.histogram_queries].
+ repeated HistogramQueryResult histogram_query_results = 2;
+
+ // The token that specifies the starting position of the next page of results.
+ // This field is empty if there are no more results.
+ string next_page_token = 3;
+
+ // The location filters that the service applied to the specified query. If
+ // any filters are lat-lng based, the [Location.location_type][google.cloud.talent.v4.Location.location_type] is
+ // [Location.LocationType.LOCATION_TYPE_UNSPECIFIED][google.cloud.talent.v4.Location.LocationType.LOCATION_TYPE_UNSPECIFIED].
+ repeated Location location_filters = 4;
+
+ // Number of jobs that match the specified query.
+ //
+ // Note: This size is precise only if the total is less than 100,000.
+ int32 total_size = 6;
+
+ // Additional information for the API invocation, such as the request
+ // tracking id.
+ ResponseMetadata metadata = 7;
+
+ // If query broadening is enabled, we may append additional results from the
+ // broadened query. This number indicates how many of the jobs returned in the
+ // jobs field are from the broadened query. These results are always at the
+ // end of the jobs list. In particular, a value of 0, or if the field isn't
+ // set, all the jobs in the jobs list are from the original
+ // (without broadening) query. If this field is non-zero, subsequent requests
+ // with offset after this result set should contain all broadened results.
+ int32 broadened_query_jobs_count = 8;
+
+ // The spell checking result, and correction.
+ SpellingCorrection spell_correction = 9;
+}
+
+// Request to create a batch of jobs.
+message BatchCreateJobsRequest {
+ // Required. The resource name of the tenant under which the job is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}". For example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ child_type: "jobs.googleapis.com/Job"
+ }
+ ];
+
+ // Required. The jobs to be created.
+ // A maximum of 200 jobs can be created in a batch.
+ repeated Job jobs = 2 [(google.api.field_behavior) = REQUIRED];
+}
+
+// Request to update a batch of jobs.
+message BatchUpdateJobsRequest {
+ // Required. The resource name of the tenant under which the job is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}". For example,
+ // "projects/foo/tenants/bar".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ child_type: "jobs.googleapis.com/Job"
+ }
+ ];
+
+ // Required. The jobs to be updated.
+ // A maximum of 200 jobs can be updated in a batch.
+ repeated Job jobs = 2 [(google.api.field_behavior) = REQUIRED];
+
+ // Strongly recommended for the best service experience. Be aware that it will
+ // also increase latency when checking the status of a batch operation.
+ //
+ // If [update_mask][google.cloud.talent.v4.BatchUpdateJobsRequest.update_mask] is provided, only the specified fields in
+ // [Job][google.cloud.talent.v4.Job] are updated. Otherwise all the fields are updated.
+ //
+ // A field mask to restrict the fields that are updated. Only
+ // top level fields of [Job][google.cloud.talent.v4.Job] are supported.
+ //
+ // If [update_mask][google.cloud.talent.v4.BatchUpdateJobsRequest.update_mask] is provided, The [Job][google.cloud.talent.v4.Job] inside
+ // [JobResult][JobOperationResult.JobResult]
+ // will only contains fields that is updated, plus the Id of the Job.
+ // Otherwise, [Job][google.cloud.talent.v4.Job] will include all fields, which can yield a very
+ // large response.
+ google.protobuf.FieldMask update_mask = 3;
+}
+
+// Request to delete a batch of jobs.
+message BatchDeleteJobsRequest {
+ // Required. The resource name of the tenant under which the job is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}". For example,
+ // "projects/foo/tenants/bar".
+ //
+ // The parent of all of the jobs specified in `names` must match this field.
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ type: "jobs.googleapis.com/Tenant"
+ }
+ ];
+
+ // The names of the jobs to delete.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ // For example, "projects/foo/tenants/bar/jobs/baz".
+ //
+ // A maximum of 200 jobs can be deleted in a batch.
+ repeated string names = 2 [(google.api.resource_reference) = {
+ type: "jobs.googleapis.com/Job"
+ }];
+}
+
+// Mutation result of a job from a batch operation.
+message JobResult {
+ // Here [Job][google.cloud.talent.v4.Job] only contains basic information including [name][google.cloud.talent.v4.Job.name],
+ // [company][google.cloud.talent.v4.Job.company], [language_code][google.cloud.talent.v4.Job.language_code]
+ // and [requisition_id][google.cloud.talent.v4.Job.requisition_id], use getJob method to retrieve
+ // detailed information of the created/updated job.
+ Job job = 1;
+
+ // The status of the job processed. This field is populated if the
+ // processing of the [job][google.cloud.talent.v4.JobResult.job] fails.
+ google.rpc.Status status = 2;
+}
+
+// The result of [JobService.BatchCreateJobs][google.cloud.talent.v4.JobService.BatchCreateJobs]. It's used to
+// replace [google.longrunning.Operation.response][google.longrunning.Operation.response] in case of success.
+message BatchCreateJobsResponse {
+ // List of job mutation results from a batch create operation. It can change
+ // until operation status is FINISHED, FAILED or CANCELLED.
+ repeated JobResult job_results = 1;
+}
+
+// The result of [JobService.BatchUpdateJobs][google.cloud.talent.v4.JobService.BatchUpdateJobs]. It's used to
+// replace [google.longrunning.Operation.response][google.longrunning.Operation.response] in case of success.
+message BatchUpdateJobsResponse {
+ // List of job mutation results from a batch update operation. It can change
+ // until operation status is FINISHED, FAILED or CANCELLED.
+ repeated JobResult job_results = 1;
+}
+
+// The result of [JobService.BatchDeleteJobs][google.cloud.talent.v4.JobService.BatchDeleteJobs]. It's used to
+// replace [google.longrunning.Operation.response][google.longrunning.Operation.response] in case of success.
+message BatchDeleteJobsResponse {
+ // List of job mutation results from a batch delete operation. It can change
+ // until operation status is FINISHED, FAILED or CANCELLED.
+ repeated JobResult job_results = 1;
+}
diff --git a/google/cloud/talent_v4/proto/tenant.proto b/google/cloud/talent_v4/proto/tenant.proto
new file mode 100644
index 00000000..a21fc06a
--- /dev/null
+++ b/google/cloud/talent_v4/proto/tenant.proto
@@ -0,0 +1,53 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "TenantProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A Tenant resource represents a tenant in the service. A tenant is a group or
+// entity that shares common access with specific privileges for resources like
+// jobs. Customer may create multiple tenants to provide data isolation for
+// different groups.
+message Tenant {
+ option (google.api.resource) = {
+ type: "jobs.googleapis.com/Tenant"
+ pattern: "projects/{project}/tenants/{tenant}"
+ };
+
+ // Required during tenant update.
+ //
+ // The resource name for a tenant. This is generated by the service when a
+ // tenant is created.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}", for example,
+ // "projects/foo/tenants/bar".
+ string name = 1;
+
+ // Required. Client side tenant identifier, used to uniquely identify the
+ // tenant.
+ //
+ // The maximum number of allowed characters is 255.
+ string external_id = 2 [(google.api.field_behavior) = REQUIRED];
+}
diff --git a/google/cloud/talent_v4/proto/tenant_service.proto b/google/cloud/talent_v4/proto/tenant_service.proto
new file mode 100644
index 00000000..8941ba7f
--- /dev/null
+++ b/google/cloud/talent_v4/proto/tenant_service.proto
@@ -0,0 +1,175 @@
+// 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.
+
+syntax = "proto3";
+
+package google.cloud.talent.v4;
+
+import "google/api/annotations.proto";
+import "google/api/client.proto";
+import "google/api/field_behavior.proto";
+import "google/api/resource.proto";
+import "google/cloud/talent/v4/common.proto";
+import "google/cloud/talent/v4/tenant.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/field_mask.proto";
+
+option go_package = "google.golang.org/genproto/googleapis/cloud/talent/v4;talent";
+option java_multiple_files = true;
+option java_outer_classname = "TenantServiceProto";
+option java_package = "com.google.cloud.talent.v4";
+option objc_class_prefix = "CTS";
+
+// A service that handles tenant management, including CRUD and enumeration.
+service TenantService {
+ option (google.api.default_host) = "jobs.googleapis.com";
+ option (google.api.oauth_scopes) =
+ "https://www.googleapis.com/auth/cloud-platform,"
+ "https://www.googleapis.com/auth/jobs";
+
+ // Creates a new tenant entity.
+ rpc CreateTenant(CreateTenantRequest) returns (Tenant) {
+ option (google.api.http) = {
+ post: "/v4/{parent=projects/*}/tenants"
+ body: "tenant"
+ };
+ option (google.api.method_signature) = "parent,tenant";
+ }
+
+ // Retrieves specified tenant.
+ rpc GetTenant(GetTenantRequest) returns (Tenant) {
+ option (google.api.http) = {
+ get: "/v4/{name=projects/*/tenants/*}"
+ };
+ option (google.api.method_signature) = "name";
+ }
+
+ // Updates specified tenant.
+ rpc UpdateTenant(UpdateTenantRequest) returns (Tenant) {
+ option (google.api.http) = {
+ patch: "/v4/{tenant.name=projects/*/tenants/*}"
+ body: "tenant"
+ };
+ option (google.api.method_signature) = "tenant,update_mask";
+ }
+
+ // Deletes specified tenant.
+ rpc DeleteTenant(DeleteTenantRequest) returns (google.protobuf.Empty) {
+ option (google.api.http) = {
+ delete: "/v4/{name=projects/*/tenants/*}"
+ };
+ option (google.api.method_signature) = "name";
+ }
+
+ // Lists all tenants associated with the project.
+ rpc ListTenants(ListTenantsRequest) returns (ListTenantsResponse) {
+ option (google.api.http) = {
+ get: "/v4/{parent=projects/*}/tenants"
+ };
+ option (google.api.method_signature) = "parent";
+ }
+}
+
+// The Request of the CreateTenant method.
+message CreateTenantRequest {
+ // Required. Resource name of the project under which the tenant is created.
+ //
+ // The format is "projects/{project_id}", for example,
+ // "projects/foo".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ type: "cloudresourcemanager.googleapis.com/Project"
+ }
+ ];
+
+ // Required. The tenant to be created.
+ Tenant tenant = 2 [(google.api.field_behavior) = REQUIRED];
+}
+
+// Request for getting a tenant by name.
+message GetTenantRequest {
+ // Required. The resource name of the tenant to be retrieved.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}", for example,
+ // "projects/foo/tenants/bar".
+ string name = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Tenant" }
+ ];
+}
+
+// Request for updating a specified tenant.
+message UpdateTenantRequest {
+ // Required. The tenant resource to replace the current resource in the
+ // system.
+ Tenant tenant = 1 [(google.api.field_behavior) = REQUIRED];
+
+ // Strongly recommended for the best service experience.
+ //
+ // If [update_mask][google.cloud.talent.v4.UpdateTenantRequest.update_mask] is
+ // provided, only the specified fields in
+ // [tenant][google.cloud.talent.v4.UpdateTenantRequest.tenant] are updated.
+ // Otherwise all the fields are updated.
+ //
+ // A field mask to specify the tenant fields to be updated. Only
+ // top level fields of [Tenant][google.cloud.talent.v4.Tenant] are supported.
+ google.protobuf.FieldMask update_mask = 2;
+}
+
+// Request to delete a tenant.
+message DeleteTenantRequest {
+ // Required. The resource name of the tenant to be deleted.
+ //
+ // The format is "projects/{project_id}/tenants/{tenant_id}", for example,
+ // "projects/foo/tenants/bar".
+ string name = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = { type: "jobs.googleapis.com/Tenant" }
+ ];
+}
+
+// List tenants for which the client has ACL visibility.
+message ListTenantsRequest {
+ // Required. Resource name of the project under which the tenant is created.
+ //
+ // The format is "projects/{project_id}", for example,
+ // "projects/foo".
+ string parent = 1 [
+ (google.api.field_behavior) = REQUIRED,
+ (google.api.resource_reference) = {
+ type: "cloudresourcemanager.googleapis.com/Project"
+ }
+ ];
+
+ // The starting indicator from which to return results.
+ string page_token = 2;
+
+ // The maximum number of tenants to be returned, at most 100.
+ // Default is 100 if a non-positive number is provided.
+ int32 page_size = 3;
+}
+
+// The List tenants response object.
+message ListTenantsResponse {
+ // Tenants for the current client.
+ repeated Tenant tenants = 1;
+
+ // A token to retrieve the next page of results.
+ string next_page_token = 2;
+
+ // Additional information for the API invocation, such as the request
+ // tracking id.
+ ResponseMetadata metadata = 3;
+}
diff --git a/google/cloud/talent_v4/py.typed b/google/cloud/talent_v4/py.typed
new file mode 100644
index 00000000..d9645927
--- /dev/null
+++ b/google/cloud/talent_v4/py.typed
@@ -0,0 +1,2 @@
+# Marker file for PEP 561.
+# The google-cloud-talent package uses inline types.
diff --git a/google/cloud/talent_v4/services/__init__.py b/google/cloud/talent_v4/services/__init__.py
new file mode 100644
index 00000000..42ffdf2b
--- /dev/null
+++ b/google/cloud/talent_v4/services/__init__.py
@@ -0,0 +1,16 @@
+# -*- 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/google/cloud/talent_v4/services/company_service/__init__.py b/google/cloud/talent_v4/services/company_service/__init__.py
new file mode 100644
index 00000000..a7154172
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/__init__.py
@@ -0,0 +1,24 @@
+# -*- 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.
+#
+
+from .client import CompanyServiceClient
+from .async_client import CompanyServiceAsyncClient
+
+__all__ = (
+ "CompanyServiceClient",
+ "CompanyServiceAsyncClient",
+)
diff --git a/google/cloud/talent_v4/services/company_service/async_client.py b/google/cloud/talent_v4/services/company_service/async_client.py
new file mode 100644
index 00000000..37769378
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/async_client.py
@@ -0,0 +1,559 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+import functools
+import re
+from typing import Dict, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import credentials # type: ignore
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.services.company_service import pagers
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import company
+from google.cloud.talent_v4.types import company as gct_company
+from google.cloud.talent_v4.types import company_service
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+
+from .transports.base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc_asyncio import CompanyServiceGrpcAsyncIOTransport
+from .client import CompanyServiceClient
+
+
+class CompanyServiceAsyncClient:
+ """A service that handles company management, including CRUD and
+ enumeration.
+ """
+
+ _client: CompanyServiceClient
+
+ DEFAULT_ENDPOINT = CompanyServiceClient.DEFAULT_ENDPOINT
+ DEFAULT_MTLS_ENDPOINT = CompanyServiceClient.DEFAULT_MTLS_ENDPOINT
+
+ company_path = staticmethod(CompanyServiceClient.company_path)
+ parse_company_path = staticmethod(CompanyServiceClient.parse_company_path)
+
+ from_service_account_file = CompanyServiceClient.from_service_account_file
+ from_service_account_json = from_service_account_file
+
+ get_transport_class = functools.partial(
+ type(CompanyServiceClient).get_transport_class, type(CompanyServiceClient)
+ )
+
+ def __init__(
+ self,
+ *,
+ credentials: credentials.Credentials = None,
+ transport: Union[str, CompanyServiceTransport] = "grpc_asyncio",
+ client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the company service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.CompanyServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (ClientOptions): Custom options for the client. It
+ won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+
+ self._client = CompanyServiceClient(
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
+ )
+
+ async def create_company(
+ self,
+ request: company_service.CreateCompanyRequest = None,
+ *,
+ parent: str = None,
+ company: gct_company.Company = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_company.Company:
+ r"""Creates a new company entity.
+
+ Args:
+ request (:class:`~.company_service.CreateCompanyRequest`):
+ The request object. The Request of the CreateCompany
+ method.
+ parent (:class:`str`):
+ Required. Resource name of the tenant under which the
+ company is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ company (:class:`~.gct_company.Company`):
+ Required. The company to be created.
+ This corresponds to the ``company`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_company.Company:
+ A Company resource represents a
+ company in the service. A company is the
+ entity that owns job postings, that is,
+ the hiring entity responsible for
+ employing applicants for the job
+ position.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, company]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = company_service.CreateCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if company is not None:
+ request.company = company
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.create_company,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def get_company(
+ self,
+ request: company_service.GetCompanyRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> company.Company:
+ r"""Retrieves specified company.
+
+ Args:
+ request (:class:`~.company_service.GetCompanyRequest`):
+ The request object. Request for getting a company by
+ name.
+ name (:class:`str`):
+ Required. The resource name of the company to be
+ retrieved.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example,
+ "projects/api-test-project/tenants/foo/companies/bar".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.company.Company:
+ A Company resource represents a
+ company in the service. A company is the
+ entity that owns job postings, that is,
+ the hiring entity responsible for
+ employing applicants for the job
+ position.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([name]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = company_service.GetCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.get_company,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def update_company(
+ self,
+ request: company_service.UpdateCompanyRequest = None,
+ *,
+ company: gct_company.Company = None,
+ update_mask: field_mask.FieldMask = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_company.Company:
+ r"""Updates specified company.
+
+ Args:
+ request (:class:`~.company_service.UpdateCompanyRequest`):
+ The request object. Request for updating a specified
+ company.
+ company (:class:`~.gct_company.Company`):
+ Required. The company resource to
+ replace the current resource in the
+ system.
+ This corresponds to the ``company`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`~.field_mask.FieldMask`):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateCompanyRequest.update_mask]
+ is provided, only the specified fields in
+ [company][google.cloud.talent.v4.UpdateCompanyRequest.company]
+ are updated. Otherwise all the fields are updated.
+
+ A field mask to specify the company fields to be
+ updated. Only top level fields of
+ [Company][google.cloud.talent.v4.Company] are supported.
+ This corresponds to the ``update_mask`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_company.Company:
+ A Company resource represents a
+ company in the service. A company is the
+ entity that owns job postings, that is,
+ the hiring entity responsible for
+ employing applicants for the job
+ position.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([company, update_mask]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = company_service.UpdateCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if company is not None:
+ request.company = company
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.update_company,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("company.name", request.company.name),)
+ ),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def delete_company(
+ self,
+ request: company_service.DeleteCompanyRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> None:
+ r"""Deletes specified company.
+ Prerequisite: The company has no jobs associated with
+ it.
+
+ Args:
+ request (:class:`~.company_service.DeleteCompanyRequest`):
+ The request object. Request to delete a company.
+ name (:class:`str`):
+ Required. The resource name of the company to be
+ deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example, "projects/foo/tenants/bar/companies/baz".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([name]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = company_service.DeleteCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.delete_company,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ await rpc(
+ request, retry=retry, timeout=timeout, metadata=metadata,
+ )
+
+ async def list_companies(
+ self,
+ request: company_service.ListCompaniesRequest = None,
+ *,
+ parent: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> pagers.ListCompaniesAsyncPager:
+ r"""Lists all companies associated with the project.
+
+ Args:
+ request (:class:`~.company_service.ListCompaniesRequest`):
+ The request object. List companies for which the client
+ has ACL visibility.
+ parent (:class:`str`):
+ Required. Resource name of the tenant under which the
+ company is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.pagers.ListCompaniesAsyncPager:
+ The List companies response object.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = company_service.ListCompaniesRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.list_companies,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListCompaniesAsyncPager(
+ method=rpc, request=request, response=response, metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("CompanyServiceAsyncClient",)
diff --git a/google/cloud/talent_v4/services/company_service/client.py b/google/cloud/talent_v4/services/company_service/client.py
new file mode 100644
index 00000000..30d6bff0
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/client.py
@@ -0,0 +1,706 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from distutils import util
+import os
+import re
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import 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
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.services.company_service import pagers
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import company
+from google.cloud.talent_v4.types import company as gct_company
+from google.cloud.talent_v4.types import company_service
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+
+from .transports.base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc import CompanyServiceGrpcTransport
+from .transports.grpc_asyncio import CompanyServiceGrpcAsyncIOTransport
+
+
+class CompanyServiceClientMeta(type):
+ """Metaclass for the CompanyService client.
+
+ This provides class-level methods for building and retrieving
+ support objects (e.g. transport) without polluting the client instance
+ objects.
+ """
+
+ _transport_registry = (
+ OrderedDict()
+ ) # type: Dict[str, Type[CompanyServiceTransport]]
+ _transport_registry["grpc"] = CompanyServiceGrpcTransport
+ _transport_registry["grpc_asyncio"] = CompanyServiceGrpcAsyncIOTransport
+
+ def get_transport_class(cls, label: str = None,) -> Type[CompanyServiceTransport]:
+ """Return an appropriate transport class.
+
+ Args:
+ label: The name of the desired transport. If none is
+ provided, then the first transport in the registry is used.
+
+ Returns:
+ The transport class to use.
+ """
+ # If a specific transport is requested, return that one.
+ if label:
+ return cls._transport_registry[label]
+
+ # No transport is requested; return the default (that is, the first one
+ # in the dictionary).
+ return next(iter(cls._transport_registry.values()))
+
+
+class CompanyServiceClient(metaclass=CompanyServiceClientMeta):
+ """A service that handles company management, including CRUD and
+ enumeration.
+ """
+
+ @staticmethod
+ def _get_default_mtls_endpoint(api_endpoint):
+ """Convert api endpoint to mTLS endpoint.
+ Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
+ "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
+ Args:
+ api_endpoint (Optional[str]): the api endpoint to convert.
+ Returns:
+ str: converted mTLS api endpoint.
+ """
+ if not api_endpoint:
+ return api_endpoint
+
+ mtls_endpoint_re = re.compile(
+ r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?"
+ )
+
+ m = mtls_endpoint_re.match(api_endpoint)
+ name, mtls, sandbox, googledomain = m.groups()
+ if mtls or not googledomain:
+ return api_endpoint
+
+ if sandbox:
+ return api_endpoint.replace(
+ "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
+ )
+
+ return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+
+ DEFAULT_ENDPOINT = "jobs.googleapis.com"
+ DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
+ DEFAULT_ENDPOINT
+ )
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ {@api.name}: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_file(filename)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
+ from_service_account_json = from_service_account_file
+
+ @staticmethod
+ def company_path(project: str, tenant: str, company: str,) -> str:
+ """Return a fully-qualified company string."""
+ return "projects/{project}/tenants/{tenant}/companies/{company}".format(
+ project=project, tenant=tenant, company=company,
+ )
+
+ @staticmethod
+ def parse_company_path(path: str) -> Dict[str, str]:
+ """Parse a company path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/tenants/(?P.+?)/companies/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
+ def __init__(
+ self,
+ *,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, CompanyServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the company service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.CompanyServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+ if isinstance(client_options, dict):
+ client_options = client_options_lib.from_dict(client_options)
+ if client_options is None:
+ client_options = client_options_lib.ClientOptions()
+
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
+ if use_mtls_env == "never":
+ api_endpoint = self.DEFAULT_ENDPOINT
+ 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
+ )
+ else:
+ raise MutualTLSChannelError(
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
+ )
+
+ # Save or instantiate the transport.
+ # Ordinarily, we provide the transport, but allowing a custom transport
+ # instance provides an extensibility point for unusual situations.
+ if isinstance(transport, CompanyServiceTransport):
+ # transport is a CompanyServiceTransport instance.
+ if credentials or client_options.credentials_file:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its credentials directly."
+ )
+ if client_options.scopes:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its scopes directly."
+ )
+ self._transport = transport
+ else:
+ Transport = type(self).get_transport_class(transport)
+ self._transport = Transport(
+ credentials=credentials,
+ credentials_file=client_options.credentials_file,
+ host=api_endpoint,
+ scopes=client_options.scopes,
+ ssl_channel_credentials=ssl_credentials,
+ quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
+ )
+
+ def create_company(
+ self,
+ request: company_service.CreateCompanyRequest = None,
+ *,
+ parent: str = None,
+ company: gct_company.Company = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_company.Company:
+ r"""Creates a new company entity.
+
+ Args:
+ request (:class:`~.company_service.CreateCompanyRequest`):
+ The request object. The Request of the CreateCompany
+ method.
+ parent (:class:`str`):
+ Required. Resource name of the tenant under which the
+ company is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ company (:class:`~.gct_company.Company`):
+ Required. The company to be created.
+ This corresponds to the ``company`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_company.Company:
+ A Company resource represents a
+ company in the service. A company is the
+ entity that owns job postings, that is,
+ the hiring entity responsible for
+ employing applicants for the job
+ position.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, company])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a company_service.CreateCompanyRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, company_service.CreateCompanyRequest):
+ request = company_service.CreateCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if company is not None:
+ request.company = company
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.create_company]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def get_company(
+ self,
+ request: company_service.GetCompanyRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> company.Company:
+ r"""Retrieves specified company.
+
+ Args:
+ request (:class:`~.company_service.GetCompanyRequest`):
+ The request object. Request for getting a company by
+ name.
+ name (:class:`str`):
+ Required. The resource name of the company to be
+ retrieved.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example,
+ "projects/api-test-project/tenants/foo/companies/bar".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.company.Company:
+ A Company resource represents a
+ company in the service. A company is the
+ entity that owns job postings, that is,
+ the hiring entity responsible for
+ employing applicants for the job
+ position.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([name])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a company_service.GetCompanyRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, company_service.GetCompanyRequest):
+ request = company_service.GetCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.get_company]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def update_company(
+ self,
+ request: company_service.UpdateCompanyRequest = None,
+ *,
+ company: gct_company.Company = None,
+ update_mask: field_mask.FieldMask = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_company.Company:
+ r"""Updates specified company.
+
+ Args:
+ request (:class:`~.company_service.UpdateCompanyRequest`):
+ The request object. Request for updating a specified
+ company.
+ company (:class:`~.gct_company.Company`):
+ Required. The company resource to
+ replace the current resource in the
+ system.
+ This corresponds to the ``company`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`~.field_mask.FieldMask`):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateCompanyRequest.update_mask]
+ is provided, only the specified fields in
+ [company][google.cloud.talent.v4.UpdateCompanyRequest.company]
+ are updated. Otherwise all the fields are updated.
+
+ A field mask to specify the company fields to be
+ updated. Only top level fields of
+ [Company][google.cloud.talent.v4.Company] are supported.
+ This corresponds to the ``update_mask`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_company.Company:
+ A Company resource represents a
+ company in the service. A company is the
+ entity that owns job postings, that is,
+ the hiring entity responsible for
+ employing applicants for the job
+ position.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([company, update_mask])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a company_service.UpdateCompanyRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, company_service.UpdateCompanyRequest):
+ request = company_service.UpdateCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if company is not None:
+ request.company = company
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.update_company]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("company.name", request.company.name),)
+ ),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def delete_company(
+ self,
+ request: company_service.DeleteCompanyRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> None:
+ r"""Deletes specified company.
+ Prerequisite: The company has no jobs associated with
+ it.
+
+ Args:
+ request (:class:`~.company_service.DeleteCompanyRequest`):
+ The request object. Request to delete a company.
+ name (:class:`str`):
+ Required. The resource name of the company to be
+ deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example, "projects/foo/tenants/bar/companies/baz".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([name])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a company_service.DeleteCompanyRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, company_service.DeleteCompanyRequest):
+ request = company_service.DeleteCompanyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_company]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ rpc(
+ request, retry=retry, timeout=timeout, metadata=metadata,
+ )
+
+ def list_companies(
+ self,
+ request: company_service.ListCompaniesRequest = None,
+ *,
+ parent: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> pagers.ListCompaniesPager:
+ r"""Lists all companies associated with the project.
+
+ Args:
+ request (:class:`~.company_service.ListCompaniesRequest`):
+ The request object. List companies for which the client
+ has ACL visibility.
+ parent (:class:`str`):
+ Required. Resource name of the tenant under which the
+ company is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.pagers.ListCompaniesPager:
+ The List companies response object.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a company_service.ListCompaniesRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, company_service.ListCompaniesRequest):
+ request = company_service.ListCompaniesRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.list_companies]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListCompaniesPager(
+ method=rpc, request=request, response=response, metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("CompanyServiceClient",)
diff --git a/google/cloud/talent_v4/services/company_service/pagers.py b/google/cloud/talent_v4/services/company_service/pagers.py
new file mode 100644
index 00000000..992c4b53
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/pagers.py
@@ -0,0 +1,149 @@
+# -*- 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.
+#
+
+from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple
+
+from google.cloud.talent_v4.types import company
+from google.cloud.talent_v4.types import company_service
+
+
+class ListCompaniesPager:
+ """A pager for iterating through ``list_companies`` requests.
+
+ This class thinly wraps an initial
+ :class:`~.company_service.ListCompaniesResponse` object, and
+ provides an ``__iter__`` method to iterate through its
+ ``companies`` field.
+
+ If there are more pages, the ``__iter__`` method will make additional
+ ``ListCompanies`` requests and continue to iterate
+ through the ``companies`` field on the
+ corresponding responses.
+
+ All the usual :class:`~.company_service.ListCompaniesResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., company_service.ListCompaniesResponse],
+ request: company_service.ListCompaniesRequest,
+ response: company_service.ListCompaniesResponse,
+ *,
+ metadata: Sequence[Tuple[str, str]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (:class:`~.company_service.ListCompaniesRequest`):
+ The initial request object.
+ response (:class:`~.company_service.ListCompaniesResponse`):
+ The initial response object.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ self._method = method
+ self._request = company_service.ListCompaniesRequest(request)
+ self._response = response
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ def pages(self) -> Iterable[company_service.ListCompaniesResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = self._method(self._request, metadata=self._metadata)
+ yield self._response
+
+ def __iter__(self) -> Iterable[company.Company]:
+ for page in self.pages:
+ yield from page.companies
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListCompaniesAsyncPager:
+ """A pager for iterating through ``list_companies`` requests.
+
+ This class thinly wraps an initial
+ :class:`~.company_service.ListCompaniesResponse` object, and
+ provides an ``__aiter__`` method to iterate through its
+ ``companies`` field.
+
+ If there are more pages, the ``__aiter__`` method will make additional
+ ``ListCompanies`` requests and continue to iterate
+ through the ``companies`` field on the
+ corresponding responses.
+
+ All the usual :class:`~.company_service.ListCompaniesResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., Awaitable[company_service.ListCompaniesResponse]],
+ request: company_service.ListCompaniesRequest,
+ response: company_service.ListCompaniesResponse,
+ *,
+ metadata: Sequence[Tuple[str, str]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (:class:`~.company_service.ListCompaniesRequest`):
+ The initial request object.
+ response (:class:`~.company_service.ListCompaniesResponse`):
+ The initial response object.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ self._method = method
+ self._request = company_service.ListCompaniesRequest(request)
+ self._response = response
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ async def pages(self) -> AsyncIterable[company_service.ListCompaniesResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = await self._method(self._request, metadata=self._metadata)
+ yield self._response
+
+ def __aiter__(self) -> AsyncIterable[company.Company]:
+ async def async_generator():
+ async for page in self.pages:
+ for response in page.companies:
+ yield response
+
+ return async_generator()
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
diff --git a/google/cloud/talent_v4/services/company_service/transports/__init__.py b/google/cloud/talent_v4/services/company_service/transports/__init__.py
new file mode 100644
index 00000000..ad1eb728
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/transports/__init__.py
@@ -0,0 +1,36 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from typing import Dict, Type
+
+from .base import CompanyServiceTransport
+from .grpc import CompanyServiceGrpcTransport
+from .grpc_asyncio import CompanyServiceGrpcAsyncIOTransport
+
+
+# Compile a registry of transports.
+_transport_registry = OrderedDict() # type: Dict[str, Type[CompanyServiceTransport]]
+_transport_registry["grpc"] = CompanyServiceGrpcTransport
+_transport_registry["grpc_asyncio"] = CompanyServiceGrpcAsyncIOTransport
+
+
+__all__ = (
+ "CompanyServiceTransport",
+ "CompanyServiceGrpcTransport",
+ "CompanyServiceGrpcAsyncIOTransport",
+)
diff --git a/google/cloud/talent_v4/services/company_service/transports/base.py b/google/cloud/talent_v4/services/company_service/transports/base.py
new file mode 100644
index 00000000..849a9354
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/transports/base.py
@@ -0,0 +1,209 @@
+# -*- 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.
+#
+
+import abc
+import typing
+import pkg_resources
+
+from google import auth # type: ignore
+from google.api_core import 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.cloud.talent_v4.types import company
+from google.cloud.talent_v4.types import company as gct_company
+from google.cloud.talent_v4.types import company_service
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+class CompanyServiceTransport(abc.ABC):
+ """Abstract transport class for CompanyService."""
+
+ AUTH_SCOPES = (
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.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,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ **kwargs,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ 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.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+ """
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ # If no credentials are provided, then determine the appropriate
+ # defaults.
+ if credentials and credentials_file:
+ raise exceptions.DuplicateCredentialArgs(
+ "'credentials_file' and 'credentials' are mutually exclusive"
+ )
+
+ if credentials_file is not None:
+ credentials, _ = auth.load_credentials_from_file(
+ credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ elif credentials is None:
+ credentials, _ = auth.default(
+ scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ # Save the credentials.
+ self._credentials = credentials
+
+ # Lifted into its own function so it can be stubbed out during tests.
+ self._prep_wrapped_messages(client_info)
+
+ def _prep_wrapped_messages(self, client_info):
+ # Precompute the wrapped methods.
+ self._wrapped_methods = {
+ self.create_company: gapic_v1.method.wrap_method(
+ self.create_company, default_timeout=30.0, client_info=client_info,
+ ),
+ self.get_company: gapic_v1.method.wrap_method(
+ self.get_company,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ self.update_company: gapic_v1.method.wrap_method(
+ self.update_company, default_timeout=30.0, client_info=client_info,
+ ),
+ self.delete_company: gapic_v1.method.wrap_method(
+ self.delete_company,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ self.list_companies: gapic_v1.method.wrap_method(
+ self.list_companies,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ }
+
+ @property
+ def create_company(
+ self,
+ ) -> typing.Callable[
+ [company_service.CreateCompanyRequest],
+ typing.Union[gct_company.Company, typing.Awaitable[gct_company.Company]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def get_company(
+ self,
+ ) -> typing.Callable[
+ [company_service.GetCompanyRequest],
+ typing.Union[company.Company, typing.Awaitable[company.Company]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def update_company(
+ self,
+ ) -> typing.Callable[
+ [company_service.UpdateCompanyRequest],
+ typing.Union[gct_company.Company, typing.Awaitable[gct_company.Company]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def delete_company(
+ self,
+ ) -> typing.Callable[
+ [company_service.DeleteCompanyRequest],
+ typing.Union[empty.Empty, typing.Awaitable[empty.Empty]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def list_companies(
+ self,
+ ) -> typing.Callable[
+ [company_service.ListCompaniesRequest],
+ typing.Union[
+ company_service.ListCompaniesResponse,
+ typing.Awaitable[company_service.ListCompaniesResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+
+__all__ = ("CompanyServiceTransport",)
diff --git a/google/cloud/talent_v4/services/company_service/transports/grpc.py b/google/cloud/talent_v4/services/company_service/transports/grpc.py
new file mode 100644
index 00000000..0f89386c
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/transports/grpc.py
@@ -0,0 +1,371 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+
+from google.cloud.talent_v4.types import company
+from google.cloud.talent_v4.types import company as gct_company
+from google.cloud.talent_v4.types import company_service
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+from .base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
+
+
+class CompanyServiceGrpcTransport(CompanyServiceTransport):
+ """gRPC backend transport for CompanyService.
+
+ A service that handles company management, including CRUD and
+ enumeration.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _stubs: Dict[str, Callable]
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Sequence[str] = None,
+ channel: grpc.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ channel (Optional[grpc.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ self._stubs = {} # type: Dict[str, Callable]
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> grpc.Channel:
+ """Create and return a gRPC channel object.
+ Args:
+ address (Optionsl[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ 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.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ grpc.Channel: A gRPC channel object.
+
+ Raises:
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ @property
+ def grpc_channel(self) -> grpc.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def create_company(
+ self,
+ ) -> Callable[[company_service.CreateCompanyRequest], gct_company.Company]:
+ r"""Return a callable for the create company method over gRPC.
+
+ Creates a new company entity.
+
+ Returns:
+ Callable[[~.CreateCompanyRequest],
+ ~.Company]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_company" not in self._stubs:
+ self._stubs["create_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/CreateCompany",
+ request_serializer=company_service.CreateCompanyRequest.serialize,
+ response_deserializer=gct_company.Company.deserialize,
+ )
+ return self._stubs["create_company"]
+
+ @property
+ def get_company(
+ self,
+ ) -> Callable[[company_service.GetCompanyRequest], company.Company]:
+ r"""Return a callable for the get company method over gRPC.
+
+ Retrieves specified company.
+
+ Returns:
+ Callable[[~.GetCompanyRequest],
+ ~.Company]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_company" not in self._stubs:
+ self._stubs["get_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/GetCompany",
+ request_serializer=company_service.GetCompanyRequest.serialize,
+ response_deserializer=company.Company.deserialize,
+ )
+ return self._stubs["get_company"]
+
+ @property
+ def update_company(
+ self,
+ ) -> Callable[[company_service.UpdateCompanyRequest], gct_company.Company]:
+ r"""Return a callable for the update company method over gRPC.
+
+ Updates specified company.
+
+ Returns:
+ Callable[[~.UpdateCompanyRequest],
+ ~.Company]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_company" not in self._stubs:
+ self._stubs["update_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/UpdateCompany",
+ request_serializer=company_service.UpdateCompanyRequest.serialize,
+ response_deserializer=gct_company.Company.deserialize,
+ )
+ return self._stubs["update_company"]
+
+ @property
+ def delete_company(
+ self,
+ ) -> Callable[[company_service.DeleteCompanyRequest], empty.Empty]:
+ r"""Return a callable for the delete company method over gRPC.
+
+ Deletes specified company.
+ Prerequisite: The company has no jobs associated with
+ it.
+
+ Returns:
+ Callable[[~.DeleteCompanyRequest],
+ ~.Empty]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_company" not in self._stubs:
+ self._stubs["delete_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/DeleteCompany",
+ request_serializer=company_service.DeleteCompanyRequest.serialize,
+ response_deserializer=empty.Empty.FromString,
+ )
+ return self._stubs["delete_company"]
+
+ @property
+ def list_companies(
+ self,
+ ) -> Callable[
+ [company_service.ListCompaniesRequest], company_service.ListCompaniesResponse
+ ]:
+ r"""Return a callable for the list companies method over gRPC.
+
+ Lists all companies associated with the project.
+
+ Returns:
+ Callable[[~.ListCompaniesRequest],
+ ~.ListCompaniesResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_companies" not in self._stubs:
+ self._stubs["list_companies"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/ListCompanies",
+ request_serializer=company_service.ListCompaniesRequest.serialize,
+ response_deserializer=company_service.ListCompaniesResponse.deserialize,
+ )
+ return self._stubs["list_companies"]
+
+
+__all__ = ("CompanyServiceGrpcTransport",)
diff --git a/google/cloud/talent_v4/services/company_service/transports/grpc_asyncio.py b/google/cloud/talent_v4/services/company_service/transports/grpc_asyncio.py
new file mode 100644
index 00000000..cbe2f0f3
--- /dev/null
+++ b/google/cloud/talent_v4/services/company_service/transports/grpc_asyncio.py
@@ -0,0 +1,376 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import gapic_v1 # type: ignore
+from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+from grpc.experimental import aio # type: ignore
+
+from google.cloud.talent_v4.types import company
+from google.cloud.talent_v4.types import company as gct_company
+from google.cloud.talent_v4.types import company_service
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+from .base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
+from .grpc import CompanyServiceGrpcTransport
+
+
+class CompanyServiceGrpcAsyncIOTransport(CompanyServiceTransport):
+ """gRPC AsyncIO backend transport for CompanyService.
+
+ A service that handles company management, including CRUD and
+ enumeration.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _grpc_channel: aio.Channel
+ _stubs: Dict[str, Callable] = {}
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> aio.Channel:
+ """Create and return a gRPC AsyncIO channel object.
+ Args:
+ address (Optional[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ aio.Channel: A gRPC AsyncIO channel object.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers_async.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: aio.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ channel (Optional[aio.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ self._stubs = {}
+
+ @property
+ def grpc_channel(self) -> aio.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def create_company(
+ self,
+ ) -> Callable[
+ [company_service.CreateCompanyRequest], Awaitable[gct_company.Company]
+ ]:
+ r"""Return a callable for the create company method over gRPC.
+
+ Creates a new company entity.
+
+ Returns:
+ Callable[[~.CreateCompanyRequest],
+ Awaitable[~.Company]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_company" not in self._stubs:
+ self._stubs["create_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/CreateCompany",
+ request_serializer=company_service.CreateCompanyRequest.serialize,
+ response_deserializer=gct_company.Company.deserialize,
+ )
+ return self._stubs["create_company"]
+
+ @property
+ def get_company(
+ self,
+ ) -> Callable[[company_service.GetCompanyRequest], Awaitable[company.Company]]:
+ r"""Return a callable for the get company method over gRPC.
+
+ Retrieves specified company.
+
+ Returns:
+ Callable[[~.GetCompanyRequest],
+ Awaitable[~.Company]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_company" not in self._stubs:
+ self._stubs["get_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/GetCompany",
+ request_serializer=company_service.GetCompanyRequest.serialize,
+ response_deserializer=company.Company.deserialize,
+ )
+ return self._stubs["get_company"]
+
+ @property
+ def update_company(
+ self,
+ ) -> Callable[
+ [company_service.UpdateCompanyRequest], Awaitable[gct_company.Company]
+ ]:
+ r"""Return a callable for the update company method over gRPC.
+
+ Updates specified company.
+
+ Returns:
+ Callable[[~.UpdateCompanyRequest],
+ Awaitable[~.Company]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_company" not in self._stubs:
+ self._stubs["update_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/UpdateCompany",
+ request_serializer=company_service.UpdateCompanyRequest.serialize,
+ response_deserializer=gct_company.Company.deserialize,
+ )
+ return self._stubs["update_company"]
+
+ @property
+ def delete_company(
+ self,
+ ) -> Callable[[company_service.DeleteCompanyRequest], Awaitable[empty.Empty]]:
+ r"""Return a callable for the delete company method over gRPC.
+
+ Deletes specified company.
+ Prerequisite: The company has no jobs associated with
+ it.
+
+ Returns:
+ Callable[[~.DeleteCompanyRequest],
+ Awaitable[~.Empty]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_company" not in self._stubs:
+ self._stubs["delete_company"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/DeleteCompany",
+ request_serializer=company_service.DeleteCompanyRequest.serialize,
+ response_deserializer=empty.Empty.FromString,
+ )
+ return self._stubs["delete_company"]
+
+ @property
+ def list_companies(
+ self,
+ ) -> Callable[
+ [company_service.ListCompaniesRequest],
+ Awaitable[company_service.ListCompaniesResponse],
+ ]:
+ r"""Return a callable for the list companies method over gRPC.
+
+ Lists all companies associated with the project.
+
+ Returns:
+ Callable[[~.ListCompaniesRequest],
+ Awaitable[~.ListCompaniesResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_companies" not in self._stubs:
+ self._stubs["list_companies"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.CompanyService/ListCompanies",
+ request_serializer=company_service.ListCompaniesRequest.serialize,
+ response_deserializer=company_service.ListCompaniesResponse.deserialize,
+ )
+ return self._stubs["list_companies"]
+
+
+__all__ = ("CompanyServiceGrpcAsyncIOTransport",)
diff --git a/google/cloud/talent_v4/services/completion/__init__.py b/google/cloud/talent_v4/services/completion/__init__.py
new file mode 100644
index 00000000..0c274210
--- /dev/null
+++ b/google/cloud/talent_v4/services/completion/__init__.py
@@ -0,0 +1,24 @@
+# -*- 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.
+#
+
+from .client import CompletionClient
+from .async_client import CompletionAsyncClient
+
+__all__ = (
+ "CompletionClient",
+ "CompletionAsyncClient",
+)
diff --git a/google/cloud/talent_v4/services/completion/async_client.py b/google/cloud/talent_v4/services/completion/async_client.py
new file mode 100644
index 00000000..e53fba44
--- /dev/null
+++ b/google/cloud/talent_v4/services/completion/async_client.py
@@ -0,0 +1,169 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+import functools
+import re
+from typing import Dict, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import credentials # type: ignore
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import completion_service
+
+from .transports.base import CompletionTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc_asyncio import CompletionGrpcAsyncIOTransport
+from .client import CompletionClient
+
+
+class CompletionAsyncClient:
+ """A service handles auto completion."""
+
+ _client: CompletionClient
+
+ DEFAULT_ENDPOINT = CompletionClient.DEFAULT_ENDPOINT
+ DEFAULT_MTLS_ENDPOINT = CompletionClient.DEFAULT_MTLS_ENDPOINT
+
+ from_service_account_file = CompletionClient.from_service_account_file
+ from_service_account_json = from_service_account_file
+
+ get_transport_class = functools.partial(
+ type(CompletionClient).get_transport_class, type(CompletionClient)
+ )
+
+ def __init__(
+ self,
+ *,
+ credentials: credentials.Credentials = None,
+ transport: Union[str, CompletionTransport] = "grpc_asyncio",
+ client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the completion client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.CompletionTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (ClientOptions): Custom options for the client. It
+ won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+
+ self._client = CompletionClient(
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
+ )
+
+ async def complete_query(
+ self,
+ request: completion_service.CompleteQueryRequest = None,
+ *,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> completion_service.CompleteQueryResponse:
+ r"""Completes the specified prefix with keyword
+ suggestions. Intended for use by a job search auto-
+ complete search box.
+
+ Args:
+ request (:class:`~.completion_service.CompleteQueryRequest`):
+ The request object. Auto-complete parameters.
+
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.completion_service.CompleteQueryResponse:
+ Response of auto-complete query.
+ """
+ # Create or coerce a protobuf request object.
+
+ request = completion_service.CompleteQueryRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.complete_query,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("tenant", request.tenant),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("CompletionAsyncClient",)
diff --git a/google/cloud/talent_v4/services/completion/client.py b/google/cloud/talent_v4/services/completion/client.py
new file mode 100644
index 00000000..af9b83dc
--- /dev/null
+++ b/google/cloud/talent_v4/services/completion/client.py
@@ -0,0 +1,308 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from distutils import util
+import os
+import re
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import 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
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import completion_service
+
+from .transports.base import CompletionTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc import CompletionGrpcTransport
+from .transports.grpc_asyncio import CompletionGrpcAsyncIOTransport
+
+
+class CompletionClientMeta(type):
+ """Metaclass for the Completion client.
+
+ This provides class-level methods for building and retrieving
+ support objects (e.g. transport) without polluting the client instance
+ objects.
+ """
+
+ _transport_registry = OrderedDict() # type: Dict[str, Type[CompletionTransport]]
+ _transport_registry["grpc"] = CompletionGrpcTransport
+ _transport_registry["grpc_asyncio"] = CompletionGrpcAsyncIOTransport
+
+ def get_transport_class(cls, label: str = None,) -> Type[CompletionTransport]:
+ """Return an appropriate transport class.
+
+ Args:
+ label: The name of the desired transport. If none is
+ provided, then the first transport in the registry is used.
+
+ Returns:
+ The transport class to use.
+ """
+ # If a specific transport is requested, return that one.
+ if label:
+ return cls._transport_registry[label]
+
+ # No transport is requested; return the default (that is, the first one
+ # in the dictionary).
+ return next(iter(cls._transport_registry.values()))
+
+
+class CompletionClient(metaclass=CompletionClientMeta):
+ """A service handles auto completion."""
+
+ @staticmethod
+ def _get_default_mtls_endpoint(api_endpoint):
+ """Convert api endpoint to mTLS endpoint.
+ Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
+ "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
+ Args:
+ api_endpoint (Optional[str]): the api endpoint to convert.
+ Returns:
+ str: converted mTLS api endpoint.
+ """
+ if not api_endpoint:
+ return api_endpoint
+
+ mtls_endpoint_re = re.compile(
+ r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?"
+ )
+
+ m = mtls_endpoint_re.match(api_endpoint)
+ name, mtls, sandbox, googledomain = m.groups()
+ if mtls or not googledomain:
+ return api_endpoint
+
+ if sandbox:
+ return api_endpoint.replace(
+ "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
+ )
+
+ return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+
+ DEFAULT_ENDPOINT = "jobs.googleapis.com"
+ DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
+ DEFAULT_ENDPOINT
+ )
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ {@api.name}: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_file(filename)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
+ from_service_account_json = from_service_account_file
+
+ def __init__(
+ self,
+ *,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, CompletionTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the completion client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.CompletionTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+ if isinstance(client_options, dict):
+ client_options = client_options_lib.from_dict(client_options)
+ if client_options is None:
+ client_options = client_options_lib.ClientOptions()
+
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
+ if use_mtls_env == "never":
+ api_endpoint = self.DEFAULT_ENDPOINT
+ 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
+ )
+ else:
+ raise MutualTLSChannelError(
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
+ )
+
+ # Save or instantiate the transport.
+ # Ordinarily, we provide the transport, but allowing a custom transport
+ # instance provides an extensibility point for unusual situations.
+ if isinstance(transport, CompletionTransport):
+ # transport is a CompletionTransport instance.
+ if credentials or client_options.credentials_file:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its credentials directly."
+ )
+ if client_options.scopes:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its scopes directly."
+ )
+ self._transport = transport
+ else:
+ Transport = type(self).get_transport_class(transport)
+ self._transport = Transport(
+ credentials=credentials,
+ credentials_file=client_options.credentials_file,
+ host=api_endpoint,
+ scopes=client_options.scopes,
+ ssl_channel_credentials=ssl_credentials,
+ quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
+ )
+
+ def complete_query(
+ self,
+ request: completion_service.CompleteQueryRequest = None,
+ *,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> completion_service.CompleteQueryResponse:
+ r"""Completes the specified prefix with keyword
+ suggestions. Intended for use by a job search auto-
+ complete search box.
+
+ Args:
+ request (:class:`~.completion_service.CompleteQueryRequest`):
+ The request object. Auto-complete parameters.
+
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.completion_service.CompleteQueryResponse:
+ Response of auto-complete query.
+ """
+ # Create or coerce a protobuf request object.
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a completion_service.CompleteQueryRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, completion_service.CompleteQueryRequest):
+ request = completion_service.CompleteQueryRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.complete_query]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("tenant", request.tenant),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("CompletionClient",)
diff --git a/google/cloud/talent_v4/services/completion/transports/__init__.py b/google/cloud/talent_v4/services/completion/transports/__init__.py
new file mode 100644
index 00000000..9256febd
--- /dev/null
+++ b/google/cloud/talent_v4/services/completion/transports/__init__.py
@@ -0,0 +1,36 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from typing import Dict, Type
+
+from .base import CompletionTransport
+from .grpc import CompletionGrpcTransport
+from .grpc_asyncio import CompletionGrpcAsyncIOTransport
+
+
+# Compile a registry of transports.
+_transport_registry = OrderedDict() # type: Dict[str, Type[CompletionTransport]]
+_transport_registry["grpc"] = CompletionGrpcTransport
+_transport_registry["grpc_asyncio"] = CompletionGrpcAsyncIOTransport
+
+
+__all__ = (
+ "CompletionTransport",
+ "CompletionGrpcTransport",
+ "CompletionGrpcAsyncIOTransport",
+)
diff --git a/google/cloud/talent_v4/services/completion/transports/base.py b/google/cloud/talent_v4/services/completion/transports/base.py
new file mode 100644
index 00000000..9f016fcc
--- /dev/null
+++ b/google/cloud/talent_v4/services/completion/transports/base.py
@@ -0,0 +1,138 @@
+# -*- 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.
+#
+
+import abc
+import typing
+import pkg_resources
+
+from google import auth # type: ignore
+from google.api_core import 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.cloud.talent_v4.types import completion_service
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+class CompletionTransport(abc.ABC):
+ """Abstract transport class for Completion."""
+
+ AUTH_SCOPES = (
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.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,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ **kwargs,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ 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.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+ """
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ # If no credentials are provided, then determine the appropriate
+ # defaults.
+ if credentials and credentials_file:
+ raise exceptions.DuplicateCredentialArgs(
+ "'credentials_file' and 'credentials' are mutually exclusive"
+ )
+
+ if credentials_file is not None:
+ credentials, _ = auth.load_credentials_from_file(
+ credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ elif credentials is None:
+ credentials, _ = auth.default(
+ scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ # Save the credentials.
+ self._credentials = credentials
+
+ # Lifted into its own function so it can be stubbed out during tests.
+ self._prep_wrapped_messages(client_info)
+
+ def _prep_wrapped_messages(self, client_info):
+ # Precompute the wrapped methods.
+ self._wrapped_methods = {
+ self.complete_query: gapic_v1.method.wrap_method(
+ self.complete_query,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ }
+
+ @property
+ def complete_query(
+ self,
+ ) -> typing.Callable[
+ [completion_service.CompleteQueryRequest],
+ typing.Union[
+ completion_service.CompleteQueryResponse,
+ typing.Awaitable[completion_service.CompleteQueryResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+
+__all__ = ("CompletionTransport",)
diff --git a/google/cloud/talent_v4/services/completion/transports/grpc.py b/google/cloud/talent_v4/services/completion/transports/grpc.py
new file mode 100644
index 00000000..68ed6ef3
--- /dev/null
+++ b/google/cloud/talent_v4/services/completion/transports/grpc.py
@@ -0,0 +1,264 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+
+from google.cloud.talent_v4.types import completion_service
+
+from .base import CompletionTransport, DEFAULT_CLIENT_INFO
+
+
+class CompletionGrpcTransport(CompletionTransport):
+ """gRPC backend transport for Completion.
+
+ A service handles auto completion.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _stubs: Dict[str, Callable]
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Sequence[str] = None,
+ channel: grpc.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ channel (Optional[grpc.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ self._stubs = {} # type: Dict[str, Callable]
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> grpc.Channel:
+ """Create and return a gRPC channel object.
+ Args:
+ address (Optionsl[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ 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.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ grpc.Channel: A gRPC channel object.
+
+ Raises:
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ @property
+ def grpc_channel(self) -> grpc.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def complete_query(
+ self,
+ ) -> Callable[
+ [completion_service.CompleteQueryRequest],
+ completion_service.CompleteQueryResponse,
+ ]:
+ r"""Return a callable for the complete query method over gRPC.
+
+ Completes the specified prefix with keyword
+ suggestions. Intended for use by a job search auto-
+ complete search box.
+
+ Returns:
+ Callable[[~.CompleteQueryRequest],
+ ~.CompleteQueryResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "complete_query" not in self._stubs:
+ self._stubs["complete_query"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.Completion/CompleteQuery",
+ request_serializer=completion_service.CompleteQueryRequest.serialize,
+ response_deserializer=completion_service.CompleteQueryResponse.deserialize,
+ )
+ return self._stubs["complete_query"]
+
+
+__all__ = ("CompletionGrpcTransport",)
diff --git a/google/cloud/talent_v4/services/completion/transports/grpc_asyncio.py b/google/cloud/talent_v4/services/completion/transports/grpc_asyncio.py
new file mode 100644
index 00000000..b24f3e89
--- /dev/null
+++ b/google/cloud/talent_v4/services/completion/transports/grpc_asyncio.py
@@ -0,0 +1,264 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import gapic_v1 # type: ignore
+from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+from grpc.experimental import aio # type: ignore
+
+from google.cloud.talent_v4.types import completion_service
+
+from .base import CompletionTransport, DEFAULT_CLIENT_INFO
+from .grpc import CompletionGrpcTransport
+
+
+class CompletionGrpcAsyncIOTransport(CompletionTransport):
+ """gRPC AsyncIO backend transport for Completion.
+
+ A service handles auto completion.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _grpc_channel: aio.Channel
+ _stubs: Dict[str, Callable] = {}
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> aio.Channel:
+ """Create and return a gRPC AsyncIO channel object.
+ Args:
+ address (Optional[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ aio.Channel: A gRPC AsyncIO channel object.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers_async.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: aio.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ channel (Optional[aio.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ self._stubs = {}
+
+ @property
+ def grpc_channel(self) -> aio.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def complete_query(
+ self,
+ ) -> Callable[
+ [completion_service.CompleteQueryRequest],
+ Awaitable[completion_service.CompleteQueryResponse],
+ ]:
+ r"""Return a callable for the complete query method over gRPC.
+
+ Completes the specified prefix with keyword
+ suggestions. Intended for use by a job search auto-
+ complete search box.
+
+ Returns:
+ Callable[[~.CompleteQueryRequest],
+ Awaitable[~.CompleteQueryResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "complete_query" not in self._stubs:
+ self._stubs["complete_query"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.Completion/CompleteQuery",
+ request_serializer=completion_service.CompleteQueryRequest.serialize,
+ response_deserializer=completion_service.CompleteQueryResponse.deserialize,
+ )
+ return self._stubs["complete_query"]
+
+
+__all__ = ("CompletionGrpcAsyncIOTransport",)
diff --git a/google/cloud/talent_v4/services/event_service/__init__.py b/google/cloud/talent_v4/services/event_service/__init__.py
new file mode 100644
index 00000000..f321845c
--- /dev/null
+++ b/google/cloud/talent_v4/services/event_service/__init__.py
@@ -0,0 +1,24 @@
+# -*- 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.
+#
+
+from .client import EventServiceClient
+from .async_client import EventServiceAsyncClient
+
+__all__ = (
+ "EventServiceClient",
+ "EventServiceAsyncClient",
+)
diff --git a/google/cloud/talent_v4/services/event_service/async_client.py b/google/cloud/talent_v4/services/event_service/async_client.py
new file mode 100644
index 00000000..2178dad2
--- /dev/null
+++ b/google/cloud/talent_v4/services/event_service/async_client.py
@@ -0,0 +1,210 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+import functools
+import re
+from typing import Dict, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import credentials # type: ignore
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.types import event
+from google.cloud.talent_v4.types import event_service
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+
+from .transports.base import EventServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc_asyncio import EventServiceGrpcAsyncIOTransport
+from .client import EventServiceClient
+
+
+class EventServiceAsyncClient:
+ """A service handles client event report."""
+
+ _client: EventServiceClient
+
+ DEFAULT_ENDPOINT = EventServiceClient.DEFAULT_ENDPOINT
+ DEFAULT_MTLS_ENDPOINT = EventServiceClient.DEFAULT_MTLS_ENDPOINT
+
+ from_service_account_file = EventServiceClient.from_service_account_file
+ from_service_account_json = from_service_account_file
+
+ get_transport_class = functools.partial(
+ type(EventServiceClient).get_transport_class, type(EventServiceClient)
+ )
+
+ def __init__(
+ self,
+ *,
+ credentials: credentials.Credentials = None,
+ transport: Union[str, EventServiceTransport] = "grpc_asyncio",
+ client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the event service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.EventServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (ClientOptions): Custom options for the client. It
+ won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+
+ self._client = EventServiceClient(
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
+ )
+
+ async def create_client_event(
+ self,
+ request: event_service.CreateClientEventRequest = None,
+ *,
+ parent: str = None,
+ client_event: event.ClientEvent = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> event.ClientEvent:
+ r"""Report events issued when end user interacts with customer's
+ application that uses Cloud Talent Solution. You may inspect the
+ created events in `self service
+ tools `__.
+ `Learn
+ more `__
+ about self service tools.
+
+ Args:
+ request (:class:`~.event_service.CreateClientEventRequest`):
+ The request object. The report event request.
+ parent (:class:`str`):
+ Required. Resource name of the tenant under which the
+ event is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ client_event (:class:`~.event.ClientEvent`):
+ Required. Events issued when end user
+ interacts with customer's application
+ that uses Cloud Talent Solution.
+ This corresponds to the ``client_event`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.event.ClientEvent:
+ An event issued when an end user
+ interacts with the application that
+ implements Cloud Talent Solution.
+ Providing this information improves the
+ quality of results for the API clients,
+ enabling the service to perform
+ optimally. The number of events sent
+ must be consistent with other calls,
+ such as job searches, issued to the
+ service by the client.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, client_event]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = event_service.CreateClientEventRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if client_event is not None:
+ request.client_event = client_event
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.create_client_event,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("EventServiceAsyncClient",)
diff --git a/google/cloud/talent_v4/services/event_service/client.py b/google/cloud/talent_v4/services/event_service/client.py
new file mode 100644
index 00000000..cc9aaed5
--- /dev/null
+++ b/google/cloud/talent_v4/services/event_service/client.py
@@ -0,0 +1,358 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from distutils import util
+import os
+import re
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import 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
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.types import event
+from google.cloud.talent_v4.types import event_service
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+
+from .transports.base import EventServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc import EventServiceGrpcTransport
+from .transports.grpc_asyncio import EventServiceGrpcAsyncIOTransport
+
+
+class EventServiceClientMeta(type):
+ """Metaclass for the EventService client.
+
+ This provides class-level methods for building and retrieving
+ support objects (e.g. transport) without polluting the client instance
+ objects.
+ """
+
+ _transport_registry = OrderedDict() # type: Dict[str, Type[EventServiceTransport]]
+ _transport_registry["grpc"] = EventServiceGrpcTransport
+ _transport_registry["grpc_asyncio"] = EventServiceGrpcAsyncIOTransport
+
+ def get_transport_class(cls, label: str = None,) -> Type[EventServiceTransport]:
+ """Return an appropriate transport class.
+
+ Args:
+ label: The name of the desired transport. If none is
+ provided, then the first transport in the registry is used.
+
+ Returns:
+ The transport class to use.
+ """
+ # If a specific transport is requested, return that one.
+ if label:
+ return cls._transport_registry[label]
+
+ # No transport is requested; return the default (that is, the first one
+ # in the dictionary).
+ return next(iter(cls._transport_registry.values()))
+
+
+class EventServiceClient(metaclass=EventServiceClientMeta):
+ """A service handles client event report."""
+
+ @staticmethod
+ def _get_default_mtls_endpoint(api_endpoint):
+ """Convert api endpoint to mTLS endpoint.
+ Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
+ "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
+ Args:
+ api_endpoint (Optional[str]): the api endpoint to convert.
+ Returns:
+ str: converted mTLS api endpoint.
+ """
+ if not api_endpoint:
+ return api_endpoint
+
+ mtls_endpoint_re = re.compile(
+ r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?"
+ )
+
+ m = mtls_endpoint_re.match(api_endpoint)
+ name, mtls, sandbox, googledomain = m.groups()
+ if mtls or not googledomain:
+ return api_endpoint
+
+ if sandbox:
+ return api_endpoint.replace(
+ "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
+ )
+
+ return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+
+ DEFAULT_ENDPOINT = "jobs.googleapis.com"
+ DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
+ DEFAULT_ENDPOINT
+ )
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ {@api.name}: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_file(filename)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
+ from_service_account_json = from_service_account_file
+
+ def __init__(
+ self,
+ *,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, EventServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the event service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.EventServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+ if isinstance(client_options, dict):
+ client_options = client_options_lib.from_dict(client_options)
+ if client_options is None:
+ client_options = client_options_lib.ClientOptions()
+
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
+ if use_mtls_env == "never":
+ api_endpoint = self.DEFAULT_ENDPOINT
+ 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
+ )
+ else:
+ raise MutualTLSChannelError(
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
+ )
+
+ # Save or instantiate the transport.
+ # Ordinarily, we provide the transport, but allowing a custom transport
+ # instance provides an extensibility point for unusual situations.
+ if isinstance(transport, EventServiceTransport):
+ # transport is a EventServiceTransport instance.
+ if credentials or client_options.credentials_file:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its credentials directly."
+ )
+ if client_options.scopes:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its scopes directly."
+ )
+ self._transport = transport
+ else:
+ Transport = type(self).get_transport_class(transport)
+ self._transport = Transport(
+ credentials=credentials,
+ credentials_file=client_options.credentials_file,
+ host=api_endpoint,
+ scopes=client_options.scopes,
+ ssl_channel_credentials=ssl_credentials,
+ quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
+ )
+
+ def create_client_event(
+ self,
+ request: event_service.CreateClientEventRequest = None,
+ *,
+ parent: str = None,
+ client_event: event.ClientEvent = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> event.ClientEvent:
+ r"""Report events issued when end user interacts with customer's
+ application that uses Cloud Talent Solution. You may inspect the
+ created events in `self service
+ tools `__.
+ `Learn
+ more `__
+ about self service tools.
+
+ Args:
+ request (:class:`~.event_service.CreateClientEventRequest`):
+ The request object. The report event request.
+ parent (:class:`str`):
+ Required. Resource name of the tenant under which the
+ event is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ client_event (:class:`~.event.ClientEvent`):
+ Required. Events issued when end user
+ interacts with customer's application
+ that uses Cloud Talent Solution.
+ This corresponds to the ``client_event`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.event.ClientEvent:
+ An event issued when an end user
+ interacts with the application that
+ implements Cloud Talent Solution.
+ Providing this information improves the
+ quality of results for the API clients,
+ enabling the service to perform
+ optimally. The number of events sent
+ must be consistent with other calls,
+ such as job searches, issued to the
+ service by the client.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, client_event])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a event_service.CreateClientEventRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, event_service.CreateClientEventRequest):
+ request = event_service.CreateClientEventRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if client_event is not None:
+ request.client_event = client_event
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.create_client_event]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("EventServiceClient",)
diff --git a/google/cloud/talent_v4/services/event_service/transports/__init__.py b/google/cloud/talent_v4/services/event_service/transports/__init__.py
new file mode 100644
index 00000000..18ca2a9d
--- /dev/null
+++ b/google/cloud/talent_v4/services/event_service/transports/__init__.py
@@ -0,0 +1,36 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from typing import Dict, Type
+
+from .base import EventServiceTransport
+from .grpc import EventServiceGrpcTransport
+from .grpc_asyncio import EventServiceGrpcAsyncIOTransport
+
+
+# Compile a registry of transports.
+_transport_registry = OrderedDict() # type: Dict[str, Type[EventServiceTransport]]
+_transport_registry["grpc"] = EventServiceGrpcTransport
+_transport_registry["grpc_asyncio"] = EventServiceGrpcAsyncIOTransport
+
+
+__all__ = (
+ "EventServiceTransport",
+ "EventServiceGrpcTransport",
+ "EventServiceGrpcAsyncIOTransport",
+)
diff --git a/google/cloud/talent_v4/services/event_service/transports/base.py b/google/cloud/talent_v4/services/event_service/transports/base.py
new file mode 100644
index 00000000..88f54bbc
--- /dev/null
+++ b/google/cloud/talent_v4/services/event_service/transports/base.py
@@ -0,0 +1,126 @@
+# -*- 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.
+#
+
+import abc
+import typing
+import pkg_resources
+
+from google import auth # type: ignore
+from google.api_core import 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.cloud.talent_v4.types import event
+from google.cloud.talent_v4.types import event_service
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+class EventServiceTransport(abc.ABC):
+ """Abstract transport class for EventService."""
+
+ AUTH_SCOPES = (
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.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,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ **kwargs,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ 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.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+ """
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ # If no credentials are provided, then determine the appropriate
+ # defaults.
+ if credentials and credentials_file:
+ raise exceptions.DuplicateCredentialArgs(
+ "'credentials_file' and 'credentials' are mutually exclusive"
+ )
+
+ if credentials_file is not None:
+ credentials, _ = auth.load_credentials_from_file(
+ credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ elif credentials is None:
+ credentials, _ = auth.default(
+ scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ # Save the credentials.
+ self._credentials = credentials
+
+ # Lifted into its own function so it can be stubbed out during tests.
+ self._prep_wrapped_messages(client_info)
+
+ def _prep_wrapped_messages(self, client_info):
+ # Precompute the wrapped methods.
+ self._wrapped_methods = {
+ self.create_client_event: gapic_v1.method.wrap_method(
+ self.create_client_event, default_timeout=30.0, client_info=client_info,
+ ),
+ }
+
+ @property
+ def create_client_event(
+ self,
+ ) -> typing.Callable[
+ [event_service.CreateClientEventRequest],
+ typing.Union[event.ClientEvent, typing.Awaitable[event.ClientEvent]],
+ ]:
+ raise NotImplementedError()
+
+
+__all__ = ("EventServiceTransport",)
diff --git a/google/cloud/talent_v4/services/event_service/transports/grpc.py b/google/cloud/talent_v4/services/event_service/transports/grpc.py
new file mode 100644
index 00000000..77b026c2
--- /dev/null
+++ b/google/cloud/talent_v4/services/event_service/transports/grpc.py
@@ -0,0 +1,266 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+
+from google.cloud.talent_v4.types import event
+from google.cloud.talent_v4.types import event_service
+
+from .base import EventServiceTransport, DEFAULT_CLIENT_INFO
+
+
+class EventServiceGrpcTransport(EventServiceTransport):
+ """gRPC backend transport for EventService.
+
+ A service handles client event report.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _stubs: Dict[str, Callable]
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Sequence[str] = None,
+ channel: grpc.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ channel (Optional[grpc.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ self._stubs = {} # type: Dict[str, Callable]
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> grpc.Channel:
+ """Create and return a gRPC channel object.
+ Args:
+ address (Optionsl[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ 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.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ grpc.Channel: A gRPC channel object.
+
+ Raises:
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ @property
+ def grpc_channel(self) -> grpc.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def create_client_event(
+ self,
+ ) -> Callable[[event_service.CreateClientEventRequest], event.ClientEvent]:
+ r"""Return a callable for the create client event method over gRPC.
+
+ Report events issued when end user interacts with customer's
+ application that uses Cloud Talent Solution. You may inspect the
+ created events in `self service
+ tools `__.
+ `Learn
+ more `__
+ about self service tools.
+
+ Returns:
+ Callable[[~.CreateClientEventRequest],
+ ~.ClientEvent]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_client_event" not in self._stubs:
+ self._stubs["create_client_event"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.EventService/CreateClientEvent",
+ request_serializer=event_service.CreateClientEventRequest.serialize,
+ response_deserializer=event.ClientEvent.deserialize,
+ )
+ return self._stubs["create_client_event"]
+
+
+__all__ = ("EventServiceGrpcTransport",)
diff --git a/google/cloud/talent_v4/services/event_service/transports/grpc_asyncio.py b/google/cloud/talent_v4/services/event_service/transports/grpc_asyncio.py
new file mode 100644
index 00000000..e79b22ae
--- /dev/null
+++ b/google/cloud/talent_v4/services/event_service/transports/grpc_asyncio.py
@@ -0,0 +1,268 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import gapic_v1 # type: ignore
+from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+from grpc.experimental import aio # type: ignore
+
+from google.cloud.talent_v4.types import event
+from google.cloud.talent_v4.types import event_service
+
+from .base import EventServiceTransport, DEFAULT_CLIENT_INFO
+from .grpc import EventServiceGrpcTransport
+
+
+class EventServiceGrpcAsyncIOTransport(EventServiceTransport):
+ """gRPC AsyncIO backend transport for EventService.
+
+ A service handles client event report.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _grpc_channel: aio.Channel
+ _stubs: Dict[str, Callable] = {}
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> aio.Channel:
+ """Create and return a gRPC AsyncIO channel object.
+ Args:
+ address (Optional[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ aio.Channel: A gRPC AsyncIO channel object.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers_async.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: aio.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ channel (Optional[aio.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ self._stubs = {}
+
+ @property
+ def grpc_channel(self) -> aio.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def create_client_event(
+ self,
+ ) -> Callable[
+ [event_service.CreateClientEventRequest], Awaitable[event.ClientEvent]
+ ]:
+ r"""Return a callable for the create client event method over gRPC.
+
+ Report events issued when end user interacts with customer's
+ application that uses Cloud Talent Solution. You may inspect the
+ created events in `self service
+ tools `__.
+ `Learn
+ more `__
+ about self service tools.
+
+ Returns:
+ Callable[[~.CreateClientEventRequest],
+ Awaitable[~.ClientEvent]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_client_event" not in self._stubs:
+ self._stubs["create_client_event"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.EventService/CreateClientEvent",
+ request_serializer=event_service.CreateClientEventRequest.serialize,
+ response_deserializer=event.ClientEvent.deserialize,
+ )
+ return self._stubs["create_client_event"]
+
+
+__all__ = ("EventServiceGrpcAsyncIOTransport",)
diff --git a/google/cloud/talent_v4/services/job_service/__init__.py b/google/cloud/talent_v4/services/job_service/__init__.py
new file mode 100644
index 00000000..5f157047
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/__init__.py
@@ -0,0 +1,24 @@
+# -*- 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.
+#
+
+from .client import JobServiceClient
+from .async_client import JobServiceAsyncClient
+
+__all__ = (
+ "JobServiceClient",
+ "JobServiceAsyncClient",
+)
diff --git a/google/cloud/talent_v4/services/job_service/async_client.py b/google/cloud/talent_v4/services/job_service/async_client.py
new file mode 100644
index 00000000..d0039885
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/async_client.py
@@ -0,0 +1,1001 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+import functools
+import re
+from typing import Dict, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import 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.talent_v4.services.job_service import pagers
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import histogram
+from google.cloud.talent_v4.types import job
+from google.cloud.talent_v4.types import job as gct_job
+from google.cloud.talent_v4.types import job_service
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+
+from .transports.base import JobServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc_asyncio import JobServiceGrpcAsyncIOTransport
+from .client import JobServiceClient
+
+
+class JobServiceAsyncClient:
+ """A service handles job management, including job CRUD,
+ enumeration and search.
+ """
+
+ _client: JobServiceClient
+
+ DEFAULT_ENDPOINT = JobServiceClient.DEFAULT_ENDPOINT
+ DEFAULT_MTLS_ENDPOINT = JobServiceClient.DEFAULT_MTLS_ENDPOINT
+
+ job_path = staticmethod(JobServiceClient.job_path)
+ parse_job_path = staticmethod(JobServiceClient.parse_job_path)
+
+ from_service_account_file = JobServiceClient.from_service_account_file
+ from_service_account_json = from_service_account_file
+
+ get_transport_class = functools.partial(
+ type(JobServiceClient).get_transport_class, type(JobServiceClient)
+ )
+
+ def __init__(
+ self,
+ *,
+ credentials: credentials.Credentials = None,
+ transport: Union[str, JobServiceTransport] = "grpc_asyncio",
+ client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the job service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.JobServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (ClientOptions): Custom options for the client. It
+ won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+
+ self._client = JobServiceClient(
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
+ )
+
+ async def create_job(
+ self,
+ request: job_service.CreateJobRequest = None,
+ *,
+ parent: str = None,
+ job: gct_job.Job = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_job.Job:
+ r"""Creates a new job.
+ Typically, the job becomes searchable within 10 seconds,
+ but it may take up to 5 minutes.
+
+ Args:
+ request (:class:`~.job_service.CreateJobRequest`):
+ The request object. Create job request.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ job (:class:`~.gct_job.Job`):
+ Required. The Job to be created.
+ This corresponds to the ``job`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_job.Job:
+ A Job resource represents a job posting (also referred
+ to as a "job listing" or "job requisition"). A job
+ belongs to a [Company][google.cloud.talent.v4.Company],
+ which is the hiring entity responsible for the job.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, job]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.CreateJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if job is not None:
+ request.job = job
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.create_job,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def batch_create_jobs(
+ self,
+ request: job_service.BatchCreateJobsRequest = None,
+ *,
+ parent: str = None,
+ jobs: Sequence[job.Job] = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Begins executing a batch create jobs operation.
+
+ Args:
+ request (:class:`~.job_service.BatchCreateJobsRequest`):
+ The request object. Request to create a batch of jobs.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ jobs (:class:`Sequence[~.job.Job]`):
+ Required. The jobs to be created.
+ A maximum of 200 jobs can be created in
+ a batch.
+ This corresponds to the ``jobs`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:``~.job_service.BatchCreateJobsResponse``: The
+ result of
+ [JobService.BatchCreateJobs][google.cloud.talent.v4.JobService.BatchCreateJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, jobs]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.BatchCreateJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if jobs is not None:
+ request.jobs = jobs
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.batch_create_jobs,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ job_service.BatchCreateJobsResponse,
+ metadata_type=common.BatchOperationMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def get_job(
+ self,
+ request: job_service.GetJobRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> job.Job:
+ r"""Retrieves the specified job, whose status is OPEN or
+ recently EXPIRED within the last 90 days.
+
+ Args:
+ request (:class:`~.job_service.GetJobRequest`):
+ The request object. Get job request.
+ name (:class:`str`):
+ Required. The resource name of the job to retrieve.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.job.Job:
+ A Job resource represents a job posting (also referred
+ to as a "job listing" or "job requisition"). A job
+ belongs to a [Company][google.cloud.talent.v4.Company],
+ which is the hiring entity responsible for the job.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([name]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.GetJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.get_job,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def update_job(
+ self,
+ request: job_service.UpdateJobRequest = None,
+ *,
+ job: gct_job.Job = None,
+ update_mask: field_mask.FieldMask = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_job.Job:
+ r"""Updates specified job.
+ Typically, updated contents become visible in search
+ results within 10 seconds, but it may take up to 5
+ minutes.
+
+ Args:
+ request (:class:`~.job_service.UpdateJobRequest`):
+ The request object. Update job request.
+ job (:class:`~.gct_job.Job`):
+ Required. The Job to be updated.
+ This corresponds to the ``job`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`~.field_mask.FieldMask`):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateJobRequest.update_mask]
+ is provided, only the specified fields in
+ [job][google.cloud.talent.v4.UpdateJobRequest.job] are
+ updated. Otherwise all the fields are updated.
+
+ A field mask to restrict the fields that are updated.
+ Only top level fields of
+ [Job][google.cloud.talent.v4.Job] are supported.
+ This corresponds to the ``update_mask`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_job.Job:
+ A Job resource represents a job posting (also referred
+ to as a "job listing" or "job requisition"). A job
+ belongs to a [Company][google.cloud.talent.v4.Company],
+ which is the hiring entity responsible for the job.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([job, update_mask]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.UpdateJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if job is not None:
+ request.job = job
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.update_job,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("job.name", request.job.name),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def batch_update_jobs(
+ self,
+ request: job_service.BatchUpdateJobsRequest = None,
+ *,
+ parent: str = None,
+ jobs: Sequence[job.Job] = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Begins executing a batch update jobs operation.
+
+ Args:
+ request (:class:`~.job_service.BatchUpdateJobsRequest`):
+ The request object. Request to update a batch of jobs.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ jobs (:class:`Sequence[~.job.Job]`):
+ Required. The jobs to be updated.
+ A maximum of 200 jobs can be updated in
+ a batch.
+ This corresponds to the ``jobs`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:``~.job_service.BatchUpdateJobsResponse``: The
+ result of
+ [JobService.BatchUpdateJobs][google.cloud.talent.v4.JobService.BatchUpdateJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, jobs]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.BatchUpdateJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if jobs is not None:
+ request.jobs = jobs
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.batch_update_jobs,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ job_service.BatchUpdateJobsResponse,
+ metadata_type=common.BatchOperationMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def delete_job(
+ self,
+ request: job_service.DeleteJobRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> None:
+ r"""Deletes the specified job.
+ Typically, the job becomes unsearchable within 10
+ seconds, but it may take up to 5 minutes.
+
+ Args:
+ request (:class:`~.job_service.DeleteJobRequest`):
+ The request object. Delete job request.
+ name (:class:`str`):
+ Required. The resource name of the job to be deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([name]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.DeleteJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.delete_job,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ await rpc(
+ request, retry=retry, timeout=timeout, metadata=metadata,
+ )
+
+ async def batch_delete_jobs(
+ self,
+ request: job_service.BatchDeleteJobsRequest = None,
+ *,
+ parent: str = None,
+ names: Sequence[str] = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Begins executing a batch delete jobs operation.
+
+ Args:
+ request (:class:`~.job_service.BatchDeleteJobsRequest`):
+ The request object. Request to delete a batch of jobs.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+
+ The parent of all of the jobs specified in ``names``
+ must match this field.
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ names (:class:`Sequence[str]`):
+ The names of the jobs to delete.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+
+ A maximum of 200 jobs can be deleted in a batch.
+ This corresponds to the ``names`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:``~.job_service.BatchDeleteJobsResponse``: The
+ result of
+ [JobService.BatchDeleteJobs][google.cloud.talent.v4.JobService.BatchDeleteJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, names]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.BatchDeleteJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if names is not None:
+ request.names = names
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.batch_delete_jobs,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ job_service.BatchDeleteJobsResponse,
+ metadata_type=common.BatchOperationMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def list_jobs(
+ self,
+ request: job_service.ListJobsRequest = None,
+ *,
+ parent: str = None,
+ filter: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> pagers.ListJobsAsyncPager:
+ r"""Lists jobs by filter.
+
+ Args:
+ request (:class:`~.job_service.ListJobsRequest`):
+ The request object. List jobs request.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ filter (:class:`str`):
+ Required. The filter string specifies the jobs to be
+ enumerated.
+
+ Supported operator: =, AND
+
+ The fields eligible for filtering are:
+
+ - ``companyName`` (Required)
+ - ``requisitionId``
+ - ``status`` Available values: OPEN, EXPIRED, ALL.
+ Defaults to OPEN if no value is specified.
+
+ Sample Query:
+
+ - companyName =
+ "projects/foo/tenants/bar/companies/baz"
+ - companyName =
+ "projects/foo/tenants/bar/companies/baz" AND
+ requisitionId = "req-1"
+ - companyName =
+ "projects/foo/tenants/bar/companies/baz" AND status =
+ "EXPIRED".
+ This corresponds to the ``filter`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.pagers.ListJobsAsyncPager:
+ List jobs response.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, filter]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = job_service.ListJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if filter is not None:
+ request.filter = filter
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.list_jobs,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListJobsAsyncPager(
+ method=rpc, request=request, response=response, metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def search_jobs(
+ self,
+ request: job_service.SearchJobsRequest = None,
+ *,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> job_service.SearchJobsResponse:
+ r"""Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs that the caller
+ has permission to search against.
+
+ Args:
+ request (:class:`~.job_service.SearchJobsRequest`):
+ The request object. The Request body of the `SearchJobs`
+ call.
+
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.job_service.SearchJobsResponse:
+ Response for SearchJob method.
+ """
+ # Create or coerce a protobuf request object.
+
+ request = job_service.SearchJobsRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.search_jobs,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def search_jobs_for_alert(
+ self,
+ request: job_service.SearchJobsRequest = None,
+ *,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> job_service.SearchJobsResponse:
+ r"""Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This API call is intended for the use case of targeting passive
+ job seekers (for example, job seekers who have signed up to
+ receive email alerts about potential job opportunities), it has
+ different algorithmic adjustments that are designed to
+ specifically target passive job seekers.
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs the caller has
+ permission to search against.
+
+ Args:
+ request (:class:`~.job_service.SearchJobsRequest`):
+ The request object. The Request body of the `SearchJobs`
+ call.
+
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.job_service.SearchJobsResponse:
+ Response for SearchJob method.
+ """
+ # Create or coerce a protobuf request object.
+
+ request = job_service.SearchJobsRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.search_jobs_for_alert,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("JobServiceAsyncClient",)
diff --git a/google/cloud/talent_v4/services/job_service/client.py b/google/cloud/talent_v4/services/job_service/client.py
new file mode 100644
index 00000000..0bb4a4e9
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/client.py
@@ -0,0 +1,1154 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from distutils import util
+import os
+import re
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import 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
+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.talent_v4.services.job_service import pagers
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import histogram
+from google.cloud.talent_v4.types import job
+from google.cloud.talent_v4.types import job as gct_job
+from google.cloud.talent_v4.types import job_service
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+
+from .transports.base import JobServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc import JobServiceGrpcTransport
+from .transports.grpc_asyncio import JobServiceGrpcAsyncIOTransport
+
+
+class JobServiceClientMeta(type):
+ """Metaclass for the JobService client.
+
+ This provides class-level methods for building and retrieving
+ support objects (e.g. transport) without polluting the client instance
+ objects.
+ """
+
+ _transport_registry = OrderedDict() # type: Dict[str, Type[JobServiceTransport]]
+ _transport_registry["grpc"] = JobServiceGrpcTransport
+ _transport_registry["grpc_asyncio"] = JobServiceGrpcAsyncIOTransport
+
+ def get_transport_class(cls, label: str = None,) -> Type[JobServiceTransport]:
+ """Return an appropriate transport class.
+
+ Args:
+ label: The name of the desired transport. If none is
+ provided, then the first transport in the registry is used.
+
+ Returns:
+ The transport class to use.
+ """
+ # If a specific transport is requested, return that one.
+ if label:
+ return cls._transport_registry[label]
+
+ # No transport is requested; return the default (that is, the first one
+ # in the dictionary).
+ return next(iter(cls._transport_registry.values()))
+
+
+class JobServiceClient(metaclass=JobServiceClientMeta):
+ """A service handles job management, including job CRUD,
+ enumeration and search.
+ """
+
+ @staticmethod
+ def _get_default_mtls_endpoint(api_endpoint):
+ """Convert api endpoint to mTLS endpoint.
+ Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
+ "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
+ Args:
+ api_endpoint (Optional[str]): the api endpoint to convert.
+ Returns:
+ str: converted mTLS api endpoint.
+ """
+ if not api_endpoint:
+ return api_endpoint
+
+ mtls_endpoint_re = re.compile(
+ r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?"
+ )
+
+ m = mtls_endpoint_re.match(api_endpoint)
+ name, mtls, sandbox, googledomain = m.groups()
+ if mtls or not googledomain:
+ return api_endpoint
+
+ if sandbox:
+ return api_endpoint.replace(
+ "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
+ )
+
+ return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+
+ DEFAULT_ENDPOINT = "jobs.googleapis.com"
+ DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
+ DEFAULT_ENDPOINT
+ )
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ {@api.name}: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_file(filename)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
+ from_service_account_json = from_service_account_file
+
+ @staticmethod
+ def job_path(project: str, tenant: str, job: str,) -> str:
+ """Return a fully-qualified job string."""
+ return "projects/{project}/tenants/{tenant}/jobs/{job}".format(
+ project=project, tenant=tenant, job=job,
+ )
+
+ @staticmethod
+ def parse_job_path(path: str) -> Dict[str, str]:
+ """Parse a job path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/tenants/(?P.+?)/jobs/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
+ def __init__(
+ self,
+ *,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, JobServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the job service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.JobServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+ if isinstance(client_options, dict):
+ client_options = client_options_lib.from_dict(client_options)
+ if client_options is None:
+ client_options = client_options_lib.ClientOptions()
+
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
+ if use_mtls_env == "never":
+ api_endpoint = self.DEFAULT_ENDPOINT
+ 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
+ )
+ else:
+ raise MutualTLSChannelError(
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
+ )
+
+ # Save or instantiate the transport.
+ # Ordinarily, we provide the transport, but allowing a custom transport
+ # instance provides an extensibility point for unusual situations.
+ if isinstance(transport, JobServiceTransport):
+ # transport is a JobServiceTransport instance.
+ if credentials or client_options.credentials_file:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its credentials directly."
+ )
+ if client_options.scopes:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its scopes directly."
+ )
+ self._transport = transport
+ else:
+ Transport = type(self).get_transport_class(transport)
+ self._transport = Transport(
+ credentials=credentials,
+ credentials_file=client_options.credentials_file,
+ host=api_endpoint,
+ scopes=client_options.scopes,
+ ssl_channel_credentials=ssl_credentials,
+ quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
+ )
+
+ def create_job(
+ self,
+ request: job_service.CreateJobRequest = None,
+ *,
+ parent: str = None,
+ job: gct_job.Job = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_job.Job:
+ r"""Creates a new job.
+ Typically, the job becomes searchable within 10 seconds,
+ but it may take up to 5 minutes.
+
+ Args:
+ request (:class:`~.job_service.CreateJobRequest`):
+ The request object. Create job request.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ job (:class:`~.gct_job.Job`):
+ Required. The Job to be created.
+ This corresponds to the ``job`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_job.Job:
+ A Job resource represents a job posting (also referred
+ to as a "job listing" or "job requisition"). A job
+ belongs to a [Company][google.cloud.talent.v4.Company],
+ which is the hiring entity responsible for the job.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, job])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.CreateJobRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.CreateJobRequest):
+ request = job_service.CreateJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if job is not None:
+ request.job = job
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.create_job]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def batch_create_jobs(
+ self,
+ request: job_service.BatchCreateJobsRequest = None,
+ *,
+ parent: str = None,
+ jobs: Sequence[job.Job] = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> operation.Operation:
+ r"""Begins executing a batch create jobs operation.
+
+ Args:
+ request (:class:`~.job_service.BatchCreateJobsRequest`):
+ The request object. Request to create a batch of jobs.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ jobs (:class:`Sequence[~.job.Job]`):
+ Required. The jobs to be created.
+ A maximum of 200 jobs can be created in
+ a batch.
+ This corresponds to the ``jobs`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:``~.job_service.BatchCreateJobsResponse``: The
+ result of
+ [JobService.BatchCreateJobs][google.cloud.talent.v4.JobService.BatchCreateJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, jobs])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.BatchCreateJobsRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.BatchCreateJobsRequest):
+ request = job_service.BatchCreateJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if jobs is not None:
+ request.jobs = jobs
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.batch_create_jobs]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ job_service.BatchCreateJobsResponse,
+ metadata_type=common.BatchOperationMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def get_job(
+ self,
+ request: job_service.GetJobRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> job.Job:
+ r"""Retrieves the specified job, whose status is OPEN or
+ recently EXPIRED within the last 90 days.
+
+ Args:
+ request (:class:`~.job_service.GetJobRequest`):
+ The request object. Get job request.
+ name (:class:`str`):
+ Required. The resource name of the job to retrieve.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.job.Job:
+ A Job resource represents a job posting (also referred
+ to as a "job listing" or "job requisition"). A job
+ belongs to a [Company][google.cloud.talent.v4.Company],
+ which is the hiring entity responsible for the job.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([name])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.GetJobRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.GetJobRequest):
+ request = job_service.GetJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.get_job]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def update_job(
+ self,
+ request: job_service.UpdateJobRequest = None,
+ *,
+ job: gct_job.Job = None,
+ update_mask: field_mask.FieldMask = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_job.Job:
+ r"""Updates specified job.
+ Typically, updated contents become visible in search
+ results within 10 seconds, but it may take up to 5
+ minutes.
+
+ Args:
+ request (:class:`~.job_service.UpdateJobRequest`):
+ The request object. Update job request.
+ job (:class:`~.gct_job.Job`):
+ Required. The Job to be updated.
+ This corresponds to the ``job`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`~.field_mask.FieldMask`):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateJobRequest.update_mask]
+ is provided, only the specified fields in
+ [job][google.cloud.talent.v4.UpdateJobRequest.job] are
+ updated. Otherwise all the fields are updated.
+
+ A field mask to restrict the fields that are updated.
+ Only top level fields of
+ [Job][google.cloud.talent.v4.Job] are supported.
+ This corresponds to the ``update_mask`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_job.Job:
+ A Job resource represents a job posting (also referred
+ to as a "job listing" or "job requisition"). A job
+ belongs to a [Company][google.cloud.talent.v4.Company],
+ which is the hiring entity responsible for the job.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([job, update_mask])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.UpdateJobRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.UpdateJobRequest):
+ request = job_service.UpdateJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if job is not None:
+ request.job = job
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.update_job]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("job.name", request.job.name),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def batch_update_jobs(
+ self,
+ request: job_service.BatchUpdateJobsRequest = None,
+ *,
+ parent: str = None,
+ jobs: Sequence[job.Job] = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> operation.Operation:
+ r"""Begins executing a batch update jobs operation.
+
+ Args:
+ request (:class:`~.job_service.BatchUpdateJobsRequest`):
+ The request object. Request to update a batch of jobs.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ jobs (:class:`Sequence[~.job.Job]`):
+ Required. The jobs to be updated.
+ A maximum of 200 jobs can be updated in
+ a batch.
+ This corresponds to the ``jobs`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:``~.job_service.BatchUpdateJobsResponse``: The
+ result of
+ [JobService.BatchUpdateJobs][google.cloud.talent.v4.JobService.BatchUpdateJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, jobs])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.BatchUpdateJobsRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.BatchUpdateJobsRequest):
+ request = job_service.BatchUpdateJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if jobs is not None:
+ request.jobs = jobs
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.batch_update_jobs]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ job_service.BatchUpdateJobsResponse,
+ metadata_type=common.BatchOperationMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def delete_job(
+ self,
+ request: job_service.DeleteJobRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> None:
+ r"""Deletes the specified job.
+ Typically, the job becomes unsearchable within 10
+ seconds, but it may take up to 5 minutes.
+
+ Args:
+ request (:class:`~.job_service.DeleteJobRequest`):
+ The request object. Delete job request.
+ name (:class:`str`):
+ Required. The resource name of the job to be deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([name])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.DeleteJobRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.DeleteJobRequest):
+ request = job_service.DeleteJobRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_job]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ rpc(
+ request, retry=retry, timeout=timeout, metadata=metadata,
+ )
+
+ def batch_delete_jobs(
+ self,
+ request: job_service.BatchDeleteJobsRequest = None,
+ *,
+ parent: str = None,
+ names: Sequence[str] = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> operation.Operation:
+ r"""Begins executing a batch delete jobs operation.
+
+ Args:
+ request (:class:`~.job_service.BatchDeleteJobsRequest`):
+ The request object. Request to delete a batch of jobs.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+
+ The parent of all of the jobs specified in ``names``
+ must match this field.
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ names (:class:`Sequence[str]`):
+ The names of the jobs to delete.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+
+ A maximum of 200 jobs can be deleted in a batch.
+ This corresponds to the ``names`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:``~.job_service.BatchDeleteJobsResponse``: The
+ result of
+ [JobService.BatchDeleteJobs][google.cloud.talent.v4.JobService.BatchDeleteJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, names])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.BatchDeleteJobsRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.BatchDeleteJobsRequest):
+ request = job_service.BatchDeleteJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if names is not None:
+ request.names = names
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.batch_delete_jobs]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ job_service.BatchDeleteJobsResponse,
+ metadata_type=common.BatchOperationMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def list_jobs(
+ self,
+ request: job_service.ListJobsRequest = None,
+ *,
+ parent: str = None,
+ filter: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> pagers.ListJobsPager:
+ r"""Lists jobs by filter.
+
+ Args:
+ request (:class:`~.job_service.ListJobsRequest`):
+ The request object. List jobs request.
+ parent (:class:`str`):
+ Required. The resource name of the tenant under which
+ the job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}". For
+ example, "projects/foo/tenants/bar".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ filter (:class:`str`):
+ Required. The filter string specifies the jobs to be
+ enumerated.
+
+ Supported operator: =, AND
+
+ The fields eligible for filtering are:
+
+ - ``companyName`` (Required)
+ - ``requisitionId``
+ - ``status`` Available values: OPEN, EXPIRED, ALL.
+ Defaults to OPEN if no value is specified.
+
+ Sample Query:
+
+ - companyName =
+ "projects/foo/tenants/bar/companies/baz"
+ - companyName =
+ "projects/foo/tenants/bar/companies/baz" AND
+ requisitionId = "req-1"
+ - companyName =
+ "projects/foo/tenants/bar/companies/baz" AND status =
+ "EXPIRED".
+ This corresponds to the ``filter`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.pagers.ListJobsPager:
+ List jobs response.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, filter])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.ListJobsRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.ListJobsRequest):
+ request = job_service.ListJobsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if filter is not None:
+ request.filter = filter
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.list_jobs]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListJobsPager(
+ method=rpc, request=request, response=response, metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def search_jobs(
+ self,
+ request: job_service.SearchJobsRequest = None,
+ *,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> job_service.SearchJobsResponse:
+ r"""Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs that the caller
+ has permission to search against.
+
+ Args:
+ request (:class:`~.job_service.SearchJobsRequest`):
+ The request object. The Request body of the `SearchJobs`
+ call.
+
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.job_service.SearchJobsResponse:
+ Response for SearchJob method.
+ """
+ # Create or coerce a protobuf request object.
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.SearchJobsRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.SearchJobsRequest):
+ request = job_service.SearchJobsRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.search_jobs]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def search_jobs_for_alert(
+ self,
+ request: job_service.SearchJobsRequest = None,
+ *,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> job_service.SearchJobsResponse:
+ r"""Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This API call is intended for the use case of targeting passive
+ job seekers (for example, job seekers who have signed up to
+ receive email alerts about potential job opportunities), it has
+ different algorithmic adjustments that are designed to
+ specifically target passive job seekers.
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs the caller has
+ permission to search against.
+
+ Args:
+ request (:class:`~.job_service.SearchJobsRequest`):
+ The request object. The Request body of the `SearchJobs`
+ call.
+
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.job_service.SearchJobsResponse:
+ Response for SearchJob method.
+ """
+ # Create or coerce a protobuf request object.
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a job_service.SearchJobsRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, job_service.SearchJobsRequest):
+ request = job_service.SearchJobsRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.search_jobs_for_alert]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("JobServiceClient",)
diff --git a/google/cloud/talent_v4/services/job_service/pagers.py b/google/cloud/talent_v4/services/job_service/pagers.py
new file mode 100644
index 00000000..e759d8e3
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/pagers.py
@@ -0,0 +1,149 @@
+# -*- 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.
+#
+
+from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple
+
+from google.cloud.talent_v4.types import job
+from google.cloud.talent_v4.types import job_service
+
+
+class ListJobsPager:
+ """A pager for iterating through ``list_jobs`` requests.
+
+ This class thinly wraps an initial
+ :class:`~.job_service.ListJobsResponse` object, and
+ provides an ``__iter__`` method to iterate through its
+ ``jobs`` field.
+
+ If there are more pages, the ``__iter__`` method will make additional
+ ``ListJobs`` requests and continue to iterate
+ through the ``jobs`` field on the
+ corresponding responses.
+
+ All the usual :class:`~.job_service.ListJobsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., job_service.ListJobsResponse],
+ request: job_service.ListJobsRequest,
+ response: job_service.ListJobsResponse,
+ *,
+ metadata: Sequence[Tuple[str, str]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (:class:`~.job_service.ListJobsRequest`):
+ The initial request object.
+ response (:class:`~.job_service.ListJobsResponse`):
+ The initial response object.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ self._method = method
+ self._request = job_service.ListJobsRequest(request)
+ self._response = response
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ def pages(self) -> Iterable[job_service.ListJobsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = self._method(self._request, metadata=self._metadata)
+ yield self._response
+
+ def __iter__(self) -> Iterable[job.Job]:
+ for page in self.pages:
+ yield from page.jobs
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListJobsAsyncPager:
+ """A pager for iterating through ``list_jobs`` requests.
+
+ This class thinly wraps an initial
+ :class:`~.job_service.ListJobsResponse` object, and
+ provides an ``__aiter__`` method to iterate through its
+ ``jobs`` field.
+
+ If there are more pages, the ``__aiter__`` method will make additional
+ ``ListJobs`` requests and continue to iterate
+ through the ``jobs`` field on the
+ corresponding responses.
+
+ All the usual :class:`~.job_service.ListJobsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., Awaitable[job_service.ListJobsResponse]],
+ request: job_service.ListJobsRequest,
+ response: job_service.ListJobsResponse,
+ *,
+ metadata: Sequence[Tuple[str, str]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (:class:`~.job_service.ListJobsRequest`):
+ The initial request object.
+ response (:class:`~.job_service.ListJobsResponse`):
+ The initial response object.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ self._method = method
+ self._request = job_service.ListJobsRequest(request)
+ self._response = response
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ async def pages(self) -> AsyncIterable[job_service.ListJobsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = await self._method(self._request, metadata=self._metadata)
+ yield self._response
+
+ def __aiter__(self) -> AsyncIterable[job.Job]:
+ async def async_generator():
+ async for page in self.pages:
+ for response in page.jobs:
+ yield response
+
+ return async_generator()
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
diff --git a/google/cloud/talent_v4/services/job_service/transports/__init__.py b/google/cloud/talent_v4/services/job_service/transports/__init__.py
new file mode 100644
index 00000000..ca4d929c
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/transports/__init__.py
@@ -0,0 +1,36 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from typing import Dict, Type
+
+from .base import JobServiceTransport
+from .grpc import JobServiceGrpcTransport
+from .grpc_asyncio import JobServiceGrpcAsyncIOTransport
+
+
+# Compile a registry of transports.
+_transport_registry = OrderedDict() # type: Dict[str, Type[JobServiceTransport]]
+_transport_registry["grpc"] = JobServiceGrpcTransport
+_transport_registry["grpc_asyncio"] = JobServiceGrpcAsyncIOTransport
+
+
+__all__ = (
+ "JobServiceTransport",
+ "JobServiceGrpcTransport",
+ "JobServiceGrpcAsyncIOTransport",
+)
diff --git a/google/cloud/talent_v4/services/job_service/transports/base.py b/google/cloud/talent_v4/services/job_service/transports/base.py
new file mode 100644
index 00000000..c5256160
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/transports/base.py
@@ -0,0 +1,282 @@
+# -*- 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.
+#
+
+import abc
+import typing
+import pkg_resources
+
+from google import auth # type: ignore
+from google.api_core import 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.cloud.talent_v4.types import job
+from google.cloud.talent_v4.types import job as gct_job
+from google.cloud.talent_v4.types import job_service
+from google.longrunning import operations_pb2 as operations # type: ignore
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+class JobServiceTransport(abc.ABC):
+ """Abstract transport class for JobService."""
+
+ AUTH_SCOPES = (
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.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,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ **kwargs,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ 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.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+ """
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ # If no credentials are provided, then determine the appropriate
+ # defaults.
+ if credentials and credentials_file:
+ raise exceptions.DuplicateCredentialArgs(
+ "'credentials_file' and 'credentials' are mutually exclusive"
+ )
+
+ if credentials_file is not None:
+ credentials, _ = auth.load_credentials_from_file(
+ credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ elif credentials is None:
+ credentials, _ = auth.default(
+ scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ # Save the credentials.
+ self._credentials = credentials
+
+ # Lifted into its own function so it can be stubbed out during tests.
+ self._prep_wrapped_messages(client_info)
+
+ def _prep_wrapped_messages(self, client_info):
+ # Precompute the wrapped methods.
+ self._wrapped_methods = {
+ self.create_job: gapic_v1.method.wrap_method(
+ self.create_job, default_timeout=30.0, client_info=client_info,
+ ),
+ self.batch_create_jobs: gapic_v1.method.wrap_method(
+ self.batch_create_jobs, default_timeout=30.0, client_info=client_info,
+ ),
+ self.get_job: gapic_v1.method.wrap_method(
+ self.get_job,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ self.update_job: gapic_v1.method.wrap_method(
+ self.update_job, default_timeout=30.0, client_info=client_info,
+ ),
+ self.batch_update_jobs: gapic_v1.method.wrap_method(
+ self.batch_update_jobs, default_timeout=30.0, client_info=client_info,
+ ),
+ self.delete_job: gapic_v1.method.wrap_method(
+ self.delete_job,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ self.batch_delete_jobs: gapic_v1.method.wrap_method(
+ self.batch_delete_jobs, default_timeout=30.0, client_info=client_info,
+ ),
+ self.list_jobs: gapic_v1.method.wrap_method(
+ self.list_jobs,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ self.search_jobs: gapic_v1.method.wrap_method(
+ self.search_jobs, default_timeout=30.0, client_info=client_info,
+ ),
+ self.search_jobs_for_alert: gapic_v1.method.wrap_method(
+ self.search_jobs_for_alert,
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ }
+
+ @property
+ def operations_client(self) -> operations_v1.OperationsClient:
+ """Return the client designed to process long-running operations."""
+ raise NotImplementedError()
+
+ @property
+ def create_job(
+ self,
+ ) -> typing.Callable[
+ [job_service.CreateJobRequest],
+ typing.Union[gct_job.Job, typing.Awaitable[gct_job.Job]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def batch_create_jobs(
+ self,
+ ) -> typing.Callable[
+ [job_service.BatchCreateJobsRequest],
+ typing.Union[operations.Operation, typing.Awaitable[operations.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def get_job(
+ self,
+ ) -> typing.Callable[
+ [job_service.GetJobRequest], typing.Union[job.Job, typing.Awaitable[job.Job]]
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def update_job(
+ self,
+ ) -> typing.Callable[
+ [job_service.UpdateJobRequest],
+ typing.Union[gct_job.Job, typing.Awaitable[gct_job.Job]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def batch_update_jobs(
+ self,
+ ) -> typing.Callable[
+ [job_service.BatchUpdateJobsRequest],
+ typing.Union[operations.Operation, typing.Awaitable[operations.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def delete_job(
+ self,
+ ) -> typing.Callable[
+ [job_service.DeleteJobRequest],
+ typing.Union[empty.Empty, typing.Awaitable[empty.Empty]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def batch_delete_jobs(
+ self,
+ ) -> typing.Callable[
+ [job_service.BatchDeleteJobsRequest],
+ typing.Union[operations.Operation, typing.Awaitable[operations.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def list_jobs(
+ self,
+ ) -> typing.Callable[
+ [job_service.ListJobsRequest],
+ typing.Union[
+ job_service.ListJobsResponse, typing.Awaitable[job_service.ListJobsResponse]
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def search_jobs(
+ self,
+ ) -> typing.Callable[
+ [job_service.SearchJobsRequest],
+ typing.Union[
+ job_service.SearchJobsResponse,
+ typing.Awaitable[job_service.SearchJobsResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def search_jobs_for_alert(
+ self,
+ ) -> typing.Callable[
+ [job_service.SearchJobsRequest],
+ typing.Union[
+ job_service.SearchJobsResponse,
+ typing.Awaitable[job_service.SearchJobsResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+
+__all__ = ("JobServiceTransport",)
diff --git a/google/cloud/talent_v4/services/job_service/transports/grpc.py b/google/cloud/talent_v4/services/job_service/transports/grpc.py
new file mode 100644
index 00000000..a8a82f6a
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/transports/grpc.py
@@ -0,0 +1,533 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Callable, Dict, Optional, Sequence, Tuple
+
+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
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+
+from google.cloud.talent_v4.types import job
+from google.cloud.talent_v4.types import job as gct_job
+from google.cloud.talent_v4.types import job_service
+from google.longrunning import operations_pb2 as operations # type: ignore
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+from .base import JobServiceTransport, DEFAULT_CLIENT_INFO
+
+
+class JobServiceGrpcTransport(JobServiceTransport):
+ """gRPC backend transport for JobService.
+
+ A service handles job management, including job CRUD,
+ enumeration and search.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _stubs: Dict[str, Callable]
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Sequence[str] = None,
+ channel: grpc.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ channel (Optional[grpc.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ self._stubs = {} # type: Dict[str, Callable]
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> grpc.Channel:
+ """Create and return a gRPC channel object.
+ Args:
+ address (Optionsl[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ 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.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ grpc.Channel: A gRPC channel object.
+
+ Raises:
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ @property
+ def grpc_channel(self) -> grpc.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def operations_client(self) -> operations_v1.OperationsClient:
+ """Create the client designed to process long-running operations.
+
+ This property caches on the instance; repeated calls return the same
+ client.
+ """
+ # Sanity check: Only create a new client if we do not already have one.
+ if "operations_client" not in self.__dict__:
+ self.__dict__["operations_client"] = operations_v1.OperationsClient(
+ self.grpc_channel
+ )
+
+ # Return the client from cache.
+ return self.__dict__["operations_client"]
+
+ @property
+ def create_job(self) -> Callable[[job_service.CreateJobRequest], gct_job.Job]:
+ r"""Return a callable for the create job method over gRPC.
+
+ Creates a new job.
+ Typically, the job becomes searchable within 10 seconds,
+ but it may take up to 5 minutes.
+
+ Returns:
+ Callable[[~.CreateJobRequest],
+ ~.Job]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_job" not in self._stubs:
+ self._stubs["create_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/CreateJob",
+ request_serializer=job_service.CreateJobRequest.serialize,
+ response_deserializer=gct_job.Job.deserialize,
+ )
+ return self._stubs["create_job"]
+
+ @property
+ def batch_create_jobs(
+ self,
+ ) -> Callable[[job_service.BatchCreateJobsRequest], operations.Operation]:
+ r"""Return a callable for the batch create jobs method over gRPC.
+
+ Begins executing a batch create jobs operation.
+
+ Returns:
+ Callable[[~.BatchCreateJobsRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "batch_create_jobs" not in self._stubs:
+ self._stubs["batch_create_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/BatchCreateJobs",
+ request_serializer=job_service.BatchCreateJobsRequest.serialize,
+ response_deserializer=operations.Operation.FromString,
+ )
+ return self._stubs["batch_create_jobs"]
+
+ @property
+ def get_job(self) -> Callable[[job_service.GetJobRequest], job.Job]:
+ r"""Return a callable for the get job method over gRPC.
+
+ Retrieves the specified job, whose status is OPEN or
+ recently EXPIRED within the last 90 days.
+
+ Returns:
+ Callable[[~.GetJobRequest],
+ ~.Job]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_job" not in self._stubs:
+ self._stubs["get_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/GetJob",
+ request_serializer=job_service.GetJobRequest.serialize,
+ response_deserializer=job.Job.deserialize,
+ )
+ return self._stubs["get_job"]
+
+ @property
+ def update_job(self) -> Callable[[job_service.UpdateJobRequest], gct_job.Job]:
+ r"""Return a callable for the update job method over gRPC.
+
+ Updates specified job.
+ Typically, updated contents become visible in search
+ results within 10 seconds, but it may take up to 5
+ minutes.
+
+ Returns:
+ Callable[[~.UpdateJobRequest],
+ ~.Job]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_job" not in self._stubs:
+ self._stubs["update_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/UpdateJob",
+ request_serializer=job_service.UpdateJobRequest.serialize,
+ response_deserializer=gct_job.Job.deserialize,
+ )
+ return self._stubs["update_job"]
+
+ @property
+ def batch_update_jobs(
+ self,
+ ) -> Callable[[job_service.BatchUpdateJobsRequest], operations.Operation]:
+ r"""Return a callable for the batch update jobs method over gRPC.
+
+ Begins executing a batch update jobs operation.
+
+ Returns:
+ Callable[[~.BatchUpdateJobsRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "batch_update_jobs" not in self._stubs:
+ self._stubs["batch_update_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/BatchUpdateJobs",
+ request_serializer=job_service.BatchUpdateJobsRequest.serialize,
+ response_deserializer=operations.Operation.FromString,
+ )
+ return self._stubs["batch_update_jobs"]
+
+ @property
+ def delete_job(self) -> Callable[[job_service.DeleteJobRequest], empty.Empty]:
+ r"""Return a callable for the delete job method over gRPC.
+
+ Deletes the specified job.
+ Typically, the job becomes unsearchable within 10
+ seconds, but it may take up to 5 minutes.
+
+ Returns:
+ Callable[[~.DeleteJobRequest],
+ ~.Empty]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_job" not in self._stubs:
+ self._stubs["delete_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/DeleteJob",
+ request_serializer=job_service.DeleteJobRequest.serialize,
+ response_deserializer=empty.Empty.FromString,
+ )
+ return self._stubs["delete_job"]
+
+ @property
+ def batch_delete_jobs(
+ self,
+ ) -> Callable[[job_service.BatchDeleteJobsRequest], operations.Operation]:
+ r"""Return a callable for the batch delete jobs method over gRPC.
+
+ Begins executing a batch delete jobs operation.
+
+ Returns:
+ Callable[[~.BatchDeleteJobsRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "batch_delete_jobs" not in self._stubs:
+ self._stubs["batch_delete_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/BatchDeleteJobs",
+ request_serializer=job_service.BatchDeleteJobsRequest.serialize,
+ response_deserializer=operations.Operation.FromString,
+ )
+ return self._stubs["batch_delete_jobs"]
+
+ @property
+ def list_jobs(
+ self,
+ ) -> Callable[[job_service.ListJobsRequest], job_service.ListJobsResponse]:
+ r"""Return a callable for the list jobs method over gRPC.
+
+ Lists jobs by filter.
+
+ Returns:
+ Callable[[~.ListJobsRequest],
+ ~.ListJobsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_jobs" not in self._stubs:
+ self._stubs["list_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/ListJobs",
+ request_serializer=job_service.ListJobsRequest.serialize,
+ response_deserializer=job_service.ListJobsResponse.deserialize,
+ )
+ return self._stubs["list_jobs"]
+
+ @property
+ def search_jobs(
+ self,
+ ) -> Callable[[job_service.SearchJobsRequest], job_service.SearchJobsResponse]:
+ r"""Return a callable for the search jobs method over gRPC.
+
+ Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs that the caller
+ has permission to search against.
+
+ Returns:
+ Callable[[~.SearchJobsRequest],
+ ~.SearchJobsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "search_jobs" not in self._stubs:
+ self._stubs["search_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/SearchJobs",
+ request_serializer=job_service.SearchJobsRequest.serialize,
+ response_deserializer=job_service.SearchJobsResponse.deserialize,
+ )
+ return self._stubs["search_jobs"]
+
+ @property
+ def search_jobs_for_alert(
+ self,
+ ) -> Callable[[job_service.SearchJobsRequest], job_service.SearchJobsResponse]:
+ r"""Return a callable for the search jobs for alert method over gRPC.
+
+ Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This API call is intended for the use case of targeting passive
+ job seekers (for example, job seekers who have signed up to
+ receive email alerts about potential job opportunities), it has
+ different algorithmic adjustments that are designed to
+ specifically target passive job seekers.
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs the caller has
+ permission to search against.
+
+ Returns:
+ Callable[[~.SearchJobsRequest],
+ ~.SearchJobsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "search_jobs_for_alert" not in self._stubs:
+ self._stubs["search_jobs_for_alert"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/SearchJobsForAlert",
+ request_serializer=job_service.SearchJobsRequest.serialize,
+ response_deserializer=job_service.SearchJobsResponse.deserialize,
+ )
+ return self._stubs["search_jobs_for_alert"]
+
+
+__all__ = ("JobServiceGrpcTransport",)
diff --git a/google/cloud/talent_v4/services/job_service/transports/grpc_asyncio.py b/google/cloud/talent_v4/services/job_service/transports/grpc_asyncio.py
new file mode 100644
index 00000000..90ccdde9
--- /dev/null
+++ b/google/cloud/talent_v4/services/job_service/transports/grpc_asyncio.py
@@ -0,0 +1,551 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+
+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.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+from grpc.experimental import aio # type: ignore
+
+from google.cloud.talent_v4.types import job
+from google.cloud.talent_v4.types import job as gct_job
+from google.cloud.talent_v4.types import job_service
+from google.longrunning import operations_pb2 as operations # type: ignore
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+from .base import JobServiceTransport, DEFAULT_CLIENT_INFO
+from .grpc import JobServiceGrpcTransport
+
+
+class JobServiceGrpcAsyncIOTransport(JobServiceTransport):
+ """gRPC AsyncIO backend transport for JobService.
+
+ A service handles job management, including job CRUD,
+ enumeration and search.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _grpc_channel: aio.Channel
+ _stubs: Dict[str, Callable] = {}
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> aio.Channel:
+ """Create and return a gRPC AsyncIO channel object.
+ Args:
+ address (Optional[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ aio.Channel: A gRPC AsyncIO channel object.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers_async.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: aio.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ channel (Optional[aio.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ self._stubs = {}
+
+ @property
+ def grpc_channel(self) -> aio.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def operations_client(self) -> operations_v1.OperationsAsyncClient:
+ """Create the client designed to process long-running operations.
+
+ This property caches on the instance; repeated calls return the same
+ client.
+ """
+ # Sanity check: Only create a new client if we do not already have one.
+ if "operations_client" not in self.__dict__:
+ self.__dict__["operations_client"] = operations_v1.OperationsAsyncClient(
+ self.grpc_channel
+ )
+
+ # Return the client from cache.
+ return self.__dict__["operations_client"]
+
+ @property
+ def create_job(
+ self,
+ ) -> Callable[[job_service.CreateJobRequest], Awaitable[gct_job.Job]]:
+ r"""Return a callable for the create job method over gRPC.
+
+ Creates a new job.
+ Typically, the job becomes searchable within 10 seconds,
+ but it may take up to 5 minutes.
+
+ Returns:
+ Callable[[~.CreateJobRequest],
+ Awaitable[~.Job]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_job" not in self._stubs:
+ self._stubs["create_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/CreateJob",
+ request_serializer=job_service.CreateJobRequest.serialize,
+ response_deserializer=gct_job.Job.deserialize,
+ )
+ return self._stubs["create_job"]
+
+ @property
+ def batch_create_jobs(
+ self,
+ ) -> Callable[
+ [job_service.BatchCreateJobsRequest], Awaitable[operations.Operation]
+ ]:
+ r"""Return a callable for the batch create jobs method over gRPC.
+
+ Begins executing a batch create jobs operation.
+
+ Returns:
+ Callable[[~.BatchCreateJobsRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "batch_create_jobs" not in self._stubs:
+ self._stubs["batch_create_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/BatchCreateJobs",
+ request_serializer=job_service.BatchCreateJobsRequest.serialize,
+ response_deserializer=operations.Operation.FromString,
+ )
+ return self._stubs["batch_create_jobs"]
+
+ @property
+ def get_job(self) -> Callable[[job_service.GetJobRequest], Awaitable[job.Job]]:
+ r"""Return a callable for the get job method over gRPC.
+
+ Retrieves the specified job, whose status is OPEN or
+ recently EXPIRED within the last 90 days.
+
+ Returns:
+ Callable[[~.GetJobRequest],
+ Awaitable[~.Job]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_job" not in self._stubs:
+ self._stubs["get_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/GetJob",
+ request_serializer=job_service.GetJobRequest.serialize,
+ response_deserializer=job.Job.deserialize,
+ )
+ return self._stubs["get_job"]
+
+ @property
+ def update_job(
+ self,
+ ) -> Callable[[job_service.UpdateJobRequest], Awaitable[gct_job.Job]]:
+ r"""Return a callable for the update job method over gRPC.
+
+ Updates specified job.
+ Typically, updated contents become visible in search
+ results within 10 seconds, but it may take up to 5
+ minutes.
+
+ Returns:
+ Callable[[~.UpdateJobRequest],
+ Awaitable[~.Job]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_job" not in self._stubs:
+ self._stubs["update_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/UpdateJob",
+ request_serializer=job_service.UpdateJobRequest.serialize,
+ response_deserializer=gct_job.Job.deserialize,
+ )
+ return self._stubs["update_job"]
+
+ @property
+ def batch_update_jobs(
+ self,
+ ) -> Callable[
+ [job_service.BatchUpdateJobsRequest], Awaitable[operations.Operation]
+ ]:
+ r"""Return a callable for the batch update jobs method over gRPC.
+
+ Begins executing a batch update jobs operation.
+
+ Returns:
+ Callable[[~.BatchUpdateJobsRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "batch_update_jobs" not in self._stubs:
+ self._stubs["batch_update_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/BatchUpdateJobs",
+ request_serializer=job_service.BatchUpdateJobsRequest.serialize,
+ response_deserializer=operations.Operation.FromString,
+ )
+ return self._stubs["batch_update_jobs"]
+
+ @property
+ def delete_job(
+ self,
+ ) -> Callable[[job_service.DeleteJobRequest], Awaitable[empty.Empty]]:
+ r"""Return a callable for the delete job method over gRPC.
+
+ Deletes the specified job.
+ Typically, the job becomes unsearchable within 10
+ seconds, but it may take up to 5 minutes.
+
+ Returns:
+ Callable[[~.DeleteJobRequest],
+ Awaitable[~.Empty]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_job" not in self._stubs:
+ self._stubs["delete_job"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/DeleteJob",
+ request_serializer=job_service.DeleteJobRequest.serialize,
+ response_deserializer=empty.Empty.FromString,
+ )
+ return self._stubs["delete_job"]
+
+ @property
+ def batch_delete_jobs(
+ self,
+ ) -> Callable[
+ [job_service.BatchDeleteJobsRequest], Awaitable[operations.Operation]
+ ]:
+ r"""Return a callable for the batch delete jobs method over gRPC.
+
+ Begins executing a batch delete jobs operation.
+
+ Returns:
+ Callable[[~.BatchDeleteJobsRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "batch_delete_jobs" not in self._stubs:
+ self._stubs["batch_delete_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/BatchDeleteJobs",
+ request_serializer=job_service.BatchDeleteJobsRequest.serialize,
+ response_deserializer=operations.Operation.FromString,
+ )
+ return self._stubs["batch_delete_jobs"]
+
+ @property
+ def list_jobs(
+ self,
+ ) -> Callable[
+ [job_service.ListJobsRequest], Awaitable[job_service.ListJobsResponse]
+ ]:
+ r"""Return a callable for the list jobs method over gRPC.
+
+ Lists jobs by filter.
+
+ Returns:
+ Callable[[~.ListJobsRequest],
+ Awaitable[~.ListJobsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_jobs" not in self._stubs:
+ self._stubs["list_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/ListJobs",
+ request_serializer=job_service.ListJobsRequest.serialize,
+ response_deserializer=job_service.ListJobsResponse.deserialize,
+ )
+ return self._stubs["list_jobs"]
+
+ @property
+ def search_jobs(
+ self,
+ ) -> Callable[
+ [job_service.SearchJobsRequest], Awaitable[job_service.SearchJobsResponse]
+ ]:
+ r"""Return a callable for the search jobs method over gRPC.
+
+ Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs that the caller
+ has permission to search against.
+
+ Returns:
+ Callable[[~.SearchJobsRequest],
+ Awaitable[~.SearchJobsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "search_jobs" not in self._stubs:
+ self._stubs["search_jobs"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/SearchJobs",
+ request_serializer=job_service.SearchJobsRequest.serialize,
+ response_deserializer=job_service.SearchJobsResponse.deserialize,
+ )
+ return self._stubs["search_jobs"]
+
+ @property
+ def search_jobs_for_alert(
+ self,
+ ) -> Callable[
+ [job_service.SearchJobsRequest], Awaitable[job_service.SearchJobsResponse]
+ ]:
+ r"""Return a callable for the search jobs for alert method over gRPC.
+
+ Searches for jobs using the provided
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ This API call is intended for the use case of targeting passive
+ job seekers (for example, job seekers who have signed up to
+ receive email alerts about potential job opportunities), it has
+ different algorithmic adjustments that are designed to
+ specifically target passive job seekers.
+
+ This call constrains the
+ [visibility][google.cloud.talent.v4.Job.visibility] of jobs
+ present in the database, and only returns jobs the caller has
+ permission to search against.
+
+ Returns:
+ Callable[[~.SearchJobsRequest],
+ Awaitable[~.SearchJobsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "search_jobs_for_alert" not in self._stubs:
+ self._stubs["search_jobs_for_alert"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.JobService/SearchJobsForAlert",
+ request_serializer=job_service.SearchJobsRequest.serialize,
+ response_deserializer=job_service.SearchJobsResponse.deserialize,
+ )
+ return self._stubs["search_jobs_for_alert"]
+
+
+__all__ = ("JobServiceGrpcAsyncIOTransport",)
diff --git a/google/cloud/talent_v4/services/tenant_service/__init__.py b/google/cloud/talent_v4/services/tenant_service/__init__.py
new file mode 100644
index 00000000..c3e2ad3b
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/__init__.py
@@ -0,0 +1,24 @@
+# -*- 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.
+#
+
+from .client import TenantServiceClient
+from .async_client import TenantServiceAsyncClient
+
+__all__ = (
+ "TenantServiceClient",
+ "TenantServiceAsyncClient",
+)
diff --git a/google/cloud/talent_v4/services/tenant_service/async_client.py b/google/cloud/talent_v4/services/tenant_service/async_client.py
new file mode 100644
index 00000000..5b57b42d
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/async_client.py
@@ -0,0 +1,555 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+import functools
+import re
+from typing import Dict, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import credentials # type: ignore
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.services.tenant_service import pagers
+from google.cloud.talent_v4.types import tenant
+from google.cloud.talent_v4.types import tenant as gct_tenant
+from google.cloud.talent_v4.types import tenant_service
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+
+from .transports.base import TenantServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc_asyncio import TenantServiceGrpcAsyncIOTransport
+from .client import TenantServiceClient
+
+
+class TenantServiceAsyncClient:
+ """A service that handles tenant management, including CRUD and
+ enumeration.
+ """
+
+ _client: TenantServiceClient
+
+ DEFAULT_ENDPOINT = TenantServiceClient.DEFAULT_ENDPOINT
+ DEFAULT_MTLS_ENDPOINT = TenantServiceClient.DEFAULT_MTLS_ENDPOINT
+
+ tenant_path = staticmethod(TenantServiceClient.tenant_path)
+ parse_tenant_path = staticmethod(TenantServiceClient.parse_tenant_path)
+
+ from_service_account_file = TenantServiceClient.from_service_account_file
+ from_service_account_json = from_service_account_file
+
+ get_transport_class = functools.partial(
+ type(TenantServiceClient).get_transport_class, type(TenantServiceClient)
+ )
+
+ def __init__(
+ self,
+ *,
+ credentials: credentials.Credentials = None,
+ transport: Union[str, TenantServiceTransport] = "grpc_asyncio",
+ client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the tenant service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.TenantServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (ClientOptions): Custom options for the client. It
+ won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+
+ self._client = TenantServiceClient(
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
+ )
+
+ async def create_tenant(
+ self,
+ request: tenant_service.CreateTenantRequest = None,
+ *,
+ parent: str = None,
+ tenant: gct_tenant.Tenant = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_tenant.Tenant:
+ r"""Creates a new tenant entity.
+
+ Args:
+ request (:class:`~.tenant_service.CreateTenantRequest`):
+ The request object. The Request of the CreateTenant
+ method.
+ parent (:class:`str`):
+ Required. Resource name of the project under which the
+ tenant is created.
+
+ The format is "projects/{project_id}", for example,
+ "projects/foo".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ tenant (:class:`~.gct_tenant.Tenant`):
+ Required. The tenant to be created.
+ This corresponds to the ``tenant`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_tenant.Tenant:
+ A Tenant resource represents a tenant
+ in the service. A tenant is a group or
+ entity that shares common access with
+ specific privileges for resources like
+ jobs. Customer may create multiple
+ tenants to provide data isolation for
+ different groups.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent, tenant]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = tenant_service.CreateTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if tenant is not None:
+ request.tenant = tenant
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.create_tenant,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def get_tenant(
+ self,
+ request: tenant_service.GetTenantRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> tenant.Tenant:
+ r"""Retrieves specified tenant.
+
+ Args:
+ request (:class:`~.tenant_service.GetTenantRequest`):
+ The request object. Request for getting a tenant by
+ name.
+ name (:class:`str`):
+ Required. The resource name of the tenant to be
+ retrieved.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.tenant.Tenant:
+ A Tenant resource represents a tenant
+ in the service. A tenant is a group or
+ entity that shares common access with
+ specific privileges for resources like
+ jobs. Customer may create multiple
+ tenants to provide data isolation for
+ different groups.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([name]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = tenant_service.GetTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.get_tenant,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def update_tenant(
+ self,
+ request: tenant_service.UpdateTenantRequest = None,
+ *,
+ tenant: gct_tenant.Tenant = None,
+ update_mask: field_mask.FieldMask = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_tenant.Tenant:
+ r"""Updates specified tenant.
+
+ Args:
+ request (:class:`~.tenant_service.UpdateTenantRequest`):
+ The request object. Request for updating a specified
+ tenant.
+ tenant (:class:`~.gct_tenant.Tenant`):
+ Required. The tenant resource to
+ replace the current resource in the
+ system.
+ This corresponds to the ``tenant`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`~.field_mask.FieldMask`):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateTenantRequest.update_mask]
+ is provided, only the specified fields in
+ [tenant][google.cloud.talent.v4.UpdateTenantRequest.tenant]
+ are updated. Otherwise all the fields are updated.
+
+ A field mask to specify the tenant fields to be updated.
+ Only top level fields of
+ [Tenant][google.cloud.talent.v4.Tenant] are supported.
+ This corresponds to the ``update_mask`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_tenant.Tenant:
+ A Tenant resource represents a tenant
+ in the service. A tenant is a group or
+ entity that shares common access with
+ specific privileges for resources like
+ jobs. Customer may create multiple
+ tenants to provide data isolation for
+ different groups.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([tenant, update_mask]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = tenant_service.UpdateTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if tenant is not None:
+ request.tenant = tenant
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.update_tenant,
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("tenant.name", request.tenant.name),)
+ ),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ async def delete_tenant(
+ self,
+ request: tenant_service.DeleteTenantRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> None:
+ r"""Deletes specified tenant.
+
+ Args:
+ request (:class:`~.tenant_service.DeleteTenantRequest`):
+ The request object. Request to delete a tenant.
+ name (:class:`str`):
+ Required. The resource name of the tenant to be deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([name]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = tenant_service.DeleteTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.delete_tenant,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ await rpc(
+ request, retry=retry, timeout=timeout, metadata=metadata,
+ )
+
+ async def list_tenants(
+ self,
+ request: tenant_service.ListTenantsRequest = None,
+ *,
+ parent: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> pagers.ListTenantsAsyncPager:
+ r"""Lists all tenants associated with the project.
+
+ Args:
+ request (:class:`~.tenant_service.ListTenantsRequest`):
+ The request object. List tenants for which the client
+ has ACL visibility.
+ parent (:class:`str`):
+ Required. Resource name of the project under which the
+ tenant is created.
+
+ The format is "projects/{project_id}", for example,
+ "projects/foo".
+ This corresponds to the ``parent`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.pagers.ListTenantsAsyncPager:
+ The List tenants response object.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ if request is not None and any([parent]):
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ request = tenant_service.ListTenantsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = gapic_v1.method_async.wrap_method(
+ self._client._transport.list_tenants,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=DEFAULT_CLIENT_INFO,
+ )
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListTenantsAsyncPager(
+ method=rpc, request=request, response=response, metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("TenantServiceAsyncClient",)
diff --git a/google/cloud/talent_v4/services/tenant_service/client.py b/google/cloud/talent_v4/services/tenant_service/client.py
new file mode 100644
index 00000000..09b14ba1
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/client.py
@@ -0,0 +1,697 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from distutils import util
+import os
+import re
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
+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 gapic_v1 # type: ignore
+from google.api_core import retry as retries # type: ignore
+from google.auth import 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
+from google.oauth2 import service_account # type: ignore
+
+from google.cloud.talent_v4.services.tenant_service import pagers
+from google.cloud.talent_v4.types import tenant
+from google.cloud.talent_v4.types import tenant as gct_tenant
+from google.cloud.talent_v4.types import tenant_service
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+
+from .transports.base import TenantServiceTransport, DEFAULT_CLIENT_INFO
+from .transports.grpc import TenantServiceGrpcTransport
+from .transports.grpc_asyncio import TenantServiceGrpcAsyncIOTransport
+
+
+class TenantServiceClientMeta(type):
+ """Metaclass for the TenantService client.
+
+ This provides class-level methods for building and retrieving
+ support objects (e.g. transport) without polluting the client instance
+ objects.
+ """
+
+ _transport_registry = OrderedDict() # type: Dict[str, Type[TenantServiceTransport]]
+ _transport_registry["grpc"] = TenantServiceGrpcTransport
+ _transport_registry["grpc_asyncio"] = TenantServiceGrpcAsyncIOTransport
+
+ def get_transport_class(cls, label: str = None,) -> Type[TenantServiceTransport]:
+ """Return an appropriate transport class.
+
+ Args:
+ label: The name of the desired transport. If none is
+ provided, then the first transport in the registry is used.
+
+ Returns:
+ The transport class to use.
+ """
+ # If a specific transport is requested, return that one.
+ if label:
+ return cls._transport_registry[label]
+
+ # No transport is requested; return the default (that is, the first one
+ # in the dictionary).
+ return next(iter(cls._transport_registry.values()))
+
+
+class TenantServiceClient(metaclass=TenantServiceClientMeta):
+ """A service that handles tenant management, including CRUD and
+ enumeration.
+ """
+
+ @staticmethod
+ def _get_default_mtls_endpoint(api_endpoint):
+ """Convert api endpoint to mTLS endpoint.
+ Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
+ "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
+ Args:
+ api_endpoint (Optional[str]): the api endpoint to convert.
+ Returns:
+ str: converted mTLS api endpoint.
+ """
+ if not api_endpoint:
+ return api_endpoint
+
+ mtls_endpoint_re = re.compile(
+ r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?"
+ )
+
+ m = mtls_endpoint_re.match(api_endpoint)
+ name, mtls, sandbox, googledomain = m.groups()
+ if mtls or not googledomain:
+ return api_endpoint
+
+ if sandbox:
+ return api_endpoint.replace(
+ "sandbox.googleapis.com", "mtls.sandbox.googleapis.com"
+ )
+
+ return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+
+ DEFAULT_ENDPOINT = "jobs.googleapis.com"
+ DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
+ DEFAULT_ENDPOINT
+ )
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ {@api.name}: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_file(filename)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
+ from_service_account_json = from_service_account_file
+
+ @staticmethod
+ def tenant_path(project: str, tenant: str,) -> str:
+ """Return a fully-qualified tenant string."""
+ return "projects/{project}/tenants/{tenant}".format(
+ project=project, tenant=tenant,
+ )
+
+ @staticmethod
+ def parse_tenant_path(path: str) -> Dict[str, str]:
+ """Parse a tenant path into its component segments."""
+ m = re.match(r"^projects/(?P.+?)/tenants/(?P.+?)$", path)
+ return m.groupdict() if m else {}
+
+ def __init__(
+ self,
+ *,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, TenantServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the tenant service client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Union[str, ~.TenantServiceTransport]): The
+ transport to use. If set to None, a transport is chosen
+ automatically.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
+ (1) The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
+ environment variable can also be used to override the endpoint:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+ if isinstance(client_options, dict):
+ client_options = client_options_lib.from_dict(client_options)
+ if client_options is None:
+ client_options = client_options_lib.ClientOptions()
+
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
+ if use_mtls_env == "never":
+ api_endpoint = self.DEFAULT_ENDPOINT
+ 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
+ )
+ else:
+ raise MutualTLSChannelError(
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
+ )
+
+ # Save or instantiate the transport.
+ # Ordinarily, we provide the transport, but allowing a custom transport
+ # instance provides an extensibility point for unusual situations.
+ if isinstance(transport, TenantServiceTransport):
+ # transport is a TenantServiceTransport instance.
+ if credentials or client_options.credentials_file:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its credentials directly."
+ )
+ if client_options.scopes:
+ raise ValueError(
+ "When providing a transport instance, "
+ "provide its scopes directly."
+ )
+ self._transport = transport
+ else:
+ Transport = type(self).get_transport_class(transport)
+ self._transport = Transport(
+ credentials=credentials,
+ credentials_file=client_options.credentials_file,
+ host=api_endpoint,
+ scopes=client_options.scopes,
+ ssl_channel_credentials=ssl_credentials,
+ quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
+ )
+
+ def create_tenant(
+ self,
+ request: tenant_service.CreateTenantRequest = None,
+ *,
+ parent: str = None,
+ tenant: gct_tenant.Tenant = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_tenant.Tenant:
+ r"""Creates a new tenant entity.
+
+ Args:
+ request (:class:`~.tenant_service.CreateTenantRequest`):
+ The request object. The Request of the CreateTenant
+ method.
+ parent (:class:`str`):
+ Required. Resource name of the project under which the
+ tenant is created.
+
+ The format is "projects/{project_id}", for example,
+ "projects/foo".
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ tenant (:class:`~.gct_tenant.Tenant`):
+ Required. The tenant to be created.
+ This corresponds to the ``tenant`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_tenant.Tenant:
+ A Tenant resource represents a tenant
+ in the service. A tenant is a group or
+ entity that shares common access with
+ specific privileges for resources like
+ jobs. Customer may create multiple
+ tenants to provide data isolation for
+ different groups.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent, tenant])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a tenant_service.CreateTenantRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, tenant_service.CreateTenantRequest):
+ request = tenant_service.CreateTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+ if tenant is not None:
+ request.tenant = tenant
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.create_tenant]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def get_tenant(
+ self,
+ request: tenant_service.GetTenantRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> tenant.Tenant:
+ r"""Retrieves specified tenant.
+
+ Args:
+ request (:class:`~.tenant_service.GetTenantRequest`):
+ The request object. Request for getting a tenant by
+ name.
+ name (:class:`str`):
+ Required. The resource name of the tenant to be
+ retrieved.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.tenant.Tenant:
+ A Tenant resource represents a tenant
+ in the service. A tenant is a group or
+ entity that shares common access with
+ specific privileges for resources like
+ jobs. Customer may create multiple
+ tenants to provide data isolation for
+ different groups.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([name])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a tenant_service.GetTenantRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, tenant_service.GetTenantRequest):
+ request = tenant_service.GetTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.get_tenant]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def update_tenant(
+ self,
+ request: tenant_service.UpdateTenantRequest = None,
+ *,
+ tenant: gct_tenant.Tenant = None,
+ update_mask: field_mask.FieldMask = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> gct_tenant.Tenant:
+ r"""Updates specified tenant.
+
+ Args:
+ request (:class:`~.tenant_service.UpdateTenantRequest`):
+ The request object. Request for updating a specified
+ tenant.
+ tenant (:class:`~.gct_tenant.Tenant`):
+ Required. The tenant resource to
+ replace the current resource in the
+ system.
+ This corresponds to the ``tenant`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`~.field_mask.FieldMask`):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateTenantRequest.update_mask]
+ is provided, only the specified fields in
+ [tenant][google.cloud.talent.v4.UpdateTenantRequest.tenant]
+ are updated. Otherwise all the fields are updated.
+
+ A field mask to specify the tenant fields to be updated.
+ Only top level fields of
+ [Tenant][google.cloud.talent.v4.Tenant] are supported.
+ This corresponds to the ``update_mask`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.gct_tenant.Tenant:
+ A Tenant resource represents a tenant
+ in the service. A tenant is a group or
+ entity that shares common access with
+ specific privileges for resources like
+ jobs. Customer may create multiple
+ tenants to provide data isolation for
+ different groups.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([tenant, update_mask])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a tenant_service.UpdateTenantRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, tenant_service.UpdateTenantRequest):
+ request = tenant_service.UpdateTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if tenant is not None:
+ request.tenant = tenant
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.update_tenant]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("tenant.name", request.tenant.name),)
+ ),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # Done; return the response.
+ return response
+
+ def delete_tenant(
+ self,
+ request: tenant_service.DeleteTenantRequest = None,
+ *,
+ name: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> None:
+ r"""Deletes specified tenant.
+
+ Args:
+ request (:class:`~.tenant_service.DeleteTenantRequest`):
+ The request object. Request to delete a tenant.
+ name (:class:`str`):
+ Required. The resource name of the tenant to be deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}", for
+ example, "projects/foo/tenants/bar".
+ 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([name])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a tenant_service.DeleteTenantRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, tenant_service.DeleteTenantRequest):
+ request = tenant_service.DeleteTenantRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_tenant]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Send the request.
+ rpc(
+ request, retry=retry, timeout=timeout, metadata=metadata,
+ )
+
+ def list_tenants(
+ self,
+ request: tenant_service.ListTenantsRequest = None,
+ *,
+ parent: str = None,
+ retry: retries.Retry = gapic_v1.method.DEFAULT,
+ timeout: float = None,
+ metadata: Sequence[Tuple[str, str]] = (),
+ ) -> pagers.ListTenantsPager:
+ r"""Lists all tenants associated with the project.
+
+ Args:
+ request (:class:`~.tenant_service.ListTenantsRequest`):
+ The request object. List tenants for which the client
+ has ACL visibility.
+ parent (:class:`str`):
+ Required. Resource name of the project under which the
+ tenant is created.
+
+ The format is "projects/{project_id}", for example,
+ "projects/foo".
+ This corresponds to the ``parent`` 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.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+
+ Returns:
+ ~.pagers.ListTenantsPager:
+ The List tenants response object.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # Sanity check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ has_flattened_params = any([parent])
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # Minor optimization to avoid making a copy if the user passes
+ # in a tenant_service.ListTenantsRequest.
+ # There's no risk of modifying the input as we've already verified
+ # there are no flattened fields.
+ if not isinstance(request, tenant_service.ListTenantsRequest):
+ request = tenant_service.ListTenantsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.list_tenants]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Send the request.
+ response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListTenantsPager(
+ method=rpc, request=request, response=response, metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+__all__ = ("TenantServiceClient",)
diff --git a/google/cloud/talent_v4/services/tenant_service/pagers.py b/google/cloud/talent_v4/services/tenant_service/pagers.py
new file mode 100644
index 00000000..d671fdb7
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/pagers.py
@@ -0,0 +1,149 @@
+# -*- 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.
+#
+
+from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple
+
+from google.cloud.talent_v4.types import tenant
+from google.cloud.talent_v4.types import tenant_service
+
+
+class ListTenantsPager:
+ """A pager for iterating through ``list_tenants`` requests.
+
+ This class thinly wraps an initial
+ :class:`~.tenant_service.ListTenantsResponse` object, and
+ provides an ``__iter__`` method to iterate through its
+ ``tenants`` field.
+
+ If there are more pages, the ``__iter__`` method will make additional
+ ``ListTenants`` requests and continue to iterate
+ through the ``tenants`` field on the
+ corresponding responses.
+
+ All the usual :class:`~.tenant_service.ListTenantsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., tenant_service.ListTenantsResponse],
+ request: tenant_service.ListTenantsRequest,
+ response: tenant_service.ListTenantsResponse,
+ *,
+ metadata: Sequence[Tuple[str, str]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (:class:`~.tenant_service.ListTenantsRequest`):
+ The initial request object.
+ response (:class:`~.tenant_service.ListTenantsResponse`):
+ The initial response object.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ self._method = method
+ self._request = tenant_service.ListTenantsRequest(request)
+ self._response = response
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ def pages(self) -> Iterable[tenant_service.ListTenantsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = self._method(self._request, metadata=self._metadata)
+ yield self._response
+
+ def __iter__(self) -> Iterable[tenant.Tenant]:
+ for page in self.pages:
+ yield from page.tenants
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListTenantsAsyncPager:
+ """A pager for iterating through ``list_tenants`` requests.
+
+ This class thinly wraps an initial
+ :class:`~.tenant_service.ListTenantsResponse` object, and
+ provides an ``__aiter__`` method to iterate through its
+ ``tenants`` field.
+
+ If there are more pages, the ``__aiter__`` method will make additional
+ ``ListTenants`` requests and continue to iterate
+ through the ``tenants`` field on the
+ corresponding responses.
+
+ All the usual :class:`~.tenant_service.ListTenantsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., Awaitable[tenant_service.ListTenantsResponse]],
+ request: tenant_service.ListTenantsRequest,
+ response: tenant_service.ListTenantsResponse,
+ *,
+ metadata: Sequence[Tuple[str, str]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (:class:`~.tenant_service.ListTenantsRequest`):
+ The initial request object.
+ response (:class:`~.tenant_service.ListTenantsResponse`):
+ The initial response object.
+ metadata (Sequence[Tuple[str, str]]): Strings which should be
+ sent along with the request as metadata.
+ """
+ self._method = method
+ self._request = tenant_service.ListTenantsRequest(request)
+ self._response = response
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ async def pages(self) -> AsyncIterable[tenant_service.ListTenantsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = await self._method(self._request, metadata=self._metadata)
+ yield self._response
+
+ def __aiter__(self) -> AsyncIterable[tenant.Tenant]:
+ async def async_generator():
+ async for page in self.pages:
+ for response in page.tenants:
+ yield response
+
+ return async_generator()
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
diff --git a/google/cloud/talent_v4/services/tenant_service/transports/__init__.py b/google/cloud/talent_v4/services/tenant_service/transports/__init__.py
new file mode 100644
index 00000000..49abfaa7
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/transports/__init__.py
@@ -0,0 +1,36 @@
+# -*- 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.
+#
+
+from collections import OrderedDict
+from typing import Dict, Type
+
+from .base import TenantServiceTransport
+from .grpc import TenantServiceGrpcTransport
+from .grpc_asyncio import TenantServiceGrpcAsyncIOTransport
+
+
+# Compile a registry of transports.
+_transport_registry = OrderedDict() # type: Dict[str, Type[TenantServiceTransport]]
+_transport_registry["grpc"] = TenantServiceGrpcTransport
+_transport_registry["grpc_asyncio"] = TenantServiceGrpcAsyncIOTransport
+
+
+__all__ = (
+ "TenantServiceTransport",
+ "TenantServiceGrpcTransport",
+ "TenantServiceGrpcAsyncIOTransport",
+)
diff --git a/google/cloud/talent_v4/services/tenant_service/transports/base.py b/google/cloud/talent_v4/services/tenant_service/transports/base.py
new file mode 100644
index 00000000..a545754c
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/transports/base.py
@@ -0,0 +1,209 @@
+# -*- 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.
+#
+
+import abc
+import typing
+import pkg_resources
+
+from google import auth # type: ignore
+from google.api_core import 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.cloud.talent_v4.types import tenant
+from google.cloud.talent_v4.types import tenant as gct_tenant
+from google.cloud.talent_v4.types import tenant_service
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+
+try:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
+ )
+except pkg_resources.DistributionNotFound:
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+
+
+class TenantServiceTransport(abc.ABC):
+ """Abstract transport class for TenantService."""
+
+ AUTH_SCOPES = (
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.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,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ **kwargs,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ 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.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+ """
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ # If no credentials are provided, then determine the appropriate
+ # defaults.
+ if credentials and credentials_file:
+ raise exceptions.DuplicateCredentialArgs(
+ "'credentials_file' and 'credentials' are mutually exclusive"
+ )
+
+ if credentials_file is not None:
+ credentials, _ = auth.load_credentials_from_file(
+ credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ elif credentials is None:
+ credentials, _ = auth.default(
+ scopes=scopes, quota_project_id=quota_project_id
+ )
+
+ # Save the credentials.
+ self._credentials = credentials
+
+ # Lifted into its own function so it can be stubbed out during tests.
+ self._prep_wrapped_messages(client_info)
+
+ def _prep_wrapped_messages(self, client_info):
+ # Precompute the wrapped methods.
+ self._wrapped_methods = {
+ self.create_tenant: gapic_v1.method.wrap_method(
+ self.create_tenant, default_timeout=30.0, client_info=client_info,
+ ),
+ self.get_tenant: gapic_v1.method.wrap_method(
+ self.get_tenant,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ self.update_tenant: gapic_v1.method.wrap_method(
+ self.update_tenant, default_timeout=30.0, client_info=client_info,
+ ),
+ self.delete_tenant: gapic_v1.method.wrap_method(
+ self.delete_tenant,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ self.list_tenants: gapic_v1.method.wrap_method(
+ self.list_tenants,
+ default_retry=retries.Retry(
+ initial=0.1,
+ maximum=60.0,
+ multiplier=1.3,
+ predicate=retries.if_exception_type(
+ exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ ),
+ ),
+ default_timeout=30.0,
+ client_info=client_info,
+ ),
+ }
+
+ @property
+ def create_tenant(
+ self,
+ ) -> typing.Callable[
+ [tenant_service.CreateTenantRequest],
+ typing.Union[gct_tenant.Tenant, typing.Awaitable[gct_tenant.Tenant]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def get_tenant(
+ self,
+ ) -> typing.Callable[
+ [tenant_service.GetTenantRequest],
+ typing.Union[tenant.Tenant, typing.Awaitable[tenant.Tenant]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def update_tenant(
+ self,
+ ) -> typing.Callable[
+ [tenant_service.UpdateTenantRequest],
+ typing.Union[gct_tenant.Tenant, typing.Awaitable[gct_tenant.Tenant]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def delete_tenant(
+ self,
+ ) -> typing.Callable[
+ [tenant_service.DeleteTenantRequest],
+ typing.Union[empty.Empty, typing.Awaitable[empty.Empty]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def list_tenants(
+ self,
+ ) -> typing.Callable[
+ [tenant_service.ListTenantsRequest],
+ typing.Union[
+ tenant_service.ListTenantsResponse,
+ typing.Awaitable[tenant_service.ListTenantsResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+
+__all__ = ("TenantServiceTransport",)
diff --git a/google/cloud/talent_v4/services/tenant_service/transports/grpc.py b/google/cloud/talent_v4/services/tenant_service/transports/grpc.py
new file mode 100644
index 00000000..acdf8307
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/transports/grpc.py
@@ -0,0 +1,367 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+
+from google.cloud.talent_v4.types import tenant
+from google.cloud.talent_v4.types import tenant as gct_tenant
+from google.cloud.talent_v4.types import tenant_service
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+from .base import TenantServiceTransport, DEFAULT_CLIENT_INFO
+
+
+class TenantServiceGrpcTransport(TenantServiceTransport):
+ """gRPC backend transport for TenantService.
+
+ A service that handles tenant management, including CRUD and
+ enumeration.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _stubs: Dict[str, Callable]
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Sequence[str] = None,
+ channel: grpc.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ channel (Optional[grpc.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ self._stubs = {} # type: Dict[str, Callable]
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: str = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> grpc.Channel:
+ """Create and return a gRPC channel object.
+ Args:
+ address (Optionsl[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ 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.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ grpc.Channel: A gRPC channel object.
+
+ Raises:
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ @property
+ def grpc_channel(self) -> grpc.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def create_tenant(
+ self,
+ ) -> Callable[[tenant_service.CreateTenantRequest], gct_tenant.Tenant]:
+ r"""Return a callable for the create tenant method over gRPC.
+
+ Creates a new tenant entity.
+
+ Returns:
+ Callable[[~.CreateTenantRequest],
+ ~.Tenant]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_tenant" not in self._stubs:
+ self._stubs["create_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/CreateTenant",
+ request_serializer=tenant_service.CreateTenantRequest.serialize,
+ response_deserializer=gct_tenant.Tenant.deserialize,
+ )
+ return self._stubs["create_tenant"]
+
+ @property
+ def get_tenant(self) -> Callable[[tenant_service.GetTenantRequest], tenant.Tenant]:
+ r"""Return a callable for the get tenant method over gRPC.
+
+ Retrieves specified tenant.
+
+ Returns:
+ Callable[[~.GetTenantRequest],
+ ~.Tenant]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_tenant" not in self._stubs:
+ self._stubs["get_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/GetTenant",
+ request_serializer=tenant_service.GetTenantRequest.serialize,
+ response_deserializer=tenant.Tenant.deserialize,
+ )
+ return self._stubs["get_tenant"]
+
+ @property
+ def update_tenant(
+ self,
+ ) -> Callable[[tenant_service.UpdateTenantRequest], gct_tenant.Tenant]:
+ r"""Return a callable for the update tenant method over gRPC.
+
+ Updates specified tenant.
+
+ Returns:
+ Callable[[~.UpdateTenantRequest],
+ ~.Tenant]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_tenant" not in self._stubs:
+ self._stubs["update_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/UpdateTenant",
+ request_serializer=tenant_service.UpdateTenantRequest.serialize,
+ response_deserializer=gct_tenant.Tenant.deserialize,
+ )
+ return self._stubs["update_tenant"]
+
+ @property
+ def delete_tenant(
+ self,
+ ) -> Callable[[tenant_service.DeleteTenantRequest], empty.Empty]:
+ r"""Return a callable for the delete tenant method over gRPC.
+
+ Deletes specified tenant.
+
+ Returns:
+ Callable[[~.DeleteTenantRequest],
+ ~.Empty]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_tenant" not in self._stubs:
+ self._stubs["delete_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/DeleteTenant",
+ request_serializer=tenant_service.DeleteTenantRequest.serialize,
+ response_deserializer=empty.Empty.FromString,
+ )
+ return self._stubs["delete_tenant"]
+
+ @property
+ def list_tenants(
+ self,
+ ) -> Callable[
+ [tenant_service.ListTenantsRequest], tenant_service.ListTenantsResponse
+ ]:
+ r"""Return a callable for the list tenants method over gRPC.
+
+ Lists all tenants associated with the project.
+
+ Returns:
+ Callable[[~.ListTenantsRequest],
+ ~.ListTenantsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_tenants" not in self._stubs:
+ self._stubs["list_tenants"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/ListTenants",
+ request_serializer=tenant_service.ListTenantsRequest.serialize,
+ response_deserializer=tenant_service.ListTenantsResponse.deserialize,
+ )
+ return self._stubs["list_tenants"]
+
+
+__all__ = ("TenantServiceGrpcTransport",)
diff --git a/google/cloud/talent_v4/services/tenant_service/transports/grpc_asyncio.py b/google/cloud/talent_v4/services/tenant_service/transports/grpc_asyncio.py
new file mode 100644
index 00000000..9624c5b7
--- /dev/null
+++ b/google/cloud/talent_v4/services/tenant_service/transports/grpc_asyncio.py
@@ -0,0 +1,370 @@
+# -*- 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.
+#
+
+import warnings
+from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+
+from google.api_core import gapic_v1 # type: ignore
+from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
+from google.auth import credentials # type: ignore
+from google.auth.transport.grpc import SslCredentials # type: ignore
+
+import grpc # type: ignore
+from grpc.experimental import aio # type: ignore
+
+from google.cloud.talent_v4.types import tenant
+from google.cloud.talent_v4.types import tenant as gct_tenant
+from google.cloud.talent_v4.types import tenant_service
+from google.protobuf import empty_pb2 as empty # type: ignore
+
+from .base import TenantServiceTransport, DEFAULT_CLIENT_INFO
+from .grpc import TenantServiceGrpcTransport
+
+
+class TenantServiceGrpcAsyncIOTransport(TenantServiceTransport):
+ """gRPC AsyncIO backend transport for TenantService.
+
+ A service that handles tenant management, including CRUD and
+ enumeration.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends protocol buffers over the wire using gRPC (which is built on
+ top of HTTP/2); the ``grpcio`` package must be installed.
+ """
+
+ _grpc_channel: aio.Channel
+ _stubs: Dict[str, Callable] = {}
+
+ @classmethod
+ def create_channel(
+ cls,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ quota_project_id: Optional[str] = None,
+ **kwargs,
+ ) -> aio.Channel:
+ """Create and return a gRPC AsyncIO channel object.
+ Args:
+ address (Optional[str]): The host for the channel to use.
+ credentials (Optional[~.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify this application to the service. If
+ none are specified, the client will attempt to ascertain
+ the credentials from the environment.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ kwargs (Optional[dict]): Keyword arguments, which are passed to the
+ channel creation.
+ Returns:
+ aio.Channel: A gRPC AsyncIO channel object.
+ """
+ scopes = scopes or cls.AUTH_SCOPES
+ return grpc_helpers_async.create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ **kwargs,
+ )
+
+ def __init__(
+ self,
+ *,
+ host: str = "jobs.googleapis.com",
+ credentials: credentials.Credentials = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: aio.Channel = None,
+ api_mtls_endpoint: str = None,
+ client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ 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
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided.
+ scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
+ service. These are only used when credentials are not specified and
+ are passed to :func:`google.auth.default`.
+ channel (Optional[aio.Channel]): A ``Channel`` instance through
+ which to make calls.
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
+ a mutual TLS channel with client SSL credentials from
+ ``client_cert_source`` or applicatin default SSL credentials.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
+ and ``credentials_file`` are passed.
+ """
+ if channel:
+ # Sanity check: Ensure that channel and credentials are not both
+ # provided.
+ credentials = False
+
+ # If a channel was explicitly provided, set it.
+ self._grpc_channel = channel
+ elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
+ host = (
+ api_mtls_endpoint
+ if ":" in api_mtls_endpoint
+ else api_mtls_endpoint + ":443"
+ )
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ ssl_credentials = SslCredentials().ssl_credentials
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
+
+ # Run the base constructor.
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
+
+ self._stubs = {}
+
+ @property
+ def grpc_channel(self) -> aio.Channel:
+ """Create the channel designed to connect to this service.
+
+ This property caches on the instance; repeated calls return
+ the same channel.
+ """
+ # Return the channel from cache.
+ return self._grpc_channel
+
+ @property
+ def create_tenant(
+ self,
+ ) -> Callable[[tenant_service.CreateTenantRequest], Awaitable[gct_tenant.Tenant]]:
+ r"""Return a callable for the create tenant method over gRPC.
+
+ Creates a new tenant entity.
+
+ Returns:
+ Callable[[~.CreateTenantRequest],
+ Awaitable[~.Tenant]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_tenant" not in self._stubs:
+ self._stubs["create_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/CreateTenant",
+ request_serializer=tenant_service.CreateTenantRequest.serialize,
+ response_deserializer=gct_tenant.Tenant.deserialize,
+ )
+ return self._stubs["create_tenant"]
+
+ @property
+ def get_tenant(
+ self,
+ ) -> Callable[[tenant_service.GetTenantRequest], Awaitable[tenant.Tenant]]:
+ r"""Return a callable for the get tenant method over gRPC.
+
+ Retrieves specified tenant.
+
+ Returns:
+ Callable[[~.GetTenantRequest],
+ Awaitable[~.Tenant]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_tenant" not in self._stubs:
+ self._stubs["get_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/GetTenant",
+ request_serializer=tenant_service.GetTenantRequest.serialize,
+ response_deserializer=tenant.Tenant.deserialize,
+ )
+ return self._stubs["get_tenant"]
+
+ @property
+ def update_tenant(
+ self,
+ ) -> Callable[[tenant_service.UpdateTenantRequest], Awaitable[gct_tenant.Tenant]]:
+ r"""Return a callable for the update tenant method over gRPC.
+
+ Updates specified tenant.
+
+ Returns:
+ Callable[[~.UpdateTenantRequest],
+ Awaitable[~.Tenant]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_tenant" not in self._stubs:
+ self._stubs["update_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/UpdateTenant",
+ request_serializer=tenant_service.UpdateTenantRequest.serialize,
+ response_deserializer=gct_tenant.Tenant.deserialize,
+ )
+ return self._stubs["update_tenant"]
+
+ @property
+ def delete_tenant(
+ self,
+ ) -> Callable[[tenant_service.DeleteTenantRequest], Awaitable[empty.Empty]]:
+ r"""Return a callable for the delete tenant method over gRPC.
+
+ Deletes specified tenant.
+
+ Returns:
+ Callable[[~.DeleteTenantRequest],
+ Awaitable[~.Empty]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_tenant" not in self._stubs:
+ self._stubs["delete_tenant"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/DeleteTenant",
+ request_serializer=tenant_service.DeleteTenantRequest.serialize,
+ response_deserializer=empty.Empty.FromString,
+ )
+ return self._stubs["delete_tenant"]
+
+ @property
+ def list_tenants(
+ self,
+ ) -> Callable[
+ [tenant_service.ListTenantsRequest],
+ Awaitable[tenant_service.ListTenantsResponse],
+ ]:
+ r"""Return a callable for the list tenants method over gRPC.
+
+ Lists all tenants associated with the project.
+
+ Returns:
+ Callable[[~.ListTenantsRequest],
+ Awaitable[~.ListTenantsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_tenants" not in self._stubs:
+ self._stubs["list_tenants"] = self.grpc_channel.unary_unary(
+ "/google.cloud.talent.v4.TenantService/ListTenants",
+ request_serializer=tenant_service.ListTenantsRequest.serialize,
+ response_deserializer=tenant_service.ListTenantsResponse.deserialize,
+ )
+ return self._stubs["list_tenants"]
+
+
+__all__ = ("TenantServiceGrpcAsyncIOTransport",)
diff --git a/google/cloud/talent_v4/types/__init__.py b/google/cloud/talent_v4/types/__init__.py
new file mode 100644
index 00000000..7e2f5b87
--- /dev/null
+++ b/google/cloud/talent_v4/types/__init__.py
@@ -0,0 +1,137 @@
+# -*- 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.
+#
+
+from .common import (
+ TimestampRange,
+ Location,
+ RequestMetadata,
+ ResponseMetadata,
+ DeviceInfo,
+ CustomAttribute,
+ SpellingCorrection,
+ CompensationInfo,
+ BatchOperationMetadata,
+)
+from .company import Company
+from .company_service import (
+ CreateCompanyRequest,
+ GetCompanyRequest,
+ UpdateCompanyRequest,
+ DeleteCompanyRequest,
+ ListCompaniesRequest,
+ ListCompaniesResponse,
+)
+from .completion_service import (
+ CompleteQueryRequest,
+ CompleteQueryResponse,
+)
+from .event import (
+ ClientEvent,
+ JobEvent,
+)
+from .event_service import CreateClientEventRequest
+from .filters import (
+ JobQuery,
+ LocationFilter,
+ CompensationFilter,
+ CommuteFilter,
+)
+from .histogram import (
+ HistogramQuery,
+ HistogramQueryResult,
+)
+from .job import Job
+from .job_service import (
+ CreateJobRequest,
+ GetJobRequest,
+ UpdateJobRequest,
+ DeleteJobRequest,
+ ListJobsRequest,
+ ListJobsResponse,
+ SearchJobsRequest,
+ SearchJobsResponse,
+ BatchCreateJobsRequest,
+ BatchUpdateJobsRequest,
+ BatchDeleteJobsRequest,
+ JobResult,
+ BatchCreateJobsResponse,
+ BatchUpdateJobsResponse,
+ BatchDeleteJobsResponse,
+)
+from .tenant import Tenant
+from .tenant_service import (
+ CreateTenantRequest,
+ GetTenantRequest,
+ UpdateTenantRequest,
+ DeleteTenantRequest,
+ ListTenantsRequest,
+ ListTenantsResponse,
+)
+
+
+__all__ = (
+ "TimestampRange",
+ "Location",
+ "RequestMetadata",
+ "ResponseMetadata",
+ "DeviceInfo",
+ "CustomAttribute",
+ "SpellingCorrection",
+ "CompensationInfo",
+ "BatchOperationMetadata",
+ "Company",
+ "CreateCompanyRequest",
+ "GetCompanyRequest",
+ "UpdateCompanyRequest",
+ "DeleteCompanyRequest",
+ "ListCompaniesRequest",
+ "ListCompaniesResponse",
+ "CompleteQueryRequest",
+ "CompleteQueryResponse",
+ "ClientEvent",
+ "JobEvent",
+ "CreateClientEventRequest",
+ "JobQuery",
+ "LocationFilter",
+ "CompensationFilter",
+ "CommuteFilter",
+ "HistogramQuery",
+ "HistogramQueryResult",
+ "Job",
+ "CreateJobRequest",
+ "GetJobRequest",
+ "UpdateJobRequest",
+ "DeleteJobRequest",
+ "ListJobsRequest",
+ "ListJobsResponse",
+ "SearchJobsRequest",
+ "SearchJobsResponse",
+ "BatchCreateJobsRequest",
+ "BatchUpdateJobsRequest",
+ "BatchDeleteJobsRequest",
+ "JobResult",
+ "BatchCreateJobsResponse",
+ "BatchUpdateJobsResponse",
+ "BatchDeleteJobsResponse",
+ "Tenant",
+ "CreateTenantRequest",
+ "GetTenantRequest",
+ "UpdateTenantRequest",
+ "DeleteTenantRequest",
+ "ListTenantsRequest",
+ "ListTenantsResponse",
+)
diff --git a/google/cloud/talent_v4/types/common.py b/google/cloud/talent_v4/types/common.py
new file mode 100644
index 00000000..e4041fc4
--- /dev/null
+++ b/google/cloud/talent_v4/types/common.py
@@ -0,0 +1,746 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+from google.protobuf import wrappers_pb2 as wrappers # type: ignore
+from google.type import latlng_pb2 as latlng # type: ignore
+from google.type import money_pb2 as money # type: ignore
+from google.type import postal_address_pb2 as gt_postal_address # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4",
+ manifest={
+ "CompanySize",
+ "JobBenefit",
+ "DegreeType",
+ "EmploymentType",
+ "JobLevel",
+ "JobCategory",
+ "PostingRegion",
+ "Visibility",
+ "HtmlSanitization",
+ "CommuteMethod",
+ "TimestampRange",
+ "Location",
+ "RequestMetadata",
+ "ResponseMetadata",
+ "DeviceInfo",
+ "CustomAttribute",
+ "SpellingCorrection",
+ "CompensationInfo",
+ "BatchOperationMetadata",
+ },
+)
+
+
+class CompanySize(proto.Enum):
+ r"""An enum that represents the size of the company."""
+ COMPANY_SIZE_UNSPECIFIED = 0
+ MINI = 1
+ SMALL = 2
+ SMEDIUM = 3
+ MEDIUM = 4
+ BIG = 5
+ BIGGER = 6
+ GIANT = 7
+
+
+class JobBenefit(proto.Enum):
+ r"""An enum that represents employee benefits included with the
+ job.
+ """
+ JOB_BENEFIT_UNSPECIFIED = 0
+ CHILD_CARE = 1
+ DENTAL = 2
+ DOMESTIC_PARTNER = 3
+ FLEXIBLE_HOURS = 4
+ MEDICAL = 5
+ LIFE_INSURANCE = 6
+ PARENTAL_LEAVE = 7
+ RETIREMENT_PLAN = 8
+ SICK_DAYS = 9
+ VACATION = 10
+ VISION = 11
+
+
+class DegreeType(proto.Enum):
+ r"""Educational degree level defined in International Standard
+ Classification of Education (ISCED).
+ """
+ DEGREE_TYPE_UNSPECIFIED = 0
+ PRIMARY_EDUCATION = 1
+ LOWER_SECONDARY_EDUCATION = 2
+ UPPER_SECONDARY_EDUCATION = 3
+ ADULT_REMEDIAL_EDUCATION = 4
+ ASSOCIATES_OR_EQUIVALENT = 5
+ BACHELORS_OR_EQUIVALENT = 6
+ MASTERS_OR_EQUIVALENT = 7
+ DOCTORAL_OR_EQUIVALENT = 8
+
+
+class EmploymentType(proto.Enum):
+ r"""An enum that represents the employment type of a job."""
+ EMPLOYMENT_TYPE_UNSPECIFIED = 0
+ FULL_TIME = 1
+ PART_TIME = 2
+ CONTRACTOR = 3
+ CONTRACT_TO_HIRE = 4
+ TEMPORARY = 5
+ INTERN = 6
+ VOLUNTEER = 7
+ PER_DIEM = 8
+ FLY_IN_FLY_OUT = 9
+ OTHER_EMPLOYMENT_TYPE = 10
+
+
+class JobLevel(proto.Enum):
+ r"""An enum that represents the required experience level
+ required for the job.
+ """
+ JOB_LEVEL_UNSPECIFIED = 0
+ ENTRY_LEVEL = 1
+ EXPERIENCED = 2
+ MANAGER = 3
+ DIRECTOR = 4
+ EXECUTIVE = 5
+
+
+class JobCategory(proto.Enum):
+ r"""An enum that represents the categorization or primary focus
+ of specific role. This value is different than the "industry"
+ associated with a role, which is related to the categorization
+ of the company listing the job.
+ """
+ JOB_CATEGORY_UNSPECIFIED = 0
+ ACCOUNTING_AND_FINANCE = 1
+ ADMINISTRATIVE_AND_OFFICE = 2
+ ADVERTISING_AND_MARKETING = 3
+ ANIMAL_CARE = 4
+ ART_FASHION_AND_DESIGN = 5
+ BUSINESS_OPERATIONS = 6
+ CLEANING_AND_FACILITIES = 7
+ COMPUTER_AND_IT = 8
+ CONSTRUCTION = 9
+ CUSTOMER_SERVICE = 10
+ EDUCATION = 11
+ ENTERTAINMENT_AND_TRAVEL = 12
+ FARMING_AND_OUTDOORS = 13
+ HEALTHCARE = 14
+ HUMAN_RESOURCES = 15
+ INSTALLATION_MAINTENANCE_AND_REPAIR = 16
+ LEGAL = 17
+ MANAGEMENT = 18
+ MANUFACTURING_AND_WAREHOUSE = 19
+ MEDIA_COMMUNICATIONS_AND_WRITING = 20
+ OIL_GAS_AND_MINING = 21
+ PERSONAL_CARE_AND_SERVICES = 22
+ PROTECTIVE_SERVICES = 23
+ REAL_ESTATE = 24
+ RESTAURANT_AND_HOSPITALITY = 25
+ SALES_AND_RETAIL = 26
+ SCIENCE_AND_ENGINEERING = 27
+ SOCIAL_SERVICES_AND_NON_PROFIT = 28
+ SPORTS_FITNESS_AND_RECREATION = 29
+ TRANSPORTATION_AND_LOGISTICS = 30
+
+
+class PostingRegion(proto.Enum):
+ r"""An enum that represents the job posting region. In most
+ cases, job postings don't need to specify a region. If a region
+ is given, jobs are eligible for searches in the specified
+ region.
+ """
+ POSTING_REGION_UNSPECIFIED = 0
+ ADMINISTRATIVE_AREA = 1
+ NATION = 2
+ TELECOMMUTE = 3
+
+
+class Visibility(proto.Enum):
+ r"""Deprecated. All resources are only visible to the owner.
+ An enum that represents who has view access to the resource.
+ """
+ VISIBILITY_UNSPECIFIED = 0
+ ACCOUNT_ONLY = 1
+ SHARED_WITH_GOOGLE = 2
+ SHARED_WITH_PUBLIC = 3
+
+
+class HtmlSanitization(proto.Enum):
+ r"""Option for HTML content sanitization on user input fields,
+ for example, job description. By setting this option, user can
+ determine whether and how sanitization is performed on these
+ fields.
+ """
+ HTML_SANITIZATION_UNSPECIFIED = 0
+ HTML_SANITIZATION_DISABLED = 1
+ SIMPLE_FORMATTING_ONLY = 2
+
+
+class CommuteMethod(proto.Enum):
+ r"""Method for commute."""
+ COMMUTE_METHOD_UNSPECIFIED = 0
+ DRIVING = 1
+ TRANSIT = 2
+ WALKING = 3
+ CYCLING = 4
+
+
+class TimestampRange(proto.Message):
+ r"""Message representing a period of time between two timestamps.
+
+ Attributes:
+ start_time (~.timestamp.Timestamp):
+ Begin of the period (inclusive).
+ end_time (~.timestamp.Timestamp):
+ End of the period (exclusive).
+ """
+
+ start_time = proto.Field(proto.MESSAGE, number=1, message=timestamp.Timestamp,)
+
+ end_time = proto.Field(proto.MESSAGE, number=2, message=timestamp.Timestamp,)
+
+
+class Location(proto.Message):
+ r"""A resource that represents a location with full geographic
+ information.
+
+ Attributes:
+ location_type (~.common.Location.LocationType):
+ The type of a location, which corresponds to the address
+ lines field of
+ [google.type.PostalAddress][google.type.PostalAddress]. For
+ example, "Downtown, Atlanta, GA, USA" has a type of
+ [LocationType.NEIGHBORHOOD][google.cloud.talent.v4.Location.LocationType.NEIGHBORHOOD],
+ and "Kansas City, KS, USA" has a type of
+ [LocationType.LOCALITY][google.cloud.talent.v4.Location.LocationType.LOCALITY].
+ postal_address (~.gt_postal_address.PostalAddress):
+ Postal address of the location that includes
+ human readable information, such as postal
+ delivery and payments addresses. Given a postal
+ address, a postal service can deliver items to a
+ premises, P.O. Box, or other delivery location.
+ lat_lng (~.latlng.LatLng):
+ An object representing a latitude/longitude
+ pair.
+ radius_miles (float):
+ Radius in miles of the job location. This value is derived
+ from the location bounding box in which a circle with the
+ specified radius centered from
+ [google.type.LatLng][google.type.LatLng] covers the area
+ associated with the job location. For example, currently,
+ "Mountain View, CA, USA" has a radius of 6.17 miles.
+ """
+
+ class LocationType(proto.Enum):
+ r"""An enum which represents the type of a location."""
+ LOCATION_TYPE_UNSPECIFIED = 0
+ COUNTRY = 1
+ ADMINISTRATIVE_AREA = 2
+ SUB_ADMINISTRATIVE_AREA = 3
+ LOCALITY = 4
+ POSTAL_CODE = 5
+ SUB_LOCALITY = 6
+ SUB_LOCALITY_1 = 7
+ SUB_LOCALITY_2 = 8
+ NEIGHBORHOOD = 9
+ STREET_ADDRESS = 10
+
+ location_type = proto.Field(proto.ENUM, number=1, enum=LocationType,)
+
+ postal_address = proto.Field(
+ proto.MESSAGE, number=2, message=gt_postal_address.PostalAddress,
+ )
+
+ lat_lng = proto.Field(proto.MESSAGE, number=3, message=latlng.LatLng,)
+
+ radius_miles = proto.Field(proto.DOUBLE, number=4)
+
+
+class RequestMetadata(proto.Message):
+ r"""Meta information related to the job searcher or entity
+ conducting the job search. This information is used to improve
+ the performance of the service.
+
+ Attributes:
+ domain (str):
+ Required if
+ [allow_missing_ids][google.cloud.talent.v4.RequestMetadata.allow_missing_ids]
+ is unset or ``false``.
+
+ The client-defined scope or source of the service call,
+ which typically is the domain on which the service has been
+ implemented and is currently being run.
+
+ For example, if the service is being run by client Foo,
+ Inc., on job board www.foo.com and career site www.bar.com,
+ then this field is set to "foo.com" for use on the job
+ board, and "bar.com" for use on the career site.
+
+ Note that any improvements to the model for a particular
+ tenant site rely on this field being set correctly to a
+ unique domain.
+
+ The maximum number of allowed characters is 255.
+ session_id (str):
+ Required if
+ [allow_missing_ids][google.cloud.talent.v4.RequestMetadata.allow_missing_ids]
+ is unset or ``false``.
+
+ A unique session identification string. A session is defined
+ as the duration of an end user's interaction with the
+ service over a certain period. Obfuscate this field for
+ privacy concerns before providing it to the service.
+
+ Note that any improvements to the model for a particular
+ tenant site rely on this field being set correctly to a
+ unique session ID.
+
+ The maximum number of allowed characters is 255.
+ user_id (str):
+ Required if
+ [allow_missing_ids][google.cloud.talent.v4.RequestMetadata.allow_missing_ids]
+ is unset or ``false``.
+
+ A unique user identification string, as determined by the
+ client. To have the strongest positive impact on search
+ quality make sure the client-level is unique. Obfuscate this
+ field for privacy concerns before providing it to the
+ service.
+
+ Note that any improvements to the model for a particular
+ tenant site rely on this field being set correctly to a
+ unique user ID.
+
+ The maximum number of allowed characters is 255.
+ allow_missing_ids (bool):
+ Only set when any of
+ [domain][google.cloud.talent.v4.RequestMetadata.domain],
+ [session_id][google.cloud.talent.v4.RequestMetadata.session_id]
+ and
+ [user_id][google.cloud.talent.v4.RequestMetadata.user_id]
+ isn't available for some reason. It is highly recommended
+ not to set this field and provide accurate
+ [domain][google.cloud.talent.v4.RequestMetadata.domain],
+ [session_id][google.cloud.talent.v4.RequestMetadata.session_id]
+ and
+ [user_id][google.cloud.talent.v4.RequestMetadata.user_id]
+ for the best service experience.
+ device_info (~.common.DeviceInfo):
+ The type of device used by the job seeker at
+ the time of the call to the service.
+ """
+
+ domain = proto.Field(proto.STRING, number=1)
+
+ session_id = proto.Field(proto.STRING, number=2)
+
+ user_id = proto.Field(proto.STRING, number=3)
+
+ allow_missing_ids = proto.Field(proto.BOOL, number=4)
+
+ device_info = proto.Field(proto.MESSAGE, number=5, message="DeviceInfo",)
+
+
+class ResponseMetadata(proto.Message):
+ r"""Additional information returned to client, such as debugging
+ information.
+
+ Attributes:
+ request_id (str):
+ A unique id associated with this call.
+ This id is logged for tracking purposes.
+ """
+
+ request_id = proto.Field(proto.STRING, number=1)
+
+
+class DeviceInfo(proto.Message):
+ r"""Device information collected from the job seeker, candidate,
+ or other entity conducting the job search. Providing this
+ information improves the quality of the search results across
+ devices.
+
+ Attributes:
+ device_type (~.common.DeviceInfo.DeviceType):
+ Type of the device.
+ id (str):
+ A device-specific ID. The ID must be a unique
+ identifier that distinguishes the device from
+ other devices.
+ """
+
+ class DeviceType(proto.Enum):
+ r"""An enumeration describing an API access portal and exposure
+ mechanism.
+ """
+ DEVICE_TYPE_UNSPECIFIED = 0
+ WEB = 1
+ MOBILE_WEB = 2
+ ANDROID = 3
+ IOS = 4
+ BOT = 5
+ OTHER = 6
+
+ device_type = proto.Field(proto.ENUM, number=1, enum=DeviceType,)
+
+ id = proto.Field(proto.STRING, number=2)
+
+
+class CustomAttribute(proto.Message):
+ r"""Custom attribute values that are either filterable or non-
+ ilterable.
+
+ Attributes:
+ string_values (Sequence[str]):
+ Exactly one of
+ [string_values][google.cloud.talent.v4.CustomAttribute.string_values]
+ or
+ [long_values][google.cloud.talent.v4.CustomAttribute.long_values]
+ must be specified.
+
+ This field is used to perform a string match
+ (``CASE_SENSITIVE_MATCH`` or ``CASE_INSENSITIVE_MATCH``)
+ search. For filterable ``string_value``\ s, a maximum total
+ number of 200 values is allowed, with each ``string_value``
+ has a byte size of no more than 500B. For unfilterable
+ ``string_values``, the maximum total byte size of
+ unfilterable ``string_values`` is 50KB.
+
+ Empty string isn't allowed.
+ long_values (Sequence[int]):
+ Exactly one of
+ [string_values][google.cloud.talent.v4.CustomAttribute.string_values]
+ or
+ [long_values][google.cloud.talent.v4.CustomAttribute.long_values]
+ must be specified.
+
+ This field is used to perform number range search. (``EQ``,
+ ``GT``, ``GE``, ``LE``, ``LT``) over filterable
+ ``long_value``.
+
+ Currently at most 1
+ [long_values][google.cloud.talent.v4.CustomAttribute.long_values]
+ is supported.
+ filterable (bool):
+ If the ``filterable`` flag is true, the custom field values
+ may be used for custom attribute filters
+ [JobQuery.custom_attribute_filter][google.cloud.talent.v4.JobQuery.custom_attribute_filter].
+ If false, these values may not be used for custom attribute
+ filters.
+
+ Default is false.
+ keyword_searchable (bool):
+ If the ``keyword_searchable`` flag is true, the keywords in
+ custom fields are searchable by keyword match. If false, the
+ values are not searchable by keyword match.
+
+ Default is false.
+ """
+
+ string_values = proto.RepeatedField(proto.STRING, number=1)
+
+ long_values = proto.RepeatedField(proto.INT64, number=2)
+
+ filterable = proto.Field(proto.BOOL, number=3)
+
+ keyword_searchable = proto.Field(proto.BOOL, number=4)
+
+
+class SpellingCorrection(proto.Message):
+ r"""Spell check result.
+
+ Attributes:
+ corrected (bool):
+ Indicates if the query was corrected by the
+ spell checker.
+ corrected_text (str):
+ Correction output consisting of the corrected
+ keyword string.
+ corrected_html (str):
+ Corrected output with html tags to highlight
+ the corrected words. Corrected words are called
+ out with the "..." html tags.
+ For example, the user input query is "software
+ enginear", where the second word, "enginear," is
+ incorrect. It should be "engineer". When
+ spelling correction is enabled, this value is
+ "software engineer".
+ """
+
+ corrected = proto.Field(proto.BOOL, number=1)
+
+ corrected_text = proto.Field(proto.STRING, number=2)
+
+ corrected_html = proto.Field(proto.STRING, number=3)
+
+
+class CompensationInfo(proto.Message):
+ r"""Job compensation details.
+
+ Attributes:
+ entries (Sequence[~.common.CompensationInfo.CompensationEntry]):
+ Job compensation information.
+
+ At most one entry can be of type
+ [CompensationInfo.CompensationType.BASE][google.cloud.talent.v4.CompensationInfo.CompensationType.BASE],
+ which is referred as **base compensation entry** for the
+ job.
+ annualized_base_compensation_range (~.common.CompensationInfo.CompensationRange):
+ Output only. Annualized base compensation range. Computed as
+ base compensation entry's
+ [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ times
+ [CompensationEntry.expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year].
+
+ See
+ [CompensationEntry][google.cloud.talent.v4.CompensationInfo.CompensationEntry]
+ for explanation on compensation annualization.
+ annualized_total_compensation_range (~.common.CompensationInfo.CompensationRange):
+ Output only. Annualized total compensation range. Computed
+ as all compensation entries'
+ [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ times
+ [CompensationEntry.expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year].
+
+ See
+ [CompensationEntry][google.cloud.talent.v4.CompensationInfo.CompensationEntry]
+ for explanation on compensation annualization.
+ """
+
+ class CompensationType(proto.Enum):
+ r"""The type of compensation.
+
+ For compensation amounts specified in non-monetary amounts, describe
+ the compensation scheme in the
+ [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description].
+
+ For example, tipping format is described in
+ [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description]
+ (for example, "expect 15-20% tips based on customer bill.") and an
+ estimate of the tips provided in
+ [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ or
+ [CompensationEntry.range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range]
+ ($10 per hour).
+
+ For example, equity is described in
+ [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description]
+ (for example, "1% - 2% equity vesting over 4 years, 1 year cliff")
+ and value estimated in
+ [CompensationEntry.amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ or
+ [CompensationEntry.range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range].
+ If no value estimate is possible, units are
+ [CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED][google.cloud.talent.v4.CompensationInfo.CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED]
+ and then further clarified in
+ [CompensationEntry.description][google.cloud.talent.v4.CompensationInfo.CompensationEntry.description]
+ field.
+ """
+ COMPENSATION_TYPE_UNSPECIFIED = 0
+ BASE = 1
+ BONUS = 2
+ SIGNING_BONUS = 3
+ EQUITY = 4
+ PROFIT_SHARING = 5
+ COMMISSIONS = 6
+ TIPS = 7
+ OTHER_COMPENSATION_TYPE = 8
+
+ class CompensationUnit(proto.Enum):
+ r"""Pay frequency."""
+ COMPENSATION_UNIT_UNSPECIFIED = 0
+ HOURLY = 1
+ DAILY = 2
+ WEEKLY = 3
+ MONTHLY = 4
+ YEARLY = 5
+ ONE_TIME = 6
+ OTHER_COMPENSATION_UNIT = 7
+
+ class CompensationEntry(proto.Message):
+ r"""A compensation entry that represents one component of compensation,
+ such as base pay, bonus, or other compensation type.
+
+ Annualization: One compensation entry can be annualized if
+
+ - it contains valid
+ [amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ or
+ [range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range].
+ - and its
+ [expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year]
+ is set or can be derived. Its annualized range is determined as
+ ([amount][google.cloud.talent.v4.CompensationInfo.CompensationEntry.amount]
+ or
+ [range][google.cloud.talent.v4.CompensationInfo.CompensationEntry.range])
+ times
+ [expected_units_per_year][google.cloud.talent.v4.CompensationInfo.CompensationEntry.expected_units_per_year].
+
+ Attributes:
+ type_ (~.common.CompensationInfo.CompensationType):
+ Compensation type.
+
+ Default is
+ [CompensationType.COMPENSATION_TYPE_UNSPECIFIED][google.cloud.talent.v4.CompensationInfo.CompensationType.COMPENSATION_TYPE_UNSPECIFIED].
+ unit (~.common.CompensationInfo.CompensationUnit):
+ Frequency of the specified amount.
+
+ Default is
+ [CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED][google.cloud.talent.v4.CompensationInfo.CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED].
+ amount (~.money.Money):
+ Compensation amount.
+ range_ (~.common.CompensationInfo.CompensationRange):
+ Compensation range.
+ description (str):
+ Compensation description. For example, could
+ indicate equity terms or provide additional
+ context to an estimated bonus.
+ expected_units_per_year (~.wrappers.DoubleValue):
+ Expected number of units paid each year. If not specified,
+ when
+ [Job.employment_types][google.cloud.talent.v4.Job.employment_types]
+ is FULLTIME, a default value is inferred based on
+ [unit][google.cloud.talent.v4.CompensationInfo.CompensationEntry.unit].
+ Default values:
+
+ - HOURLY: 2080
+ - DAILY: 260
+ - WEEKLY: 52
+ - MONTHLY: 12
+ - ANNUAL: 1
+ """
+
+ type_ = proto.Field(
+ proto.ENUM, number=1, enum="CompensationInfo.CompensationType",
+ )
+
+ unit = proto.Field(
+ proto.ENUM, number=2, enum="CompensationInfo.CompensationUnit",
+ )
+
+ amount = proto.Field(
+ proto.MESSAGE, number=3, oneof="compensation_amount", message=money.Money,
+ )
+
+ range_ = proto.Field(
+ proto.MESSAGE,
+ number=4,
+ oneof="compensation_amount",
+ message="CompensationInfo.CompensationRange",
+ )
+
+ description = proto.Field(proto.STRING, number=5)
+
+ expected_units_per_year = proto.Field(
+ proto.MESSAGE, number=6, message=wrappers.DoubleValue,
+ )
+
+ class CompensationRange(proto.Message):
+ r"""Compensation range.
+
+ Attributes:
+ max_compensation (~.money.Money):
+ The maximum amount of compensation. If left empty, the value
+ is set to a maximal compensation value and the currency code
+ is set to match the [currency
+ code][google.type.Money.currency_code] of min_compensation.
+ min_compensation (~.money.Money):
+ The minimum amount of compensation. If left empty, the value
+ is set to zero and the currency code is set to match the
+ [currency code][google.type.Money.currency_code] of
+ max_compensation.
+ """
+
+ max_compensation = proto.Field(proto.MESSAGE, number=2, message=money.Money,)
+
+ min_compensation = proto.Field(proto.MESSAGE, number=1, message=money.Money,)
+
+ entries = proto.RepeatedField(proto.MESSAGE, number=1, message=CompensationEntry,)
+
+ annualized_base_compensation_range = proto.Field(
+ proto.MESSAGE, number=2, message=CompensationRange,
+ )
+
+ annualized_total_compensation_range = proto.Field(
+ proto.MESSAGE, number=3, message=CompensationRange,
+ )
+
+
+class BatchOperationMetadata(proto.Message):
+ r"""Metadata used for long running operations returned by CTS batch
+ APIs. It's used to replace
+ [google.longrunning.Operation.metadata][google.longrunning.Operation.metadata].
+
+ Attributes:
+ state (~.common.BatchOperationMetadata.State):
+ The state of a long running operation.
+ state_description (str):
+ More detailed information about operation
+ state.
+ success_count (int):
+ Count of successful item(s) inside an
+ operation.
+ failure_count (int):
+ Count of failed item(s) inside an operation.
+ total_count (int):
+ Count of total item(s) inside an operation.
+ create_time (~.timestamp.Timestamp):
+ The time when the batch operation is created.
+ update_time (~.timestamp.Timestamp):
+ The time when the batch operation status is updated. The
+ metadata and the
+ [update_time][google.cloud.talent.v4.BatchOperationMetadata.update_time]
+ is refreshed every minute otherwise cached data is returned.
+ end_time (~.timestamp.Timestamp):
+ The time when the batch operation is finished and
+ [google.longrunning.Operation.done][google.longrunning.Operation.done]
+ is set to ``true``.
+ """
+
+ class State(proto.Enum):
+ r""""""
+ STATE_UNSPECIFIED = 0
+ INITIALIZING = 1
+ PROCESSING = 2
+ SUCCEEDED = 3
+ FAILED = 4
+ CANCELLING = 5
+ CANCELLED = 6
+
+ state = proto.Field(proto.ENUM, number=1, enum=State,)
+
+ state_description = proto.Field(proto.STRING, number=2)
+
+ success_count = proto.Field(proto.INT32, number=3)
+
+ failure_count = proto.Field(proto.INT32, number=4)
+
+ total_count = proto.Field(proto.INT32, number=5)
+
+ create_time = proto.Field(proto.MESSAGE, number=6, message=timestamp.Timestamp,)
+
+ update_time = proto.Field(proto.MESSAGE, number=7, message=timestamp.Timestamp,)
+
+ end_time = proto.Field(proto.MESSAGE, number=8, message=timestamp.Timestamp,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/company.py b/google/cloud/talent_v4/types/company.py
new file mode 100644
index 00000000..9955928e
--- /dev/null
+++ b/google/cloud/talent_v4/types/company.py
@@ -0,0 +1,144 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import common
+
+
+__protobuf__ = proto.module(package="google.cloud.talent.v4", manifest={"Company",},)
+
+
+class Company(proto.Message):
+ r"""A Company resource represents a company in the service. A
+ company is the entity that owns job postings, that is, the
+ hiring entity responsible for employing applicants for the job
+ position.
+
+ Attributes:
+ name (str):
+ Required during company update.
+
+ The resource name for a company. This is generated by the
+ service when a company is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example, "projects/foo/tenants/bar/companies/baz".
+ display_name (str):
+ Required. The display name of the company,
+ for example, "Google LLC".
+ external_id (str):
+ Required. Client side company identifier,
+ used to uniquely identify the company.
+
+ The maximum number of allowed characters is 255.
+ size (~.common.CompanySize):
+ The employer's company size.
+ headquarters_address (str):
+ The street address of the company's main headquarters, which
+ may be different from the job location. The service attempts
+ to geolocate the provided address, and populates a more
+ specific location wherever possible in
+ [DerivedInfo.headquarters_location][google.cloud.talent.v4.Company.DerivedInfo.headquarters_location].
+ hiring_agency (bool):
+ Set to true if it is the hiring agency that
+ post jobs for other employers.
+
+ Defaults to false if not provided.
+ eeo_text (str):
+ Equal Employment Opportunity legal disclaimer
+ text to be associated with all jobs, and
+ typically to be displayed in all roles.
+
+ The maximum number of allowed characters is 500.
+ website_uri (str):
+ The URI representing the company's primary
+ web site or home page, for example,
+ "https://www.google.com".
+ The maximum number of allowed characters is 255.
+ career_site_uri (str):
+ The URI to employer's career site or careers
+ page on the employer's web site, for example,
+ "https://careers.google.com".
+ image_uri (str):
+ A URI that hosts the employer's company logo.
+ keyword_searchable_job_custom_attributes (Sequence[str]):
+ A list of keys of filterable
+ [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes],
+ whose corresponding ``string_values`` are used in keyword
+ searches. Jobs with ``string_values`` under these specified
+ field keys are returned if any of the values match the
+ search keyword. Custom field values with parenthesis,
+ brackets and special symbols are not searchable as-is, and
+ those keyword queries must be surrounded by quotes.
+ derived_info (~.company.Company.DerivedInfo):
+ Output only. Derived details about the
+ company.
+ suspended (bool):
+ Output only. Indicates whether a company is
+ flagged to be suspended from public availability
+ by the service when job content appears
+ suspicious, abusive, or spammy.
+ """
+
+ class DerivedInfo(proto.Message):
+ r"""Derived details about the company.
+
+ Attributes:
+ headquarters_location (~.common.Location):
+ A structured headquarters location of the company, resolved
+ from
+ [Company.headquarters_address][google.cloud.talent.v4.Company.headquarters_address]
+ if provided.
+ """
+
+ headquarters_location = proto.Field(
+ proto.MESSAGE, number=1, message=common.Location,
+ )
+
+ name = proto.Field(proto.STRING, number=1)
+
+ display_name = proto.Field(proto.STRING, number=2)
+
+ external_id = proto.Field(proto.STRING, number=3)
+
+ size = proto.Field(proto.ENUM, number=4, enum=common.CompanySize,)
+
+ headquarters_address = proto.Field(proto.STRING, number=5)
+
+ hiring_agency = proto.Field(proto.BOOL, number=6)
+
+ eeo_text = proto.Field(proto.STRING, number=7)
+
+ website_uri = proto.Field(proto.STRING, number=8)
+
+ career_site_uri = proto.Field(proto.STRING, number=9)
+
+ image_uri = proto.Field(proto.STRING, number=10)
+
+ keyword_searchable_job_custom_attributes = proto.RepeatedField(
+ proto.STRING, number=11
+ )
+
+ derived_info = proto.Field(proto.MESSAGE, number=12, message=DerivedInfo,)
+
+ suspended = proto.Field(proto.BOOL, number=13)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/company_service.py b/google/cloud/talent_v4/types/company_service.py
new file mode 100644
index 00000000..0e166ef9
--- /dev/null
+++ b/google/cloud/talent_v4/types/company_service.py
@@ -0,0 +1,178 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import company as gct_company
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4",
+ manifest={
+ "CreateCompanyRequest",
+ "GetCompanyRequest",
+ "UpdateCompanyRequest",
+ "DeleteCompanyRequest",
+ "ListCompaniesRequest",
+ "ListCompaniesResponse",
+ },
+)
+
+
+class CreateCompanyRequest(proto.Message):
+ r"""The Request of the CreateCompany method.
+
+ Attributes:
+ parent (str):
+ Required. Resource name of the tenant under which the
+ company is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}",
+ for example, "projects/foo/tenants/bar".
+ company (~.gct_company.Company):
+ Required. The company to be created.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ company = proto.Field(proto.MESSAGE, number=2, message=gct_company.Company,)
+
+
+class GetCompanyRequest(proto.Message):
+ r"""Request for getting a company by name.
+
+ Attributes:
+ name (str):
+ Required. The resource name of the company to be retrieved.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example,
+ "projects/api-test-project/tenants/foo/companies/bar".
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+
+class UpdateCompanyRequest(proto.Message):
+ r"""Request for updating a specified company.
+
+ Attributes:
+ company (~.gct_company.Company):
+ Required. The company resource to replace the
+ current resource in the system.
+ update_mask (~.field_mask.FieldMask):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateCompanyRequest.update_mask]
+ is provided, only the specified fields in
+ [company][google.cloud.talent.v4.UpdateCompanyRequest.company]
+ are updated. Otherwise all the fields are updated.
+
+ A field mask to specify the company fields to be updated.
+ Only top level fields of
+ [Company][google.cloud.talent.v4.Company] are supported.
+ """
+
+ company = proto.Field(proto.MESSAGE, number=1, message=gct_company.Company,)
+
+ update_mask = proto.Field(proto.MESSAGE, number=2, message=field_mask.FieldMask,)
+
+
+class DeleteCompanyRequest(proto.Message):
+ r"""Request to delete a company.
+
+ Attributes:
+ name (str):
+ Required. The resource name of the company to be deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example, "projects/foo/tenants/bar/companies/baz".
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+
+class ListCompaniesRequest(proto.Message):
+ r"""List companies for which the client has ACL visibility.
+
+ Attributes:
+ parent (str):
+ Required. Resource name of the tenant under which the
+ company is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}",
+ for example, "projects/foo/tenants/bar".
+ page_token (str):
+ The starting indicator from which to return
+ results.
+ page_size (int):
+ The maximum number of companies to be
+ returned, at most 100. Default is 100 if a non-
+ positive number is provided.
+ require_open_jobs (bool):
+ Set to true if the companies requested must have open jobs.
+
+ Defaults to false.
+
+ If true, at most
+ [page_size][google.cloud.talent.v4.ListCompaniesRequest.page_size]
+ of companies are fetched, among which only those with open
+ jobs are returned.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ page_token = proto.Field(proto.STRING, number=2)
+
+ page_size = proto.Field(proto.INT32, number=3)
+
+ require_open_jobs = proto.Field(proto.BOOL, number=4)
+
+
+class ListCompaniesResponse(proto.Message):
+ r"""The List companies response object.
+
+ Attributes:
+ companies (Sequence[~.gct_company.Company]):
+ Companies for the current client.
+ next_page_token (str):
+ A token to retrieve the next page of results.
+ metadata (~.common.ResponseMetadata):
+ Additional information for the API
+ invocation, such as the request tracking id.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ companies = proto.RepeatedField(
+ proto.MESSAGE, number=1, message=gct_company.Company,
+ )
+
+ next_page_token = proto.Field(proto.STRING, number=2)
+
+ metadata = proto.Field(proto.MESSAGE, number=3, message=common.ResponseMetadata,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/completion_service.py b/google/cloud/talent_v4/types/completion_service.py
new file mode 100644
index 00000000..1e25c9a9
--- /dev/null
+++ b/google/cloud/talent_v4/types/completion_service.py
@@ -0,0 +1,136 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import common
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4",
+ manifest={"CompleteQueryRequest", "CompleteQueryResponse",},
+)
+
+
+class CompleteQueryRequest(proto.Message):
+ r"""Auto-complete parameters.
+
+ Attributes:
+ tenant (str):
+ Required. Resource name of tenant the completion is
+ performed within.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}",
+ for example, "projects/foo/tenants/bar".
+ query (str):
+ Required. The query used to generate
+ suggestions.
+ The maximum number of allowed characters is 255.
+ language_codes (Sequence[str]):
+ The list of languages of the query. This is the BCP-47
+ language code, such as "en-US" or "sr-Latn". For more
+ information, see `Tags for Identifying
+ Languages `__.
+
+ The maximum number of allowed characters is 255.
+ page_size (int):
+ Required. Completion result count.
+ The maximum allowed page size is 10.
+ company (str):
+ If provided, restricts completion to specified company.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}",
+ for example, "projects/foo/tenants/bar/companies/baz".
+ scope (~.completion_service.CompleteQueryRequest.CompletionScope):
+ The scope of the completion. The defaults is
+ [CompletionScope.PUBLIC][google.cloud.talent.v4.CompleteQueryRequest.CompletionScope.PUBLIC].
+ type_ (~.completion_service.CompleteQueryRequest.CompletionType):
+ The completion topic. The default is
+ [CompletionType.COMBINED][google.cloud.talent.v4.CompleteQueryRequest.CompletionType.COMBINED].
+ """
+
+ class CompletionScope(proto.Enum):
+ r"""Enum to specify the scope of completion."""
+ COMPLETION_SCOPE_UNSPECIFIED = 0
+ TENANT = 1
+ PUBLIC = 2
+
+ class CompletionType(proto.Enum):
+ r"""Enum to specify auto-completion topics."""
+ COMPLETION_TYPE_UNSPECIFIED = 0
+ JOB_TITLE = 1
+ COMPANY_NAME = 2
+ COMBINED = 3
+
+ tenant = proto.Field(proto.STRING, number=1)
+
+ query = proto.Field(proto.STRING, number=2)
+
+ language_codes = proto.RepeatedField(proto.STRING, number=3)
+
+ page_size = proto.Field(proto.INT32, number=4)
+
+ company = proto.Field(proto.STRING, number=5)
+
+ scope = proto.Field(proto.ENUM, number=6, enum=CompletionScope,)
+
+ type_ = proto.Field(proto.ENUM, number=7, enum=CompletionType,)
+
+
+class CompleteQueryResponse(proto.Message):
+ r"""Response of auto-complete query.
+
+ Attributes:
+ completion_results (Sequence[~.completion_service.CompleteQueryResponse.CompletionResult]):
+ Results of the matching job/company
+ candidates.
+ metadata (~.common.ResponseMetadata):
+ Additional information for the API
+ invocation, such as the request tracking id.
+ """
+
+ class CompletionResult(proto.Message):
+ r"""Resource that represents completion results.
+
+ Attributes:
+ suggestion (str):
+ The suggestion for the query.
+ type_ (~.completion_service.CompleteQueryRequest.CompletionType):
+ The completion topic.
+ image_uri (str):
+ The URI of the company image for
+ [COMPANY_NAME][google.cloud.talent.v4.CompleteQueryRequest.CompletionType.COMPANY_NAME].
+ """
+
+ suggestion = proto.Field(proto.STRING, number=1)
+
+ type_ = proto.Field(
+ proto.ENUM, number=2, enum=CompleteQueryRequest.CompletionType,
+ )
+
+ image_uri = proto.Field(proto.STRING, number=3)
+
+ completion_results = proto.RepeatedField(
+ proto.MESSAGE, number=1, message=CompletionResult,
+ )
+
+ metadata = proto.Field(proto.MESSAGE, number=2, message=common.ResponseMetadata,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/event.py b/google/cloud/talent_v4/types/event.py
new file mode 100644
index 00000000..8ecb3a87
--- /dev/null
+++ b/google/cloud/talent_v4/types/event.py
@@ -0,0 +1,118 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4", manifest={"ClientEvent", "JobEvent",},
+)
+
+
+class ClientEvent(proto.Message):
+ r"""An event issued when an end user interacts with the
+ application that implements Cloud Talent Solution. Providing
+ this information improves the quality of results for the API
+ clients, enabling the service to perform optimally. The number
+ of events sent must be consistent with other calls, such as job
+ searches, issued to the service by the client.
+
+ Attributes:
+ request_id (str):
+ Strongly recommended for the best service experience.
+
+ A unique ID generated in the API responses. It can be found
+ in
+ [ResponseMetadata.request_id][google.cloud.talent.v4.ResponseMetadata.request_id].
+ event_id (str):
+ Required. A unique identifier, generated by
+ the client application.
+ create_time (~.timestamp.Timestamp):
+ Required. The timestamp of the event.
+ job_event (~.event.JobEvent):
+ An event issued when a job seeker interacts
+ with the application that implements Cloud
+ Talent Solution.
+ event_notes (str):
+ Notes about the event provided by recruiters
+ or other users, for example, feedback on why a
+ job was bookmarked.
+ """
+
+ request_id = proto.Field(proto.STRING, number=1)
+
+ event_id = proto.Field(proto.STRING, number=2)
+
+ create_time = proto.Field(proto.MESSAGE, number=4, message=timestamp.Timestamp,)
+
+ job_event = proto.Field(proto.MESSAGE, number=5, oneof="event", message="JobEvent",)
+
+ event_notes = proto.Field(proto.STRING, number=9)
+
+
+class JobEvent(proto.Message):
+ r"""An event issued when a job seeker interacts with the
+ application that implements Cloud Talent Solution.
+
+ Attributes:
+ type_ (~.event.JobEvent.JobEventType):
+ Required. The type of the event (see
+ [JobEventType][google.cloud.talent.v4.JobEvent.JobEventType]).
+ jobs (Sequence[str]):
+ Required. The [job name(s)][google.cloud.talent.v4.Job.name]
+ associated with this event. For example, if this is an
+ [impression][google.cloud.talent.v4.JobEvent.JobEventType.IMPRESSION]
+ event, this field contains the identifiers of all jobs shown
+ to the job seeker. If this was a
+ [view][google.cloud.talent.v4.JobEvent.JobEventType.VIEW]
+ event, this field contains the identifier of the viewed job.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}",
+ for example, "projects/foo/tenants/bar/jobs/baz".
+ """
+
+ class JobEventType(proto.Enum):
+ r"""An enumeration of an event attributed to the behavior of the
+ end user, such as a job seeker.
+ """
+ JOB_EVENT_TYPE_UNSPECIFIED = 0
+ IMPRESSION = 1
+ VIEW = 2
+ VIEW_REDIRECT = 3
+ APPLICATION_START = 4
+ APPLICATION_FINISH = 5
+ APPLICATION_QUICK_SUBMISSION = 6
+ APPLICATION_REDIRECT = 7
+ APPLICATION_START_FROM_SEARCH = 8
+ APPLICATION_REDIRECT_FROM_SEARCH = 9
+ APPLICATION_COMPANY_SUBMIT = 10
+ BOOKMARK = 11
+ NOTIFICATION = 12
+ HIRED = 13
+ SENT_CV = 14
+ INTERVIEW_GRANTED = 15
+
+ type_ = proto.Field(proto.ENUM, number=1, enum=JobEventType,)
+
+ jobs = proto.RepeatedField(proto.STRING, number=2)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/event_service.py b/google/cloud/talent_v4/types/event_service.py
new file mode 100644
index 00000000..264d2f2d
--- /dev/null
+++ b/google/cloud/talent_v4/types/event_service.py
@@ -0,0 +1,50 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import event
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4", manifest={"CreateClientEventRequest",},
+)
+
+
+class CreateClientEventRequest(proto.Message):
+ r"""The report event request.
+
+ Attributes:
+ parent (str):
+ Required. Resource name of the tenant under which the event
+ is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}",
+ for example, "projects/foo/tenants/bar".
+ client_event (~.event.ClientEvent):
+ Required. Events issued when end user
+ interacts with customer's application that uses
+ Cloud Talent Solution.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ client_event = proto.Field(proto.MESSAGE, number=2, message=event.ClientEvent,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/filters.py b/google/cloud/talent_v4/types/filters.py
new file mode 100644
index 00000000..62a8aa57
--- /dev/null
+++ b/google/cloud/talent_v4/types/filters.py
@@ -0,0 +1,396 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import common
+from google.protobuf import duration_pb2 as duration # type: ignore
+from google.type import latlng_pb2 as latlng # type: ignore
+from google.type import timeofday_pb2 as timeofday # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4",
+ manifest={"JobQuery", "LocationFilter", "CompensationFilter", "CommuteFilter",},
+)
+
+
+class JobQuery(proto.Message):
+ r"""The query required to perform a search query.
+
+ Attributes:
+ query (str):
+ The query string that matches against the job
+ title, description, and location fields.
+
+ The maximum number of allowed characters is 255.
+ query_language_code (str):
+ The language code of
+ [query][google.cloud.talent.v4.JobQuery.query]. For example,
+ "en-US". This field helps to better interpret the query.
+
+ If a value isn't specified, the query language code is
+ automatically detected, which may not be accurate.
+
+ Language code should be in BCP-47 format, such as "en-US" or
+ "sr-Latn". For more information, see `Tags for Identifying
+ Languages `__.
+ companies (Sequence[str]):
+ This filter specifies the company entities to search
+ against.
+
+ If a value isn't specified, jobs are searched for against
+ all companies.
+
+ If multiple values are specified, jobs are searched against
+ the companies specified.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}".
+ For example, "projects/foo/tenants/bar/companies/baz".
+
+ At most 20 company filters are allowed.
+ location_filters (Sequence[~.filters.LocationFilter]):
+ The location filter specifies geo-regions containing the
+ jobs to search against. See
+ [LocationFilter][google.cloud.talent.v4.LocationFilter] for
+ more information.
+
+ If a location value isn't specified, jobs fitting the other
+ search criteria are retrieved regardless of where they're
+ located.
+
+ If multiple values are specified, jobs are retrieved from
+ any of the specified locations. If different values are
+ specified for the
+ [LocationFilter.distance_in_miles][google.cloud.talent.v4.LocationFilter.distance_in_miles]
+ parameter, the maximum provided distance is used for all
+ locations.
+
+ At most 5 location filters are allowed.
+ job_categories (Sequence[~.common.JobCategory]):
+ The category filter specifies the categories of jobs to
+ search against. See
+ [JobCategory][google.cloud.talent.v4.JobCategory] for more
+ information.
+
+ If a value isn't specified, jobs from any category are
+ searched against.
+
+ If multiple values are specified, jobs from any of the
+ specified categories are searched against.
+ commute_filter (~.filters.CommuteFilter):
+ Allows filtering jobs by commute time with different travel
+ methods (for example, driving or public transit).
+
+ Note: This only works when you specify a
+ [CommuteMethod][google.cloud.talent.v4.CommuteMethod]. In
+ this case,
+ [location_filters][google.cloud.talent.v4.JobQuery.location_filters]
+ is ignored.
+
+ Currently we don't support sorting by commute time.
+ company_display_names (Sequence[str]):
+ This filter specifies the exact company
+ [Company.display_name][google.cloud.talent.v4.Company.display_name]
+ of the jobs to search against.
+
+ If a value isn't specified, jobs within the search results
+ are associated with any company.
+
+ If multiple values are specified, jobs within the search
+ results may be associated with any of the specified
+ companies.
+
+ At most 20 company display name filters are allowed.
+ compensation_filter (~.filters.CompensationFilter):
+ This search filter is applied only to
+ [Job.compensation_info][google.cloud.talent.v4.Job.compensation_info].
+ For example, if the filter is specified as "Hourly job with
+ per-hour compensation > $15", only jobs meeting these
+ criteria are searched. If a filter isn't defined, all open
+ jobs are searched.
+ custom_attribute_filter (str):
+ This filter specifies a structured syntax to match against
+ the
+ [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes]
+ marked as ``filterable``.
+
+ The syntax for this expression is a subset of SQL syntax.
+
+ Supported operators are: ``=``, ``!=``, ``<``, ``<=``,
+ ``>``, and ``>=`` where the left of the operator is a custom
+ field key and the right of the operator is a number or a
+ quoted string. You must escape backslash (\) and quote (")
+ characters.
+
+ Supported functions are ``LOWER([field_name])`` to perform a
+ case insensitive match and ``EMPTY([field_name])`` to filter
+ on the existence of a key.
+
+ Boolean expressions (AND/OR/NOT) are supported up to 3
+ levels of nesting (for example, "((A AND B AND C) OR NOT D)
+ AND E"), a maximum of 100 comparisons or functions are
+ allowed in the expression. The expression must be < 6000
+ bytes in length.
+
+ Sample Query:
+ ``(LOWER(driving_license)="class \"a\"" OR EMPTY(driving_license)) AND driving_years > 10``
+ disable_spell_check (bool):
+ This flag controls the spell-check feature.
+ If false, the service attempts to correct a
+ misspelled query, for example, "enginee" is
+ corrected to "engineer".
+ Defaults to false: a spell check is performed.
+ employment_types (Sequence[~.common.EmploymentType]):
+ The employment type filter specifies the employment type of
+ jobs to search against, such as
+ [EmploymentType.FULL_TIME][google.cloud.talent.v4.EmploymentType.FULL_TIME].
+
+ If a value isn't specified, jobs in the search results
+ includes any employment type.
+
+ If multiple values are specified, jobs in the search results
+ include any of the specified employment types.
+ language_codes (Sequence[str]):
+ This filter specifies the locale of jobs to search against,
+ for example, "en-US".
+
+ If a value isn't specified, the search results can contain
+ jobs in any locale.
+
+ Language codes should be in BCP-47 format, such as "en-US"
+ or "sr-Latn". For more information, see `Tags for
+ Identifying
+ Languages `__.
+
+ At most 10 language code filters are allowed.
+ publish_time_range (~.common.TimestampRange):
+ Jobs published within a range specified by
+ this filter are searched against.
+ excluded_jobs (Sequence[str]):
+ This filter specifies a list of job names to
+ be excluded during search.
+ At most 400 excluded job names are allowed.
+ """
+
+ query = proto.Field(proto.STRING, number=1)
+
+ query_language_code = proto.Field(proto.STRING, number=14)
+
+ companies = proto.RepeatedField(proto.STRING, number=2)
+
+ location_filters = proto.RepeatedField(
+ proto.MESSAGE, number=3, message="LocationFilter",
+ )
+
+ job_categories = proto.RepeatedField(proto.ENUM, number=4, enum=common.JobCategory,)
+
+ commute_filter = proto.Field(proto.MESSAGE, number=5, message="CommuteFilter",)
+
+ company_display_names = proto.RepeatedField(proto.STRING, number=6)
+
+ compensation_filter = proto.Field(
+ proto.MESSAGE, number=7, message="CompensationFilter",
+ )
+
+ custom_attribute_filter = proto.Field(proto.STRING, number=8)
+
+ disable_spell_check = proto.Field(proto.BOOL, number=9)
+
+ employment_types = proto.RepeatedField(
+ proto.ENUM, number=10, enum=common.EmploymentType,
+ )
+
+ language_codes = proto.RepeatedField(proto.STRING, number=11)
+
+ publish_time_range = proto.Field(
+ proto.MESSAGE, number=12, message=common.TimestampRange,
+ )
+
+ excluded_jobs = proto.RepeatedField(proto.STRING, number=13)
+
+
+class LocationFilter(proto.Message):
+ r"""Geographic region of the search.
+
+ Attributes:
+ address (str):
+ The address name, such as "Mountain View" or
+ "Bay Area".
+ region_code (str):
+ CLDR region code of the country/region of the address. This
+ is used to address ambiguity of the user-input location, for
+ example, "Liverpool" against "Liverpool, NY, US" or
+ "Liverpool, UK".
+
+ Set this field to bias location resolution toward a specific
+ country or territory. If this field is not set, application
+ behavior is biased toward the United States by default.
+
+ See
+ https://www.unicode.org/cldr/charts/30/supplemental/territory_information.html
+ for details. Example: "CH" for Switzerland.
+ lat_lng (~.latlng.LatLng):
+ The latitude and longitude of the geographic center to
+ search from. This field is ignored if ``address`` is
+ provided.
+ distance_in_miles (float):
+ The distance_in_miles is applied when the location being
+ searched for is identified as a city or smaller. This field
+ is ignored if the location being searched for is a state or
+ larger.
+ telecommute_preference (~.filters.LocationFilter.TelecommutePreference):
+ Allows the client to return jobs without a set location,
+ specifically, telecommuting jobs (telecommuting is
+ considered by the service as a special location.
+ [Job.posting_region][google.cloud.talent.v4.Job.posting_region]
+ indicates if a job permits telecommuting. If this field is
+ set to
+ [TelecommutePreference.TELECOMMUTE_ALLOWED][google.cloud.talent.v4.LocationFilter.TelecommutePreference.TELECOMMUTE_ALLOWED],
+ telecommuting jobs are searched, and
+ [address][google.cloud.talent.v4.LocationFilter.address] and
+ [lat_lng][google.cloud.talent.v4.LocationFilter.lat_lng] are
+ ignored. If not set or set to
+ [TelecommutePreference.TELECOMMUTE_EXCLUDED][google.cloud.talent.v4.LocationFilter.TelecommutePreference.TELECOMMUTE_EXCLUDED],
+ telecommute job are not searched.
+
+ This filter can be used by itself to search exclusively for
+ telecommuting jobs, or it can be combined with another
+ location filter to search for a combination of job
+ locations, such as "Mountain View" or "telecommuting" jobs.
+ However, when used in combination with other location
+ filters, telecommuting jobs can be treated as less relevant
+ than other jobs in the search response.
+
+ This field is only used for job search requests.
+ """
+
+ class TelecommutePreference(proto.Enum):
+ r"""Specify whether to include telecommute jobs."""
+ TELECOMMUTE_PREFERENCE_UNSPECIFIED = 0
+ TELECOMMUTE_EXCLUDED = 1
+ TELECOMMUTE_ALLOWED = 2
+
+ address = proto.Field(proto.STRING, number=1)
+
+ region_code = proto.Field(proto.STRING, number=2)
+
+ lat_lng = proto.Field(proto.MESSAGE, number=3, message=latlng.LatLng,)
+
+ distance_in_miles = proto.Field(proto.DOUBLE, number=4)
+
+ telecommute_preference = proto.Field(
+ proto.ENUM, number=5, enum=TelecommutePreference,
+ )
+
+
+class CompensationFilter(proto.Message):
+ r"""Filter on job compensation type and amount.
+
+ Attributes:
+ type_ (~.filters.CompensationFilter.FilterType):
+ Required. Type of filter.
+ units (Sequence[~.common.CompensationInfo.CompensationUnit]):
+ Required. Specify desired ``base compensation entry's``
+ [CompensationInfo.CompensationUnit][google.cloud.talent.v4.CompensationInfo.CompensationUnit].
+ range_ (~.common.CompensationInfo.CompensationRange):
+ Compensation range.
+ include_jobs_with_unspecified_compensation_range (bool):
+ If set to true, jobs with unspecified
+ compensation range fields are included.
+ """
+
+ class FilterType(proto.Enum):
+ r"""Specify the type of filtering."""
+ FILTER_TYPE_UNSPECIFIED = 0
+ UNIT_ONLY = 1
+ UNIT_AND_AMOUNT = 2
+ ANNUALIZED_BASE_AMOUNT = 3
+ ANNUALIZED_TOTAL_AMOUNT = 4
+
+ type_ = proto.Field(proto.ENUM, number=1, enum=FilterType,)
+
+ units = proto.RepeatedField(
+ proto.ENUM, number=2, enum=common.CompensationInfo.CompensationUnit,
+ )
+
+ range_ = proto.Field(
+ proto.MESSAGE, number=3, message=common.CompensationInfo.CompensationRange,
+ )
+
+ include_jobs_with_unspecified_compensation_range = proto.Field(proto.BOOL, number=4)
+
+
+class CommuteFilter(proto.Message):
+ r"""Parameters needed for commute search.
+
+ Attributes:
+ commute_method (~.common.CommuteMethod):
+ Required. The method of transportation to
+ calculate the commute time for.
+ start_coordinates (~.latlng.LatLng):
+ Required. The latitude and longitude of the
+ location to calculate the commute time from.
+ travel_duration (~.duration.Duration):
+ Required. The maximum travel time in seconds. The maximum
+ allowed value is ``3600s`` (one hour). Format is ``123s``.
+ allow_imprecise_addresses (bool):
+ If ``true``, jobs without street level addresses may also be
+ returned. For city level addresses, the city center is used.
+ For state and coarser level addresses, text matching is
+ used. If this field is set to ``false`` or isn't specified,
+ only jobs that include street level addresses will be
+ returned by commute search.
+ road_traffic (~.filters.CommuteFilter.RoadTraffic):
+ Specifies the traffic density to use when
+ calculating commute time.
+ departure_time (~.timeofday.TimeOfDay):
+ The departure time used to calculate traffic impact,
+ represented as
+ [google.type.TimeOfDay][google.type.TimeOfDay] in local time
+ zone.
+
+ Currently traffic model is restricted to hour level
+ resolution.
+ """
+
+ class RoadTraffic(proto.Enum):
+ r"""The traffic density to use when calculating commute time."""
+ ROAD_TRAFFIC_UNSPECIFIED = 0
+ TRAFFIC_FREE = 1
+ BUSY_HOUR = 2
+
+ commute_method = proto.Field(proto.ENUM, number=1, enum=common.CommuteMethod,)
+
+ start_coordinates = proto.Field(proto.MESSAGE, number=2, message=latlng.LatLng,)
+
+ travel_duration = proto.Field(proto.MESSAGE, number=3, message=duration.Duration,)
+
+ allow_imprecise_addresses = proto.Field(proto.BOOL, number=4)
+
+ road_traffic = proto.Field(
+ proto.ENUM, number=5, oneof="traffic_option", enum=RoadTraffic,
+ )
+
+ departure_time = proto.Field(
+ proto.MESSAGE, number=6, oneof="traffic_option", message=timeofday.TimeOfDay,
+ )
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/histogram.py b/google/cloud/talent_v4/types/histogram.py
new file mode 100644
index 00000000..ac6443df
--- /dev/null
+++ b/google/cloud/talent_v4/types/histogram.py
@@ -0,0 +1,72 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4",
+ manifest={"HistogramQuery", "HistogramQueryResult",},
+)
+
+
+class HistogramQuery(proto.Message):
+ r"""The histogram request.
+
+ Attributes:
+ histogram_query (str):
+ An expression specifies a histogram request against matching
+ jobs for searches.
+
+ See
+ [SearchJobsRequest.histogram_queries][google.cloud.talent.v4.SearchJobsRequest.histogram_queries]
+ for details about syntax.
+ """
+
+ histogram_query = proto.Field(proto.STRING, number=1)
+
+
+class HistogramQueryResult(proto.Message):
+ r"""Histogram result that matches
+ [HistogramQuery][google.cloud.talent.v4.HistogramQuery] specified in
+ searches.
+
+ Attributes:
+ histogram_query (str):
+ Requested histogram expression.
+ histogram (Sequence[~.gct_histogram.HistogramQueryResult.HistogramEntry]):
+ A map from the values of the facet associated with distinct
+ values to the number of matching entries with corresponding
+ value.
+
+ The key format is:
+
+ - (for string histogram) string values stored in the field.
+ - (for named numeric bucket) name specified in ``bucket()``
+ function, like for ``bucket(0, MAX, "non-negative")``,
+ the key will be ``non-negative``.
+ - (for anonymous numeric bucket) range formatted as
+ ``-``, for example, ``0-1000``, ``MIN-0``, and
+ ``0-MAX``.
+ """
+
+ histogram_query = proto.Field(proto.STRING, number=1)
+
+ histogram = proto.MapField(proto.STRING, proto.INT64, number=2)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/job.py b/google/cloud/talent_v4/types/job.py
new file mode 100644
index 00000000..f1320f94
--- /dev/null
+++ b/google/cloud/talent_v4/types/job.py
@@ -0,0 +1,479 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import common
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+
+
+__protobuf__ = proto.module(package="google.cloud.talent.v4", manifest={"Job",},)
+
+
+class Job(proto.Message):
+ r"""A Job resource represents a job posting (also referred to as a "job
+ listing" or "job requisition"). A job belongs to a
+ [Company][google.cloud.talent.v4.Company], which is the hiring
+ entity responsible for the job.
+
+ Attributes:
+ name (str):
+ Required during job update.
+
+ The resource name for the job. This is generated by the
+ service when a job is created.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+
+ Use of this field in job queries and API calls is preferred
+ over the use of
+ [requisition_id][google.cloud.talent.v4.Job.requisition_id]
+ since this value is unique.
+ company (str):
+ Required. The resource name of the company listing the job.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/companies/{company_id}".
+ For example, "projects/foo/tenants/bar/companies/baz".
+ requisition_id (str):
+ Required. The requisition ID, also referred to as the
+ posting ID, is assigned by the client to identify a job.
+ This field is intended to be used by clients for client
+ identification and tracking of postings. A job isn't allowed
+ to be created if there is another job with the same
+ [company][google.cloud.talent.v4.Job.name],
+ [language_code][google.cloud.talent.v4.Job.language_code]
+ and
+ [requisition_id][google.cloud.talent.v4.Job.requisition_id].
+
+ The maximum number of allowed characters is 255.
+ title (str):
+ Required. The title of the job, such as
+ "Software Engineer"
+ The maximum number of allowed characters is 500.
+ description (str):
+ Required. The description of the job, which typically
+ includes a multi-paragraph description of the company and
+ related information. Separate fields are provided on the job
+ object for
+ [responsibilities][google.cloud.talent.v4.Job.responsibilities],
+ [qualifications][google.cloud.talent.v4.Job.qualifications],
+ and other job characteristics. Use of these separate job
+ fields is recommended.
+
+ This field accepts and sanitizes HTML input, and also
+ accepts bold, italic, ordered list, and unordered list
+ markup tags.
+
+ The maximum number of allowed characters is 100,000.
+ addresses (Sequence[str]):
+ Strongly recommended for the best service experience.
+
+ Location(s) where the employer is looking to hire for this
+ job posting.
+
+ Specifying the full street address(es) of the hiring
+ location enables better API results, especially job searches
+ by commute time.
+
+ At most 50 locations are allowed for best search
+ performance. If a job has more locations, it is suggested to
+ split it into multiple jobs with unique
+ [requisition_id][google.cloud.talent.v4.Job.requisition_id]s
+ (e.g. 'ReqA' becomes 'ReqA-1', 'ReqA-2', and so on.) as
+ multiple jobs with the same
+ [company][google.cloud.talent.v4.Job.company],
+ [language_code][google.cloud.talent.v4.Job.language_code]
+ and
+ [requisition_id][google.cloud.talent.v4.Job.requisition_id]
+ are not allowed. If the original
+ [requisition_id][google.cloud.talent.v4.Job.requisition_id]
+ must be preserved, a custom field should be used for
+ storage. It is also suggested to group the locations that
+ close to each other in the same job for better search
+ experience.
+
+ The maximum number of allowed characters is 500.
+ application_info (~.job.Job.ApplicationInfo):
+ Job application information.
+ job_benefits (Sequence[~.common.JobBenefit]):
+ The benefits included with the job.
+ compensation_info (~.common.CompensationInfo):
+ Job compensation information (a.k.a. "pay
+ rate") i.e., the compensation that will paid to
+ the employee.
+ custom_attributes (Sequence[~.job.Job.CustomAttributesEntry]):
+ A map of fields to hold both filterable and non-filterable
+ custom job attributes that are not covered by the provided
+ structured fields.
+
+ The keys of the map are strings up to 64 bytes and must
+ match the pattern: [a-zA-Z][a-zA-Z0-9\_]*. For example,
+ key0LikeThis or KEY_1_LIKE_THIS.
+
+ At most 100 filterable and at most 100 unfilterable keys are
+ supported. For filterable ``string_values``, across all keys
+ at most 200 values are allowed, with each string no more
+ than 255 characters. For unfilterable ``string_values``, the
+ maximum total size of ``string_values`` across all keys is
+ 50KB.
+ degree_types (Sequence[~.common.DegreeType]):
+ The desired education degrees for the job,
+ such as Bachelors, Masters.
+ department (str):
+ The department or functional area within the
+ company with the open position.
+
+ The maximum number of allowed characters is 255.
+ employment_types (Sequence[~.common.EmploymentType]):
+ The employment type(s) of a job, for example, [full
+ time][google.cloud.talent.v4.EmploymentType.FULL_TIME] or
+ [part
+ time][google.cloud.talent.v4.EmploymentType.PART_TIME].
+ incentives (str):
+ A description of bonus, commission, and other
+ compensation incentives associated with the job
+ not including salary or pay.
+ The maximum number of allowed characters is
+ 10,000.
+ language_code (str):
+ The language of the posting. This field is distinct from any
+ requirements for fluency that are associated with the job.
+
+ Language codes must be in BCP-47 format, such as "en-US" or
+ "sr-Latn". For more information, see `Tags for Identifying
+ Languages `__\ {:
+ class="external" target="_blank" }.
+
+ If this field is unspecified and
+ [Job.description][google.cloud.talent.v4.Job.description] is
+ present, detected language code based on
+ [Job.description][google.cloud.talent.v4.Job.description] is
+ assigned, otherwise defaults to 'en_US'.
+ job_level (~.common.JobLevel):
+ The experience level associated with the job,
+ such as "Entry Level".
+ promotion_value (int):
+ A promotion value of the job, as determined by the client.
+ The value determines the sort order of the jobs returned
+ when searching for jobs using the featured jobs search call,
+ with higher promotional values being returned first and ties
+ being resolved by relevance sort. Only the jobs with a
+ promotionValue >0 are returned in a FEATURED_JOB_SEARCH.
+
+ Default value is 0, and negative values are treated as 0.
+ qualifications (str):
+ A description of the qualifications required to perform the
+ job. The use of this field is recommended as an alternative
+ to using the more general
+ [description][google.cloud.talent.v4.Job.description] field.
+
+ This field accepts and sanitizes HTML input, and also
+ accepts bold, italic, ordered list, and unordered list
+ markup tags.
+
+ The maximum number of allowed characters is 10,000.
+ responsibilities (str):
+ A description of job responsibilities. The use of this field
+ is recommended as an alternative to using the more general
+ [description][google.cloud.talent.v4.Job.description] field.
+
+ This field accepts and sanitizes HTML input, and also
+ accepts bold, italic, ordered list, and unordered list
+ markup tags.
+
+ The maximum number of allowed characters is 10,000.
+ posting_region (~.common.PostingRegion):
+ The job
+ [PostingRegion][google.cloud.talent.v4.PostingRegion] (for
+ example, state, country) throughout which the job is
+ available. If this field is set, a
+ [LocationFilter][google.cloud.talent.v4.LocationFilter] in a
+ search query within the job region finds this job posting if
+ an exact location match isn't specified. If this field is
+ set to
+ [PostingRegion.NATION][google.cloud.talent.v4.PostingRegion.NATION]
+ or
+ [PostingRegion.ADMINISTRATIVE_AREA][google.cloud.talent.v4.PostingRegion.ADMINISTRATIVE_AREA],
+ setting job
+ [Job.addresses][google.cloud.talent.v4.Job.addresses] to the
+ same location level as this field is strongly recommended.
+ visibility (~.common.Visibility):
+ Deprecated. The job is only visible to the owner.
+
+ The visibility of the job.
+
+ Defaults to
+ [Visibility.ACCOUNT_ONLY][google.cloud.talent.v4.Visibility.ACCOUNT_ONLY]
+ if not specified.
+ job_start_time (~.timestamp.Timestamp):
+ The start timestamp of the job in UTC time
+ zone. Typically this field is used for
+ contracting engagements. Invalid timestamps are
+ ignored.
+ job_end_time (~.timestamp.Timestamp):
+ The end timestamp of the job. Typically this
+ field is used for contracting engagements.
+ Invalid timestamps are ignored.
+ posting_publish_time (~.timestamp.Timestamp):
+ The timestamp this job posting was most
+ recently published. The default value is the
+ time the request arrives at the server. Invalid
+ timestamps are ignored.
+ posting_expire_time (~.timestamp.Timestamp):
+ Strongly recommended for the best service experience.
+
+ The expiration timestamp of the job. After this timestamp,
+ the job is marked as expired, and it no longer appears in
+ search results. The expired job can't be listed by the
+ [ListJobs][google.cloud.talent.v4.JobService.ListJobs] API,
+ but it can be retrieved with the
+ [GetJob][google.cloud.talent.v4.JobService.GetJob] API or
+ updated with the
+ [UpdateJob][google.cloud.talent.v4.JobService.UpdateJob] API
+ or deleted with the
+ [DeleteJob][google.cloud.talent.v4.JobService.DeleteJob]
+ API. An expired job can be updated and opened again by using
+ a future expiration timestamp. Updating an expired job fails
+ if there is another existing open job with same
+ [company][google.cloud.talent.v4.Job.company],
+ [language_code][google.cloud.talent.v4.Job.language_code]
+ and
+ [requisition_id][google.cloud.talent.v4.Job.requisition_id].
+
+ The expired jobs are retained in our system for 90 days.
+ However, the overall expired job count cannot exceed 3 times
+ the maximum number of open jobs over previous 7 days. If
+ this threshold is exceeded, expired jobs are cleaned out in
+ order of earliest expire time. Expired jobs are no longer
+ accessible after they are cleaned out.
+
+ Invalid timestamps are ignored, and treated as expire time
+ not provided.
+
+ If the timestamp is before the instant request is made, the
+ job is treated as expired immediately on creation. This kind
+ of job can not be updated. And when creating a job with past
+ timestamp, the
+ [posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ must be set before
+ [posting_expire_time][google.cloud.talent.v4.Job.posting_expire_time].
+ The purpose of this feature is to allow other objects, such
+ as [Application][], to refer a job that didn't exist in the
+ system prior to becoming expired. If you want to modify a
+ job that was expired on creation, delete it and create a new
+ one.
+
+ If this value isn't provided at the time of job creation or
+ is invalid, the job posting expires after 30 days from the
+ job's creation time. For example, if the job was created on
+ 2017/01/01 13:00AM UTC with an unspecified expiration date,
+ the job expires after 2017/01/31 13:00AM UTC.
+
+ If this value isn't provided on job update, it depends on
+ the field masks set by
+ [UpdateJobRequest.update_mask][google.cloud.talent.v4.UpdateJobRequest.update_mask].
+ If the field masks include
+ [job_end_time][google.cloud.talent.v4.Job.job_end_time], or
+ the masks are empty meaning that every field is updated, the
+ job posting expires after 30 days from the job's last update
+ time. Otherwise the expiration date isn't updated.
+ posting_create_time (~.timestamp.Timestamp):
+ Output only. The timestamp when this job
+ posting was created.
+ posting_update_time (~.timestamp.Timestamp):
+ Output only. The timestamp when this job
+ posting was last updated.
+ company_display_name (str):
+ Output only. Display name of the company
+ listing the job.
+ derived_info (~.job.Job.DerivedInfo):
+ Output only. Derived details about the job
+ posting.
+ processing_options (~.job.Job.ProcessingOptions):
+ Options for job processing.
+ """
+
+ class ApplicationInfo(proto.Message):
+ r"""Application related details of a job posting.
+
+ Attributes:
+ emails (Sequence[str]):
+ Use this field to specify email address(es)
+ to which resumes or applications can be sent.
+ The maximum number of allowed characters for
+ each entry is 255.
+ instruction (str):
+ Use this field to provide instructions, such
+ as "Mail your application to ...", that a
+ candidate can follow to apply for the job.
+ This field accepts and sanitizes HTML input, and
+ also accepts bold, italic, ordered list, and
+ unordered list markup tags.
+ The maximum number of allowed characters is
+ 3,000.
+ uris (Sequence[str]):
+ Use this URI field to direct an applicant to
+ a website, for example to link to an online
+ application form.
+ The maximum number of allowed characters for
+ each entry is 2,000.
+ """
+
+ emails = proto.RepeatedField(proto.STRING, number=1)
+
+ instruction = proto.Field(proto.STRING, number=2)
+
+ uris = proto.RepeatedField(proto.STRING, number=3)
+
+ class DerivedInfo(proto.Message):
+ r"""Derived details about the job posting.
+
+ Attributes:
+ locations (Sequence[~.common.Location]):
+ Structured locations of the job, resolved from
+ [Job.addresses][google.cloud.talent.v4.Job.addresses].
+
+ [locations][google.cloud.talent.v4.Job.DerivedInfo.locations]
+ are exactly matched to
+ [Job.addresses][google.cloud.talent.v4.Job.addresses] in the
+ same order.
+ job_categories (Sequence[~.common.JobCategory]):
+ Job categories derived from
+ [Job.title][google.cloud.talent.v4.Job.title] and
+ [Job.description][google.cloud.talent.v4.Job.description].
+ """
+
+ locations = proto.RepeatedField(
+ proto.MESSAGE, number=1, message=common.Location,
+ )
+
+ job_categories = proto.RepeatedField(
+ proto.ENUM, number=3, enum=common.JobCategory,
+ )
+
+ class ProcessingOptions(proto.Message):
+ r"""Options for job processing.
+
+ Attributes:
+ disable_street_address_resolution (bool):
+ If set to ``true``, the service does not attempt to resolve
+ a more precise address for the job.
+ html_sanitization (~.common.HtmlSanitization):
+ Option for job HTML content sanitization. Applied fields
+ are:
+
+ - description
+ - applicationInfo.instruction
+ - incentives
+ - qualifications
+ - responsibilities
+
+ HTML tags in these fields may be stripped if sanitiazation
+ isn't disabled.
+
+ Defaults to
+ [HtmlSanitization.SIMPLE_FORMATTING_ONLY][google.cloud.talent.v4.HtmlSanitization.SIMPLE_FORMATTING_ONLY].
+ """
+
+ disable_street_address_resolution = proto.Field(proto.BOOL, number=1)
+
+ html_sanitization = proto.Field(
+ proto.ENUM, number=2, enum=common.HtmlSanitization,
+ )
+
+ name = proto.Field(proto.STRING, number=1)
+
+ company = proto.Field(proto.STRING, number=2)
+
+ requisition_id = proto.Field(proto.STRING, number=3)
+
+ title = proto.Field(proto.STRING, number=4)
+
+ description = proto.Field(proto.STRING, number=5)
+
+ addresses = proto.RepeatedField(proto.STRING, number=6)
+
+ application_info = proto.Field(proto.MESSAGE, number=7, message=ApplicationInfo,)
+
+ job_benefits = proto.RepeatedField(proto.ENUM, number=8, enum=common.JobBenefit,)
+
+ compensation_info = proto.Field(
+ proto.MESSAGE, number=9, message=common.CompensationInfo,
+ )
+
+ custom_attributes = proto.MapField(
+ proto.STRING, proto.MESSAGE, number=10, message=common.CustomAttribute,
+ )
+
+ degree_types = proto.RepeatedField(proto.ENUM, number=11, enum=common.DegreeType,)
+
+ department = proto.Field(proto.STRING, number=12)
+
+ employment_types = proto.RepeatedField(
+ proto.ENUM, number=13, enum=common.EmploymentType,
+ )
+
+ incentives = proto.Field(proto.STRING, number=14)
+
+ language_code = proto.Field(proto.STRING, number=15)
+
+ job_level = proto.Field(proto.ENUM, number=16, enum=common.JobLevel,)
+
+ promotion_value = proto.Field(proto.INT32, number=17)
+
+ qualifications = proto.Field(proto.STRING, number=18)
+
+ responsibilities = proto.Field(proto.STRING, number=19)
+
+ posting_region = proto.Field(proto.ENUM, number=20, enum=common.PostingRegion,)
+
+ visibility = proto.Field(proto.ENUM, number=21, enum=common.Visibility,)
+
+ job_start_time = proto.Field(proto.MESSAGE, number=22, message=timestamp.Timestamp,)
+
+ job_end_time = proto.Field(proto.MESSAGE, number=23, message=timestamp.Timestamp,)
+
+ posting_publish_time = proto.Field(
+ proto.MESSAGE, number=24, message=timestamp.Timestamp,
+ )
+
+ posting_expire_time = proto.Field(
+ proto.MESSAGE, number=25, message=timestamp.Timestamp,
+ )
+
+ posting_create_time = proto.Field(
+ proto.MESSAGE, number=26, message=timestamp.Timestamp,
+ )
+
+ posting_update_time = proto.Field(
+ proto.MESSAGE, number=27, message=timestamp.Timestamp,
+ )
+
+ company_display_name = proto.Field(proto.STRING, number=28)
+
+ derived_info = proto.Field(proto.MESSAGE, number=29, message=DerivedInfo,)
+
+ processing_options = proto.Field(
+ proto.MESSAGE, number=30, message=ProcessingOptions,
+ )
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/job_service.py b/google/cloud/talent_v4/types/job_service.py
new file mode 100644
index 00000000..4a1b765a
--- /dev/null
+++ b/google/cloud/talent_v4/types/job_service.py
@@ -0,0 +1,923 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import filters
+from google.cloud.talent_v4.types import histogram
+from google.cloud.talent_v4.types import job as gct_job
+from google.protobuf import duration_pb2 as duration # type: ignore
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+from google.rpc import status_pb2 as gr_status # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4",
+ manifest={
+ "JobView",
+ "CreateJobRequest",
+ "GetJobRequest",
+ "UpdateJobRequest",
+ "DeleteJobRequest",
+ "ListJobsRequest",
+ "ListJobsResponse",
+ "SearchJobsRequest",
+ "SearchJobsResponse",
+ "BatchCreateJobsRequest",
+ "BatchUpdateJobsRequest",
+ "BatchDeleteJobsRequest",
+ "JobResult",
+ "BatchCreateJobsResponse",
+ "BatchUpdateJobsResponse",
+ "BatchDeleteJobsResponse",
+ },
+)
+
+
+class JobView(proto.Enum):
+ r"""An enum that specifies the job attributes that are returned in the
+ [MatchingJob.job][google.cloud.talent.v4.SearchJobsResponse.MatchingJob.job]
+ or
+ [ListJobsResponse.jobs][google.cloud.talent.v4.ListJobsResponse.jobs]
+ fields.
+ """
+ JOB_VIEW_UNSPECIFIED = 0
+ JOB_VIEW_ID_ONLY = 1
+ JOB_VIEW_MINIMAL = 2
+ JOB_VIEW_SMALL = 3
+ JOB_VIEW_FULL = 4
+
+
+class CreateJobRequest(proto.Message):
+ r"""Create job request.
+
+ Attributes:
+ parent (str):
+ Required. The resource name of the tenant under which the
+ job is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}".
+ For example, "projects/foo/tenants/bar".
+ job (~.gct_job.Job):
+ Required. The Job to be created.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ job = proto.Field(proto.MESSAGE, number=2, message=gct_job.Job,)
+
+
+class GetJobRequest(proto.Message):
+ r"""Get job request.
+
+ Attributes:
+ name (str):
+ Required. The resource name of the job to retrieve.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+
+class UpdateJobRequest(proto.Message):
+ r"""Update job request.
+
+ Attributes:
+ job (~.gct_job.Job):
+ Required. The Job to be updated.
+ update_mask (~.field_mask.FieldMask):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateJobRequest.update_mask]
+ is provided, only the specified fields in
+ [job][google.cloud.talent.v4.UpdateJobRequest.job] are
+ updated. Otherwise all the fields are updated.
+
+ A field mask to restrict the fields that are updated. Only
+ top level fields of [Job][google.cloud.talent.v4.Job] are
+ supported.
+ """
+
+ job = proto.Field(proto.MESSAGE, number=1, message=gct_job.Job,)
+
+ update_mask = proto.Field(proto.MESSAGE, number=2, message=field_mask.FieldMask,)
+
+
+class DeleteJobRequest(proto.Message):
+ r"""Delete job request.
+
+ Attributes:
+ name (str):
+ Required. The resource name of the job to be deleted.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+
+class ListJobsRequest(proto.Message):
+ r"""List jobs request.
+
+ Attributes:
+ parent (str):
+ Required. The resource name of the tenant under which the
+ job is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}".
+ For example, "projects/foo/tenants/bar".
+ filter (str):
+ Required. The filter string specifies the jobs to be
+ enumerated.
+
+ Supported operator: =, AND
+
+ The fields eligible for filtering are:
+
+ - ``companyName`` (Required)
+ - ``requisitionId``
+ - ``status`` Available values: OPEN, EXPIRED, ALL. Defaults
+ to OPEN if no value is specified.
+
+ Sample Query:
+
+ - companyName = "projects/foo/tenants/bar/companies/baz"
+ - companyName = "projects/foo/tenants/bar/companies/baz"
+ AND requisitionId = "req-1"
+ - companyName = "projects/foo/tenants/bar/companies/baz"
+ AND status = "EXPIRED".
+ page_token (str):
+ The starting point of a query result.
+ page_size (int):
+ The maximum number of jobs to be returned per page of
+ results.
+
+ If
+ [job_view][google.cloud.talent.v4.ListJobsRequest.job_view]
+ is set to
+ [JobView.JOB_VIEW_ID_ONLY][google.cloud.talent.v4.JobView.JOB_VIEW_ID_ONLY],
+ the maximum allowed page size is 1000. Otherwise, the
+ maximum allowed page size is 100.
+
+ Default is 100 if empty or a number < 1 is specified.
+ job_view (~.job_service.JobView):
+ The desired job attributes returned for jobs in the search
+ response. Defaults to
+ [JobView.JOB_VIEW_FULL][google.cloud.talent.v4.JobView.JOB_VIEW_FULL]
+ if no value is specified.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ filter = proto.Field(proto.STRING, number=2)
+
+ page_token = proto.Field(proto.STRING, number=3)
+
+ page_size = proto.Field(proto.INT32, number=4)
+
+ job_view = proto.Field(proto.ENUM, number=5, enum="JobView",)
+
+
+class ListJobsResponse(proto.Message):
+ r"""List jobs response.
+
+ Attributes:
+ jobs (Sequence[~.gct_job.Job]):
+ The Jobs for a given company.
+ The maximum number of items returned is based on
+ the limit field provided in the request.
+ next_page_token (str):
+ A token to retrieve the next page of results.
+ metadata (~.common.ResponseMetadata):
+ Additional information for the API
+ invocation, such as the request tracking id.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ jobs = proto.RepeatedField(proto.MESSAGE, number=1, message=gct_job.Job,)
+
+ next_page_token = proto.Field(proto.STRING, number=2)
+
+ metadata = proto.Field(proto.MESSAGE, number=3, message=common.ResponseMetadata,)
+
+
+class SearchJobsRequest(proto.Message):
+ r"""The Request body of the ``SearchJobs`` call.
+
+ Attributes:
+ parent (str):
+ Required. The resource name of the tenant to search within.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}".
+ For example, "projects/foo/tenants/bar".
+ search_mode (~.job_service.SearchJobsRequest.SearchMode):
+ Mode of a search.
+
+ Defaults to
+ [SearchMode.JOB_SEARCH][google.cloud.talent.v4.SearchJobsRequest.SearchMode.JOB_SEARCH].
+ request_metadata (~.common.RequestMetadata):
+ Required. The meta information collected about the job
+ searcher, used to improve the search quality of the service.
+ The identifiers (such as ``user_id``) are provided by users,
+ and must be unique and consistent.
+ job_query (~.filters.JobQuery):
+ Query used to search against jobs, such as
+ keyword, location filters, etc.
+ enable_broadening (bool):
+ Controls whether to broaden the search when
+ it produces sparse results. Broadened queries
+ append results to the end of the matching
+ results list.
+
+ Defaults to false.
+ histogram_queries (Sequence[~.histogram.HistogramQuery]):
+ An expression specifies a histogram request against matching
+ jobs.
+
+ Expression syntax is an aggregation function call with
+ histogram facets and other options.
+
+ Available aggregation function calls are:
+
+ - ``count(string_histogram_facet)``: Count the number of
+ matching entities, for each distinct attribute value.
+ - ``count(numeric_histogram_facet, list of buckets)``:
+ Count the number of matching entities within each bucket.
+
+ Data types:
+
+ - Histogram facet: facet names with format
+ [a-zA-Z][a-zA-Z0-9\_]+.
+ - String: string like "any string with backslash escape for
+ quote(")."
+ - Number: whole number and floating point number like 10,
+ -1 and -0.01.
+ - List: list of elements with comma(,) separator surrounded
+ by square brackets, for example, [1, 2, 3] and ["one",
+ "two", "three"].
+
+ Built-in constants:
+
+ - MIN (minimum number similar to java Double.MIN_VALUE)
+ - MAX (maximum number similar to java Double.MAX_VALUE)
+
+ Built-in functions:
+
+ - bucket(start, end[, label]): bucket built-in function
+ creates a bucket with range of [start, end). Note that
+ the end is exclusive, for example, bucket(1, MAX,
+ "positive number") or bucket(1, 10).
+
+ Job histogram facets:
+
+ - company_display_name: histogram by
+ [Job.company_display_name][google.cloud.talent.v4.Job.company_display_name].
+ - employment_type: histogram by
+ [Job.employment_types][google.cloud.talent.v4.Job.employment_types],
+ for example, "FULL_TIME", "PART_TIME".
+ - company_size: histogram by
+ [CompanySize][google.cloud.talent.v4.CompanySize], for
+ example, "SMALL", "MEDIUM", "BIG".
+ - publish_time_in_month: histogram by the
+ [Job.posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ in months. Must specify list of numeric buckets in spec.
+ - publish_time_in_year: histogram by the
+ [Job.posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ in years. Must specify list of numeric buckets in spec.
+ - degree_types: histogram by the
+ [Job.degree_types][google.cloud.talent.v4.Job.degree_types],
+ for example, "Bachelors", "Masters".
+ - job_level: histogram by the
+ [Job.job_level][google.cloud.talent.v4.Job.job_level],
+ for example, "Entry Level".
+ - country: histogram by the country code of jobs, for
+ example, "US", "FR".
+ - admin1: histogram by the admin1 code of jobs, which is a
+ global placeholder referring to the state, province, or
+ the particular term a country uses to define the
+ geographic structure below the country level, for
+ example, "CA", "IL".
+ - city: histogram by a combination of the "city name,
+ admin1 code". For example, "Mountain View, CA", "New
+ York, NY".
+ - admin1_country: histogram by a combination of the "admin1
+ code, country", for example, "CA, US", "IL, US".
+ - city_coordinate: histogram by the city center's GPS
+ coordinates (latitude and longitude), for example,
+ 37.4038522,-122.0987765. Since the coordinates of a city
+ center can change, customers may need to refresh them
+ periodically.
+ - locale: histogram by the
+ [Job.language_code][google.cloud.talent.v4.Job.language_code],
+ for example, "en-US", "fr-FR".
+ - language: histogram by the language subtag of the
+ [Job.language_code][google.cloud.talent.v4.Job.language_code],
+ for example, "en", "fr".
+ - category: histogram by the
+ [JobCategory][google.cloud.talent.v4.JobCategory], for
+ example, "COMPUTER_AND_IT", "HEALTHCARE".
+ - base_compensation_unit: histogram by the
+ [CompensationInfo.CompensationUnit][google.cloud.talent.v4.CompensationInfo.CompensationUnit]
+ of base salary, for example, "WEEKLY", "MONTHLY".
+ - base_compensation: histogram by the base salary. Must
+ specify list of numeric buckets to group results by.
+ - annualized_base_compensation: histogram by the base
+ annualized salary. Must specify list of numeric buckets
+ to group results by.
+ - annualized_total_compensation: histogram by the total
+ annualized salary. Must specify list of numeric buckets
+ to group results by.
+ - string_custom_attribute: histogram by string
+ [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes].
+ Values can be accessed via square bracket notations like
+ string_custom_attribute["key1"].
+ - numeric_custom_attribute: histogram by numeric
+ [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes].
+ Values can be accessed via square bracket notations like
+ numeric_custom_attribute["key1"]. Must specify list of
+ numeric buckets to group results by.
+
+ Example expressions:
+
+ - ``count(admin1)``
+ - ``count(base_compensation, [bucket(1000, 10000), bucket(10000, 100000), bucket(100000, MAX)])``
+ - ``count(string_custom_attribute["some-string-custom-attribute"])``
+ - ``count(numeric_custom_attribute["some-numeric-custom-attribute"], [bucket(MIN, 0, "negative"), bucket(0, MAX, "non-negative"])``
+ job_view (~.job_service.JobView):
+ The desired job attributes returned for jobs in the search
+ response. Defaults to
+ [JobView.JOB_VIEW_SMALL][google.cloud.talent.v4.JobView.JOB_VIEW_SMALL]
+ if no value is specified.
+ offset (int):
+ An integer that specifies the current offset (that is,
+ starting result location, amongst the jobs deemed by the API
+ as relevant) in search results. This field is only
+ considered if
+ [page_token][google.cloud.talent.v4.SearchJobsRequest.page_token]
+ is unset.
+
+ The maximum allowed value is 5000. Otherwise an error is
+ thrown.
+
+ For example, 0 means to return results starting from the
+ first matching job, and 10 means to return from the 11th
+ job. This can be used for pagination, (for example, pageSize
+ = 10 and offset = 10 means to return from the second page).
+ max_page_size (int):
+ A limit on the number of jobs returned in the
+ search results. Increasing this value above the
+ default value of 10 can increase search response
+ time. The value can be between 1 and 100.
+ page_token (str):
+ The token specifying the current offset within search
+ results. See
+ [SearchJobsResponse.next_page_token][google.cloud.talent.v4.SearchJobsResponse.next_page_token]
+ for an explanation of how to obtain the next set of query
+ results.
+ order_by (str):
+ The criteria determining how search results are sorted.
+ Default is ``"relevance desc"``.
+
+ Supported options are:
+
+ - ``"relevance desc"``: By relevance descending, as
+ determined by the API algorithms. Relevance thresholding
+ of query results is only available with this ordering.
+ - ``"posting_publish_time desc"``: By
+ [Job.posting_publish_time][google.cloud.talent.v4.Job.posting_publish_time]
+ descending.
+ - ``"posting_update_time desc"``: By
+ [Job.posting_update_time][google.cloud.talent.v4.Job.posting_update_time]
+ descending.
+ - ``"title"``: By
+ [Job.title][google.cloud.talent.v4.Job.title] ascending.
+ - ``"title desc"``: By
+ [Job.title][google.cloud.talent.v4.Job.title] descending.
+ - ``"annualized_base_compensation"``: By job's
+ [CompensationInfo.annualized_base_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_base_compensation_range]
+ ascending. Jobs whose annualized base compensation is
+ unspecified are put at the end of search results.
+ - ``"annualized_base_compensation desc"``: By job's
+ [CompensationInfo.annualized_base_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_base_compensation_range]
+ descending. Jobs whose annualized base compensation is
+ unspecified are put at the end of search results.
+ - ``"annualized_total_compensation"``: By job's
+ [CompensationInfo.annualized_total_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_total_compensation_range]
+ ascending. Jobs whose annualized base compensation is
+ unspecified are put at the end of search results.
+ - ``"annualized_total_compensation desc"``: By job's
+ [CompensationInfo.annualized_total_compensation_range][google.cloud.talent.v4.CompensationInfo.annualized_total_compensation_range]
+ descending. Jobs whose annualized base compensation is
+ unspecified are put at the end of search results.
+ - ``"custom_ranking desc"``: By the relevance score
+ adjusted to the
+ [SearchJobsRequest.CustomRankingInfo.ranking_expression][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.ranking_expression]
+ with weight factor assigned by
+ [SearchJobsRequest.CustomRankingInfo.importance_level][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.importance_level]
+ in descending order.
+ - Location sorting: Use the special syntax to order jobs by
+ distance: ``"distance_from('Hawaii')"``: Order by
+ distance from Hawaii. ``"distance_from(19.89, 155.5)"``:
+ Order by distance from a coordinate.
+ ``"distance_from('Hawaii'), distance_from('Puerto Rico')"``:
+ Order by multiple locations. See details below.
+ ``"distance_from('Hawaii'), distance_from(19.89, 155.5)"``:
+ Order by multiple locations. See details below. The
+ string can have a maximum of 256 characters. When
+ multiple distance centers are provided, a job that is
+ close to any of the distance centers would have a high
+ rank. When a job has multiple locations, the job location
+ closest to one of the distance centers will be used. Jobs
+ that don't have locations will be ranked at the bottom.
+ Distance is calculated with a precision of 11.3 meters
+ (37.4 feet). Diversification strategy is still applied
+ unless explicitly disabled in
+ [diversification_level][google.cloud.talent.v4.SearchJobsRequest.diversification_level].
+ diversification_level (~.job_service.SearchJobsRequest.DiversificationLevel):
+ Controls whether highly similar jobs are returned next to
+ each other in the search results. Jobs are identified as
+ highly similar based on their titles, job categories, and
+ locations. Highly similar results are clustered so that only
+ one representative job of the cluster is displayed to the
+ job seeker higher up in the results, with the other jobs
+ being displayed lower down in the results.
+
+ Defaults to
+ [DiversificationLevel.SIMPLE][google.cloud.talent.v4.SearchJobsRequest.DiversificationLevel.SIMPLE]
+ if no value is specified.
+ custom_ranking_info (~.job_service.SearchJobsRequest.CustomRankingInfo):
+ Controls over how job documents get ranked on
+ top of existing relevance score (determined by
+ API algorithm).
+ disable_keyword_match (bool):
+ Controls whether to disable exact keyword match on
+ [Job.title][google.cloud.talent.v4.Job.title],
+ [Job.description][google.cloud.talent.v4.Job.description],
+ [Job.company_display_name][google.cloud.talent.v4.Job.company_display_name],
+ [Job.addresses][google.cloud.talent.v4.Job.addresses],
+ [Job.qualifications][google.cloud.talent.v4.Job.qualifications].
+ When disable keyword match is turned off, a keyword match
+ returns jobs that do not match given category filters when
+ there are matching keywords. For example, for the query
+ "program manager," a result is returned even if the job
+ posting has the title "software developer," which doesn't
+ fall into "program manager" ontology, but does have "program
+ manager" appearing in its description.
+
+ For queries like "cloud" that don't contain title or
+ location specific ontology, jobs with "cloud" keyword
+ matches are returned regardless of this flag's value.
+
+ Use
+ [Company.keyword_searchable_job_custom_attributes][google.cloud.talent.v4.Company.keyword_searchable_job_custom_attributes]
+ if company-specific globally matched custom field/attribute
+ string values are needed. Enabling keyword match improves
+ recall of subsequent search requests.
+
+ Defaults to false.
+ """
+
+ class SearchMode(proto.Enum):
+ r"""A string-represented enumeration of the job search mode. The
+ service operate differently for different modes of service.
+ """
+ SEARCH_MODE_UNSPECIFIED = 0
+ JOB_SEARCH = 1
+ FEATURED_JOB_SEARCH = 2
+
+ class DiversificationLevel(proto.Enum):
+ r"""Controls whether highly similar jobs are returned next to
+ each other in the search results. Jobs are identified as highly
+ similar based on their titles, job categories, and locations.
+ Highly similar results are clustered so that only one
+ representative job of the cluster is displayed to the job seeker
+ higher up in the results, with the other jobs being displayed
+ lower down in the results.
+ """
+ DIVERSIFICATION_LEVEL_UNSPECIFIED = 0
+ DISABLED = 1
+ SIMPLE = 2
+
+ class CustomRankingInfo(proto.Message):
+ r"""Custom ranking information for
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+
+ Attributes:
+ importance_level (~.job_service.SearchJobsRequest.CustomRankingInfo.ImportanceLevel):
+ Required. Controls over how important the score of
+ [CustomRankingInfo.ranking_expression][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.ranking_expression]
+ gets applied to job's final ranking position.
+
+ An error is thrown if not specified.
+ ranking_expression (str):
+ Required. Controls over how job documents get ranked on top
+ of existing relevance score (determined by API algorithm). A
+ combination of the ranking expression and relevance score is
+ used to determine job's final ranking position.
+
+ The syntax for this expression is a subset of Google SQL
+ syntax.
+
+ Supported operators are: +, -, \*, /, where the left and
+ right side of the operator is either a numeric
+ [Job.custom_attributes][google.cloud.talent.v4.Job.custom_attributes]
+ key, integer/double value or an expression that can be
+ evaluated to a number.
+
+ Parenthesis are supported to adjust calculation precedence.
+ The expression must be < 100 characters in length.
+
+ The expression is considered invalid for a job if the
+ expression references custom attributes that are not
+ populated on the job or if the expression results in a
+ divide by zero. If an expression is invalid for a job, that
+ job is demoted to the end of the results.
+
+ Sample ranking expression (year + 25) \* 0.25 - (freshness /
+ 0.5)
+ """
+
+ class ImportanceLevel(proto.Enum):
+ r"""The importance level for
+ [CustomRankingInfo.ranking_expression][google.cloud.talent.v4.SearchJobsRequest.CustomRankingInfo.ranking_expression].
+ """
+ IMPORTANCE_LEVEL_UNSPECIFIED = 0
+ NONE = 1
+ LOW = 2
+ MILD = 3
+ MEDIUM = 4
+ HIGH = 5
+ EXTREME = 6
+
+ importance_level = proto.Field(
+ proto.ENUM,
+ number=1,
+ enum="SearchJobsRequest.CustomRankingInfo.ImportanceLevel",
+ )
+
+ ranking_expression = proto.Field(proto.STRING, number=2)
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ search_mode = proto.Field(proto.ENUM, number=2, enum=SearchMode,)
+
+ request_metadata = proto.Field(
+ proto.MESSAGE, number=3, message=common.RequestMetadata,
+ )
+
+ job_query = proto.Field(proto.MESSAGE, number=4, message=filters.JobQuery,)
+
+ enable_broadening = proto.Field(proto.BOOL, number=5)
+
+ histogram_queries = proto.RepeatedField(
+ proto.MESSAGE, number=7, message=histogram.HistogramQuery,
+ )
+
+ job_view = proto.Field(proto.ENUM, number=8, enum="JobView",)
+
+ offset = proto.Field(proto.INT32, number=9)
+
+ max_page_size = proto.Field(proto.INT32, number=10)
+
+ page_token = proto.Field(proto.STRING, number=11)
+
+ order_by = proto.Field(proto.STRING, number=12)
+
+ diversification_level = proto.Field(
+ proto.ENUM, number=13, enum=DiversificationLevel,
+ )
+
+ custom_ranking_info = proto.Field(
+ proto.MESSAGE, number=14, message=CustomRankingInfo,
+ )
+
+ disable_keyword_match = proto.Field(proto.BOOL, number=16)
+
+
+class SearchJobsResponse(proto.Message):
+ r"""Response for SearchJob method.
+
+ Attributes:
+ matching_jobs (Sequence[~.job_service.SearchJobsResponse.MatchingJob]):
+ The Job entities that match the specified
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+ histogram_query_results (Sequence[~.histogram.HistogramQueryResult]):
+ The histogram results that match with specified
+ [SearchJobsRequest.histogram_queries][google.cloud.talent.v4.SearchJobsRequest.histogram_queries].
+ next_page_token (str):
+ The token that specifies the starting
+ position of the next page of results. This field
+ is empty if there are no more results.
+ location_filters (Sequence[~.common.Location]):
+ The location filters that the service applied to the
+ specified query. If any filters are lat-lng based, the
+ [Location.location_type][google.cloud.talent.v4.Location.location_type]
+ is
+ [Location.LocationType.LOCATION_TYPE_UNSPECIFIED][google.cloud.talent.v4.Location.LocationType.LOCATION_TYPE_UNSPECIFIED].
+ total_size (int):
+ Number of jobs that match the specified
+ query.
+ Note: This size is precise only if the total is
+ less than 100,000.
+ metadata (~.common.ResponseMetadata):
+ Additional information for the API
+ invocation, such as the request tracking id.
+ broadened_query_jobs_count (int):
+ If query broadening is enabled, we may append
+ additional results from the broadened query.
+ This number indicates how many of the jobs
+ returned in the jobs field are from the
+ broadened query. These results are always at the
+ end of the jobs list. In particular, a value of
+ 0, or if the field isn't set, all the jobs in
+ the jobs list are from the original (without
+ broadening) query. If this field is non-zero,
+ subsequent requests with offset after this
+ result set should contain all broadened results.
+ spell_correction (~.common.SpellingCorrection):
+ The spell checking result, and correction.
+ """
+
+ class MatchingJob(proto.Message):
+ r"""Job entry with metadata inside
+ [SearchJobsResponse][google.cloud.talent.v4.SearchJobsResponse].
+
+ Attributes:
+ job (~.gct_job.Job):
+ Job resource that matches the specified
+ [SearchJobsRequest][google.cloud.talent.v4.SearchJobsRequest].
+ job_summary (str):
+ A summary of the job with core information
+ that's displayed on the search results listing
+ page.
+ job_title_snippet (str):
+ Contains snippets of text from the
+ [Job.title][google.cloud.talent.v4.Job.title] field most
+ closely matching a search query's keywords, if available.
+ The matching query keywords are enclosed in HTML bold tags.
+ search_text_snippet (str):
+ Contains snippets of text from the
+ [Job.description][google.cloud.talent.v4.Job.description]
+ and similar fields that most closely match a search query's
+ keywords, if available. All HTML tags in the original fields
+ are stripped when returned in this field, and matching query
+ keywords are enclosed in HTML bold tags.
+ commute_info (~.job_service.SearchJobsResponse.CommuteInfo):
+ Commute information which is generated based on specified
+ [CommuteFilter][google.cloud.talent.v4.CommuteFilter].
+ """
+
+ job = proto.Field(proto.MESSAGE, number=1, message=gct_job.Job,)
+
+ job_summary = proto.Field(proto.STRING, number=2)
+
+ job_title_snippet = proto.Field(proto.STRING, number=3)
+
+ search_text_snippet = proto.Field(proto.STRING, number=4)
+
+ commute_info = proto.Field(
+ proto.MESSAGE, number=5, message="SearchJobsResponse.CommuteInfo",
+ )
+
+ class CommuteInfo(proto.Message):
+ r"""Commute details related to this job.
+
+ Attributes:
+ job_location (~.common.Location):
+ Location used as the destination in the
+ commute calculation.
+ travel_duration (~.duration.Duration):
+ The number of seconds required to travel to
+ the job location from the query location. A
+ duration of 0 seconds indicates that the job
+ isn't reachable within the requested duration,
+ but was returned as part of an expanded query.
+ """
+
+ job_location = proto.Field(proto.MESSAGE, number=1, message=common.Location,)
+
+ travel_duration = proto.Field(
+ proto.MESSAGE, number=2, message=duration.Duration,
+ )
+
+ @property
+ def raw_page(self):
+ return self
+
+ matching_jobs = proto.RepeatedField(proto.MESSAGE, number=1, message=MatchingJob,)
+
+ histogram_query_results = proto.RepeatedField(
+ proto.MESSAGE, number=2, message=histogram.HistogramQueryResult,
+ )
+
+ next_page_token = proto.Field(proto.STRING, number=3)
+
+ location_filters = proto.RepeatedField(
+ proto.MESSAGE, number=4, message=common.Location,
+ )
+
+ total_size = proto.Field(proto.INT32, number=6)
+
+ metadata = proto.Field(proto.MESSAGE, number=7, message=common.ResponseMetadata,)
+
+ broadened_query_jobs_count = proto.Field(proto.INT32, number=8)
+
+ spell_correction = proto.Field(
+ proto.MESSAGE, number=9, message=common.SpellingCorrection,
+ )
+
+
+class BatchCreateJobsRequest(proto.Message):
+ r"""Request to create a batch of jobs.
+
+ Attributes:
+ parent (str):
+ Required. The resource name of the tenant under which the
+ job is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}".
+ For example, "projects/foo/tenants/bar".
+ jobs (Sequence[~.gct_job.Job]):
+ Required. The jobs to be created.
+ A maximum of 200 jobs can be created in a batch.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ jobs = proto.RepeatedField(proto.MESSAGE, number=2, message=gct_job.Job,)
+
+
+class BatchUpdateJobsRequest(proto.Message):
+ r"""Request to update a batch of jobs.
+
+ Attributes:
+ parent (str):
+ Required. The resource name of the tenant under which the
+ job is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}".
+ For example, "projects/foo/tenants/bar".
+ jobs (Sequence[~.gct_job.Job]):
+ Required. The jobs to be updated.
+ A maximum of 200 jobs can be updated in a batch.
+ update_mask (~.field_mask.FieldMask):
+ Strongly recommended for the best service experience. Be
+ aware that it will also increase latency when checking the
+ status of a batch operation.
+
+ If
+ [update_mask][google.cloud.talent.v4.BatchUpdateJobsRequest.update_mask]
+ is provided, only the specified fields in
+ [Job][google.cloud.talent.v4.Job] are updated. Otherwise all
+ the fields are updated.
+
+ A field mask to restrict the fields that are updated. Only
+ top level fields of [Job][google.cloud.talent.v4.Job] are
+ supported.
+
+ If
+ [update_mask][google.cloud.talent.v4.BatchUpdateJobsRequest.update_mask]
+ is provided, The [Job][google.cloud.talent.v4.Job] inside
+ [JobResult][JobOperationResult.JobResult] will only contains
+ fields that is updated, plus the Id of the Job. Otherwise,
+ [Job][google.cloud.talent.v4.Job] will include all fields,
+ which can yield a very large response.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ jobs = proto.RepeatedField(proto.MESSAGE, number=2, message=gct_job.Job,)
+
+ update_mask = proto.Field(proto.MESSAGE, number=3, message=field_mask.FieldMask,)
+
+
+class BatchDeleteJobsRequest(proto.Message):
+ r"""Request to delete a batch of jobs.
+
+ Attributes:
+ parent (str):
+ Required. The resource name of the tenant under which the
+ job is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}".
+ For example, "projects/foo/tenants/bar".
+
+ The parent of all of the jobs specified in ``names`` must
+ match this field.
+ names (Sequence[str]):
+ The names of the jobs to delete.
+
+ The format is
+ "projects/{project_id}/tenants/{tenant_id}/jobs/{job_id}".
+ For example, "projects/foo/tenants/bar/jobs/baz".
+
+ A maximum of 200 jobs can be deleted in a batch.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ names = proto.RepeatedField(proto.STRING, number=2)
+
+
+class JobResult(proto.Message):
+ r"""Mutation result of a job from a batch operation.
+
+ Attributes:
+ job (~.gct_job.Job):
+ Here [Job][google.cloud.talent.v4.Job] only contains basic
+ information including
+ [name][google.cloud.talent.v4.Job.name],
+ [company][google.cloud.talent.v4.Job.company],
+ [language_code][google.cloud.talent.v4.Job.language_code]
+ and
+ [requisition_id][google.cloud.talent.v4.Job.requisition_id],
+ use getJob method to retrieve detailed information of the
+ created/updated job.
+ status (~.gr_status.Status):
+ The status of the job processed. This field is populated if
+ the processing of the
+ [job][google.cloud.talent.v4.JobResult.job] fails.
+ """
+
+ job = proto.Field(proto.MESSAGE, number=1, message=gct_job.Job,)
+
+ status = proto.Field(proto.MESSAGE, number=2, message=gr_status.Status,)
+
+
+class BatchCreateJobsResponse(proto.Message):
+ r"""The result of
+ [JobService.BatchCreateJobs][google.cloud.talent.v4.JobService.BatchCreateJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ Attributes:
+ job_results (Sequence[~.job_service.JobResult]):
+ List of job mutation results from a batch
+ create operation. It can change until operation
+ status is FINISHED, FAILED or CANCELLED.
+ """
+
+ job_results = proto.RepeatedField(proto.MESSAGE, number=1, message=JobResult,)
+
+
+class BatchUpdateJobsResponse(proto.Message):
+ r"""The result of
+ [JobService.BatchUpdateJobs][google.cloud.talent.v4.JobService.BatchUpdateJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ Attributes:
+ job_results (Sequence[~.job_service.JobResult]):
+ List of job mutation results from a batch
+ update operation. It can change until operation
+ status is FINISHED, FAILED or CANCELLED.
+ """
+
+ job_results = proto.RepeatedField(proto.MESSAGE, number=1, message=JobResult,)
+
+
+class BatchDeleteJobsResponse(proto.Message):
+ r"""The result of
+ [JobService.BatchDeleteJobs][google.cloud.talent.v4.JobService.BatchDeleteJobs].
+ It's used to replace
+ [google.longrunning.Operation.response][google.longrunning.Operation.response]
+ in case of success.
+
+ Attributes:
+ job_results (Sequence[~.job_service.JobResult]):
+ List of job mutation results from a batch
+ delete operation. It can change until operation
+ status is FINISHED, FAILED or CANCELLED.
+ """
+
+ job_results = proto.RepeatedField(proto.MESSAGE, number=1, message=JobResult,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/tenant.py b/google/cloud/talent_v4/types/tenant.py
new file mode 100644
index 00000000..0299d6a3
--- /dev/null
+++ b/google/cloud/talent_v4/types/tenant.py
@@ -0,0 +1,51 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+__protobuf__ = proto.module(package="google.cloud.talent.v4", manifest={"Tenant",},)
+
+
+class Tenant(proto.Message):
+ r"""A Tenant resource represents a tenant in the service. A
+ tenant is a group or entity that shares common access with
+ specific privileges for resources like jobs. Customer may create
+ multiple tenants to provide data isolation for different groups.
+
+ Attributes:
+ name (str):
+ Required during tenant update.
+
+ The resource name for a tenant. This is generated by the
+ service when a tenant is created.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}",
+ for example, "projects/foo/tenants/bar".
+ external_id (str):
+ Required. Client side tenant identifier, used
+ to uniquely identify the tenant.
+
+ The maximum number of allowed characters is 255.
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+ external_id = proto.Field(proto.STRING, number=2)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4/types/tenant_service.py b/google/cloud/talent_v4/types/tenant_service.py
new file mode 100644
index 00000000..2f77b0d1
--- /dev/null
+++ b/google/cloud/talent_v4/types/tenant_service.py
@@ -0,0 +1,162 @@
+# -*- 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.
+#
+
+import proto # type: ignore
+
+
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import tenant as gct_tenant
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.cloud.talent.v4",
+ manifest={
+ "CreateTenantRequest",
+ "GetTenantRequest",
+ "UpdateTenantRequest",
+ "DeleteTenantRequest",
+ "ListTenantsRequest",
+ "ListTenantsResponse",
+ },
+)
+
+
+class CreateTenantRequest(proto.Message):
+ r"""The Request of the CreateTenant method.
+
+ Attributes:
+ parent (str):
+ Required. Resource name of the project under which the
+ tenant is created.
+
+ The format is "projects/{project_id}", for example,
+ "projects/foo".
+ tenant (~.gct_tenant.Tenant):
+ Required. The tenant to be created.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ tenant = proto.Field(proto.MESSAGE, number=2, message=gct_tenant.Tenant,)
+
+
+class GetTenantRequest(proto.Message):
+ r"""Request for getting a tenant by name.
+
+ Attributes:
+ name (str):
+ Required. The resource name of the tenant to be retrieved.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}",
+ for example, "projects/foo/tenants/bar".
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+
+class UpdateTenantRequest(proto.Message):
+ r"""Request for updating a specified tenant.
+
+ Attributes:
+ tenant (~.gct_tenant.Tenant):
+ Required. The tenant resource to replace the
+ current resource in the system.
+ update_mask (~.field_mask.FieldMask):
+ Strongly recommended for the best service experience.
+
+ If
+ [update_mask][google.cloud.talent.v4.UpdateTenantRequest.update_mask]
+ is provided, only the specified fields in
+ [tenant][google.cloud.talent.v4.UpdateTenantRequest.tenant]
+ are updated. Otherwise all the fields are updated.
+
+ A field mask to specify the tenant fields to be updated.
+ Only top level fields of
+ [Tenant][google.cloud.talent.v4.Tenant] are supported.
+ """
+
+ tenant = proto.Field(proto.MESSAGE, number=1, message=gct_tenant.Tenant,)
+
+ update_mask = proto.Field(proto.MESSAGE, number=2, message=field_mask.FieldMask,)
+
+
+class DeleteTenantRequest(proto.Message):
+ r"""Request to delete a tenant.
+
+ Attributes:
+ name (str):
+ Required. The resource name of the tenant to be deleted.
+
+ The format is "projects/{project_id}/tenants/{tenant_id}",
+ for example, "projects/foo/tenants/bar".
+ """
+
+ name = proto.Field(proto.STRING, number=1)
+
+
+class ListTenantsRequest(proto.Message):
+ r"""List tenants for which the client has ACL visibility.
+
+ Attributes:
+ parent (str):
+ Required. Resource name of the project under which the
+ tenant is created.
+
+ The format is "projects/{project_id}", for example,
+ "projects/foo".
+ page_token (str):
+ The starting indicator from which to return
+ results.
+ page_size (int):
+ The maximum number of tenants to be returned,
+ at most 100. Default is 100 if a non-positive
+ number is provided.
+ """
+
+ parent = proto.Field(proto.STRING, number=1)
+
+ page_token = proto.Field(proto.STRING, number=2)
+
+ page_size = proto.Field(proto.INT32, number=3)
+
+
+class ListTenantsResponse(proto.Message):
+ r"""The List tenants response object.
+
+ Attributes:
+ tenants (Sequence[~.gct_tenant.Tenant]):
+ Tenants for the current client.
+ next_page_token (str):
+ A token to retrieve the next page of results.
+ metadata (~.common.ResponseMetadata):
+ Additional information for the API
+ invocation, such as the request tracking id.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ tenants = proto.RepeatedField(proto.MESSAGE, number=1, message=gct_tenant.Tenant,)
+
+ next_page_token = proto.Field(proto.STRING, number=2)
+
+ metadata = proto.Field(proto.MESSAGE, number=3, message=common.ResponseMetadata,)
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/talent_v4beta1/services/application_service/async_client.py b/google/cloud/talent_v4beta1/services/application_service/async_client.py
index f91a96d2..1dd27354 100644
--- a/google/cloud/talent_v4beta1/services/application_service/async_client.py
+++ b/google/cloud/talent_v4beta1/services/application_service/async_client.py
@@ -37,7 +37,7 @@
from google.protobuf import wrappers_pb2 as wrappers # type: ignore
from google.type import date_pb2 as date # type: ignore
-from .transports.base import ApplicationServiceTransport
+from .transports.base import ApplicationServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import ApplicationServiceGrpcAsyncIOTransport
from .client import ApplicationServiceClient
@@ -53,6 +53,9 @@ class ApplicationServiceAsyncClient:
DEFAULT_MTLS_ENDPOINT = ApplicationServiceClient.DEFAULT_MTLS_ENDPOINT
application_path = staticmethod(ApplicationServiceClient.application_path)
+ parse_application_path = staticmethod(
+ ApplicationServiceClient.parse_application_path
+ )
from_service_account_file = ApplicationServiceClient.from_service_account_file
from_service_account_json = from_service_account_file
@@ -68,6 +71,7 @@ def __init__(
credentials: credentials.Credentials = None,
transport: Union[str, ApplicationServiceTransport] = "grpc_asyncio",
client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the application service client.
@@ -83,16 +87,19 @@ def __init__(
client_options (ClientOptions): Custom options for the client. It
won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -100,7 +107,10 @@ def __init__(
"""
self._client = ApplicationServiceClient(
- credentials=credentials, transport=transport, client_options=client_options,
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
)
async def create_application(
@@ -172,7 +182,7 @@ async def create_application(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.create_application,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -252,11 +262,11 @@ async def get_application(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -328,7 +338,7 @@ async def update_application(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.update_application,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -403,11 +413,11 @@ async def delete_application(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -488,11 +498,11 @@ async def list_applications(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -515,11 +525,11 @@ async def list_applications(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("ApplicationServiceAsyncClient",)
diff --git a/google/cloud/talent_v4beta1/services/application_service/client.py b/google/cloud/talent_v4beta1/services/application_service/client.py
index 8c5153f2..451c12bd 100644
--- a/google/cloud/talent_v4beta1/services/application_service/client.py
+++ b/google/cloud/talent_v4beta1/services/application_service/client.py
@@ -16,17 +16,19 @@
#
from collections import OrderedDict
+from distutils import util
import os
import re
-from typing import Callable, Dict, Sequence, Tuple, Type, Union
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
import pkg_resources
-import google.api_core.client_options as ClientOptions # type: ignore
+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 gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
from google.auth import 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
from google.oauth2 import service_account # type: ignore
@@ -39,7 +41,7 @@
from google.protobuf import wrappers_pb2 as wrappers # type: ignore
from google.type import date_pb2 as date # type: ignore
-from .transports.base import ApplicationServiceTransport
+from .transports.base import ApplicationServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import ApplicationServiceGrpcTransport
from .transports.grpc_asyncio import ApplicationServiceGrpcAsyncIOTransport
@@ -159,9 +161,10 @@ def parse_application_path(path: str) -> Dict[str, str]:
def __init__(
self,
*,
- credentials: credentials.Credentials = None,
- transport: Union[str, ApplicationServiceTransport] = None,
- client_options: ClientOptions = None,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, ApplicationServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the application service client.
@@ -174,48 +177,74 @@ def __init__(
transport (Union[str, ~.ApplicationServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
if isinstance(client_options, dict):
- client_options = ClientOptions.from_dict(client_options)
+ client_options = client_options_lib.from_dict(client_options)
if client_options is None:
- client_options = ClientOptions.ClientOptions()
+ client_options = client_options_lib.ClientOptions()
- if client_options.api_endpoint is None:
- use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
if use_mtls_env == "never":
- client_options.api_endpoint = self.DEFAULT_ENDPOINT
+ api_endpoint = self.DEFAULT_ENDPOINT
elif use_mtls_env == "always":
- client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
+ api_endpoint = self.DEFAULT_MTLS_ENDPOINT
elif use_mtls_env == "auto":
- has_client_cert_source = (
- client_options.client_cert_source is not None
- or mtls.has_default_client_cert_source()
- )
- client_options.api_endpoint = (
- self.DEFAULT_MTLS_ENDPOINT
- if has_client_cert_source
- else self.DEFAULT_ENDPOINT
+ api_endpoint = (
+ self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
)
else:
raise MutualTLSChannelError(
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
)
# Save or instantiate the transport.
@@ -239,11 +268,11 @@ def __init__(
self._transport = Transport(
credentials=credentials,
credentials_file=client_options.credentials_file,
- host=client_options.api_endpoint,
+ host=api_endpoint,
scopes=client_options.scopes,
- api_mtls_endpoint=client_options.api_endpoint,
- client_cert_source=client_options.client_cert_source,
+ ssl_channel_credentials=ssl_credentials,
quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
)
def create_application(
@@ -644,11 +673,11 @@ def list_applications(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("ApplicationServiceClient",)
diff --git a/google/cloud/talent_v4beta1/services/application_service/transports/base.py b/google/cloud/talent_v4beta1/services/application_service/transports/base.py
index 5dbc0fd6..83ba6405 100644
--- a/google/cloud/talent_v4beta1/services/application_service/transports/base.py
+++ b/google/cloud/talent_v4beta1/services/application_service/transports/base.py
@@ -19,7 +19,7 @@
import typing
import pkg_resources
-from google import auth
+from google import auth # type: ignore
from google.api_core import exceptions # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
@@ -32,11 +32,11 @@
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
class ApplicationServiceTransport(abc.ABC):
@@ -55,6 +55,7 @@ def __init__(
credentials_file: typing.Optional[str] = None,
scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES,
quota_project_id: typing.Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
**kwargs,
) -> None:
"""Instantiate the transport.
@@ -72,6 +73,11 @@ def __init__(
scope (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):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
@@ -99,13 +105,13 @@ def __init__(
self._credentials = credentials
# Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages()
+ self._prep_wrapped_messages(client_info)
- def _prep_wrapped_messages(self):
+ def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
self.create_application: gapic_v1.method.wrap_method(
- self.create_application, default_timeout=30.0, client_info=_client_info,
+ self.create_application, default_timeout=30.0, client_info=client_info,
),
self.get_application: gapic_v1.method.wrap_method(
self.get_application,
@@ -114,14 +120,14 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.update_application: gapic_v1.method.wrap_method(
- self.update_application, default_timeout=30.0, client_info=_client_info,
+ self.update_application, default_timeout=30.0, client_info=client_info,
),
self.delete_application: gapic_v1.method.wrap_method(
self.delete_application,
@@ -130,11 +136,11 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.list_applications: gapic_v1.method.wrap_method(
self.list_applications,
@@ -143,11 +149,11 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
}
diff --git a/google/cloud/talent_v4beta1/services/application_service/transports/grpc.py b/google/cloud/talent_v4beta1/services/application_service/transports/grpc.py
index 2d6a96cb..44696413 100644
--- a/google/cloud/talent_v4beta1/services/application_service/transports/grpc.py
+++ b/google/cloud/talent_v4beta1/services/application_service/transports/grpc.py
@@ -15,14 +15,15 @@
# limitations under the License.
#
+import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple
from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
-
import grpc # type: ignore
from google.cloud.talent_v4beta1.types import application
@@ -30,7 +31,7 @@
from google.cloud.talent_v4beta1.types import application_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import ApplicationServiceTransport
+from .base import ApplicationServiceTransport, DEFAULT_CLIENT_INFO
class ApplicationServiceGrpcTransport(ApplicationServiceTransport):
@@ -59,7 +60,9 @@ def __init__(
channel: grpc.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id: Optional[str] = None
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -78,16 +81,23 @@ def __init__(
ignored if ``channel`` is provided.
channel (Optional[grpc.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
@@ -103,6 +113,11 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
@@ -133,6 +148,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
self._stubs = {} # type: Dict[str, Callable]
@@ -143,6 +175,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
@classmethod
@@ -153,7 +186,7 @@ def create_channel(
credentials_file: str = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
- **kwargs
+ **kwargs,
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
@@ -187,7 +220,7 @@ def create_channel(
credentials_file=credentials_file,
scopes=scopes,
quota_project_id=quota_project_id,
- **kwargs
+ **kwargs,
)
@property
@@ -197,13 +230,6 @@ def grpc_channel(self) -> grpc.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/application_service/transports/grpc_asyncio.py b/google/cloud/talent_v4beta1/services/application_service/transports/grpc_asyncio.py
index d4cc0a9a..9e466530 100644
--- a/google/cloud/talent_v4beta1/services/application_service/transports/grpc_asyncio.py
+++ b/google/cloud/talent_v4beta1/services/application_service/transports/grpc_asyncio.py
@@ -15,9 +15,12 @@
# limitations under the License.
#
+import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+from google.api_core import gapic_v1 # type: ignore
from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
@@ -29,7 +32,7 @@
from google.cloud.talent_v4beta1.types import application_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import ApplicationServiceTransport
+from .base import ApplicationServiceTransport, DEFAULT_CLIENT_INFO
from .grpc import ApplicationServiceGrpcTransport
@@ -101,7 +104,9 @@ def __init__(
channel: aio.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -121,16 +126,23 @@ def __init__(
are passed to :func:`google.auth.default`.
channel (Optional[aio.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -146,12 +158,22 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
else api_mtls_endpoint + ":443"
)
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
# Create SSL credentials with client_cert_source or application
# default SSL credentials.
if client_cert_source:
@@ -171,6 +193,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
# Run the base constructor.
super().__init__(
@@ -179,6 +218,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
self._stubs = {}
@@ -190,13 +230,6 @@ def grpc_channel(self) -> aio.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/company_service/async_client.py b/google/cloud/talent_v4beta1/services/company_service/async_client.py
index 1fd21447..a26d1475 100644
--- a/google/cloud/talent_v4beta1/services/company_service/async_client.py
+++ b/google/cloud/talent_v4beta1/services/company_service/async_client.py
@@ -34,7 +34,7 @@
from google.cloud.talent_v4beta1.types import company as gct_company
from google.cloud.talent_v4beta1.types import company_service
-from .transports.base import CompanyServiceTransport
+from .transports.base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import CompanyServiceGrpcAsyncIOTransport
from .client import CompanyServiceClient
@@ -50,6 +50,7 @@ class CompanyServiceAsyncClient:
DEFAULT_MTLS_ENDPOINT = CompanyServiceClient.DEFAULT_MTLS_ENDPOINT
company_path = staticmethod(CompanyServiceClient.company_path)
+ parse_company_path = staticmethod(CompanyServiceClient.parse_company_path)
from_service_account_file = CompanyServiceClient.from_service_account_file
from_service_account_json = from_service_account_file
@@ -64,6 +65,7 @@ def __init__(
credentials: credentials.Credentials = None,
transport: Union[str, CompanyServiceTransport] = "grpc_asyncio",
client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the company service client.
@@ -79,16 +81,19 @@ def __init__(
client_options (ClientOptions): Custom options for the client. It
won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -96,7 +101,10 @@ def __init__(
"""
self._client = CompanyServiceClient(
- credentials=credentials, transport=transport, client_options=client_options,
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
)
async def create_company(
@@ -173,7 +181,7 @@ async def create_company(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.create_company,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -260,11 +268,11 @@ async def get_company(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -340,7 +348,7 @@ async def update_company(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.update_company,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -419,11 +427,11 @@ async def delete_company(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -506,11 +514,11 @@ async def list_companies(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -533,11 +541,11 @@ async def list_companies(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("CompanyServiceAsyncClient",)
diff --git a/google/cloud/talent_v4beta1/services/company_service/client.py b/google/cloud/talent_v4beta1/services/company_service/client.py
index 0a323981..b180385e 100644
--- a/google/cloud/talent_v4beta1/services/company_service/client.py
+++ b/google/cloud/talent_v4beta1/services/company_service/client.py
@@ -16,17 +16,19 @@
#
from collections import OrderedDict
+from distutils import util
import os
import re
-from typing import Callable, Dict, Sequence, Tuple, Type, Union
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
import pkg_resources
-import google.api_core.client_options as ClientOptions # type: ignore
+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 gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
from google.auth import 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
from google.oauth2 import service_account # type: ignore
@@ -36,7 +38,7 @@
from google.cloud.talent_v4beta1.types import company as gct_company
from google.cloud.talent_v4beta1.types import company_service
-from .transports.base import CompanyServiceTransport
+from .transports.base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import CompanyServiceGrpcTransport
from .transports.grpc_asyncio import CompanyServiceGrpcAsyncIOTransport
@@ -152,9 +154,10 @@ def parse_company_path(path: str) -> Dict[str, str]:
def __init__(
self,
*,
- credentials: credentials.Credentials = None,
- transport: Union[str, CompanyServiceTransport] = None,
- client_options: ClientOptions = None,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, CompanyServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the company service client.
@@ -167,48 +170,74 @@ def __init__(
transport (Union[str, ~.CompanyServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
if isinstance(client_options, dict):
- client_options = ClientOptions.from_dict(client_options)
+ client_options = client_options_lib.from_dict(client_options)
if client_options is None:
- client_options = ClientOptions.ClientOptions()
+ client_options = client_options_lib.ClientOptions()
- if client_options.api_endpoint is None:
- use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
if use_mtls_env == "never":
- client_options.api_endpoint = self.DEFAULT_ENDPOINT
+ api_endpoint = self.DEFAULT_ENDPOINT
elif use_mtls_env == "always":
- client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
+ api_endpoint = self.DEFAULT_MTLS_ENDPOINT
elif use_mtls_env == "auto":
- has_client_cert_source = (
- client_options.client_cert_source is not None
- or mtls.has_default_client_cert_source()
- )
- client_options.api_endpoint = (
- self.DEFAULT_MTLS_ENDPOINT
- if has_client_cert_source
- else self.DEFAULT_ENDPOINT
+ api_endpoint = (
+ self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
)
else:
raise MutualTLSChannelError(
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
)
# Save or instantiate the transport.
@@ -232,11 +261,11 @@ def __init__(
self._transport = Transport(
credentials=credentials,
credentials_file=client_options.credentials_file,
- host=client_options.api_endpoint,
+ host=api_endpoint,
scopes=client_options.scopes,
- api_mtls_endpoint=client_options.api_endpoint,
- client_cert_source=client_options.client_cert_source,
+ ssl_channel_credentials=ssl_credentials,
quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
)
def create_company(
@@ -659,11 +688,11 @@ def list_companies(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("CompanyServiceClient",)
diff --git a/google/cloud/talent_v4beta1/services/company_service/transports/base.py b/google/cloud/talent_v4beta1/services/company_service/transports/base.py
index 8a1ec615..39fb541b 100644
--- a/google/cloud/talent_v4beta1/services/company_service/transports/base.py
+++ b/google/cloud/talent_v4beta1/services/company_service/transports/base.py
@@ -19,7 +19,7 @@
import typing
import pkg_resources
-from google import auth
+from google import auth # type: ignore
from google.api_core import exceptions # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
@@ -32,11 +32,11 @@
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
class CompanyServiceTransport(abc.ABC):
@@ -55,6 +55,7 @@ def __init__(
credentials_file: typing.Optional[str] = None,
scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES,
quota_project_id: typing.Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
**kwargs,
) -> None:
"""Instantiate the transport.
@@ -72,6 +73,11 @@ def __init__(
scope (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):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
@@ -99,13 +105,13 @@ def __init__(
self._credentials = credentials
# Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages()
+ self._prep_wrapped_messages(client_info)
- def _prep_wrapped_messages(self):
+ def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
self.create_company: gapic_v1.method.wrap_method(
- self.create_company, default_timeout=30.0, client_info=_client_info,
+ self.create_company, default_timeout=30.0, client_info=client_info,
),
self.get_company: gapic_v1.method.wrap_method(
self.get_company,
@@ -114,14 +120,14 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.update_company: gapic_v1.method.wrap_method(
- self.update_company, default_timeout=30.0, client_info=_client_info,
+ self.update_company, default_timeout=30.0, client_info=client_info,
),
self.delete_company: gapic_v1.method.wrap_method(
self.delete_company,
@@ -130,11 +136,11 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.list_companies: gapic_v1.method.wrap_method(
self.list_companies,
@@ -143,11 +149,11 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
}
diff --git a/google/cloud/talent_v4beta1/services/company_service/transports/grpc.py b/google/cloud/talent_v4beta1/services/company_service/transports/grpc.py
index d1b583d6..47b84500 100644
--- a/google/cloud/talent_v4beta1/services/company_service/transports/grpc.py
+++ b/google/cloud/talent_v4beta1/services/company_service/transports/grpc.py
@@ -15,14 +15,15 @@
# limitations under the License.
#
+import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple
from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
-
import grpc # type: ignore
from google.cloud.talent_v4beta1.types import company
@@ -30,7 +31,7 @@
from google.cloud.talent_v4beta1.types import company_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import CompanyServiceTransport
+from .base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
class CompanyServiceGrpcTransport(CompanyServiceTransport):
@@ -59,7 +60,9 @@ def __init__(
channel: grpc.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id: Optional[str] = None
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -78,16 +81,23 @@ def __init__(
ignored if ``channel`` is provided.
channel (Optional[grpc.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
@@ -103,6 +113,11 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
@@ -133,6 +148,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
self._stubs = {} # type: Dict[str, Callable]
@@ -143,6 +175,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
@classmethod
@@ -153,7 +186,7 @@ def create_channel(
credentials_file: str = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
- **kwargs
+ **kwargs,
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
@@ -187,7 +220,7 @@ def create_channel(
credentials_file=credentials_file,
scopes=scopes,
quota_project_id=quota_project_id,
- **kwargs
+ **kwargs,
)
@property
@@ -197,13 +230,6 @@ def grpc_channel(self) -> grpc.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/company_service/transports/grpc_asyncio.py b/google/cloud/talent_v4beta1/services/company_service/transports/grpc_asyncio.py
index c5a11616..9806cd0a 100644
--- a/google/cloud/talent_v4beta1/services/company_service/transports/grpc_asyncio.py
+++ b/google/cloud/talent_v4beta1/services/company_service/transports/grpc_asyncio.py
@@ -15,9 +15,12 @@
# limitations under the License.
#
+import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+from google.api_core import gapic_v1 # type: ignore
from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
@@ -29,7 +32,7 @@
from google.cloud.talent_v4beta1.types import company_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import CompanyServiceTransport
+from .base import CompanyServiceTransport, DEFAULT_CLIENT_INFO
from .grpc import CompanyServiceGrpcTransport
@@ -101,7 +104,9 @@ def __init__(
channel: aio.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -121,16 +126,23 @@ def __init__(
are passed to :func:`google.auth.default`.
channel (Optional[aio.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -146,12 +158,22 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
else api_mtls_endpoint + ":443"
)
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
# Create SSL credentials with client_cert_source or application
# default SSL credentials.
if client_cert_source:
@@ -171,6 +193,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
# Run the base constructor.
super().__init__(
@@ -179,6 +218,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
self._stubs = {}
@@ -190,13 +230,6 @@ def grpc_channel(self) -> aio.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/completion/async_client.py b/google/cloud/talent_v4beta1/services/completion/async_client.py
index 268aabed..7c46b2c7 100644
--- a/google/cloud/talent_v4beta1/services/completion/async_client.py
+++ b/google/cloud/talent_v4beta1/services/completion/async_client.py
@@ -31,7 +31,7 @@
from google.cloud.talent_v4beta1.types import common
from google.cloud.talent_v4beta1.types import completion_service
-from .transports.base import CompletionTransport
+from .transports.base import CompletionTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import CompletionGrpcAsyncIOTransport
from .client import CompletionClient
@@ -57,6 +57,7 @@ def __init__(
credentials: credentials.Credentials = None,
transport: Union[str, CompletionTransport] = "grpc_asyncio",
client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the completion client.
@@ -72,16 +73,19 @@ def __init__(
client_options (ClientOptions): Custom options for the client. It
won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -89,7 +93,10 @@ def __init__(
"""
self._client = CompletionClient(
- credentials=credentials, transport=transport, client_options=client_options,
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
)
async def complete_query(
@@ -131,11 +138,11 @@ async def complete_query(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -152,11 +159,11 @@ async def complete_query(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("CompletionAsyncClient",)
diff --git a/google/cloud/talent_v4beta1/services/completion/client.py b/google/cloud/talent_v4beta1/services/completion/client.py
index 9efe4cd5..21fa1335 100644
--- a/google/cloud/talent_v4beta1/services/completion/client.py
+++ b/google/cloud/talent_v4beta1/services/completion/client.py
@@ -16,24 +16,26 @@
#
from collections import OrderedDict
+from distutils import util
import os
import re
-from typing import Callable, Dict, Sequence, Tuple, Type, Union
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
import pkg_resources
-import google.api_core.client_options as ClientOptions # type: ignore
+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 gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
from google.auth import 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
from google.oauth2 import service_account # type: ignore
from google.cloud.talent_v4beta1.types import common
from google.cloud.talent_v4beta1.types import completion_service
-from .transports.base import CompletionTransport
+from .transports.base import CompletionTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import CompletionGrpcTransport
from .transports.grpc_asyncio import CompletionGrpcAsyncIOTransport
@@ -129,9 +131,10 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
def __init__(
self,
*,
- credentials: credentials.Credentials = None,
- transport: Union[str, CompletionTransport] = None,
- client_options: ClientOptions = None,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, CompletionTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the completion client.
@@ -144,48 +147,74 @@ def __init__(
transport (Union[str, ~.CompletionTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
if isinstance(client_options, dict):
- client_options = ClientOptions.from_dict(client_options)
+ client_options = client_options_lib.from_dict(client_options)
if client_options is None:
- client_options = ClientOptions.ClientOptions()
+ client_options = client_options_lib.ClientOptions()
- if client_options.api_endpoint is None:
- use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
if use_mtls_env == "never":
- client_options.api_endpoint = self.DEFAULT_ENDPOINT
+ api_endpoint = self.DEFAULT_ENDPOINT
elif use_mtls_env == "always":
- client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
+ api_endpoint = self.DEFAULT_MTLS_ENDPOINT
elif use_mtls_env == "auto":
- has_client_cert_source = (
- client_options.client_cert_source is not None
- or mtls.has_default_client_cert_source()
- )
- client_options.api_endpoint = (
- self.DEFAULT_MTLS_ENDPOINT
- if has_client_cert_source
- else self.DEFAULT_ENDPOINT
+ api_endpoint = (
+ self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
)
else:
raise MutualTLSChannelError(
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
)
# Save or instantiate the transport.
@@ -209,11 +238,11 @@ def __init__(
self._transport = Transport(
credentials=credentials,
credentials_file=client_options.credentials_file,
- host=client_options.api_endpoint,
+ host=api_endpoint,
scopes=client_options.scopes,
- api_mtls_endpoint=client_options.api_endpoint,
- client_cert_source=client_options.client_cert_source,
+ ssl_channel_credentials=ssl_credentials,
quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
)
def complete_query(
@@ -269,11 +298,11 @@ def complete_query(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("CompletionClient",)
diff --git a/google/cloud/talent_v4beta1/services/completion/transports/base.py b/google/cloud/talent_v4beta1/services/completion/transports/base.py
index 50688320..95e41990 100644
--- a/google/cloud/talent_v4beta1/services/completion/transports/base.py
+++ b/google/cloud/talent_v4beta1/services/completion/transports/base.py
@@ -19,7 +19,7 @@
import typing
import pkg_resources
-from google import auth
+from google import auth # type: ignore
from google.api_core import exceptions # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
@@ -29,11 +29,11 @@
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
class CompletionTransport(abc.ABC):
@@ -52,6 +52,7 @@ def __init__(
credentials_file: typing.Optional[str] = None,
scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES,
quota_project_id: typing.Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
**kwargs,
) -> None:
"""Instantiate the transport.
@@ -69,6 +70,11 @@ def __init__(
scope (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):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
@@ -96,9 +102,9 @@ def __init__(
self._credentials = credentials
# Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages()
+ self._prep_wrapped_messages(client_info)
- def _prep_wrapped_messages(self):
+ def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
self.complete_query: gapic_v1.method.wrap_method(
@@ -108,11 +114,11 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
}
diff --git a/google/cloud/talent_v4beta1/services/completion/transports/grpc.py b/google/cloud/talent_v4beta1/services/completion/transports/grpc.py
index 24e2add7..9661fd31 100644
--- a/google/cloud/talent_v4beta1/services/completion/transports/grpc.py
+++ b/google/cloud/talent_v4beta1/services/completion/transports/grpc.py
@@ -15,19 +15,20 @@
# limitations under the License.
#
+import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple
from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
-
import grpc # type: ignore
from google.cloud.talent_v4beta1.types import completion_service
-from .base import CompletionTransport
+from .base import CompletionTransport, DEFAULT_CLIENT_INFO
class CompletionGrpcTransport(CompletionTransport):
@@ -55,7 +56,9 @@ def __init__(
channel: grpc.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id: Optional[str] = None
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -74,16 +77,23 @@ def __init__(
ignored if ``channel`` is provided.
channel (Optional[grpc.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
@@ -99,6 +109,11 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
@@ -129,6 +144,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
self._stubs = {} # type: Dict[str, Callable]
@@ -139,6 +171,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
@classmethod
@@ -149,7 +182,7 @@ def create_channel(
credentials_file: str = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
- **kwargs
+ **kwargs,
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
@@ -183,7 +216,7 @@ def create_channel(
credentials_file=credentials_file,
scopes=scopes,
quota_project_id=quota_project_id,
- **kwargs
+ **kwargs,
)
@property
@@ -193,13 +226,6 @@ def grpc_channel(self) -> grpc.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/completion/transports/grpc_asyncio.py b/google/cloud/talent_v4beta1/services/completion/transports/grpc_asyncio.py
index 5e153a28..a47bd5d1 100644
--- a/google/cloud/talent_v4beta1/services/completion/transports/grpc_asyncio.py
+++ b/google/cloud/talent_v4beta1/services/completion/transports/grpc_asyncio.py
@@ -15,9 +15,12 @@
# limitations under the License.
#
+import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+from google.api_core import gapic_v1 # type: ignore
from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
@@ -26,7 +29,7 @@
from google.cloud.talent_v4beta1.types import completion_service
-from .base import CompletionTransport
+from .base import CompletionTransport, DEFAULT_CLIENT_INFO
from .grpc import CompletionGrpcTransport
@@ -97,7 +100,9 @@ def __init__(
channel: aio.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -117,16 +122,23 @@ def __init__(
are passed to :func:`google.auth.default`.
channel (Optional[aio.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -142,12 +154,22 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
else api_mtls_endpoint + ":443"
)
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
# Create SSL credentials with client_cert_source or application
# default SSL credentials.
if client_cert_source:
@@ -167,6 +189,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
# Run the base constructor.
super().__init__(
@@ -175,6 +214,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
self._stubs = {}
@@ -186,13 +226,6 @@ def grpc_channel(self) -> aio.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/event_service/async_client.py b/google/cloud/talent_v4beta1/services/event_service/async_client.py
index 668407fb..2404be11 100644
--- a/google/cloud/talent_v4beta1/services/event_service/async_client.py
+++ b/google/cloud/talent_v4beta1/services/event_service/async_client.py
@@ -32,7 +32,7 @@
from google.cloud.talent_v4beta1.types import event_service
from google.protobuf import timestamp_pb2 as timestamp # type: ignore
-from .transports.base import EventServiceTransport
+from .transports.base import EventServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import EventServiceGrpcAsyncIOTransport
from .client import EventServiceClient
@@ -58,6 +58,7 @@ def __init__(
credentials: credentials.Credentials = None,
transport: Union[str, EventServiceTransport] = "grpc_asyncio",
client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the event service client.
@@ -73,16 +74,19 @@ def __init__(
client_options (ClientOptions): Custom options for the client. It
won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -90,7 +94,10 @@ def __init__(
"""
self._client = EventServiceClient(
- credentials=credentials, transport=transport, client_options=client_options,
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
)
async def create_client_event(
@@ -178,7 +185,7 @@ async def create_client_event(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.create_client_event,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -195,11 +202,11 @@ async def create_client_event(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("EventServiceAsyncClient",)
diff --git a/google/cloud/talent_v4beta1/services/event_service/client.py b/google/cloud/talent_v4beta1/services/event_service/client.py
index b24e2173..fc49c064 100644
--- a/google/cloud/talent_v4beta1/services/event_service/client.py
+++ b/google/cloud/talent_v4beta1/services/event_service/client.py
@@ -16,17 +16,19 @@
#
from collections import OrderedDict
+from distutils import util
import os
import re
-from typing import Callable, Dict, Sequence, Tuple, Type, Union
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
import pkg_resources
-import google.api_core.client_options as ClientOptions # type: ignore
+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 gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
from google.auth import 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
from google.oauth2 import service_account # type: ignore
@@ -34,7 +36,7 @@
from google.cloud.talent_v4beta1.types import event_service
from google.protobuf import timestamp_pb2 as timestamp # type: ignore
-from .transports.base import EventServiceTransport
+from .transports.base import EventServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import EventServiceGrpcTransport
from .transports.grpc_asyncio import EventServiceGrpcAsyncIOTransport
@@ -130,9 +132,10 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
def __init__(
self,
*,
- credentials: credentials.Credentials = None,
- transport: Union[str, EventServiceTransport] = None,
- client_options: ClientOptions = None,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, EventServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the event service client.
@@ -145,48 +148,74 @@ def __init__(
transport (Union[str, ~.EventServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
if isinstance(client_options, dict):
- client_options = ClientOptions.from_dict(client_options)
+ client_options = client_options_lib.from_dict(client_options)
if client_options is None:
- client_options = ClientOptions.ClientOptions()
+ client_options = client_options_lib.ClientOptions()
- if client_options.api_endpoint is None:
- use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
if use_mtls_env == "never":
- client_options.api_endpoint = self.DEFAULT_ENDPOINT
+ api_endpoint = self.DEFAULT_ENDPOINT
elif use_mtls_env == "always":
- client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
+ api_endpoint = self.DEFAULT_MTLS_ENDPOINT
elif use_mtls_env == "auto":
- has_client_cert_source = (
- client_options.client_cert_source is not None
- or mtls.has_default_client_cert_source()
- )
- client_options.api_endpoint = (
- self.DEFAULT_MTLS_ENDPOINT
- if has_client_cert_source
- else self.DEFAULT_ENDPOINT
+ api_endpoint = (
+ self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
)
else:
raise MutualTLSChannelError(
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
)
# Save or instantiate the transport.
@@ -210,11 +239,11 @@ def __init__(
self._transport = Transport(
credentials=credentials,
credentials_file=client_options.credentials_file,
- host=client_options.api_endpoint,
+ host=api_endpoint,
scopes=client_options.scopes,
- api_mtls_endpoint=client_options.api_endpoint,
- client_cert_source=client_options.client_cert_source,
+ ssl_channel_credentials=ssl_credentials,
quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
)
def create_client_event(
@@ -321,11 +350,11 @@ def create_client_event(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("EventServiceClient",)
diff --git a/google/cloud/talent_v4beta1/services/event_service/transports/base.py b/google/cloud/talent_v4beta1/services/event_service/transports/base.py
index 2394cfd0..cd643c9d 100644
--- a/google/cloud/talent_v4beta1/services/event_service/transports/base.py
+++ b/google/cloud/talent_v4beta1/services/event_service/transports/base.py
@@ -19,7 +19,7 @@
import typing
import pkg_resources
-from google import auth
+from google import auth # type: ignore
from google.api_core import exceptions # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
@@ -30,11 +30,11 @@
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
class EventServiceTransport(abc.ABC):
@@ -53,6 +53,7 @@ def __init__(
credentials_file: typing.Optional[str] = None,
scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES,
quota_project_id: typing.Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
**kwargs,
) -> None:
"""Instantiate the transport.
@@ -70,6 +71,11 @@ def __init__(
scope (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):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
@@ -97,15 +103,13 @@ def __init__(
self._credentials = credentials
# Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages()
+ self._prep_wrapped_messages(client_info)
- def _prep_wrapped_messages(self):
+ def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
self.create_client_event: gapic_v1.method.wrap_method(
- self.create_client_event,
- default_timeout=30.0,
- client_info=_client_info,
+ self.create_client_event, default_timeout=30.0, client_info=client_info,
),
}
diff --git a/google/cloud/talent_v4beta1/services/event_service/transports/grpc.py b/google/cloud/talent_v4beta1/services/event_service/transports/grpc.py
index 50109487..e870b468 100644
--- a/google/cloud/talent_v4beta1/services/event_service/transports/grpc.py
+++ b/google/cloud/talent_v4beta1/services/event_service/transports/grpc.py
@@ -15,20 +15,21 @@
# limitations under the License.
#
+import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple
from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
-
import grpc # type: ignore
from google.cloud.talent_v4beta1.types import event
from google.cloud.talent_v4beta1.types import event_service
-from .base import EventServiceTransport
+from .base import EventServiceTransport, DEFAULT_CLIENT_INFO
class EventServiceGrpcTransport(EventServiceTransport):
@@ -56,7 +57,9 @@ def __init__(
channel: grpc.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id: Optional[str] = None
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -75,16 +78,23 @@ def __init__(
ignored if ``channel`` is provided.
channel (Optional[grpc.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
@@ -100,6 +110,11 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
@@ -130,6 +145,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
self._stubs = {} # type: Dict[str, Callable]
@@ -140,6 +172,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
@classmethod
@@ -150,7 +183,7 @@ def create_channel(
credentials_file: str = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
- **kwargs
+ **kwargs,
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
@@ -184,7 +217,7 @@ def create_channel(
credentials_file=credentials_file,
scopes=scopes,
quota_project_id=quota_project_id,
- **kwargs
+ **kwargs,
)
@property
@@ -194,13 +227,6 @@ def grpc_channel(self) -> grpc.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/event_service/transports/grpc_asyncio.py b/google/cloud/talent_v4beta1/services/event_service/transports/grpc_asyncio.py
index 1d1235da..c2400f5d 100644
--- a/google/cloud/talent_v4beta1/services/event_service/transports/grpc_asyncio.py
+++ b/google/cloud/talent_v4beta1/services/event_service/transports/grpc_asyncio.py
@@ -15,9 +15,12 @@
# limitations under the License.
#
+import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+from google.api_core import gapic_v1 # type: ignore
from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
@@ -27,7 +30,7 @@
from google.cloud.talent_v4beta1.types import event
from google.cloud.talent_v4beta1.types import event_service
-from .base import EventServiceTransport
+from .base import EventServiceTransport, DEFAULT_CLIENT_INFO
from .grpc import EventServiceGrpcTransport
@@ -98,7 +101,9 @@ def __init__(
channel: aio.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -118,16 +123,23 @@ def __init__(
are passed to :func:`google.auth.default`.
channel (Optional[aio.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -143,12 +155,22 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
else api_mtls_endpoint + ":443"
)
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
# Create SSL credentials with client_cert_source or application
# default SSL credentials.
if client_cert_source:
@@ -168,6 +190,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
# Run the base constructor.
super().__init__(
@@ -176,6 +215,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
self._stubs = {}
@@ -187,13 +227,6 @@ def grpc_channel(self) -> aio.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/job_service/async_client.py b/google/cloud/talent_v4beta1/services/job_service/async_client.py
index 876d3477..ec355cf2 100644
--- a/google/cloud/talent_v4beta1/services/job_service/async_client.py
+++ b/google/cloud/talent_v4beta1/services/job_service/async_client.py
@@ -28,8 +28,8 @@
from google.auth import credentials # type: ignore
from google.oauth2 import service_account # type: ignore
-from google.api_core import operation
-from google.api_core import operation_async
+from google.api_core import operation # type: ignore
+from google.api_core import operation_async # type: ignore
from google.cloud.talent_v4beta1.services.job_service import pagers
from google.cloud.talent_v4beta1.types import common
from google.cloud.talent_v4beta1.types import job
@@ -37,7 +37,7 @@
from google.cloud.talent_v4beta1.types import job_service
from google.protobuf import timestamp_pb2 as timestamp # type: ignore
-from .transports.base import JobServiceTransport
+from .transports.base import JobServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import JobServiceGrpcAsyncIOTransport
from .client import JobServiceClient
@@ -53,6 +53,7 @@ class JobServiceAsyncClient:
DEFAULT_MTLS_ENDPOINT = JobServiceClient.DEFAULT_MTLS_ENDPOINT
job_path = staticmethod(JobServiceClient.job_path)
+ parse_job_path = staticmethod(JobServiceClient.parse_job_path)
from_service_account_file = JobServiceClient.from_service_account_file
from_service_account_json = from_service_account_file
@@ -67,6 +68,7 @@ def __init__(
credentials: credentials.Credentials = None,
transport: Union[str, JobServiceTransport] = "grpc_asyncio",
client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the job service client.
@@ -82,16 +84,19 @@ def __init__(
client_options (ClientOptions): Custom options for the client. It
won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -99,7 +104,10 @@ def __init__(
"""
self._client = JobServiceClient(
- credentials=credentials, transport=transport, client_options=client_options,
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
)
async def create_job(
@@ -176,7 +184,7 @@ async def create_job(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.create_job,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -269,7 +277,7 @@ async def batch_create_jobs(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.batch_create_jobs,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -361,11 +369,11 @@ async def get_job(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -440,7 +448,7 @@ async def update_job(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.update_job,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -533,7 +541,7 @@ async def batch_update_jobs(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.batch_update_jobs,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -617,11 +625,11 @@ async def delete_job(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -710,7 +718,7 @@ async def batch_delete_jobs(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.batch_delete_jobs,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -820,11 +828,11 @@ async def list_jobs(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -889,7 +897,7 @@ async def search_jobs(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.search_jobs,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -960,7 +968,7 @@ async def search_jobs_for_alert(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.search_jobs_for_alert,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -983,11 +991,11 @@ async def search_jobs_for_alert(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("JobServiceAsyncClient",)
diff --git a/google/cloud/talent_v4beta1/services/job_service/client.py b/google/cloud/talent_v4beta1/services/job_service/client.py
index 79149b6a..bbcd5035 100644
--- a/google/cloud/talent_v4beta1/services/job_service/client.py
+++ b/google/cloud/talent_v4beta1/services/job_service/client.py
@@ -16,22 +16,24 @@
#
from collections import OrderedDict
+from distutils import util
import os
import re
-from typing import Callable, Dict, Sequence, Tuple, Type, Union
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
import pkg_resources
-import google.api_core.client_options as ClientOptions # type: ignore
+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 gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
from google.auth import 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
from google.oauth2 import service_account # type: ignore
-from google.api_core import operation
-from google.api_core import operation_async
+from google.api_core import operation # type: ignore
+from google.api_core import operation_async # type: ignore
from google.cloud.talent_v4beta1.services.job_service import pagers
from google.cloud.talent_v4beta1.types import common
from google.cloud.talent_v4beta1.types import job
@@ -39,7 +41,7 @@
from google.cloud.talent_v4beta1.types import job_service
from google.protobuf import timestamp_pb2 as timestamp # type: ignore
-from .transports.base import JobServiceTransport
+from .transports.base import JobServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import JobServiceGrpcTransport
from .transports.grpc_asyncio import JobServiceGrpcAsyncIOTransport
@@ -153,9 +155,10 @@ def parse_job_path(path: str) -> Dict[str, str]:
def __init__(
self,
*,
- credentials: credentials.Credentials = None,
- transport: Union[str, JobServiceTransport] = None,
- client_options: ClientOptions = None,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, JobServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the job service client.
@@ -168,48 +171,74 @@ def __init__(
transport (Union[str, ~.JobServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
if isinstance(client_options, dict):
- client_options = ClientOptions.from_dict(client_options)
+ client_options = client_options_lib.from_dict(client_options)
if client_options is None:
- client_options = ClientOptions.ClientOptions()
+ client_options = client_options_lib.ClientOptions()
- if client_options.api_endpoint is None:
- use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
if use_mtls_env == "never":
- client_options.api_endpoint = self.DEFAULT_ENDPOINT
+ api_endpoint = self.DEFAULT_ENDPOINT
elif use_mtls_env == "always":
- client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
+ api_endpoint = self.DEFAULT_MTLS_ENDPOINT
elif use_mtls_env == "auto":
- has_client_cert_source = (
- client_options.client_cert_source is not None
- or mtls.has_default_client_cert_source()
- )
- client_options.api_endpoint = (
- self.DEFAULT_MTLS_ENDPOINT
- if has_client_cert_source
- else self.DEFAULT_ENDPOINT
+ api_endpoint = (
+ self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
)
else:
raise MutualTLSChannelError(
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
)
# Save or instantiate the transport.
@@ -233,11 +262,11 @@ def __init__(
self._transport = Transport(
credentials=credentials,
credentials_file=client_options.credentials_file,
- host=client_options.api_endpoint,
+ host=api_endpoint,
scopes=client_options.scopes,
- api_mtls_endpoint=client_options.api_endpoint,
- client_cert_source=client_options.client_cert_source,
+ ssl_channel_credentials=ssl_credentials,
quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
)
def create_job(
@@ -1115,11 +1144,11 @@ def search_jobs_for_alert(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("JobServiceClient",)
diff --git a/google/cloud/talent_v4beta1/services/job_service/transports/base.py b/google/cloud/talent_v4beta1/services/job_service/transports/base.py
index 7214b944..ffef5f17 100644
--- a/google/cloud/talent_v4beta1/services/job_service/transports/base.py
+++ b/google/cloud/talent_v4beta1/services/job_service/transports/base.py
@@ -19,7 +19,7 @@
import typing
import pkg_resources
-from google import auth
+from google import auth # type: ignore
from google.api_core import exceptions # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
@@ -34,11 +34,11 @@
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
class JobServiceTransport(abc.ABC):
@@ -57,6 +57,7 @@ def __init__(
credentials_file: typing.Optional[str] = None,
scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES,
quota_project_id: typing.Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
**kwargs,
) -> None:
"""Instantiate the transport.
@@ -74,6 +75,11 @@ def __init__(
scope (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):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
@@ -101,16 +107,16 @@ def __init__(
self._credentials = credentials
# Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages()
+ self._prep_wrapped_messages(client_info)
- def _prep_wrapped_messages(self):
+ def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
self.create_job: gapic_v1.method.wrap_method(
- self.create_job, default_timeout=30.0, client_info=_client_info,
+ self.create_job, default_timeout=30.0, client_info=client_info,
),
self.batch_create_jobs: gapic_v1.method.wrap_method(
- self.batch_create_jobs, default_timeout=30.0, client_info=_client_info,
+ self.batch_create_jobs, default_timeout=30.0, client_info=client_info,
),
self.get_job: gapic_v1.method.wrap_method(
self.get_job,
@@ -119,17 +125,17 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.update_job: gapic_v1.method.wrap_method(
- self.update_job, default_timeout=30.0, client_info=_client_info,
+ self.update_job, default_timeout=30.0, client_info=client_info,
),
self.batch_update_jobs: gapic_v1.method.wrap_method(
- self.batch_update_jobs, default_timeout=30.0, client_info=_client_info,
+ self.batch_update_jobs, default_timeout=30.0, client_info=client_info,
),
self.delete_job: gapic_v1.method.wrap_method(
self.delete_job,
@@ -138,14 +144,14 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.batch_delete_jobs: gapic_v1.method.wrap_method(
- self.batch_delete_jobs, default_timeout=30.0, client_info=_client_info,
+ self.batch_delete_jobs, default_timeout=30.0, client_info=client_info,
),
self.list_jobs: gapic_v1.method.wrap_method(
self.list_jobs,
@@ -154,19 +160,19 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.search_jobs: gapic_v1.method.wrap_method(
- self.search_jobs, default_timeout=30.0, client_info=_client_info,
+ self.search_jobs, default_timeout=30.0, client_info=client_info,
),
self.search_jobs_for_alert: gapic_v1.method.wrap_method(
self.search_jobs_for_alert,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
}
diff --git a/google/cloud/talent_v4beta1/services/job_service/transports/grpc.py b/google/cloud/talent_v4beta1/services/job_service/transports/grpc.py
index 85549fe7..b1113951 100644
--- a/google/cloud/talent_v4beta1/services/job_service/transports/grpc.py
+++ b/google/cloud/talent_v4beta1/services/job_service/transports/grpc.py
@@ -15,15 +15,16 @@
# limitations under the License.
#
+import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple
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
from google.auth.transport.grpc import SslCredentials # type: ignore
-
import grpc # type: ignore
from google.cloud.talent_v4beta1.types import job
@@ -32,7 +33,7 @@
from google.longrunning import operations_pb2 as operations # type: ignore
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import JobServiceTransport
+from .base import JobServiceTransport, DEFAULT_CLIENT_INFO
class JobServiceGrpcTransport(JobServiceTransport):
@@ -61,7 +62,9 @@ def __init__(
channel: grpc.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id: Optional[str] = None
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -80,16 +83,23 @@ def __init__(
ignored if ``channel`` is provided.
channel (Optional[grpc.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
@@ -105,6 +115,11 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
@@ -135,6 +150,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
self._stubs = {} # type: Dict[str, Callable]
@@ -145,6 +177,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
@classmethod
@@ -155,7 +188,7 @@ def create_channel(
credentials_file: str = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
- **kwargs
+ **kwargs,
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
@@ -189,7 +222,7 @@ def create_channel(
credentials_file=credentials_file,
scopes=scopes,
quota_project_id=quota_project_id,
- **kwargs
+ **kwargs,
)
@property
@@ -199,13 +232,6 @@ def grpc_channel(self) -> grpc.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/job_service/transports/grpc_asyncio.py b/google/cloud/talent_v4beta1/services/job_service/transports/grpc_asyncio.py
index b350d32d..0da963e3 100644
--- a/google/cloud/talent_v4beta1/services/job_service/transports/grpc_asyncio.py
+++ b/google/cloud/talent_v4beta1/services/job_service/transports/grpc_asyncio.py
@@ -15,10 +15,13 @@
# limitations under the License.
#
+import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+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.transport.grpc import SslCredentials # type: ignore
@@ -31,7 +34,7 @@
from google.longrunning import operations_pb2 as operations # type: ignore
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import JobServiceTransport
+from .base import JobServiceTransport, DEFAULT_CLIENT_INFO
from .grpc import JobServiceGrpcTransport
@@ -103,7 +106,9 @@ def __init__(
channel: aio.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -123,16 +128,23 @@ def __init__(
are passed to :func:`google.auth.default`.
channel (Optional[aio.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -148,12 +160,22 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
else api_mtls_endpoint + ":443"
)
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
# Create SSL credentials with client_cert_source or application
# default SSL credentials.
if client_cert_source:
@@ -173,6 +195,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
# Run the base constructor.
super().__init__(
@@ -181,6 +220,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
self._stubs = {}
@@ -192,13 +232,6 @@ def grpc_channel(self) -> aio.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/profile_service/async_client.py b/google/cloud/talent_v4beta1/services/profile_service/async_client.py
index 786f1760..6f039380 100644
--- a/google/cloud/talent_v4beta1/services/profile_service/async_client.py
+++ b/google/cloud/talent_v4beta1/services/profile_service/async_client.py
@@ -37,7 +37,7 @@
from google.protobuf import timestamp_pb2 as timestamp # type: ignore
from google.protobuf import wrappers_pb2 as wrappers # type: ignore
-from .transports.base import ProfileServiceTransport
+from .transports.base import ProfileServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import ProfileServiceGrpcAsyncIOTransport
from .client import ProfileServiceClient
@@ -53,6 +53,7 @@ class ProfileServiceAsyncClient:
DEFAULT_MTLS_ENDPOINT = ProfileServiceClient.DEFAULT_MTLS_ENDPOINT
profile_path = staticmethod(ProfileServiceClient.profile_path)
+ parse_profile_path = staticmethod(ProfileServiceClient.parse_profile_path)
from_service_account_file = ProfileServiceClient.from_service_account_file
from_service_account_json = from_service_account_file
@@ -67,6 +68,7 @@ def __init__(
credentials: credentials.Credentials = None,
transport: Union[str, ProfileServiceTransport] = "grpc_asyncio",
client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the profile service client.
@@ -82,16 +84,19 @@ def __init__(
client_options (ClientOptions): Custom options for the client. It
won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -99,7 +104,10 @@ def __init__(
"""
self._client = ProfileServiceClient(
- credentials=credentials, transport=transport, client_options=client_options,
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
)
async def list_profiles(
@@ -167,11 +175,11 @@ async def list_profiles(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -261,7 +269,7 @@ async def create_profile(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.create_profile,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -340,11 +348,11 @@ async def get_profile(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -416,7 +424,7 @@ async def update_profile(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.update_profile,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -491,11 +499,11 @@ async def delete_profile(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -555,7 +563,7 @@ async def search_profiles(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.search_profiles,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -578,11 +586,11 @@ async def search_profiles(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("ProfileServiceAsyncClient",)
diff --git a/google/cloud/talent_v4beta1/services/profile_service/client.py b/google/cloud/talent_v4beta1/services/profile_service/client.py
index 627735f6..89579796 100644
--- a/google/cloud/talent_v4beta1/services/profile_service/client.py
+++ b/google/cloud/talent_v4beta1/services/profile_service/client.py
@@ -16,17 +16,19 @@
#
from collections import OrderedDict
+from distutils import util
import os
import re
-from typing import Callable, Dict, Sequence, Tuple, Type, Union
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
import pkg_resources
-import google.api_core.client_options as ClientOptions # type: ignore
+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 gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
from google.auth import 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
from google.oauth2 import service_account # type: ignore
@@ -39,7 +41,7 @@
from google.protobuf import timestamp_pb2 as timestamp # type: ignore
from google.protobuf import wrappers_pb2 as wrappers # type: ignore
-from .transports.base import ProfileServiceTransport
+from .transports.base import ProfileServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import ProfileServiceGrpcTransport
from .transports.grpc_asyncio import ProfileServiceGrpcAsyncIOTransport
@@ -155,9 +157,10 @@ def parse_profile_path(path: str) -> Dict[str, str]:
def __init__(
self,
*,
- credentials: credentials.Credentials = None,
- transport: Union[str, ProfileServiceTransport] = None,
- client_options: ClientOptions = None,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, ProfileServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the profile service client.
@@ -170,48 +173,74 @@ def __init__(
transport (Union[str, ~.ProfileServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
if isinstance(client_options, dict):
- client_options = ClientOptions.from_dict(client_options)
+ client_options = client_options_lib.from_dict(client_options)
if client_options is None:
- client_options = ClientOptions.ClientOptions()
+ client_options = client_options_lib.ClientOptions()
- if client_options.api_endpoint is None:
- use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
if use_mtls_env == "never":
- client_options.api_endpoint = self.DEFAULT_ENDPOINT
+ api_endpoint = self.DEFAULT_ENDPOINT
elif use_mtls_env == "always":
- client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
+ api_endpoint = self.DEFAULT_MTLS_ENDPOINT
elif use_mtls_env == "auto":
- has_client_cert_source = (
- client_options.client_cert_source is not None
- or mtls.has_default_client_cert_source()
- )
- client_options.api_endpoint = (
- self.DEFAULT_MTLS_ENDPOINT
- if has_client_cert_source
- else self.DEFAULT_ENDPOINT
+ api_endpoint = (
+ self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
)
else:
raise MutualTLSChannelError(
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
)
# Save or instantiate the transport.
@@ -235,11 +264,11 @@ def __init__(
self._transport = Transport(
credentials=credentials,
credentials_file=client_options.credentials_file,
- host=client_options.api_endpoint,
+ host=api_endpoint,
scopes=client_options.scopes,
- api_mtls_endpoint=client_options.api_endpoint,
- client_cert_source=client_options.client_cert_source,
+ ssl_channel_credentials=ssl_credentials,
quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
)
def list_profiles(
@@ -705,11 +734,11 @@ def search_profiles(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("ProfileServiceClient",)
diff --git a/google/cloud/talent_v4beta1/services/profile_service/transports/base.py b/google/cloud/talent_v4beta1/services/profile_service/transports/base.py
index 707cc262..dbd36ea2 100644
--- a/google/cloud/talent_v4beta1/services/profile_service/transports/base.py
+++ b/google/cloud/talent_v4beta1/services/profile_service/transports/base.py
@@ -19,7 +19,7 @@
import typing
import pkg_resources
-from google import auth
+from google import auth # type: ignore
from google.api_core import exceptions # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
@@ -32,11 +32,11 @@
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
class ProfileServiceTransport(abc.ABC):
@@ -55,6 +55,7 @@ def __init__(
credentials_file: typing.Optional[str] = None,
scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES,
quota_project_id: typing.Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
**kwargs,
) -> None:
"""Instantiate the transport.
@@ -72,6 +73,11 @@ def __init__(
scope (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):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
@@ -99,9 +105,9 @@ def __init__(
self._credentials = credentials
# Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages()
+ self._prep_wrapped_messages(client_info)
- def _prep_wrapped_messages(self):
+ def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
self.list_profiles: gapic_v1.method.wrap_method(
@@ -111,14 +117,14 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.create_profile: gapic_v1.method.wrap_method(
- self.create_profile, default_timeout=30.0, client_info=_client_info,
+ self.create_profile, default_timeout=30.0, client_info=client_info,
),
self.get_profile: gapic_v1.method.wrap_method(
self.get_profile,
@@ -127,14 +133,14 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.update_profile: gapic_v1.method.wrap_method(
- self.update_profile, default_timeout=30.0, client_info=_client_info,
+ self.update_profile, default_timeout=30.0, client_info=client_info,
),
self.delete_profile: gapic_v1.method.wrap_method(
self.delete_profile,
@@ -143,14 +149,14 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.search_profiles: gapic_v1.method.wrap_method(
- self.search_profiles, default_timeout=30.0, client_info=_client_info,
+ self.search_profiles, default_timeout=30.0, client_info=client_info,
),
}
diff --git a/google/cloud/talent_v4beta1/services/profile_service/transports/grpc.py b/google/cloud/talent_v4beta1/services/profile_service/transports/grpc.py
index 0970a782..1c4965c0 100644
--- a/google/cloud/talent_v4beta1/services/profile_service/transports/grpc.py
+++ b/google/cloud/talent_v4beta1/services/profile_service/transports/grpc.py
@@ -15,14 +15,15 @@
# limitations under the License.
#
+import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple
from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
-
import grpc # type: ignore
from google.cloud.talent_v4beta1.types import profile
@@ -30,7 +31,7 @@
from google.cloud.talent_v4beta1.types import profile_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import ProfileServiceTransport
+from .base import ProfileServiceTransport, DEFAULT_CLIENT_INFO
class ProfileServiceGrpcTransport(ProfileServiceTransport):
@@ -59,7 +60,9 @@ def __init__(
channel: grpc.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id: Optional[str] = None
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -78,16 +81,23 @@ def __init__(
ignored if ``channel`` is provided.
channel (Optional[grpc.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
@@ -103,6 +113,11 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
@@ -133,6 +148,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
self._stubs = {} # type: Dict[str, Callable]
@@ -143,6 +175,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
@classmethod
@@ -153,7 +186,7 @@ def create_channel(
credentials_file: str = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
- **kwargs
+ **kwargs,
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
@@ -187,7 +220,7 @@ def create_channel(
credentials_file=credentials_file,
scopes=scopes,
quota_project_id=quota_project_id,
- **kwargs
+ **kwargs,
)
@property
@@ -197,13 +230,6 @@ def grpc_channel(self) -> grpc.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/profile_service/transports/grpc_asyncio.py b/google/cloud/talent_v4beta1/services/profile_service/transports/grpc_asyncio.py
index c8ce2e0f..2a38ebf1 100644
--- a/google/cloud/talent_v4beta1/services/profile_service/transports/grpc_asyncio.py
+++ b/google/cloud/talent_v4beta1/services/profile_service/transports/grpc_asyncio.py
@@ -15,9 +15,12 @@
# limitations under the License.
#
+import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+from google.api_core import gapic_v1 # type: ignore
from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
@@ -29,7 +32,7 @@
from google.cloud.talent_v4beta1.types import profile_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import ProfileServiceTransport
+from .base import ProfileServiceTransport, DEFAULT_CLIENT_INFO
from .grpc import ProfileServiceGrpcTransport
@@ -101,7 +104,9 @@ def __init__(
channel: aio.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -121,16 +126,23 @@ def __init__(
are passed to :func:`google.auth.default`.
channel (Optional[aio.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -146,12 +158,22 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
else api_mtls_endpoint + ":443"
)
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
# Create SSL credentials with client_cert_source or application
# default SSL credentials.
if client_cert_source:
@@ -171,6 +193,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
# Run the base constructor.
super().__init__(
@@ -179,6 +218,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
self._stubs = {}
@@ -190,13 +230,6 @@ def grpc_channel(self) -> aio.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/tenant_service/async_client.py b/google/cloud/talent_v4beta1/services/tenant_service/async_client.py
index 1c5a5bce..b0f64fc3 100644
--- a/google/cloud/talent_v4beta1/services/tenant_service/async_client.py
+++ b/google/cloud/talent_v4beta1/services/tenant_service/async_client.py
@@ -33,7 +33,7 @@
from google.cloud.talent_v4beta1.types import tenant as gct_tenant
from google.cloud.talent_v4beta1.types import tenant_service
-from .transports.base import TenantServiceTransport
+from .transports.base import TenantServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import TenantServiceGrpcAsyncIOTransport
from .client import TenantServiceClient
@@ -49,6 +49,7 @@ class TenantServiceAsyncClient:
DEFAULT_MTLS_ENDPOINT = TenantServiceClient.DEFAULT_MTLS_ENDPOINT
tenant_path = staticmethod(TenantServiceClient.tenant_path)
+ parse_tenant_path = staticmethod(TenantServiceClient.parse_tenant_path)
from_service_account_file = TenantServiceClient.from_service_account_file
from_service_account_json = from_service_account_file
@@ -63,6 +64,7 @@ def __init__(
credentials: credentials.Credentials = None,
transport: Union[str, TenantServiceTransport] = "grpc_asyncio",
client_options: ClientOptions = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the tenant service client.
@@ -78,16 +80,19 @@ def __init__(
client_options (ClientOptions): Custom options for the client. It
won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -95,7 +100,10 @@ def __init__(
"""
self._client = TenantServiceClient(
- credentials=credentials, transport=transport, client_options=client_options,
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
)
async def create_tenant(
@@ -170,7 +178,7 @@ async def create_tenant(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.create_tenant,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -254,11 +262,11 @@ async def get_tenant(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -335,7 +343,7 @@ async def update_tenant(
rpc = gapic_v1.method_async.wrap_method(
self._client._transport.update_tenant,
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -408,11 +416,11 @@ async def delete_tenant(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -491,11 +499,11 @@ async def list_tenants(
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=DEFAULT_CLIENT_INFO,
)
# Certain fields should be provided within the metadata header;
@@ -518,11 +526,11 @@ async def list_tenants(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("TenantServiceAsyncClient",)
diff --git a/google/cloud/talent_v4beta1/services/tenant_service/client.py b/google/cloud/talent_v4beta1/services/tenant_service/client.py
index c896e9a6..401d2057 100644
--- a/google/cloud/talent_v4beta1/services/tenant_service/client.py
+++ b/google/cloud/talent_v4beta1/services/tenant_service/client.py
@@ -16,17 +16,19 @@
#
from collections import OrderedDict
+from distutils import util
import os
import re
-from typing import Callable, Dict, Sequence, Tuple, Type, Union
+from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
import pkg_resources
-import google.api_core.client_options as ClientOptions # type: ignore
+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 gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
from google.auth import 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
from google.oauth2 import service_account # type: ignore
@@ -35,7 +37,7 @@
from google.cloud.talent_v4beta1.types import tenant as gct_tenant
from google.cloud.talent_v4beta1.types import tenant_service
-from .transports.base import TenantServiceTransport
+from .transports.base import TenantServiceTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import TenantServiceGrpcTransport
from .transports.grpc_asyncio import TenantServiceGrpcAsyncIOTransport
@@ -146,9 +148,10 @@ def parse_tenant_path(path: str) -> Dict[str, str]:
def __init__(
self,
*,
- credentials: credentials.Credentials = None,
- transport: Union[str, TenantServiceTransport] = None,
- client_options: ClientOptions = None,
+ credentials: Optional[credentials.Credentials] = None,
+ transport: Union[str, TenantServiceTransport, None] = None,
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the tenant service client.
@@ -161,48 +164,74 @@ def __init__(
transport (Union[str, ~.TenantServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
+ client_options (client_options_lib.ClientOptions): Custom options for the
+ client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS
+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
environment variable can also be used to override the endpoint:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint, this is the default value for
- the environment variable) and "auto" (auto switch to the default
- mTLS endpoint if client SSL credentials is present). However,
- the ``api_endpoint`` property takes precedence if provided.
- (2) The ``client_cert_source`` property is used to provide client
- SSL credentials for mutual TLS transport. If not provided, the
- default SSL credentials will be used if present.
+ use the default regular endpoint) and "auto" (auto switch to the
+ default mTLS endpoint if client certificate is present, this is
+ the default value). However, the ``api_endpoint`` property takes
+ precedence if provided.
+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide client certificate for mutual TLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
if isinstance(client_options, dict):
- client_options = ClientOptions.from_dict(client_options)
+ client_options = client_options_lib.from_dict(client_options)
if client_options is None:
- client_options = ClientOptions.ClientOptions()
+ client_options = client_options_lib.ClientOptions()
- if client_options.api_endpoint is None:
- use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
+ # Create SSL credentials for mutual TLS if needed.
+ use_client_cert = bool(
+ util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
+ )
+
+ ssl_credentials = None
+ is_mtls = False
+ if use_client_cert:
+ if client_options.client_cert_source:
+ import grpc # type: ignore
+
+ cert, key = client_options.client_cert_source()
+ ssl_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ is_mtls = True
+ else:
+ creds = SslCredentials()
+ is_mtls = creds.is_mtls
+ ssl_credentials = creds.ssl_credentials if is_mtls else None
+
+ # Figure out which api endpoint to use.
+ if client_options.api_endpoint is not None:
+ api_endpoint = client_options.api_endpoint
+ else:
+ use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
if use_mtls_env == "never":
- client_options.api_endpoint = self.DEFAULT_ENDPOINT
+ api_endpoint = self.DEFAULT_ENDPOINT
elif use_mtls_env == "always":
- client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
+ api_endpoint = self.DEFAULT_MTLS_ENDPOINT
elif use_mtls_env == "auto":
- has_client_cert_source = (
- client_options.client_cert_source is not None
- or mtls.has_default_client_cert_source()
- )
- client_options.api_endpoint = (
- self.DEFAULT_MTLS_ENDPOINT
- if has_client_cert_source
- else self.DEFAULT_ENDPOINT
+ api_endpoint = (
+ self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
)
else:
raise MutualTLSChannelError(
- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
)
# Save or instantiate the transport.
@@ -226,11 +255,11 @@ def __init__(
self._transport = Transport(
credentials=credentials,
credentials_file=client_options.credentials_file,
- host=client_options.api_endpoint,
+ host=api_endpoint,
scopes=client_options.scopes,
- api_mtls_endpoint=client_options.api_endpoint,
- client_cert_source=client_options.client_cert_source,
+ ssl_channel_credentials=ssl_credentials,
quota_project_id=client_options.quota_project_id,
+ client_info=client_info,
)
def create_tenant(
@@ -639,11 +668,11 @@ def list_tenants(
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
__all__ = ("TenantServiceClient",)
diff --git a/google/cloud/talent_v4beta1/services/tenant_service/transports/base.py b/google/cloud/talent_v4beta1/services/tenant_service/transports/base.py
index 1146ef46..b0f77c0d 100644
--- a/google/cloud/talent_v4beta1/services/tenant_service/transports/base.py
+++ b/google/cloud/talent_v4beta1/services/tenant_service/transports/base.py
@@ -19,7 +19,7 @@
import typing
import pkg_resources
-from google import auth
+from google import auth # type: ignore
from google.api_core import exceptions # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import retry as retries # type: ignore
@@ -32,11 +32,11 @@
try:
- _client_info = gapic_v1.client_info.ClientInfo(
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
gapic_version=pkg_resources.get_distribution("google-cloud-talent",).version,
)
except pkg_resources.DistributionNotFound:
- _client_info = gapic_v1.client_info.ClientInfo()
+ DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
class TenantServiceTransport(abc.ABC):
@@ -55,6 +55,7 @@ def __init__(
credentials_file: typing.Optional[str] = None,
scopes: typing.Optional[typing.Sequence[str]] = AUTH_SCOPES,
quota_project_id: typing.Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
**kwargs,
) -> None:
"""Instantiate the transport.
@@ -72,6 +73,11 @@ def __init__(
scope (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):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ":" not in host:
@@ -99,13 +105,13 @@ def __init__(
self._credentials = credentials
# Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages()
+ self._prep_wrapped_messages(client_info)
- def _prep_wrapped_messages(self):
+ def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
self.create_tenant: gapic_v1.method.wrap_method(
- self.create_tenant, default_timeout=30.0, client_info=_client_info,
+ self.create_tenant, default_timeout=30.0, client_info=client_info,
),
self.get_tenant: gapic_v1.method.wrap_method(
self.get_tenant,
@@ -114,14 +120,14 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.update_tenant: gapic_v1.method.wrap_method(
- self.update_tenant, default_timeout=30.0, client_info=_client_info,
+ self.update_tenant, default_timeout=30.0, client_info=client_info,
),
self.delete_tenant: gapic_v1.method.wrap_method(
self.delete_tenant,
@@ -130,11 +136,11 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
self.list_tenants: gapic_v1.method.wrap_method(
self.list_tenants,
@@ -143,11 +149,11 @@ def _prep_wrapped_messages(self):
maximum=60.0,
multiplier=1.3,
predicate=retries.if_exception_type(
- exceptions.ServiceUnavailable, exceptions.DeadlineExceeded,
+ exceptions.DeadlineExceeded, exceptions.ServiceUnavailable,
),
),
default_timeout=30.0,
- client_info=_client_info,
+ client_info=client_info,
),
}
diff --git a/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc.py b/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc.py
index 267845be..a1a331df 100644
--- a/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc.py
+++ b/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc.py
@@ -15,14 +15,15 @@
# limitations under the License.
#
+import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple
from google.api_core import grpc_helpers # type: ignore
+from google.api_core import gapic_v1 # type: ignore
from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
-
import grpc # type: ignore
from google.cloud.talent_v4beta1.types import tenant
@@ -30,7 +31,7 @@
from google.cloud.talent_v4beta1.types import tenant_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import TenantServiceTransport
+from .base import TenantServiceTransport, DEFAULT_CLIENT_INFO
class TenantServiceGrpcTransport(TenantServiceTransport):
@@ -59,7 +60,9 @@ def __init__(
channel: grpc.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id: Optional[str] = None
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -78,16 +81,23 @@ def __init__(
ignored if ``channel`` is provided.
channel (Optional[grpc.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
@@ -103,6 +113,11 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
@@ -133,6 +148,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
self._stubs = {} # type: Dict[str, Callable]
@@ -143,6 +175,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
@classmethod
@@ -153,7 +186,7 @@ def create_channel(
credentials_file: str = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
- **kwargs
+ **kwargs,
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
@@ -187,7 +220,7 @@ def create_channel(
credentials_file=credentials_file,
scopes=scopes,
quota_project_id=quota_project_id,
- **kwargs
+ **kwargs,
)
@property
@@ -197,13 +230,6 @@ def grpc_channel(self) -> grpc.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc_asyncio.py b/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc_asyncio.py
index 95e6ddbc..b87d1e04 100644
--- a/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc_asyncio.py
+++ b/google/cloud/talent_v4beta1/services/tenant_service/transports/grpc_asyncio.py
@@ -15,9 +15,12 @@
# limitations under the License.
#
+import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple
+from google.api_core import gapic_v1 # type: ignore
from google.api_core import grpc_helpers_async # type: ignore
+from google import auth # type: ignore
from google.auth import credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
@@ -29,7 +32,7 @@
from google.cloud.talent_v4beta1.types import tenant_service
from google.protobuf import empty_pb2 as empty # type: ignore
-from .base import TenantServiceTransport
+from .base import TenantServiceTransport, DEFAULT_CLIENT_INFO
from .grpc import TenantServiceGrpcTransport
@@ -101,7 +104,9 @@ def __init__(
channel: aio.Channel = None,
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
+ ssl_channel_credentials: grpc.ChannelCredentials = None,
quota_project_id=None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiate the transport.
@@ -121,16 +126,23 @@ def __init__(
are passed to :func:`google.auth.default`.
channel (Optional[aio.Channel]): A ``Channel`` instance through
which to make calls.
- api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If
- provided, it overrides the ``host`` argument and tries to create
+ api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
+ If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
``client_cert_source`` or applicatin default SSL credentials.
- client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A
- callback to provide client SSL certificate bytes and private key
- bytes, both in PEM format. It is ignored if ``api_mtls_endpoint``
- is None.
+ client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ Deprecated. A callback to provide client SSL certificate bytes and
+ private key bytes, both in PEM format. It is ignored if
+ ``api_mtls_endpoint`` is None.
+ ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
+ for grpc channel. It is ignored if ``channel`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -146,12 +158,22 @@ def __init__(
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
elif api_mtls_endpoint:
+ warnings.warn(
+ "api_mtls_endpoint and client_cert_source are deprecated",
+ DeprecationWarning,
+ )
+
host = (
api_mtls_endpoint
if ":" in api_mtls_endpoint
else api_mtls_endpoint + ":443"
)
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
# Create SSL credentials with client_cert_source or application
# default SSL credentials.
if client_cert_source:
@@ -171,6 +193,23 @@ def __init__(
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
)
+ else:
+ host = host if ":" in host else host + ":443"
+
+ if credentials is None:
+ credentials, _ = auth.default(
+ scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
+ )
+
+ # create a new channel. The provided one is ignored.
+ self._grpc_channel = type(self).create_channel(
+ host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ ssl_credentials=ssl_channel_credentials,
+ scopes=scopes or self.AUTH_SCOPES,
+ quota_project_id=quota_project_id,
+ )
# Run the base constructor.
super().__init__(
@@ -179,6 +218,7 @@ def __init__(
credentials_file=credentials_file,
scopes=scopes or self.AUTH_SCOPES,
quota_project_id=quota_project_id,
+ client_info=client_info,
)
self._stubs = {}
@@ -190,13 +230,6 @@ def grpc_channel(self) -> aio.Channel:
This property caches on the instance; repeated calls return
the same channel.
"""
- # Sanity check: Only create a new channel if we do not already
- # have one.
- if not hasattr(self, "_grpc_channel"):
- self._grpc_channel = self.create_channel(
- self._host, credentials=self._credentials,
- )
-
# Return the channel from cache.
return self._grpc_channel
diff --git a/google/cloud/talent_v4beta1/types/common.py b/google/cloud/talent_v4beta1/types/common.py
index 6b7b74c7..61614a0a 100644
--- a/google/cloud/talent_v4beta1/types/common.py
+++ b/google/cloud/talent_v4beta1/types/common.py
@@ -631,7 +631,7 @@ class CompensationEntry(proto.Message):
[expected_units_per_year][google.cloud.talent.v4beta1.CompensationInfo.CompensationEntry.expected_units_per_year].
Attributes:
- type (~.common.CompensationInfo.CompensationType):
+ type_ (~.common.CompensationInfo.CompensationType):
Compensation type.
Default is
@@ -643,7 +643,7 @@ class CompensationEntry(proto.Message):
[CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED][google.cloud.talent.v4beta1.CompensationInfo.CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED].
amount (~.money.Money):
Compensation amount.
- range (~.common.CompensationInfo.CompensationRange):
+ range_ (~.common.CompensationInfo.CompensationRange):
Compensation range.
description (str):
Compensation description. For example, could
@@ -664,7 +664,7 @@ class CompensationEntry(proto.Message):
- ANNUAL: 1
"""
- type = proto.Field(
+ type_ = proto.Field(
proto.ENUM, number=1, enum="CompensationInfo.CompensationType",
)
@@ -676,7 +676,7 @@ class CompensationEntry(proto.Message):
proto.MESSAGE, number=3, oneof="compensation_amount", message=money.Money,
)
- range = proto.Field(
+ range_ = proto.Field(
proto.MESSAGE,
number=4,
oneof="compensation_amount",
@@ -810,9 +810,9 @@ class Rating(proto.Message):
Attributes:
overall (float):
Overall score.
- min (float):
+ min_ (float):
The minimum value for the score.
- max (float):
+ max_ (float):
The maximum value for the score.
interval (float):
The steps within the score (for example,
@@ -822,9 +822,9 @@ class Rating(proto.Message):
overall = proto.Field(proto.DOUBLE, number=1)
- min = proto.Field(proto.DOUBLE, number=2)
+ min_ = proto.Field(proto.DOUBLE, number=2)
- max = proto.Field(proto.DOUBLE, number=3)
+ max_ = proto.Field(proto.DOUBLE, number=3)
interval = proto.Field(proto.DOUBLE, number=4)
diff --git a/google/cloud/talent_v4beta1/types/completion_service.py b/google/cloud/talent_v4beta1/types/completion_service.py
index 353336e3..662afd21 100644
--- a/google/cloud/talent_v4beta1/types/completion_service.py
+++ b/google/cloud/talent_v4beta1/types/completion_service.py
@@ -66,7 +66,7 @@ class CompleteQueryRequest(proto.Message):
scope (~.completion_service.CompleteQueryRequest.CompletionScope):
The scope of the completion. The defaults is
[CompletionScope.PUBLIC][google.cloud.talent.v4beta1.CompleteQueryRequest.CompletionScope.PUBLIC].
- type (~.completion_service.CompleteQueryRequest.CompletionType):
+ type_ (~.completion_service.CompleteQueryRequest.CompletionType):
The completion topic. The default is
[CompletionType.COMBINED][google.cloud.talent.v4beta1.CompleteQueryRequest.CompletionType.COMBINED].
"""
@@ -96,7 +96,7 @@ class CompletionType(proto.Enum):
scope = proto.Field(proto.ENUM, number=6, enum=CompletionScope,)
- type = proto.Field(proto.ENUM, number=7, enum=CompletionType,)
+ type_ = proto.Field(proto.ENUM, number=7, enum=CompletionType,)
class CompleteQueryResponse(proto.Message):
@@ -117,7 +117,7 @@ class CompletionResult(proto.Message):
Attributes:
suggestion (str):
The suggestion for the query.
- type (~.completion_service.CompleteQueryRequest.CompletionType):
+ type_ (~.completion_service.CompleteQueryRequest.CompletionType):
The completion topic.
image_uri (str):
The URI of the company image for
@@ -126,7 +126,7 @@ class CompletionResult(proto.Message):
suggestion = proto.Field(proto.STRING, number=1)
- type = proto.Field(
+ type_ = proto.Field(
proto.ENUM, number=2, enum=CompleteQueryRequest.CompletionType,
)
diff --git a/google/cloud/talent_v4beta1/types/event.py b/google/cloud/talent_v4beta1/types/event.py
index e1726ebd..4583b654 100644
--- a/google/cloud/talent_v4beta1/types/event.py
+++ b/google/cloud/talent_v4beta1/types/event.py
@@ -81,7 +81,7 @@ class JobEvent(proto.Message):
application that implements Cloud Talent Solution.
Attributes:
- type (~.event.JobEvent.JobEventType):
+ type_ (~.event.JobEvent.JobEventType):
Required. The type of the event (see
[JobEventType][google.cloud.talent.v4beta1.JobEvent.JobEventType]).
jobs (Sequence[str]):
@@ -127,7 +127,7 @@ class JobEventType(proto.Enum):
SENT_CV = 14
INTERVIEW_GRANTED = 15
- type = proto.Field(proto.ENUM, number=1, enum=JobEventType,)
+ type_ = proto.Field(proto.ENUM, number=1, enum=JobEventType,)
jobs = proto.RepeatedField(proto.STRING, number=2)
@@ -139,7 +139,7 @@ class ProfileEvent(proto.Message):
application that implements Cloud Talent Solution.
Attributes:
- type (~.event.ProfileEvent.ProfileEventType):
+ type_ (~.event.ProfileEvent.ProfileEventType):
Required. Type of event.
profiles (Sequence[str]):
Required. The [profile
@@ -168,7 +168,7 @@ class ProfileEventType(proto.Enum):
VIEW = 2
BOOKMARK = 3
- type = proto.Field(proto.ENUM, number=1, enum=ProfileEventType,)
+ type_ = proto.Field(proto.ENUM, number=1, enum=ProfileEventType,)
profiles = proto.RepeatedField(proto.STRING, number=2)
diff --git a/google/cloud/talent_v4beta1/types/filters.py b/google/cloud/talent_v4beta1/types/filters.py
index c30a4e26..48d631b4 100644
--- a/google/cloud/talent_v4beta1/types/filters.py
+++ b/google/cloud/talent_v4beta1/types/filters.py
@@ -701,12 +701,12 @@ class CompensationFilter(proto.Message):
r"""Filter on job compensation type and amount.
Attributes:
- type (~.filters.CompensationFilter.FilterType):
+ type_ (~.filters.CompensationFilter.FilterType):
Required. Type of filter.
units (Sequence[~.common.CompensationInfo.CompensationUnit]):
Required. Specify desired ``base compensation entry's``
[CompensationInfo.CompensationUnit][google.cloud.talent.v4beta1.CompensationInfo.CompensationUnit].
- range (~.common.CompensationInfo.CompensationRange):
+ range_ (~.common.CompensationInfo.CompensationRange):
Compensation range.
include_jobs_with_unspecified_compensation_range (bool):
If set to true, jobs with unspecified
@@ -721,13 +721,13 @@ class FilterType(proto.Enum):
ANNUALIZED_BASE_AMOUNT = 3
ANNUALIZED_TOTAL_AMOUNT = 4
- type = proto.Field(proto.ENUM, number=1, enum=FilterType,)
+ type_ = proto.Field(proto.ENUM, number=1, enum=FilterType,)
units = proto.RepeatedField(
proto.ENUM, number=2, enum=common.CompensationInfo.CompensationUnit,
)
- range = proto.Field(
+ range_ = proto.Field(
proto.MESSAGE, number=3, message=common.CompensationInfo.CompensationRange,
)
@@ -1045,7 +1045,7 @@ class AvailabilityFilter(proto.Message):
Attributes:
signal_type (~.common.AvailabilitySignalType):
Required. Type of signal to apply filter on.
- range (~.common.TimestampRange):
+ range_ (~.common.TimestampRange):
Required. Range of times to filter candidate
signals by.
required (bool):
@@ -1060,7 +1060,7 @@ class AvailabilityFilter(proto.Message):
signal_type = proto.Field(proto.ENUM, number=1, enum=common.AvailabilitySignalType,)
- range = proto.Field(proto.MESSAGE, number=2, message=common.TimestampRange,)
+ range_ = proto.Field(proto.MESSAGE, number=2, message=common.TimestampRange,)
required = proto.Field(proto.BOOL, number=3)
diff --git a/google/cloud/talent_v4beta1/types/profile.py b/google/cloud/talent_v4beta1/types/profile.py
index ceba029a..7a63d345 100644
--- a/google/cloud/talent_v4beta1/types/profile.py
+++ b/google/cloud/talent_v4beta1/types/profile.py
@@ -390,7 +390,7 @@ class AvailabilitySignal(proto.Message):
r"""Candidate availability signal.
Attributes:
- type (~.common.AvailabilitySignalType):
+ type_ (~.common.AvailabilitySignalType):
Type of signal.
last_update_time (~.timestamp.Timestamp):
Timestamp of when the given availability
@@ -411,7 +411,7 @@ class AvailabilitySignal(proto.Message):
[type][google.cloud.talent.v4beta1.AvailabilitySignal.type].
"""
- type = proto.Field(proto.ENUM, number=1, enum=common.AvailabilitySignalType,)
+ type_ = proto.Field(proto.ENUM, number=1, enum=common.AvailabilitySignalType,)
last_update_time = proto.Field(
proto.MESSAGE, number=2, message=timestamp.Timestamp,
@@ -590,7 +590,7 @@ class Phone(proto.Message):
usage (~.common.ContactInfoUsage):
The usage of the phone. For example, SCHOOL,
WORK, PERSONAL.
- type (~.profile.Phone.PhoneType):
+ type_ (~.profile.Phone.PhoneType):
The phone type. For example, LANDLINE,
MOBILE, FAX.
number (str):
@@ -623,7 +623,7 @@ class PhoneType(proto.Enum):
usage = proto.Field(proto.ENUM, number=1, enum=common.ContactInfoUsage,)
- type = proto.Field(proto.ENUM, number=2, enum=PhoneType,)
+ type_ = proto.Field(proto.ENUM, number=2, enum=PhoneType,)
number = proto.Field(proto.STRING, number=3)
diff --git a/noxfile.py b/noxfile.py
index 8e537c9d..0235144d 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -151,7 +151,7 @@ def docs(session):
"""Build the docs for this library."""
session.install("-e", ".")
- session.install("sphinx<3.0.0", "alabaster", "recommonmark")
+ session.install("sphinx", "alabaster", "recommonmark")
shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
session.run(
diff --git a/samples/snippets/job_search_autocomplete_job_title.py b/samples/snippets/job_search_autocomplete_job_title.py
index e9f52868..782517c1 100644
--- a/samples/snippets/job_search_autocomplete_job_title.py
+++ b/samples/snippets/job_search_autocomplete_job_title.py
@@ -47,7 +47,7 @@ def complete_query(project_id, tenant_id, query):
print(f"Suggested title: {result.suggestion}")
# Suggestion type is JOB_TITLE or COMPANY_TITLE
print(
- f"Suggestion type: {talent_v4beta1.CompleteQueryRequest.CompletionType(result.type).name}"
+ f"Suggestion type: {talent_v4beta1.CompleteQueryRequest.CompletionType(result.type_).name}"
)
diff --git a/samples/snippets/job_search_commute_search.py b/samples/snippets/job_search_commute_search.py
index 0b768441..d38a0ae4 100644
--- a/samples/snippets/job_search_commute_search.py
+++ b/samples/snippets/job_search_commute_search.py
@@ -59,7 +59,7 @@ def search_jobs(project_id, tenant_id):
request_metadata=request_metadata,
job_query=job_query,
)
- for response_item in client.search_jobs(request=request):
+ for response_item in client.search_jobs(request=request).matching_jobs:
print(f"Job summary: {response_item.job_summary}")
print(f"Job title snippet: {response_item.job_title_snippet}")
job = response_item.job
diff --git a/samples/snippets/job_search_custom_ranking_search.py b/samples/snippets/job_search_custom_ranking_search.py
index 015291e4..6f1addc9 100644
--- a/samples/snippets/job_search_custom_ranking_search.py
+++ b/samples/snippets/job_search_custom_ranking_search.py
@@ -55,7 +55,7 @@ def search_jobs(project_id, tenant_id):
custom_ranking_info=custom_ranking_info,
order_by=order_by
)
- for response_item in client.search_jobs(request=request):
+ for response_item in client.search_jobs(request=request).matching_jobs:
print(f"Job summary: {response_item.job_summary}")
print(f"Job title snippet: {response_item.job_title_snippet}")
job = response_item.job
diff --git a/samples/snippets/job_search_histogram_search.py b/samples/snippets/job_search_histogram_search.py
index 73bbc974..5a6a9145 100644
--- a/samples/snippets/job_search_histogram_search.py
+++ b/samples/snippets/job_search_histogram_search.py
@@ -55,7 +55,7 @@ def search_jobs(project_id, tenant_id, query):
request_metadata=request_metadata,
histogram_queries=histogram_queries,
)
- for response_item in client.search_jobs(request=request):
+ for response_item in client.search_jobs(request=request).matching_jobs:
print("Job summary: {response_item.job_summary}")
print("Job title snippet: {response_item.job_title_snippet}")
job = response_item.job
diff --git a/scripts/fixup_talent_v4_keywords.py b/scripts/fixup_talent_v4_keywords.py
new file mode 100644
index 00000000..0f86462f
--- /dev/null
+++ b/scripts/fixup_talent_v4_keywords.py
@@ -0,0 +1,199 @@
+# -*- 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.
+#
+
+import argparse
+import os
+import libcst as cst
+import pathlib
+import sys
+from typing import (Any, Callable, Dict, List, Sequence, Tuple)
+
+
+def partition(
+ predicate: Callable[[Any], bool],
+ iterator: Sequence[Any]
+) -> Tuple[List[Any], List[Any]]:
+ """A stable, out-of-place partition."""
+ results = ([], [])
+
+ for i in iterator:
+ results[int(predicate(i))].append(i)
+
+ # Returns trueList, falseList
+ return results[1], results[0]
+
+
+class talentCallTransformer(cst.CSTTransformer):
+ CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata')
+ METHOD_TO_PARAMS: Dict[str, Tuple[str]] = {
+ 'batch_create_jobs': ('parent', 'jobs', ),
+ 'batch_delete_jobs': ('parent', 'names', ),
+ 'batch_update_jobs': ('parent', 'jobs', 'update_mask', ),
+ 'complete_query': ('tenant', 'query', 'page_size', 'language_codes', 'company', 'scope', 'type_', ),
+ 'create_client_event': ('parent', 'client_event', ),
+ 'create_company': ('parent', 'company', ),
+ 'create_job': ('parent', 'job', ),
+ 'create_tenant': ('parent', 'tenant', ),
+ 'delete_company': ('name', ),
+ 'delete_job': ('name', ),
+ 'delete_tenant': ('name', ),
+ 'get_company': ('name', ),
+ 'get_job': ('name', ),
+ 'get_tenant': ('name', ),
+ 'list_companies': ('parent', 'page_token', 'page_size', 'require_open_jobs', ),
+ 'list_jobs': ('parent', 'filter', 'page_token', 'page_size', 'job_view', ),
+ 'list_tenants': ('parent', 'page_token', 'page_size', ),
+ 'search_jobs': ('parent', 'request_metadata', 'search_mode', 'job_query', 'enable_broadening', 'histogram_queries', 'job_view', 'offset', 'max_page_size', 'page_token', 'order_by', 'diversification_level', 'custom_ranking_info', 'disable_keyword_match', ),
+ 'search_jobs_for_alert': ('parent', 'request_metadata', 'search_mode', 'job_query', 'enable_broadening', 'histogram_queries', 'job_view', 'offset', 'max_page_size', 'page_token', 'order_by', 'diversification_level', 'custom_ranking_info', 'disable_keyword_match', ),
+ 'update_company': ('company', 'update_mask', ),
+ 'update_job': ('job', 'update_mask', ),
+ 'update_tenant': ('tenant', 'update_mask', ),
+
+ }
+
+ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode:
+ try:
+ key = original.func.attr.value
+ kword_params = self.METHOD_TO_PARAMS[key]
+ except (AttributeError, KeyError):
+ # Either not a method from the API or too convoluted to be sure.
+ return updated
+
+ # If the existing code is valid, keyword args come after positional args.
+ # Therefore, all positional args must map to the first parameters.
+ args, kwargs = partition(lambda a: not bool(a.keyword), updated.args)
+ if any(k.keyword.value == "request" for k in kwargs):
+ # We've already fixed this file, don't fix it again.
+ return updated
+
+ kwargs, ctrl_kwargs = partition(
+ lambda a: not a.keyword.value in self.CTRL_PARAMS,
+ kwargs
+ )
+
+ args, ctrl_args = args[:len(kword_params)], args[len(kword_params):]
+ ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl))
+ for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS))
+
+ request_arg = cst.Arg(
+ value=cst.Dict([
+ cst.DictElement(
+ cst.SimpleString("'{}'".format(name)),
+ cst.Element(value=arg.value)
+ )
+ # Note: the args + kwargs looks silly, but keep in mind that
+ # the control parameters had to be stripped out, and that
+ # those could have been passed positionally or by keyword.
+ for name, arg in zip(kword_params, args + kwargs)]),
+ keyword=cst.Name("request")
+ )
+
+ return updated.with_changes(
+ args=[request_arg] + ctrl_kwargs
+ )
+
+
+def fix_files(
+ in_dir: pathlib.Path,
+ out_dir: pathlib.Path,
+ *,
+ transformer=talentCallTransformer(),
+):
+ """Duplicate the input dir to the output dir, fixing file method calls.
+
+ Preconditions:
+ * in_dir is a real directory
+ * out_dir is a real, empty directory
+ """
+ pyfile_gen = (
+ pathlib.Path(os.path.join(root, f))
+ for root, _, files in os.walk(in_dir)
+ for f in files if os.path.splitext(f)[1] == ".py"
+ )
+
+ for fpath in pyfile_gen:
+ with open(fpath, 'r') as f:
+ src = f.read()
+
+ # Parse the code and insert method call fixes.
+ tree = cst.parse_module(src)
+ updated = tree.visit(transformer)
+
+ # Create the path and directory structure for the new file.
+ updated_path = out_dir.joinpath(fpath.relative_to(in_dir))
+ updated_path.parent.mkdir(parents=True, exist_ok=True)
+
+ # Generate the updated source file at the corresponding path.
+ with open(updated_path, 'w') as f:
+ f.write(updated.code)
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ description="""Fix up source that uses the talent client library.
+
+The existing sources are NOT overwritten but are copied to output_dir with changes made.
+
+Note: This tool operates at a best-effort level at converting positional
+ parameters in client method calls to keyword based parameters.
+ Cases where it WILL FAIL include
+ A) * or ** expansion in a method call.
+ B) Calls via function or method alias (includes free function calls)
+ C) Indirect or dispatched calls (e.g. the method is looked up dynamically)
+
+ These all constitute false negatives. The tool will also detect false
+ positives when an API method shares a name with another method.
+""")
+ parser.add_argument(
+ '-d',
+ '--input-directory',
+ required=True,
+ dest='input_dir',
+ help='the input directory to walk for python files to fix up',
+ )
+ parser.add_argument(
+ '-o',
+ '--output-directory',
+ required=True,
+ dest='output_dir',
+ help='the directory to output files fixed via un-flattening',
+ )
+ args = parser.parse_args()
+ input_dir = pathlib.Path(args.input_dir)
+ output_dir = pathlib.Path(args.output_dir)
+ if not input_dir.is_dir():
+ print(
+ f"input directory '{input_dir}' does not exist or is not a directory",
+ file=sys.stderr,
+ )
+ sys.exit(-1)
+
+ if not output_dir.is_dir():
+ print(
+ f"output directory '{output_dir}' does not exist or is not a directory",
+ file=sys.stderr,
+ )
+ sys.exit(-1)
+
+ if os.listdir(output_dir):
+ print(
+ f"output directory '{output_dir}' is not empty",
+ file=sys.stderr,
+ )
+ sys.exit(-1)
+
+ fix_files(input_dir, output_dir)
diff --git a/synth.metadata b/synth.metadata
index ddbee2fb..498d930d 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -39,6 +39,15 @@
"language": "python",
"generator": "bazel"
}
+ },
+ {
+ "client": {
+ "source": "googleapis",
+ "apiName": "talent",
+ "apiVersion": "v4",
+ "language": "python",
+ "generator": "bazel"
+ }
}
]
}
\ No newline at end of file
diff --git a/synth.py b/synth.py
index 6481c072..78cbbc9e 100644
--- a/synth.py
+++ b/synth.py
@@ -20,7 +20,7 @@
gapic = gcp.GAPICBazel()
common = gcp.CommonTemplates()
-versions = ["v4beta1"]
+versions = ["v4beta1", "v4"]
excludes = ["setup.py", "nox*.py", "README.rst", "docs/conf.py", "docs/index.rst"]
# ----------------------------------------------------------------------------
@@ -30,7 +30,7 @@
library = gapic.py_library(
service="talent",
version=version,
- bazel_target=f"//google/cloud/talent/{version}:talent-{version}-py",
+ bazel_target=f"//google/cloud/talent/{version}:talent-{version}-py",
include_protos=True
)
s.move(library, excludes=excludes)
@@ -58,8 +58,6 @@
)
s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good .coveragerc file
-# TODO(busunkim): Use latest sphinx after microgenerator transition
-s.replace("noxfile.py", """['"]sphinx['"]""", '"sphinx<3.0.0"')
# Temporarily disable warnings due to
# https://github.com/googleapis/gapic-generator-python/issues/525
s.replace("noxfile.py", '[\"\']-W[\"\']', '# "-W"')
diff --git a/tests/unit/gapic/talent_v4/__init__.py b/tests/unit/gapic/talent_v4/__init__.py
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/tests/unit/gapic/talent_v4/__init__.py
@@ -0,0 +1 @@
+
diff --git a/tests/unit/gapic/talent_v4/test_company_service.py b/tests/unit/gapic/talent_v4/test_company_service.py
new file mode 100644
index 00000000..7bf7ac24
--- /dev/null
+++ b/tests/unit/gapic/talent_v4/test_company_service.py
@@ -0,0 +1,2111 @@
+# -*- 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.
+#
+
+import os
+import mock
+
+import grpc
+from grpc.experimental import aio
+import math
+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 gapic_v1
+from google.api_core import grpc_helpers
+from google.api_core import grpc_helpers_async
+from google.auth import credentials
+from google.auth.exceptions import MutualTLSChannelError
+from google.cloud.talent_v4.services.company_service import CompanyServiceAsyncClient
+from google.cloud.talent_v4.services.company_service import CompanyServiceClient
+from google.cloud.talent_v4.services.company_service import pagers
+from google.cloud.talent_v4.services.company_service import transports
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import company
+from google.cloud.talent_v4.types import company as gct_company
+from google.cloud.talent_v4.types import company_service
+from google.oauth2 import service_account
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+from google.type import latlng_pb2 as latlng # type: ignore
+from google.type import postal_address_pb2 as gt_postal_address # type: ignore
+
+
+def client_cert_source_callback():
+ return b"cert bytes", b"key bytes"
+
+
+# If default endpoint is localhost, then default mtls endpoint will be the same.
+# This method modifies the default endpoint so the client can produce a different
+# mtls endpoint for endpoint testing purposes.
+def modify_default_endpoint(client):
+ return (
+ "foo.googleapis.com"
+ if ("localhost" in client.DEFAULT_ENDPOINT)
+ else client.DEFAULT_ENDPOINT
+ )
+
+
+def test__get_default_mtls_endpoint():
+ api_endpoint = "example.googleapis.com"
+ api_mtls_endpoint = "example.mtls.googleapis.com"
+ sandbox_endpoint = "example.sandbox.googleapis.com"
+ sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com"
+ non_googleapi = "api.example.com"
+
+ assert CompanyServiceClient._get_default_mtls_endpoint(None) is None
+ assert (
+ CompanyServiceClient._get_default_mtls_endpoint(api_endpoint)
+ == api_mtls_endpoint
+ )
+ assert (
+ CompanyServiceClient._get_default_mtls_endpoint(api_mtls_endpoint)
+ == api_mtls_endpoint
+ )
+ assert (
+ CompanyServiceClient._get_default_mtls_endpoint(sandbox_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert (
+ CompanyServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert (
+ CompanyServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class", [CompanyServiceClient, CompanyServiceAsyncClient]
+)
+def test_company_service_client_from_service_account_file(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_file"
+ ) as factory:
+ factory.return_value = creds
+ client = client_class.from_service_account_file("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ client = client_class.from_service_account_json("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_company_service_client_get_transport_class():
+ transport = CompanyServiceClient.get_transport_class()
+ assert transport == transports.CompanyServiceGrpcTransport
+
+ transport = CompanyServiceClient.get_transport_class("grpc")
+ assert transport == transports.CompanyServiceGrpcTransport
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (CompanyServiceClient, transports.CompanyServiceGrpcTransport, "grpc"),
+ (
+ CompanyServiceAsyncClient,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+@mock.patch.object(
+ CompanyServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompanyServiceClient),
+)
+@mock.patch.object(
+ CompanyServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompanyServiceAsyncClient),
+)
+def test_company_service_client_client_options(
+ client_class, transport_class, transport_name
+):
+ # Check that if channel is provided we won't create a new one.
+ with mock.patch.object(CompanyServiceClient, "get_transport_class") as gtc:
+ transport = transport_class(credentials=credentials.AnonymousCredentials())
+ client = client_class(transport=transport)
+ gtc.assert_not_called()
+
+ # Check that if channel is provided via str we will create a new one.
+ with mock.patch.object(CompanyServiceClient, "get_transport_class") as gtc:
+ client = client_class(transport=transport_name)
+ gtc.assert_called()
+
+ # Check the case api_endpoint is provided.
+ options = client_options.ClientOptions(api_endpoint="squid.clam.whelk")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "never".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "always".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_MTLS_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (CompanyServiceClient, transports.CompanyServiceGrpcTransport, "grpc", "true"),
+ (
+ CompanyServiceAsyncClient,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (CompanyServiceClient, transports.CompanyServiceGrpcTransport, "grpc", "false"),
+ (
+ CompanyServiceAsyncClient,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ CompanyServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompanyServiceClient),
+)
+@mock.patch.object(
+ CompanyServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompanyServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_company_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ options = client_options.ClientOptions(
+ client_cert_source=client_cert_source_callback
+ )
+ with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
+ with mock.patch(
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
+ ):
+ patched.return_value = None
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (CompanyServiceClient, transports.CompanyServiceGrpcTransport, "grpc"),
+ (
+ CompanyServiceAsyncClient,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_company_service_client_client_options_scopes(
+ client_class, transport_class, transport_name
+):
+ # Check the case scopes are provided.
+ options = client_options.ClientOptions(scopes=["1", "2"],)
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=["1", "2"],
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (CompanyServiceClient, transports.CompanyServiceGrpcTransport, "grpc"),
+ (
+ CompanyServiceAsyncClient,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_company_service_client_client_options_credentials_file(
+ client_class, transport_class, transport_name
+):
+ # Check the case credentials file is provided.
+ options = client_options.ClientOptions(credentials_file="credentials.json")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file="credentials.json",
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_company_service_client_client_options_from_dict():
+ with mock.patch(
+ "google.cloud.talent_v4.services.company_service.transports.CompanyServiceGrpcTransport.__init__"
+ ) as grpc_transport:
+ grpc_transport.return_value = None
+ client = CompanyServiceClient(
+ client_options={"api_endpoint": "squid.clam.whelk"}
+ )
+ grpc_transport.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_create_company(
+ transport: str = "grpc", request_type=company_service.CreateCompanyRequest
+):
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_company.Company(
+ name="name_value",
+ display_name="display_name_value",
+ external_id="external_id_value",
+ size=common.CompanySize.MINI,
+ headquarters_address="headquarters_address_value",
+ hiring_agency=True,
+ eeo_text="eeo_text_value",
+ website_uri="website_uri_value",
+ career_site_uri="career_site_uri_value",
+ image_uri="image_uri_value",
+ keyword_searchable_job_custom_attributes=[
+ "keyword_searchable_job_custom_attributes_value"
+ ],
+ suspended=True,
+ )
+
+ response = client.create_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == company_service.CreateCompanyRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_company.Company)
+
+ assert response.name == "name_value"
+
+ assert response.display_name == "display_name_value"
+
+ assert response.external_id == "external_id_value"
+
+ assert response.size == common.CompanySize.MINI
+
+ assert response.headquarters_address == "headquarters_address_value"
+
+ assert response.hiring_agency is True
+
+ assert response.eeo_text == "eeo_text_value"
+
+ assert response.website_uri == "website_uri_value"
+
+ assert response.career_site_uri == "career_site_uri_value"
+
+ assert response.image_uri == "image_uri_value"
+
+ assert response.keyword_searchable_job_custom_attributes == [
+ "keyword_searchable_job_custom_attributes_value"
+ ]
+
+ assert response.suspended is True
+
+
+def test_create_company_from_dict():
+ test_create_company(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_create_company_async(transport: str = "grpc_asyncio"):
+ client = CompanyServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = company_service.CreateCompanyRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ gct_company.Company(
+ name="name_value",
+ display_name="display_name_value",
+ external_id="external_id_value",
+ size=common.CompanySize.MINI,
+ headquarters_address="headquarters_address_value",
+ hiring_agency=True,
+ eeo_text="eeo_text_value",
+ website_uri="website_uri_value",
+ career_site_uri="career_site_uri_value",
+ image_uri="image_uri_value",
+ keyword_searchable_job_custom_attributes=[
+ "keyword_searchable_job_custom_attributes_value"
+ ],
+ suspended=True,
+ )
+ )
+
+ response = await client.create_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_company.Company)
+
+ assert response.name == "name_value"
+
+ assert response.display_name == "display_name_value"
+
+ assert response.external_id == "external_id_value"
+
+ assert response.size == common.CompanySize.MINI
+
+ assert response.headquarters_address == "headquarters_address_value"
+
+ assert response.hiring_agency is True
+
+ assert response.eeo_text == "eeo_text_value"
+
+ assert response.website_uri == "website_uri_value"
+
+ assert response.career_site_uri == "career_site_uri_value"
+
+ assert response.image_uri == "image_uri_value"
+
+ assert response.keyword_searchable_job_custom_attributes == [
+ "keyword_searchable_job_custom_attributes_value"
+ ]
+
+ assert response.suspended is True
+
+
+def test_create_company_field_headers():
+ client = CompanyServiceClient(credentials=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 = company_service.CreateCompanyRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_company), "__call__") as call:
+ call.return_value = gct_company.Company()
+
+ client.create_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_create_company_field_headers_async():
+ client = CompanyServiceAsyncClient(credentials=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 = company_service.CreateCompanyRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_company), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_company.Company())
+
+ await client.create_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_create_company_flattened():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_company.Company()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.create_company(
+ parent="parent_value", company=gct_company.Company(name="name_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].company == gct_company.Company(name="name_value")
+
+
+def test_create_company_flattened_error():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.create_company(
+ company_service.CreateCompanyRequest(),
+ parent="parent_value",
+ company=gct_company.Company(name="name_value"),
+ )
+
+
+@pytest.mark.asyncio
+async def test_create_company_flattened_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_company.Company()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_company.Company())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.create_company(
+ parent="parent_value", company=gct_company.Company(name="name_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].company == gct_company.Company(name="name_value")
+
+
+@pytest.mark.asyncio
+async def test_create_company_flattened_error_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.create_company(
+ company_service.CreateCompanyRequest(),
+ parent="parent_value",
+ company=gct_company.Company(name="name_value"),
+ )
+
+
+def test_get_company(
+ transport: str = "grpc", request_type=company_service.GetCompanyRequest
+):
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = company.Company(
+ name="name_value",
+ display_name="display_name_value",
+ external_id="external_id_value",
+ size=common.CompanySize.MINI,
+ headquarters_address="headquarters_address_value",
+ hiring_agency=True,
+ eeo_text="eeo_text_value",
+ website_uri="website_uri_value",
+ career_site_uri="career_site_uri_value",
+ image_uri="image_uri_value",
+ keyword_searchable_job_custom_attributes=[
+ "keyword_searchable_job_custom_attributes_value"
+ ],
+ suspended=True,
+ )
+
+ response = client.get_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == company_service.GetCompanyRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, company.Company)
+
+ assert response.name == "name_value"
+
+ assert response.display_name == "display_name_value"
+
+ assert response.external_id == "external_id_value"
+
+ assert response.size == common.CompanySize.MINI
+
+ assert response.headquarters_address == "headquarters_address_value"
+
+ assert response.hiring_agency is True
+
+ assert response.eeo_text == "eeo_text_value"
+
+ assert response.website_uri == "website_uri_value"
+
+ assert response.career_site_uri == "career_site_uri_value"
+
+ assert response.image_uri == "image_uri_value"
+
+ assert response.keyword_searchable_job_custom_attributes == [
+ "keyword_searchable_job_custom_attributes_value"
+ ]
+
+ assert response.suspended is True
+
+
+def test_get_company_from_dict():
+ test_get_company(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_get_company_async(transport: str = "grpc_asyncio"):
+ client = CompanyServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = company_service.GetCompanyRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.get_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ company.Company(
+ name="name_value",
+ display_name="display_name_value",
+ external_id="external_id_value",
+ size=common.CompanySize.MINI,
+ headquarters_address="headquarters_address_value",
+ hiring_agency=True,
+ eeo_text="eeo_text_value",
+ website_uri="website_uri_value",
+ career_site_uri="career_site_uri_value",
+ image_uri="image_uri_value",
+ keyword_searchable_job_custom_attributes=[
+ "keyword_searchable_job_custom_attributes_value"
+ ],
+ suspended=True,
+ )
+ )
+
+ response = await client.get_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, company.Company)
+
+ assert response.name == "name_value"
+
+ assert response.display_name == "display_name_value"
+
+ assert response.external_id == "external_id_value"
+
+ assert response.size == common.CompanySize.MINI
+
+ assert response.headquarters_address == "headquarters_address_value"
+
+ assert response.hiring_agency is True
+
+ assert response.eeo_text == "eeo_text_value"
+
+ assert response.website_uri == "website_uri_value"
+
+ assert response.career_site_uri == "career_site_uri_value"
+
+ assert response.image_uri == "image_uri_value"
+
+ assert response.keyword_searchable_job_custom_attributes == [
+ "keyword_searchable_job_custom_attributes_value"
+ ]
+
+ assert response.suspended is True
+
+
+def test_get_company_field_headers():
+ client = CompanyServiceClient(credentials=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 = company_service.GetCompanyRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_company), "__call__") as call:
+ call.return_value = company.Company()
+
+ client.get_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_get_company_field_headers_async():
+ client = CompanyServiceAsyncClient(credentials=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 = company_service.GetCompanyRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.get_company), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(company.Company())
+
+ await client.get_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+def test_get_company_flattened():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = company.Company()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.get_company(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].name == "name_value"
+
+
+def test_get_company_flattened_error():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.get_company(
+ company_service.GetCompanyRequest(), name="name_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_get_company_flattened_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.get_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = company.Company()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(company.Company())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.get_company(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # 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_get_company_flattened_error_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.get_company(
+ company_service.GetCompanyRequest(), name="name_value",
+ )
+
+
+def test_update_company(
+ transport: str = "grpc", request_type=company_service.UpdateCompanyRequest
+):
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_company.Company(
+ name="name_value",
+ display_name="display_name_value",
+ external_id="external_id_value",
+ size=common.CompanySize.MINI,
+ headquarters_address="headquarters_address_value",
+ hiring_agency=True,
+ eeo_text="eeo_text_value",
+ website_uri="website_uri_value",
+ career_site_uri="career_site_uri_value",
+ image_uri="image_uri_value",
+ keyword_searchable_job_custom_attributes=[
+ "keyword_searchable_job_custom_attributes_value"
+ ],
+ suspended=True,
+ )
+
+ response = client.update_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == company_service.UpdateCompanyRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_company.Company)
+
+ assert response.name == "name_value"
+
+ assert response.display_name == "display_name_value"
+
+ assert response.external_id == "external_id_value"
+
+ assert response.size == common.CompanySize.MINI
+
+ assert response.headquarters_address == "headquarters_address_value"
+
+ assert response.hiring_agency is True
+
+ assert response.eeo_text == "eeo_text_value"
+
+ assert response.website_uri == "website_uri_value"
+
+ assert response.career_site_uri == "career_site_uri_value"
+
+ assert response.image_uri == "image_uri_value"
+
+ assert response.keyword_searchable_job_custom_attributes == [
+ "keyword_searchable_job_custom_attributes_value"
+ ]
+
+ assert response.suspended is True
+
+
+def test_update_company_from_dict():
+ test_update_company(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_update_company_async(transport: str = "grpc_asyncio"):
+ client = CompanyServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = company_service.UpdateCompanyRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ gct_company.Company(
+ name="name_value",
+ display_name="display_name_value",
+ external_id="external_id_value",
+ size=common.CompanySize.MINI,
+ headquarters_address="headquarters_address_value",
+ hiring_agency=True,
+ eeo_text="eeo_text_value",
+ website_uri="website_uri_value",
+ career_site_uri="career_site_uri_value",
+ image_uri="image_uri_value",
+ keyword_searchable_job_custom_attributes=[
+ "keyword_searchable_job_custom_attributes_value"
+ ],
+ suspended=True,
+ )
+ )
+
+ response = await client.update_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_company.Company)
+
+ assert response.name == "name_value"
+
+ assert response.display_name == "display_name_value"
+
+ assert response.external_id == "external_id_value"
+
+ assert response.size == common.CompanySize.MINI
+
+ assert response.headquarters_address == "headquarters_address_value"
+
+ assert response.hiring_agency is True
+
+ assert response.eeo_text == "eeo_text_value"
+
+ assert response.website_uri == "website_uri_value"
+
+ assert response.career_site_uri == "career_site_uri_value"
+
+ assert response.image_uri == "image_uri_value"
+
+ assert response.keyword_searchable_job_custom_attributes == [
+ "keyword_searchable_job_custom_attributes_value"
+ ]
+
+ assert response.suspended is True
+
+
+def test_update_company_field_headers():
+ client = CompanyServiceClient(credentials=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 = company_service.UpdateCompanyRequest()
+ request.company.name = "company.name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_company), "__call__") as call:
+ call.return_value = gct_company.Company()
+
+ client.update_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "company.name=company.name/value",) in kw[
+ "metadata"
+ ]
+
+
+@pytest.mark.asyncio
+async def test_update_company_field_headers_async():
+ client = CompanyServiceAsyncClient(credentials=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 = company_service.UpdateCompanyRequest()
+ request.company.name = "company.name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_company), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_company.Company())
+
+ await client.update_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "company.name=company.name/value",) in kw[
+ "metadata"
+ ]
+
+
+def test_update_company_flattened():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_company.Company()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.update_company(
+ company=gct_company.Company(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].company == gct_company.Company(name="name_value")
+
+ assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"])
+
+
+def test_update_company_flattened_error():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.update_company(
+ company_service.UpdateCompanyRequest(),
+ company=gct_company.Company(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+
+@pytest.mark.asyncio
+async def test_update_company_flattened_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_company.Company()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_company.Company())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.update_company(
+ company=gct_company.Company(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].company == gct_company.Company(name="name_value")
+
+ assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"])
+
+
+@pytest.mark.asyncio
+async def test_update_company_flattened_error_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.update_company(
+ company_service.UpdateCompanyRequest(),
+ company=gct_company.Company(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+
+def test_delete_company(
+ transport: str = "grpc", request_type=company_service.DeleteCompanyRequest
+):
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ response = client.delete_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == company_service.DeleteCompanyRequest()
+
+ # Establish that the response is the type that we expect.
+ assert response is None
+
+
+def test_delete_company_from_dict():
+ test_delete_company(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_delete_company_async(transport: str = "grpc_asyncio"):
+ client = CompanyServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = company_service.DeleteCompanyRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+
+ response = await client.delete_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert response is None
+
+
+def test_delete_company_field_headers():
+ client = CompanyServiceClient(credentials=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 = company_service.DeleteCompanyRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_company), "__call__") as call:
+ call.return_value = None
+
+ client.delete_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_delete_company_field_headers_async():
+ client = CompanyServiceAsyncClient(credentials=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 = company_service.DeleteCompanyRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_company), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+
+ await client.delete_company(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+def test_delete_company_flattened():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_company), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.delete_company(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].name == "name_value"
+
+
+def test_delete_company_flattened_error():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.delete_company(
+ company_service.DeleteCompanyRequest(), name="name_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_delete_company_flattened_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_company), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.delete_company(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # 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_delete_company_flattened_error_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.delete_company(
+ company_service.DeleteCompanyRequest(), name="name_value",
+ )
+
+
+def test_list_companies(
+ transport: str = "grpc", request_type=company_service.ListCompaniesRequest
+):
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_companies), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = company_service.ListCompaniesResponse(
+ next_page_token="next_page_token_value",
+ )
+
+ response = client.list_companies(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == company_service.ListCompaniesRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, pagers.ListCompaniesPager)
+
+ assert response.next_page_token == "next_page_token_value"
+
+
+def test_list_companies_from_dict():
+ test_list_companies(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_list_companies_async(transport: str = "grpc_asyncio"):
+ client = CompanyServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = company_service.ListCompaniesRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_companies), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ company_service.ListCompaniesResponse(
+ next_page_token="next_page_token_value",
+ )
+ )
+
+ response = await client.list_companies(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, pagers.ListCompaniesAsyncPager)
+
+ assert response.next_page_token == "next_page_token_value"
+
+
+def test_list_companies_field_headers():
+ client = CompanyServiceClient(credentials=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 = company_service.ListCompaniesRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_companies), "__call__") as call:
+ call.return_value = company_service.ListCompaniesResponse()
+
+ client.list_companies(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_list_companies_field_headers_async():
+ client = CompanyServiceAsyncClient(credentials=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 = company_service.ListCompaniesRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_companies), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ company_service.ListCompaniesResponse()
+ )
+
+ await client.list_companies(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_list_companies_flattened():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_companies), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = company_service.ListCompaniesResponse()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.list_companies(parent="parent_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+
+def test_list_companies_flattened_error():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.list_companies(
+ company_service.ListCompaniesRequest(), parent="parent_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_list_companies_flattened_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_companies), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = company_service.ListCompaniesResponse()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ company_service.ListCompaniesResponse()
+ )
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.list_companies(parent="parent_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+
+@pytest.mark.asyncio
+async def test_list_companies_flattened_error_async():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.list_companies(
+ company_service.ListCompaniesRequest(), parent="parent_value",
+ )
+
+
+def test_list_companies_pager():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_companies), "__call__") as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(), company.Company(),],
+ next_page_token="abc",
+ ),
+ company_service.ListCompaniesResponse(companies=[], next_page_token="def",),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(),], next_page_token="ghi",
+ ),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(),],
+ ),
+ RuntimeError,
+ )
+
+ metadata = ()
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)),
+ )
+ pager = client.list_companies(request={})
+
+ assert pager._metadata == metadata
+
+ results = [i for i in pager]
+ assert len(results) == 6
+ assert all(isinstance(i, company.Company) for i in results)
+
+
+def test_list_companies_pages():
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_companies), "__call__") as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(), company.Company(),],
+ next_page_token="abc",
+ ),
+ company_service.ListCompaniesResponse(companies=[], next_page_token="def",),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(),], next_page_token="ghi",
+ ),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(),],
+ ),
+ RuntimeError,
+ )
+ pages = list(client.list_companies(request={}).pages)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
+
+
+@pytest.mark.asyncio
+async def test_list_companies_async_pager():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_companies),
+ "__call__",
+ new_callable=mock.AsyncMock,
+ ) as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(), company.Company(),],
+ next_page_token="abc",
+ ),
+ company_service.ListCompaniesResponse(companies=[], next_page_token="def",),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(),], next_page_token="ghi",
+ ),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(),],
+ ),
+ RuntimeError,
+ )
+ async_pager = await client.list_companies(request={},)
+ assert async_pager.next_page_token == "abc"
+ responses = []
+ async for response in async_pager:
+ responses.append(response)
+
+ assert len(responses) == 6
+ assert all(isinstance(i, company.Company) for i in responses)
+
+
+@pytest.mark.asyncio
+async def test_list_companies_async_pages():
+ client = CompanyServiceAsyncClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_companies),
+ "__call__",
+ new_callable=mock.AsyncMock,
+ ) as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(), company.Company(),],
+ next_page_token="abc",
+ ),
+ company_service.ListCompaniesResponse(companies=[], next_page_token="def",),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(),], next_page_token="ghi",
+ ),
+ company_service.ListCompaniesResponse(
+ companies=[company.Company(), company.Company(),],
+ ),
+ RuntimeError,
+ )
+ pages = []
+ async for page_ in (await client.list_companies(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
+
+
+def test_credentials_transport_error():
+ # It is an error to provide credentials and a transport instance.
+ transport = transports.CompanyServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # It is an error to provide a credentials file and a transport instance.
+ transport = transports.CompanyServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = CompanyServiceClient(
+ client_options={"credentials_file": "credentials.json"},
+ transport=transport,
+ )
+
+ # It is an error to provide scopes and a transport instance.
+ transport = transports.CompanyServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = CompanyServiceClient(
+ client_options={"scopes": ["1", "2"]}, transport=transport,
+ )
+
+
+def test_transport_instance():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.CompanyServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ client = CompanyServiceClient(transport=transport)
+ assert client._transport is transport
+
+
+def test_transport_get_channel():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.CompanyServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+ transport = transports.CompanyServiceGrpcAsyncIOTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.CompanyServiceGrpcTransport,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ ],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
+def test_transport_grpc_default():
+ # A client should use the gRPC transport by default.
+ client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
+ assert isinstance(client._transport, transports.CompanyServiceGrpcTransport,)
+
+
+def test_company_service_base_transport_error():
+ # Passing both a credentials object and credentials_file should raise an error
+ with pytest.raises(exceptions.DuplicateCredentialArgs):
+ transport = transports.CompanyServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ credentials_file="credentials.json",
+ )
+
+
+def test_company_service_base_transport():
+ # Instantiate the base transport.
+ with mock.patch(
+ "google.cloud.talent_v4.services.company_service.transports.CompanyServiceTransport.__init__"
+ ) as Transport:
+ Transport.return_value = None
+ transport = transports.CompanyServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+
+ # Every method on the transport should just blindly
+ # raise NotImplementedError.
+ methods = (
+ "create_company",
+ "get_company",
+ "update_company",
+ "delete_company",
+ "list_companies",
+ )
+ for method in methods:
+ with pytest.raises(NotImplementedError):
+ getattr(transport, method)(request=object())
+
+
+def test_company_service_base_transport_with_credentials_file():
+ # Instantiate the base transport with a credentials file
+ with mock.patch.object(
+ auth, "load_credentials_from_file"
+ ) as load_creds, mock.patch(
+ "google.cloud.talent_v4.services.company_service.transports.CompanyServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ load_creds.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.CompanyServiceTransport(
+ credentials_file="credentials.json", quota_project_id="octopus",
+ )
+ load_creds.assert_called_once_with(
+ "credentials.json",
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_company_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(
+ "google.cloud.talent_v4.services.company_service.transports.CompanyServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.CompanyServiceTransport()
+ adc.assert_called_once()
+
+
+def test_company_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)
+ CompanyServiceClient()
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id=None,
+ )
+
+
+def test_company_service_transport_auth_adc():
+ # 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.CompanyServiceGrpcTransport(
+ host="squid.clam.whelk", quota_project_id="octopus"
+ )
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_company_service_host_no_port():
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(api_endpoint="jobs.googleapis.com"),
+ )
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_company_service_host_with_port():
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(
+ api_endpoint="jobs.googleapis.com:8000"
+ ),
+ )
+ assert client._transport._host == "jobs.googleapis.com:8000"
+
+
+def test_company_service_grpc_transport_channel():
+ channel = grpc.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.CompanyServiceGrpcTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+def test_company_service_grpc_asyncio_transport_channel():
+ channel = aio.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.CompanyServiceGrpcAsyncIOTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.CompanyServiceGrpcTransport,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_company_service_transport_channel_mtls_with_client_cert_source(
+ transport_class,
+):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.CompanyServiceGrpcTransport,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_company_service_transport_channel_mtls_with_adc(transport_class):
+ mock_ssl_cred = mock.Mock()
+ with mock.patch.multiple(
+ "google.auth.transport.grpc.SslCredentials",
+ __init__=mock.Mock(return_value=None),
+ ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
+ ):
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+def test_company_path():
+ project = "squid"
+ tenant = "clam"
+ company = "whelk"
+
+ expected = "projects/{project}/tenants/{tenant}/companies/{company}".format(
+ project=project, tenant=tenant, company=company,
+ )
+ actual = CompanyServiceClient.company_path(project, tenant, company)
+ assert expected == actual
+
+
+def test_parse_company_path():
+ expected = {
+ "project": "octopus",
+ "tenant": "oyster",
+ "company": "nudibranch",
+ }
+ path = CompanyServiceClient.company_path(**expected)
+
+ # Check that the path construction is reversible.
+ actual = CompanyServiceClient.parse_company_path(path)
+ assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.CompanyServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.CompanyServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = CompanyServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4/test_completion.py b/tests/unit/gapic/talent_v4/test_completion.py
new file mode 100644
index 00000000..390d8e24
--- /dev/null
+++ b/tests/unit/gapic/talent_v4/test_completion.py
@@ -0,0 +1,851 @@
+# -*- 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.
+#
+
+import os
+import mock
+
+import grpc
+from grpc.experimental import aio
+import math
+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 gapic_v1
+from google.api_core import grpc_helpers
+from google.api_core import grpc_helpers_async
+from google.auth import credentials
+from google.auth.exceptions import MutualTLSChannelError
+from google.cloud.talent_v4.services.completion import CompletionAsyncClient
+from google.cloud.talent_v4.services.completion import CompletionClient
+from google.cloud.talent_v4.services.completion import transports
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import completion_service
+from google.oauth2 import service_account
+
+
+def client_cert_source_callback():
+ return b"cert bytes", b"key bytes"
+
+
+# If default endpoint is localhost, then default mtls endpoint will be the same.
+# This method modifies the default endpoint so the client can produce a different
+# mtls endpoint for endpoint testing purposes.
+def modify_default_endpoint(client):
+ return (
+ "foo.googleapis.com"
+ if ("localhost" in client.DEFAULT_ENDPOINT)
+ else client.DEFAULT_ENDPOINT
+ )
+
+
+def test__get_default_mtls_endpoint():
+ api_endpoint = "example.googleapis.com"
+ api_mtls_endpoint = "example.mtls.googleapis.com"
+ sandbox_endpoint = "example.sandbox.googleapis.com"
+ sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com"
+ non_googleapi = "api.example.com"
+
+ assert CompletionClient._get_default_mtls_endpoint(None) is None
+ assert (
+ CompletionClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint
+ )
+ assert (
+ CompletionClient._get_default_mtls_endpoint(api_mtls_endpoint)
+ == api_mtls_endpoint
+ )
+ assert (
+ CompletionClient._get_default_mtls_endpoint(sandbox_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert (
+ CompletionClient._get_default_mtls_endpoint(sandbox_mtls_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert CompletionClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
+
+
+@pytest.mark.parametrize("client_class", [CompletionClient, CompletionAsyncClient])
+def test_completion_client_from_service_account_file(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_file"
+ ) as factory:
+ factory.return_value = creds
+ client = client_class.from_service_account_file("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ client = client_class.from_service_account_json("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_completion_client_get_transport_class():
+ transport = CompletionClient.get_transport_class()
+ assert transport == transports.CompletionGrpcTransport
+
+ transport = CompletionClient.get_transport_class("grpc")
+ assert transport == transports.CompletionGrpcTransport
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (CompletionClient, transports.CompletionGrpcTransport, "grpc"),
+ (
+ CompletionAsyncClient,
+ transports.CompletionGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+@mock.patch.object(
+ CompletionClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionClient)
+)
+@mock.patch.object(
+ CompletionAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompletionAsyncClient),
+)
+def test_completion_client_client_options(
+ client_class, transport_class, transport_name
+):
+ # Check that if channel is provided we won't create a new one.
+ with mock.patch.object(CompletionClient, "get_transport_class") as gtc:
+ transport = transport_class(credentials=credentials.AnonymousCredentials())
+ client = client_class(transport=transport)
+ gtc.assert_not_called()
+
+ # Check that if channel is provided via str we will create a new one.
+ with mock.patch.object(CompletionClient, "get_transport_class") as gtc:
+ client = client_class(transport=transport_name)
+ gtc.assert_called()
+
+ # Check the case api_endpoint is provided.
+ options = client_options.ClientOptions(api_endpoint="squid.clam.whelk")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "never".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "always".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_MTLS_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (CompletionClient, transports.CompletionGrpcTransport, "grpc", "true"),
+ (
+ CompletionAsyncClient,
+ transports.CompletionGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (CompletionClient, transports.CompletionGrpcTransport, "grpc", "false"),
+ (
+ CompletionAsyncClient,
+ transports.CompletionGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ CompletionClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionClient)
+)
+@mock.patch.object(
+ CompletionAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompletionAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_completion_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ options = client_options.ClientOptions(
+ client_cert_source=client_cert_source_callback
+ )
+ with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
+ with mock.patch(
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
+ ):
+ patched.return_value = None
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (CompletionClient, transports.CompletionGrpcTransport, "grpc"),
+ (
+ CompletionAsyncClient,
+ transports.CompletionGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_completion_client_client_options_scopes(
+ client_class, transport_class, transport_name
+):
+ # Check the case scopes are provided.
+ options = client_options.ClientOptions(scopes=["1", "2"],)
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=["1", "2"],
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (CompletionClient, transports.CompletionGrpcTransport, "grpc"),
+ (
+ CompletionAsyncClient,
+ transports.CompletionGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_completion_client_client_options_credentials_file(
+ client_class, transport_class, transport_name
+):
+ # Check the case credentials file is provided.
+ options = client_options.ClientOptions(credentials_file="credentials.json")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file="credentials.json",
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_completion_client_client_options_from_dict():
+ with mock.patch(
+ "google.cloud.talent_v4.services.completion.transports.CompletionGrpcTransport.__init__"
+ ) as grpc_transport:
+ grpc_transport.return_value = None
+ client = CompletionClient(client_options={"api_endpoint": "squid.clam.whelk"})
+ grpc_transport.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_complete_query(
+ transport: str = "grpc", request_type=completion_service.CompleteQueryRequest
+):
+ client = CompletionClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.complete_query), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = completion_service.CompleteQueryResponse()
+
+ response = client.complete_query(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == completion_service.CompleteQueryRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, completion_service.CompleteQueryResponse)
+
+
+def test_complete_query_from_dict():
+ test_complete_query(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_complete_query_async(transport: str = "grpc_asyncio"):
+ client = CompletionAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = completion_service.CompleteQueryRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.complete_query), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ completion_service.CompleteQueryResponse()
+ )
+
+ response = await client.complete_query(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, completion_service.CompleteQueryResponse)
+
+
+def test_complete_query_field_headers():
+ client = CompletionClient(credentials=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 = completion_service.CompleteQueryRequest()
+ request.tenant = "tenant/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.complete_query), "__call__") as call:
+ call.return_value = completion_service.CompleteQueryResponse()
+
+ client.complete_query(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "tenant=tenant/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_complete_query_field_headers_async():
+ client = CompletionAsyncClient(credentials=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 = completion_service.CompleteQueryRequest()
+ request.tenant = "tenant/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.complete_query), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ completion_service.CompleteQueryResponse()
+ )
+
+ await client.complete_query(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "tenant=tenant/value",) in kw["metadata"]
+
+
+def test_credentials_transport_error():
+ # It is an error to provide credentials and a transport instance.
+ transport = transports.CompletionGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = CompletionClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # It is an error to provide a credentials file and a transport instance.
+ transport = transports.CompletionGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = CompletionClient(
+ client_options={"credentials_file": "credentials.json"},
+ transport=transport,
+ )
+
+ # It is an error to provide scopes and a transport instance.
+ transport = transports.CompletionGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = CompletionClient(
+ client_options={"scopes": ["1", "2"]}, transport=transport,
+ )
+
+
+def test_transport_instance():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.CompletionGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ client = CompletionClient(transport=transport)
+ assert client._transport is transport
+
+
+def test_transport_get_channel():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.CompletionGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+ transport = transports.CompletionGrpcAsyncIOTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.CompletionGrpcTransport, transports.CompletionGrpcAsyncIOTransport],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
+def test_transport_grpc_default():
+ # A client should use the gRPC transport by default.
+ client = CompletionClient(credentials=credentials.AnonymousCredentials(),)
+ assert isinstance(client._transport, transports.CompletionGrpcTransport,)
+
+
+def test_completion_base_transport_error():
+ # Passing both a credentials object and credentials_file should raise an error
+ with pytest.raises(exceptions.DuplicateCredentialArgs):
+ transport = transports.CompletionTransport(
+ credentials=credentials.AnonymousCredentials(),
+ credentials_file="credentials.json",
+ )
+
+
+def test_completion_base_transport():
+ # Instantiate the base transport.
+ with mock.patch(
+ "google.cloud.talent_v4.services.completion.transports.CompletionTransport.__init__"
+ ) as Transport:
+ Transport.return_value = None
+ transport = transports.CompletionTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+
+ # Every method on the transport should just blindly
+ # raise NotImplementedError.
+ methods = ("complete_query",)
+ for method in methods:
+ with pytest.raises(NotImplementedError):
+ getattr(transport, method)(request=object())
+
+
+def test_completion_base_transport_with_credentials_file():
+ # Instantiate the base transport with a credentials file
+ with mock.patch.object(
+ auth, "load_credentials_from_file"
+ ) as load_creds, mock.patch(
+ "google.cloud.talent_v4.services.completion.transports.CompletionTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ load_creds.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.CompletionTransport(
+ credentials_file="credentials.json", quota_project_id="octopus",
+ )
+ load_creds.assert_called_once_with(
+ "credentials.json",
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_completion_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(
+ "google.cloud.talent_v4.services.completion.transports.CompletionTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.CompletionTransport()
+ adc.assert_called_once()
+
+
+def test_completion_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)
+ CompletionClient()
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id=None,
+ )
+
+
+def test_completion_transport_auth_adc():
+ # 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.CompletionGrpcTransport(
+ host="squid.clam.whelk", quota_project_id="octopus"
+ )
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_completion_host_no_port():
+ client = CompletionClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(api_endpoint="jobs.googleapis.com"),
+ )
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_completion_host_with_port():
+ client = CompletionClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(
+ api_endpoint="jobs.googleapis.com:8000"
+ ),
+ )
+ assert client._transport._host == "jobs.googleapis.com:8000"
+
+
+def test_completion_grpc_transport_channel():
+ channel = grpc.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.CompletionGrpcTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+def test_completion_grpc_asyncio_transport_channel():
+ channel = aio.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.CompletionGrpcAsyncIOTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.CompletionGrpcTransport, transports.CompletionGrpcAsyncIOTransport],
+)
+def test_completion_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.CompletionGrpcTransport, transports.CompletionGrpcAsyncIOTransport],
+)
+def test_completion_transport_channel_mtls_with_adc(transport_class):
+ mock_ssl_cred = mock.Mock()
+ with mock.patch.multiple(
+ "google.auth.transport.grpc.SslCredentials",
+ __init__=mock.Mock(return_value=None),
+ ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
+ ):
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.CompletionTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = CompletionClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.CompletionTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = CompletionClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4/test_event_service.py b/tests/unit/gapic/talent_v4/test_event_service.py
new file mode 100644
index 00000000..dd38cf40
--- /dev/null
+++ b/tests/unit/gapic/talent_v4/test_event_service.py
@@ -0,0 +1,958 @@
+# -*- 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.
+#
+
+import os
+import mock
+
+import grpc
+from grpc.experimental import aio
+import math
+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 gapic_v1
+from google.api_core import grpc_helpers
+from google.api_core import grpc_helpers_async
+from google.auth import credentials
+from google.auth.exceptions import MutualTLSChannelError
+from google.cloud.talent_v4.services.event_service import EventServiceAsyncClient
+from google.cloud.talent_v4.services.event_service import EventServiceClient
+from google.cloud.talent_v4.services.event_service import transports
+from google.cloud.talent_v4.types import event
+from google.cloud.talent_v4.types import event_service
+from google.oauth2 import service_account
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+
+
+def client_cert_source_callback():
+ return b"cert bytes", b"key bytes"
+
+
+# If default endpoint is localhost, then default mtls endpoint will be the same.
+# This method modifies the default endpoint so the client can produce a different
+# mtls endpoint for endpoint testing purposes.
+def modify_default_endpoint(client):
+ return (
+ "foo.googleapis.com"
+ if ("localhost" in client.DEFAULT_ENDPOINT)
+ else client.DEFAULT_ENDPOINT
+ )
+
+
+def test__get_default_mtls_endpoint():
+ api_endpoint = "example.googleapis.com"
+ api_mtls_endpoint = "example.mtls.googleapis.com"
+ sandbox_endpoint = "example.sandbox.googleapis.com"
+ sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com"
+ non_googleapi = "api.example.com"
+
+ assert EventServiceClient._get_default_mtls_endpoint(None) is None
+ assert (
+ EventServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint
+ )
+ assert (
+ EventServiceClient._get_default_mtls_endpoint(api_mtls_endpoint)
+ == api_mtls_endpoint
+ )
+ assert (
+ EventServiceClient._get_default_mtls_endpoint(sandbox_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert (
+ EventServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert EventServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
+
+
+@pytest.mark.parametrize("client_class", [EventServiceClient, EventServiceAsyncClient])
+def test_event_service_client_from_service_account_file(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_file"
+ ) as factory:
+ factory.return_value = creds
+ client = client_class.from_service_account_file("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ client = client_class.from_service_account_json("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_event_service_client_get_transport_class():
+ transport = EventServiceClient.get_transport_class()
+ assert transport == transports.EventServiceGrpcTransport
+
+ transport = EventServiceClient.get_transport_class("grpc")
+ assert transport == transports.EventServiceGrpcTransport
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (EventServiceClient, transports.EventServiceGrpcTransport, "grpc"),
+ (
+ EventServiceAsyncClient,
+ transports.EventServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+@mock.patch.object(
+ EventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(EventServiceClient)
+)
+@mock.patch.object(
+ EventServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(EventServiceAsyncClient),
+)
+def test_event_service_client_client_options(
+ client_class, transport_class, transport_name
+):
+ # Check that if channel is provided we won't create a new one.
+ with mock.patch.object(EventServiceClient, "get_transport_class") as gtc:
+ transport = transport_class(credentials=credentials.AnonymousCredentials())
+ client = client_class(transport=transport)
+ gtc.assert_not_called()
+
+ # Check that if channel is provided via str we will create a new one.
+ with mock.patch.object(EventServiceClient, "get_transport_class") as gtc:
+ client = client_class(transport=transport_name)
+ gtc.assert_called()
+
+ # Check the case api_endpoint is provided.
+ options = client_options.ClientOptions(api_endpoint="squid.clam.whelk")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "never".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "always".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_MTLS_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (EventServiceClient, transports.EventServiceGrpcTransport, "grpc", "true"),
+ (
+ EventServiceAsyncClient,
+ transports.EventServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (EventServiceClient, transports.EventServiceGrpcTransport, "grpc", "false"),
+ (
+ EventServiceAsyncClient,
+ transports.EventServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ EventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(EventServiceClient)
+)
+@mock.patch.object(
+ EventServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(EventServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_event_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ options = client_options.ClientOptions(
+ client_cert_source=client_cert_source_callback
+ )
+ with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
+ with mock.patch(
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
+ ):
+ patched.return_value = None
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (EventServiceClient, transports.EventServiceGrpcTransport, "grpc"),
+ (
+ EventServiceAsyncClient,
+ transports.EventServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_event_service_client_client_options_scopes(
+ client_class, transport_class, transport_name
+):
+ # Check the case scopes are provided.
+ options = client_options.ClientOptions(scopes=["1", "2"],)
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=["1", "2"],
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (EventServiceClient, transports.EventServiceGrpcTransport, "grpc"),
+ (
+ EventServiceAsyncClient,
+ transports.EventServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_event_service_client_client_options_credentials_file(
+ client_class, transport_class, transport_name
+):
+ # Check the case credentials file is provided.
+ options = client_options.ClientOptions(credentials_file="credentials.json")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file="credentials.json",
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_event_service_client_client_options_from_dict():
+ with mock.patch(
+ "google.cloud.talent_v4.services.event_service.transports.EventServiceGrpcTransport.__init__"
+ ) as grpc_transport:
+ grpc_transport.return_value = None
+ client = EventServiceClient(client_options={"api_endpoint": "squid.clam.whelk"})
+ grpc_transport.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_create_client_event(
+ transport: str = "grpc", request_type=event_service.CreateClientEventRequest
+):
+ client = EventServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.create_client_event), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = event.ClientEvent(
+ request_id="request_id_value",
+ event_id="event_id_value",
+ event_notes="event_notes_value",
+ job_event=event.JobEvent(type_=event.JobEvent.JobEventType.IMPRESSION),
+ )
+
+ response = client.create_client_event(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == event_service.CreateClientEventRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, event.ClientEvent)
+
+ assert response.request_id == "request_id_value"
+
+ assert response.event_id == "event_id_value"
+
+ assert response.event_notes == "event_notes_value"
+
+
+def test_create_client_event_from_dict():
+ test_create_client_event(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_create_client_event_async(transport: str = "grpc_asyncio"):
+ client = EventServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = event_service.CreateClientEventRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_client_event), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ event.ClientEvent(
+ request_id="request_id_value",
+ event_id="event_id_value",
+ event_notes="event_notes_value",
+ )
+ )
+
+ response = await client.create_client_event(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, event.ClientEvent)
+
+ assert response.request_id == "request_id_value"
+
+ assert response.event_id == "event_id_value"
+
+ assert response.event_notes == "event_notes_value"
+
+
+def test_create_client_event_field_headers():
+ client = EventServiceClient(credentials=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 = event_service.CreateClientEventRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.create_client_event), "__call__"
+ ) as call:
+ call.return_value = event.ClientEvent()
+
+ client.create_client_event(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_create_client_event_field_headers_async():
+ client = EventServiceAsyncClient(credentials=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 = event_service.CreateClientEventRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_client_event), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(event.ClientEvent())
+
+ await client.create_client_event(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_create_client_event_flattened():
+ client = EventServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.create_client_event), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = event.ClientEvent()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.create_client_event(
+ parent="parent_value",
+ client_event=event.ClientEvent(request_id="request_id_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].client_event == event.ClientEvent(request_id="request_id_value")
+
+
+def test_create_client_event_flattened_error():
+ client = EventServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.create_client_event(
+ event_service.CreateClientEventRequest(),
+ parent="parent_value",
+ client_event=event.ClientEvent(request_id="request_id_value"),
+ )
+
+
+@pytest.mark.asyncio
+async def test_create_client_event_flattened_async():
+ client = EventServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_client_event), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = event.ClientEvent()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(event.ClientEvent())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.create_client_event(
+ parent="parent_value",
+ client_event=event.ClientEvent(request_id="request_id_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].client_event == event.ClientEvent(request_id="request_id_value")
+
+
+@pytest.mark.asyncio
+async def test_create_client_event_flattened_error_async():
+ client = EventServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.create_client_event(
+ event_service.CreateClientEventRequest(),
+ parent="parent_value",
+ client_event=event.ClientEvent(request_id="request_id_value"),
+ )
+
+
+def test_credentials_transport_error():
+ # It is an error to provide credentials and a transport instance.
+ transport = transports.EventServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = EventServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # It is an error to provide a credentials file and a transport instance.
+ transport = transports.EventServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = EventServiceClient(
+ client_options={"credentials_file": "credentials.json"},
+ transport=transport,
+ )
+
+ # It is an error to provide scopes and a transport instance.
+ transport = transports.EventServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = EventServiceClient(
+ client_options={"scopes": ["1", "2"]}, transport=transport,
+ )
+
+
+def test_transport_instance():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.EventServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ client = EventServiceClient(transport=transport)
+ assert client._transport is transport
+
+
+def test_transport_get_channel():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.EventServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+ transport = transports.EventServiceGrpcAsyncIOTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.EventServiceGrpcTransport, transports.EventServiceGrpcAsyncIOTransport],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
+def test_transport_grpc_default():
+ # A client should use the gRPC transport by default.
+ client = EventServiceClient(credentials=credentials.AnonymousCredentials(),)
+ assert isinstance(client._transport, transports.EventServiceGrpcTransport,)
+
+
+def test_event_service_base_transport_error():
+ # Passing both a credentials object and credentials_file should raise an error
+ with pytest.raises(exceptions.DuplicateCredentialArgs):
+ transport = transports.EventServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ credentials_file="credentials.json",
+ )
+
+
+def test_event_service_base_transport():
+ # Instantiate the base transport.
+ with mock.patch(
+ "google.cloud.talent_v4.services.event_service.transports.EventServiceTransport.__init__"
+ ) as Transport:
+ Transport.return_value = None
+ transport = transports.EventServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+
+ # Every method on the transport should just blindly
+ # raise NotImplementedError.
+ methods = ("create_client_event",)
+ for method in methods:
+ with pytest.raises(NotImplementedError):
+ getattr(transport, method)(request=object())
+
+
+def test_event_service_base_transport_with_credentials_file():
+ # Instantiate the base transport with a credentials file
+ with mock.patch.object(
+ auth, "load_credentials_from_file"
+ ) as load_creds, mock.patch(
+ "google.cloud.talent_v4.services.event_service.transports.EventServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ load_creds.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.EventServiceTransport(
+ credentials_file="credentials.json", quota_project_id="octopus",
+ )
+ load_creds.assert_called_once_with(
+ "credentials.json",
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_event_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(
+ "google.cloud.talent_v4.services.event_service.transports.EventServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.EventServiceTransport()
+ adc.assert_called_once()
+
+
+def test_event_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)
+ EventServiceClient()
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id=None,
+ )
+
+
+def test_event_service_transport_auth_adc():
+ # 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.EventServiceGrpcTransport(
+ host="squid.clam.whelk", quota_project_id="octopus"
+ )
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_event_service_host_no_port():
+ client = EventServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(api_endpoint="jobs.googleapis.com"),
+ )
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_event_service_host_with_port():
+ client = EventServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(
+ api_endpoint="jobs.googleapis.com:8000"
+ ),
+ )
+ assert client._transport._host == "jobs.googleapis.com:8000"
+
+
+def test_event_service_grpc_transport_channel():
+ channel = grpc.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.EventServiceGrpcTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+def test_event_service_grpc_asyncio_transport_channel():
+ channel = aio.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.EventServiceGrpcAsyncIOTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.EventServiceGrpcTransport, transports.EventServiceGrpcAsyncIOTransport],
+)
+def test_event_service_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.EventServiceGrpcTransport, transports.EventServiceGrpcAsyncIOTransport],
+)
+def test_event_service_transport_channel_mtls_with_adc(transport_class):
+ mock_ssl_cred = mock.Mock()
+ with mock.patch.multiple(
+ "google.auth.transport.grpc.SslCredentials",
+ __init__=mock.Mock(return_value=None),
+ ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
+ ):
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.EventServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = EventServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.EventServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = EventServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4/test_job_service.py b/tests/unit/gapic/talent_v4/test_job_service.py
new file mode 100644
index 00000000..e8bf3b66
--- /dev/null
+++ b/tests/unit/gapic/talent_v4/test_job_service.py
@@ -0,0 +1,3087 @@
+# -*- 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.
+#
+
+import os
+import mock
+
+import grpc
+from grpc.experimental import aio
+import math
+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 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.exceptions import MutualTLSChannelError
+from google.cloud.talent_v4.services.job_service import JobServiceAsyncClient
+from google.cloud.talent_v4.services.job_service import JobServiceClient
+from google.cloud.talent_v4.services.job_service import pagers
+from google.cloud.talent_v4.services.job_service import transports
+from google.cloud.talent_v4.types import common
+from google.cloud.talent_v4.types import filters
+from google.cloud.talent_v4.types import histogram
+from google.cloud.talent_v4.types import job
+from google.cloud.talent_v4.types import job as gct_job
+from google.cloud.talent_v4.types import job_service
+from google.longrunning import operations_pb2
+from google.oauth2 import service_account
+from google.protobuf import duration_pb2 as duration # type: ignore
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+from google.protobuf import timestamp_pb2 as timestamp # type: ignore
+from google.protobuf import wrappers_pb2 as wrappers # type: ignore
+from google.type import latlng_pb2 as latlng # type: ignore
+from google.type import money_pb2 as money # type: ignore
+from google.type import postal_address_pb2 as gt_postal_address # type: ignore
+from google.type import timeofday_pb2 as timeofday # type: ignore
+
+
+def client_cert_source_callback():
+ return b"cert bytes", b"key bytes"
+
+
+# If default endpoint is localhost, then default mtls endpoint will be the same.
+# This method modifies the default endpoint so the client can produce a different
+# mtls endpoint for endpoint testing purposes.
+def modify_default_endpoint(client):
+ return (
+ "foo.googleapis.com"
+ if ("localhost" in client.DEFAULT_ENDPOINT)
+ else client.DEFAULT_ENDPOINT
+ )
+
+
+def test__get_default_mtls_endpoint():
+ api_endpoint = "example.googleapis.com"
+ api_mtls_endpoint = "example.mtls.googleapis.com"
+ sandbox_endpoint = "example.sandbox.googleapis.com"
+ sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com"
+ non_googleapi = "api.example.com"
+
+ assert JobServiceClient._get_default_mtls_endpoint(None) is None
+ assert (
+ JobServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint
+ )
+ assert (
+ JobServiceClient._get_default_mtls_endpoint(api_mtls_endpoint)
+ == api_mtls_endpoint
+ )
+ assert (
+ JobServiceClient._get_default_mtls_endpoint(sandbox_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert (
+ JobServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert JobServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
+
+
+@pytest.mark.parametrize("client_class", [JobServiceClient, JobServiceAsyncClient])
+def test_job_service_client_from_service_account_file(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_file"
+ ) as factory:
+ factory.return_value = creds
+ client = client_class.from_service_account_file("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ client = client_class.from_service_account_json("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_job_service_client_get_transport_class():
+ transport = JobServiceClient.get_transport_class()
+ assert transport == transports.JobServiceGrpcTransport
+
+ transport = JobServiceClient.get_transport_class("grpc")
+ assert transport == transports.JobServiceGrpcTransport
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (JobServiceClient, transports.JobServiceGrpcTransport, "grpc"),
+ (
+ JobServiceAsyncClient,
+ transports.JobServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+@mock.patch.object(
+ JobServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(JobServiceClient)
+)
+@mock.patch.object(
+ JobServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(JobServiceAsyncClient),
+)
+def test_job_service_client_client_options(
+ client_class, transport_class, transport_name
+):
+ # Check that if channel is provided we won't create a new one.
+ with mock.patch.object(JobServiceClient, "get_transport_class") as gtc:
+ transport = transport_class(credentials=credentials.AnonymousCredentials())
+ client = client_class(transport=transport)
+ gtc.assert_not_called()
+
+ # Check that if channel is provided via str we will create a new one.
+ with mock.patch.object(JobServiceClient, "get_transport_class") as gtc:
+ client = client_class(transport=transport_name)
+ gtc.assert_called()
+
+ # Check the case api_endpoint is provided.
+ options = client_options.ClientOptions(api_endpoint="squid.clam.whelk")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "never".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "always".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_MTLS_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (JobServiceClient, transports.JobServiceGrpcTransport, "grpc", "true"),
+ (
+ JobServiceAsyncClient,
+ transports.JobServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (JobServiceClient, transports.JobServiceGrpcTransport, "grpc", "false"),
+ (
+ JobServiceAsyncClient,
+ transports.JobServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ JobServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(JobServiceClient)
+)
+@mock.patch.object(
+ JobServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(JobServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_job_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ options = client_options.ClientOptions(
+ client_cert_source=client_cert_source_callback
+ )
+ with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
+ with mock.patch(
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
+ ):
+ patched.return_value = None
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (JobServiceClient, transports.JobServiceGrpcTransport, "grpc"),
+ (
+ JobServiceAsyncClient,
+ transports.JobServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_job_service_client_client_options_scopes(
+ client_class, transport_class, transport_name
+):
+ # Check the case scopes are provided.
+ options = client_options.ClientOptions(scopes=["1", "2"],)
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=["1", "2"],
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (JobServiceClient, transports.JobServiceGrpcTransport, "grpc"),
+ (
+ JobServiceAsyncClient,
+ transports.JobServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_job_service_client_client_options_credentials_file(
+ client_class, transport_class, transport_name
+):
+ # Check the case credentials file is provided.
+ options = client_options.ClientOptions(credentials_file="credentials.json")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file="credentials.json",
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_job_service_client_client_options_from_dict():
+ with mock.patch(
+ "google.cloud.talent_v4.services.job_service.transports.JobServiceGrpcTransport.__init__"
+ ) as grpc_transport:
+ grpc_transport.return_value = None
+ client = JobServiceClient(client_options={"api_endpoint": "squid.clam.whelk"})
+ grpc_transport.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_create_job(transport: str = "grpc", request_type=job_service.CreateJobRequest):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_job.Job(
+ name="name_value",
+ company="company_value",
+ requisition_id="requisition_id_value",
+ title="title_value",
+ description="description_value",
+ addresses=["addresses_value"],
+ job_benefits=[common.JobBenefit.CHILD_CARE],
+ degree_types=[common.DegreeType.PRIMARY_EDUCATION],
+ department="department_value",
+ employment_types=[common.EmploymentType.FULL_TIME],
+ incentives="incentives_value",
+ language_code="language_code_value",
+ job_level=common.JobLevel.ENTRY_LEVEL,
+ promotion_value=1635,
+ qualifications="qualifications_value",
+ responsibilities="responsibilities_value",
+ posting_region=common.PostingRegion.ADMINISTRATIVE_AREA,
+ visibility=common.Visibility.ACCOUNT_ONLY,
+ company_display_name="company_display_name_value",
+ )
+
+ response = client.create_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.CreateJobRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_job.Job)
+
+ assert response.name == "name_value"
+
+ assert response.company == "company_value"
+
+ assert response.requisition_id == "requisition_id_value"
+
+ assert response.title == "title_value"
+
+ assert response.description == "description_value"
+
+ assert response.addresses == ["addresses_value"]
+
+ assert response.job_benefits == [common.JobBenefit.CHILD_CARE]
+
+ assert response.degree_types == [common.DegreeType.PRIMARY_EDUCATION]
+
+ assert response.department == "department_value"
+
+ assert response.employment_types == [common.EmploymentType.FULL_TIME]
+
+ assert response.incentives == "incentives_value"
+
+ assert response.language_code == "language_code_value"
+
+ assert response.job_level == common.JobLevel.ENTRY_LEVEL
+
+ assert response.promotion_value == 1635
+
+ assert response.qualifications == "qualifications_value"
+
+ assert response.responsibilities == "responsibilities_value"
+
+ assert response.posting_region == common.PostingRegion.ADMINISTRATIVE_AREA
+
+ assert response.visibility == common.Visibility.ACCOUNT_ONLY
+
+ assert response.company_display_name == "company_display_name_value"
+
+
+def test_create_job_from_dict():
+ test_create_job(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_create_job_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.CreateJobRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_job), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ gct_job.Job(
+ name="name_value",
+ company="company_value",
+ requisition_id="requisition_id_value",
+ title="title_value",
+ description="description_value",
+ addresses=["addresses_value"],
+ job_benefits=[common.JobBenefit.CHILD_CARE],
+ degree_types=[common.DegreeType.PRIMARY_EDUCATION],
+ department="department_value",
+ employment_types=[common.EmploymentType.FULL_TIME],
+ incentives="incentives_value",
+ language_code="language_code_value",
+ job_level=common.JobLevel.ENTRY_LEVEL,
+ promotion_value=1635,
+ qualifications="qualifications_value",
+ responsibilities="responsibilities_value",
+ posting_region=common.PostingRegion.ADMINISTRATIVE_AREA,
+ visibility=common.Visibility.ACCOUNT_ONLY,
+ company_display_name="company_display_name_value",
+ )
+ )
+
+ response = await client.create_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_job.Job)
+
+ assert response.name == "name_value"
+
+ assert response.company == "company_value"
+
+ assert response.requisition_id == "requisition_id_value"
+
+ assert response.title == "title_value"
+
+ assert response.description == "description_value"
+
+ assert response.addresses == ["addresses_value"]
+
+ assert response.job_benefits == [common.JobBenefit.CHILD_CARE]
+
+ assert response.degree_types == [common.DegreeType.PRIMARY_EDUCATION]
+
+ assert response.department == "department_value"
+
+ assert response.employment_types == [common.EmploymentType.FULL_TIME]
+
+ assert response.incentives == "incentives_value"
+
+ assert response.language_code == "language_code_value"
+
+ assert response.job_level == common.JobLevel.ENTRY_LEVEL
+
+ assert response.promotion_value == 1635
+
+ assert response.qualifications == "qualifications_value"
+
+ assert response.responsibilities == "responsibilities_value"
+
+ assert response.posting_region == common.PostingRegion.ADMINISTRATIVE_AREA
+
+ assert response.visibility == common.Visibility.ACCOUNT_ONLY
+
+ assert response.company_display_name == "company_display_name_value"
+
+
+def test_create_job_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.CreateJobRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_job), "__call__") as call:
+ call.return_value = gct_job.Job()
+
+ client.create_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_create_job_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.CreateJobRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_job), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_job.Job())
+
+ await client.create_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_create_job_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_job.Job()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.create_job(
+ parent="parent_value", job=gct_job.Job(name="name_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].job == gct_job.Job(name="name_value")
+
+
+def test_create_job_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.create_job(
+ job_service.CreateJobRequest(),
+ parent="parent_value",
+ job=gct_job.Job(name="name_value"),
+ )
+
+
+@pytest.mark.asyncio
+async def test_create_job_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_job), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_job.Job()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_job.Job())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.create_job(
+ parent="parent_value", job=gct_job.Job(name="name_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].job == gct_job.Job(name="name_value")
+
+
+@pytest.mark.asyncio
+async def test_create_job_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.create_job(
+ job_service.CreateJobRequest(),
+ parent="parent_value",
+ job=gct_job.Job(name="name_value"),
+ )
+
+
+def test_batch_create_jobs(
+ transport: str = "grpc", request_type=job_service.BatchCreateJobsRequest
+):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_create_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = operations_pb2.Operation(name="operations/spam")
+
+ response = client.batch_create_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.BatchCreateJobsRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, future.Future)
+
+
+def test_batch_create_jobs_from_dict():
+ test_batch_create_jobs(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_batch_create_jobs_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.BatchCreateJobsRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_create_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/spam")
+ )
+
+ response = await client.batch_create_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, future.Future)
+
+
+def test_batch_create_jobs_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.BatchCreateJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_create_jobs), "__call__"
+ ) as call:
+ call.return_value = operations_pb2.Operation(name="operations/op")
+
+ client.batch_create_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_batch_create_jobs_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.BatchCreateJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_create_jobs), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/op")
+ )
+
+ await client.batch_create_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_batch_create_jobs_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_create_jobs), "__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.batch_create_jobs(
+ parent="parent_value", jobs=[job.Job(name="name_value")],
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].jobs == [job.Job(name="name_value")]
+
+
+def test_batch_create_jobs_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.batch_create_jobs(
+ job_service.BatchCreateJobsRequest(),
+ parent="parent_value",
+ jobs=[job.Job(name="name_value")],
+ )
+
+
+@pytest.mark.asyncio
+async def test_batch_create_jobs_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_create_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = operations_pb2.Operation(name="operations/op")
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/spam")
+ )
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.batch_create_jobs(
+ parent="parent_value", jobs=[job.Job(name="name_value")],
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].jobs == [job.Job(name="name_value")]
+
+
+@pytest.mark.asyncio
+async def test_batch_create_jobs_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.batch_create_jobs(
+ job_service.BatchCreateJobsRequest(),
+ parent="parent_value",
+ jobs=[job.Job(name="name_value")],
+ )
+
+
+def test_get_job(transport: str = "grpc", request_type=job_service.GetJobRequest):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job.Job(
+ name="name_value",
+ company="company_value",
+ requisition_id="requisition_id_value",
+ title="title_value",
+ description="description_value",
+ addresses=["addresses_value"],
+ job_benefits=[common.JobBenefit.CHILD_CARE],
+ degree_types=[common.DegreeType.PRIMARY_EDUCATION],
+ department="department_value",
+ employment_types=[common.EmploymentType.FULL_TIME],
+ incentives="incentives_value",
+ language_code="language_code_value",
+ job_level=common.JobLevel.ENTRY_LEVEL,
+ promotion_value=1635,
+ qualifications="qualifications_value",
+ responsibilities="responsibilities_value",
+ posting_region=common.PostingRegion.ADMINISTRATIVE_AREA,
+ visibility=common.Visibility.ACCOUNT_ONLY,
+ company_display_name="company_display_name_value",
+ )
+
+ response = client.get_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.GetJobRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, job.Job)
+
+ assert response.name == "name_value"
+
+ assert response.company == "company_value"
+
+ assert response.requisition_id == "requisition_id_value"
+
+ assert response.title == "title_value"
+
+ assert response.description == "description_value"
+
+ assert response.addresses == ["addresses_value"]
+
+ assert response.job_benefits == [common.JobBenefit.CHILD_CARE]
+
+ assert response.degree_types == [common.DegreeType.PRIMARY_EDUCATION]
+
+ assert response.department == "department_value"
+
+ assert response.employment_types == [common.EmploymentType.FULL_TIME]
+
+ assert response.incentives == "incentives_value"
+
+ assert response.language_code == "language_code_value"
+
+ assert response.job_level == common.JobLevel.ENTRY_LEVEL
+
+ assert response.promotion_value == 1635
+
+ assert response.qualifications == "qualifications_value"
+
+ assert response.responsibilities == "responsibilities_value"
+
+ assert response.posting_region == common.PostingRegion.ADMINISTRATIVE_AREA
+
+ assert response.visibility == common.Visibility.ACCOUNT_ONLY
+
+ assert response.company_display_name == "company_display_name_value"
+
+
+def test_get_job_from_dict():
+ test_get_job(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_get_job_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.GetJobRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._client._transport.get_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job.Job(
+ name="name_value",
+ company="company_value",
+ requisition_id="requisition_id_value",
+ title="title_value",
+ description="description_value",
+ addresses=["addresses_value"],
+ job_benefits=[common.JobBenefit.CHILD_CARE],
+ degree_types=[common.DegreeType.PRIMARY_EDUCATION],
+ department="department_value",
+ employment_types=[common.EmploymentType.FULL_TIME],
+ incentives="incentives_value",
+ language_code="language_code_value",
+ job_level=common.JobLevel.ENTRY_LEVEL,
+ promotion_value=1635,
+ qualifications="qualifications_value",
+ responsibilities="responsibilities_value",
+ posting_region=common.PostingRegion.ADMINISTRATIVE_AREA,
+ visibility=common.Visibility.ACCOUNT_ONLY,
+ company_display_name="company_display_name_value",
+ )
+ )
+
+ response = await client.get_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, job.Job)
+
+ assert response.name == "name_value"
+
+ assert response.company == "company_value"
+
+ assert response.requisition_id == "requisition_id_value"
+
+ assert response.title == "title_value"
+
+ assert response.description == "description_value"
+
+ assert response.addresses == ["addresses_value"]
+
+ assert response.job_benefits == [common.JobBenefit.CHILD_CARE]
+
+ assert response.degree_types == [common.DegreeType.PRIMARY_EDUCATION]
+
+ assert response.department == "department_value"
+
+ assert response.employment_types == [common.EmploymentType.FULL_TIME]
+
+ assert response.incentives == "incentives_value"
+
+ assert response.language_code == "language_code_value"
+
+ assert response.job_level == common.JobLevel.ENTRY_LEVEL
+
+ assert response.promotion_value == 1635
+
+ assert response.qualifications == "qualifications_value"
+
+ assert response.responsibilities == "responsibilities_value"
+
+ assert response.posting_region == common.PostingRegion.ADMINISTRATIVE_AREA
+
+ assert response.visibility == common.Visibility.ACCOUNT_ONLY
+
+ assert response.company_display_name == "company_display_name_value"
+
+
+def test_get_job_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.GetJobRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_job), "__call__") as call:
+ call.return_value = job.Job()
+
+ client.get_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_get_job_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.GetJobRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._client._transport.get_job), "__call__") as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(job.Job())
+
+ await client.get_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+def test_get_job_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job.Job()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.get_job(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].name == "name_value"
+
+
+def test_get_job_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.get_job(
+ job_service.GetJobRequest(), name="name_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_get_job_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._client._transport.get_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job.Job()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(job.Job())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.get_job(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # 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_get_job_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.get_job(
+ job_service.GetJobRequest(), name="name_value",
+ )
+
+
+def test_update_job(transport: str = "grpc", request_type=job_service.UpdateJobRequest):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_job.Job(
+ name="name_value",
+ company="company_value",
+ requisition_id="requisition_id_value",
+ title="title_value",
+ description="description_value",
+ addresses=["addresses_value"],
+ job_benefits=[common.JobBenefit.CHILD_CARE],
+ degree_types=[common.DegreeType.PRIMARY_EDUCATION],
+ department="department_value",
+ employment_types=[common.EmploymentType.FULL_TIME],
+ incentives="incentives_value",
+ language_code="language_code_value",
+ job_level=common.JobLevel.ENTRY_LEVEL,
+ promotion_value=1635,
+ qualifications="qualifications_value",
+ responsibilities="responsibilities_value",
+ posting_region=common.PostingRegion.ADMINISTRATIVE_AREA,
+ visibility=common.Visibility.ACCOUNT_ONLY,
+ company_display_name="company_display_name_value",
+ )
+
+ response = client.update_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.UpdateJobRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_job.Job)
+
+ assert response.name == "name_value"
+
+ assert response.company == "company_value"
+
+ assert response.requisition_id == "requisition_id_value"
+
+ assert response.title == "title_value"
+
+ assert response.description == "description_value"
+
+ assert response.addresses == ["addresses_value"]
+
+ assert response.job_benefits == [common.JobBenefit.CHILD_CARE]
+
+ assert response.degree_types == [common.DegreeType.PRIMARY_EDUCATION]
+
+ assert response.department == "department_value"
+
+ assert response.employment_types == [common.EmploymentType.FULL_TIME]
+
+ assert response.incentives == "incentives_value"
+
+ assert response.language_code == "language_code_value"
+
+ assert response.job_level == common.JobLevel.ENTRY_LEVEL
+
+ assert response.promotion_value == 1635
+
+ assert response.qualifications == "qualifications_value"
+
+ assert response.responsibilities == "responsibilities_value"
+
+ assert response.posting_region == common.PostingRegion.ADMINISTRATIVE_AREA
+
+ assert response.visibility == common.Visibility.ACCOUNT_ONLY
+
+ assert response.company_display_name == "company_display_name_value"
+
+
+def test_update_job_from_dict():
+ test_update_job(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_update_job_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.UpdateJobRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_job), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ gct_job.Job(
+ name="name_value",
+ company="company_value",
+ requisition_id="requisition_id_value",
+ title="title_value",
+ description="description_value",
+ addresses=["addresses_value"],
+ job_benefits=[common.JobBenefit.CHILD_CARE],
+ degree_types=[common.DegreeType.PRIMARY_EDUCATION],
+ department="department_value",
+ employment_types=[common.EmploymentType.FULL_TIME],
+ incentives="incentives_value",
+ language_code="language_code_value",
+ job_level=common.JobLevel.ENTRY_LEVEL,
+ promotion_value=1635,
+ qualifications="qualifications_value",
+ responsibilities="responsibilities_value",
+ posting_region=common.PostingRegion.ADMINISTRATIVE_AREA,
+ visibility=common.Visibility.ACCOUNT_ONLY,
+ company_display_name="company_display_name_value",
+ )
+ )
+
+ response = await client.update_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_job.Job)
+
+ assert response.name == "name_value"
+
+ assert response.company == "company_value"
+
+ assert response.requisition_id == "requisition_id_value"
+
+ assert response.title == "title_value"
+
+ assert response.description == "description_value"
+
+ assert response.addresses == ["addresses_value"]
+
+ assert response.job_benefits == [common.JobBenefit.CHILD_CARE]
+
+ assert response.degree_types == [common.DegreeType.PRIMARY_EDUCATION]
+
+ assert response.department == "department_value"
+
+ assert response.employment_types == [common.EmploymentType.FULL_TIME]
+
+ assert response.incentives == "incentives_value"
+
+ assert response.language_code == "language_code_value"
+
+ assert response.job_level == common.JobLevel.ENTRY_LEVEL
+
+ assert response.promotion_value == 1635
+
+ assert response.qualifications == "qualifications_value"
+
+ assert response.responsibilities == "responsibilities_value"
+
+ assert response.posting_region == common.PostingRegion.ADMINISTRATIVE_AREA
+
+ assert response.visibility == common.Visibility.ACCOUNT_ONLY
+
+ assert response.company_display_name == "company_display_name_value"
+
+
+def test_update_job_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.UpdateJobRequest()
+ request.job.name = "job.name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_job), "__call__") as call:
+ call.return_value = gct_job.Job()
+
+ client.update_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "job.name=job.name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_update_job_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.UpdateJobRequest()
+ request.job.name = "job.name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_job), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_job.Job())
+
+ await client.update_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "job.name=job.name/value",) in kw["metadata"]
+
+
+def test_update_job_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_job.Job()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.update_job(
+ job=gct_job.Job(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].job == gct_job.Job(name="name_value")
+
+ assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"])
+
+
+def test_update_job_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.update_job(
+ job_service.UpdateJobRequest(),
+ job=gct_job.Job(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+
+@pytest.mark.asyncio
+async def test_update_job_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_job), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_job.Job()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_job.Job())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.update_job(
+ job=gct_job.Job(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].job == gct_job.Job(name="name_value")
+
+ assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"])
+
+
+@pytest.mark.asyncio
+async def test_update_job_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.update_job(
+ job_service.UpdateJobRequest(),
+ job=gct_job.Job(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+
+def test_batch_update_jobs(
+ transport: str = "grpc", request_type=job_service.BatchUpdateJobsRequest
+):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_update_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = operations_pb2.Operation(name="operations/spam")
+
+ response = client.batch_update_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.BatchUpdateJobsRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, future.Future)
+
+
+def test_batch_update_jobs_from_dict():
+ test_batch_update_jobs(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_batch_update_jobs_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.BatchUpdateJobsRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_update_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/spam")
+ )
+
+ response = await client.batch_update_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, future.Future)
+
+
+def test_batch_update_jobs_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.BatchUpdateJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_update_jobs), "__call__"
+ ) as call:
+ call.return_value = operations_pb2.Operation(name="operations/op")
+
+ client.batch_update_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_batch_update_jobs_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.BatchUpdateJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_update_jobs), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/op")
+ )
+
+ await client.batch_update_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_batch_update_jobs_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_update_jobs), "__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.batch_update_jobs(
+ parent="parent_value", jobs=[job.Job(name="name_value")],
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].jobs == [job.Job(name="name_value")]
+
+
+def test_batch_update_jobs_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.batch_update_jobs(
+ job_service.BatchUpdateJobsRequest(),
+ parent="parent_value",
+ jobs=[job.Job(name="name_value")],
+ )
+
+
+@pytest.mark.asyncio
+async def test_batch_update_jobs_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_update_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = operations_pb2.Operation(name="operations/op")
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/spam")
+ )
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.batch_update_jobs(
+ parent="parent_value", jobs=[job.Job(name="name_value")],
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].jobs == [job.Job(name="name_value")]
+
+
+@pytest.mark.asyncio
+async def test_batch_update_jobs_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.batch_update_jobs(
+ job_service.BatchUpdateJobsRequest(),
+ parent="parent_value",
+ jobs=[job.Job(name="name_value")],
+ )
+
+
+def test_delete_job(transport: str = "grpc", request_type=job_service.DeleteJobRequest):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ response = client.delete_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.DeleteJobRequest()
+
+ # Establish that the response is the type that we expect.
+ assert response is None
+
+
+def test_delete_job_from_dict():
+ test_delete_job(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_delete_job_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.DeleteJobRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_job), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+
+ response = await client.delete_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert response is None
+
+
+def test_delete_job_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.DeleteJobRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_job), "__call__") as call:
+ call.return_value = None
+
+ client.delete_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_delete_job_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.DeleteJobRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_job), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+
+ await client.delete_job(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+def test_delete_job_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_job), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.delete_job(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].name == "name_value"
+
+
+def test_delete_job_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.delete_job(
+ job_service.DeleteJobRequest(), name="name_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_delete_job_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_job), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.delete_job(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # 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_delete_job_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.delete_job(
+ job_service.DeleteJobRequest(), name="name_value",
+ )
+
+
+def test_batch_delete_jobs(
+ transport: str = "grpc", request_type=job_service.BatchDeleteJobsRequest
+):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_delete_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = operations_pb2.Operation(name="operations/spam")
+
+ response = client.batch_delete_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.BatchDeleteJobsRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, future.Future)
+
+
+def test_batch_delete_jobs_from_dict():
+ test_batch_delete_jobs(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_batch_delete_jobs_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.BatchDeleteJobsRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_delete_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/spam")
+ )
+
+ response = await client.batch_delete_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, future.Future)
+
+
+def test_batch_delete_jobs_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.BatchDeleteJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_delete_jobs), "__call__"
+ ) as call:
+ call.return_value = operations_pb2.Operation(name="operations/op")
+
+ client.batch_delete_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_batch_delete_jobs_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.BatchDeleteJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_delete_jobs), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/op")
+ )
+
+ await client.batch_delete_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_batch_delete_jobs_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.batch_delete_jobs), "__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.batch_delete_jobs(
+ parent="parent_value", names=["names_value"],
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].names == ["names_value"]
+
+
+def test_batch_delete_jobs_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.batch_delete_jobs(
+ job_service.BatchDeleteJobsRequest(),
+ parent="parent_value",
+ names=["names_value"],
+ )
+
+
+@pytest.mark.asyncio
+async def test_batch_delete_jobs_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.batch_delete_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = operations_pb2.Operation(name="operations/op")
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ operations_pb2.Operation(name="operations/spam")
+ )
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.batch_delete_jobs(
+ parent="parent_value", names=["names_value"],
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].names == ["names_value"]
+
+
+@pytest.mark.asyncio
+async def test_batch_delete_jobs_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.batch_delete_jobs(
+ job_service.BatchDeleteJobsRequest(),
+ parent="parent_value",
+ names=["names_value"],
+ )
+
+
+def test_list_jobs(transport: str = "grpc", request_type=job_service.ListJobsRequest):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_jobs), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job_service.ListJobsResponse(
+ next_page_token="next_page_token_value",
+ )
+
+ response = client.list_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.ListJobsRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, pagers.ListJobsPager)
+
+ assert response.next_page_token == "next_page_token_value"
+
+
+def test_list_jobs_from_dict():
+ test_list_jobs(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_list_jobs_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.ListJobsRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job_service.ListJobsResponse(next_page_token="next_page_token_value",)
+ )
+
+ response = await client.list_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, pagers.ListJobsAsyncPager)
+
+ assert response.next_page_token == "next_page_token_value"
+
+
+def test_list_jobs_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.ListJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_jobs), "__call__") as call:
+ call.return_value = job_service.ListJobsResponse()
+
+ client.list_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_list_jobs_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.ListJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_jobs), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job_service.ListJobsResponse()
+ )
+
+ await client.list_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_list_jobs_flattened():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_jobs), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job_service.ListJobsResponse()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.list_jobs(
+ parent="parent_value", filter="filter_value",
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].filter == "filter_value"
+
+
+def test_list_jobs_flattened_error():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.list_jobs(
+ job_service.ListJobsRequest(), parent="parent_value", filter="filter_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_list_jobs_flattened_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job_service.ListJobsResponse()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job_service.ListJobsResponse()
+ )
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.list_jobs(parent="parent_value", filter="filter_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].filter == "filter_value"
+
+
+@pytest.mark.asyncio
+async def test_list_jobs_flattened_error_async():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.list_jobs(
+ job_service.ListJobsRequest(), parent="parent_value", filter="filter_value",
+ )
+
+
+def test_list_jobs_pager():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_jobs), "__call__") as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ job_service.ListJobsResponse(
+ jobs=[job.Job(), job.Job(), job.Job(),], next_page_token="abc",
+ ),
+ job_service.ListJobsResponse(jobs=[], next_page_token="def",),
+ job_service.ListJobsResponse(jobs=[job.Job(),], next_page_token="ghi",),
+ job_service.ListJobsResponse(jobs=[job.Job(), job.Job(),],),
+ RuntimeError,
+ )
+
+ metadata = ()
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)),
+ )
+ pager = client.list_jobs(request={})
+
+ assert pager._metadata == metadata
+
+ results = [i for i in pager]
+ assert len(results) == 6
+ assert all(isinstance(i, job.Job) for i in results)
+
+
+def test_list_jobs_pages():
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_jobs), "__call__") as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ job_service.ListJobsResponse(
+ jobs=[job.Job(), job.Job(), job.Job(),], next_page_token="abc",
+ ),
+ job_service.ListJobsResponse(jobs=[], next_page_token="def",),
+ job_service.ListJobsResponse(jobs=[job.Job(),], next_page_token="ghi",),
+ job_service.ListJobsResponse(jobs=[job.Job(), job.Job(),],),
+ RuntimeError,
+ )
+ pages = list(client.list_jobs(request={}).pages)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
+
+
+@pytest.mark.asyncio
+async def test_list_jobs_async_pager():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_jobs),
+ "__call__",
+ new_callable=mock.AsyncMock,
+ ) as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ job_service.ListJobsResponse(
+ jobs=[job.Job(), job.Job(), job.Job(),], next_page_token="abc",
+ ),
+ job_service.ListJobsResponse(jobs=[], next_page_token="def",),
+ job_service.ListJobsResponse(jobs=[job.Job(),], next_page_token="ghi",),
+ job_service.ListJobsResponse(jobs=[job.Job(), job.Job(),],),
+ RuntimeError,
+ )
+ async_pager = await client.list_jobs(request={},)
+ assert async_pager.next_page_token == "abc"
+ responses = []
+ async for response in async_pager:
+ responses.append(response)
+
+ assert len(responses) == 6
+ assert all(isinstance(i, job.Job) for i in responses)
+
+
+@pytest.mark.asyncio
+async def test_list_jobs_async_pages():
+ client = JobServiceAsyncClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_jobs),
+ "__call__",
+ new_callable=mock.AsyncMock,
+ ) as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ job_service.ListJobsResponse(
+ jobs=[job.Job(), job.Job(), job.Job(),], next_page_token="abc",
+ ),
+ job_service.ListJobsResponse(jobs=[], next_page_token="def",),
+ job_service.ListJobsResponse(jobs=[job.Job(),], next_page_token="ghi",),
+ job_service.ListJobsResponse(jobs=[job.Job(), job.Job(),],),
+ RuntimeError,
+ )
+ pages = []
+ async for page_ in (await client.list_jobs(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
+
+
+def test_search_jobs(
+ transport: str = "grpc", request_type=job_service.SearchJobsRequest
+):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.search_jobs), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job_service.SearchJobsResponse(
+ next_page_token="next_page_token_value",
+ total_size=1086,
+ broadened_query_jobs_count=2766,
+ )
+
+ response = client.search_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.SearchJobsRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, job_service.SearchJobsResponse)
+
+ assert response.next_page_token == "next_page_token_value"
+
+ assert response.total_size == 1086
+
+ assert response.broadened_query_jobs_count == 2766
+
+
+def test_search_jobs_from_dict():
+ test_search_jobs(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_search_jobs_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.SearchJobsRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.search_jobs), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job_service.SearchJobsResponse(
+ next_page_token="next_page_token_value",
+ total_size=1086,
+ broadened_query_jobs_count=2766,
+ )
+ )
+
+ response = await client.search_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, job_service.SearchJobsResponse)
+
+ assert response.next_page_token == "next_page_token_value"
+
+ assert response.total_size == 1086
+
+ assert response.broadened_query_jobs_count == 2766
+
+
+def test_search_jobs_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.SearchJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.search_jobs), "__call__") as call:
+ call.return_value = job_service.SearchJobsResponse()
+
+ client.search_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_search_jobs_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.SearchJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.search_jobs), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job_service.SearchJobsResponse()
+ )
+
+ await client.search_jobs(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_search_jobs_for_alert(
+ transport: str = "grpc", request_type=job_service.SearchJobsRequest
+):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.search_jobs_for_alert), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = job_service.SearchJobsResponse(
+ next_page_token="next_page_token_value",
+ total_size=1086,
+ broadened_query_jobs_count=2766,
+ )
+
+ response = client.search_jobs_for_alert(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == job_service.SearchJobsRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, job_service.SearchJobsResponse)
+
+ assert response.next_page_token == "next_page_token_value"
+
+ assert response.total_size == 1086
+
+ assert response.broadened_query_jobs_count == 2766
+
+
+def test_search_jobs_for_alert_from_dict():
+ test_search_jobs_for_alert(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_search_jobs_for_alert_async(transport: str = "grpc_asyncio"):
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = job_service.SearchJobsRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.search_jobs_for_alert), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job_service.SearchJobsResponse(
+ next_page_token="next_page_token_value",
+ total_size=1086,
+ broadened_query_jobs_count=2766,
+ )
+ )
+
+ response = await client.search_jobs_for_alert(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, job_service.SearchJobsResponse)
+
+ assert response.next_page_token == "next_page_token_value"
+
+ assert response.total_size == 1086
+
+ assert response.broadened_query_jobs_count == 2766
+
+
+def test_search_jobs_for_alert_field_headers():
+ client = JobServiceClient(credentials=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 = job_service.SearchJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._transport.search_jobs_for_alert), "__call__"
+ ) as call:
+ call.return_value = job_service.SearchJobsResponse()
+
+ client.search_jobs_for_alert(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_search_jobs_for_alert_field_headers_async():
+ client = JobServiceAsyncClient(credentials=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 = job_service.SearchJobsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.search_jobs_for_alert), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ job_service.SearchJobsResponse()
+ )
+
+ await client.search_jobs_for_alert(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_credentials_transport_error():
+ # It is an error to provide credentials and a transport instance.
+ transport = transports.JobServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # It is an error to provide a credentials file and a transport instance.
+ transport = transports.JobServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = JobServiceClient(
+ client_options={"credentials_file": "credentials.json"},
+ transport=transport,
+ )
+
+ # It is an error to provide scopes and a transport instance.
+ transport = transports.JobServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = JobServiceClient(
+ client_options={"scopes": ["1", "2"]}, transport=transport,
+ )
+
+
+def test_transport_instance():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.JobServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ client = JobServiceClient(transport=transport)
+ assert client._transport is transport
+
+
+def test_transport_get_channel():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.JobServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+ transport = transports.JobServiceGrpcAsyncIOTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.JobServiceGrpcTransport, transports.JobServiceGrpcAsyncIOTransport],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
+def test_transport_grpc_default():
+ # A client should use the gRPC transport by default.
+ client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
+ assert isinstance(client._transport, transports.JobServiceGrpcTransport,)
+
+
+def test_job_service_base_transport_error():
+ # Passing both a credentials object and credentials_file should raise an error
+ with pytest.raises(exceptions.DuplicateCredentialArgs):
+ transport = transports.JobServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ credentials_file="credentials.json",
+ )
+
+
+def test_job_service_base_transport():
+ # Instantiate the base transport.
+ with mock.patch(
+ "google.cloud.talent_v4.services.job_service.transports.JobServiceTransport.__init__"
+ ) as Transport:
+ Transport.return_value = None
+ transport = transports.JobServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+
+ # Every method on the transport should just blindly
+ # raise NotImplementedError.
+ methods = (
+ "create_job",
+ "batch_create_jobs",
+ "get_job",
+ "update_job",
+ "batch_update_jobs",
+ "delete_job",
+ "batch_delete_jobs",
+ "list_jobs",
+ "search_jobs",
+ "search_jobs_for_alert",
+ )
+ for method in methods:
+ with pytest.raises(NotImplementedError):
+ getattr(transport, method)(request=object())
+
+ # Additionally, the LRO client (a property) should
+ # also raise NotImplementedError
+ with pytest.raises(NotImplementedError):
+ transport.operations_client
+
+
+def test_job_service_base_transport_with_credentials_file():
+ # Instantiate the base transport with a credentials file
+ with mock.patch.object(
+ auth, "load_credentials_from_file"
+ ) as load_creds, mock.patch(
+ "google.cloud.talent_v4.services.job_service.transports.JobServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ load_creds.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.JobServiceTransport(
+ credentials_file="credentials.json", quota_project_id="octopus",
+ )
+ load_creds.assert_called_once_with(
+ "credentials.json",
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_job_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(
+ "google.cloud.talent_v4.services.job_service.transports.JobServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.JobServiceTransport()
+ adc.assert_called_once()
+
+
+def test_job_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)
+ JobServiceClient()
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id=None,
+ )
+
+
+def test_job_service_transport_auth_adc():
+ # 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.JobServiceGrpcTransport(
+ host="squid.clam.whelk", quota_project_id="octopus"
+ )
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_job_service_host_no_port():
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(api_endpoint="jobs.googleapis.com"),
+ )
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_job_service_host_with_port():
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(
+ api_endpoint="jobs.googleapis.com:8000"
+ ),
+ )
+ assert client._transport._host == "jobs.googleapis.com:8000"
+
+
+def test_job_service_grpc_transport_channel():
+ channel = grpc.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.JobServiceGrpcTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+def test_job_service_grpc_asyncio_transport_channel():
+ channel = aio.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.JobServiceGrpcAsyncIOTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.JobServiceGrpcTransport, transports.JobServiceGrpcAsyncIOTransport],
+)
+def test_job_service_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.JobServiceGrpcTransport, transports.JobServiceGrpcAsyncIOTransport],
+)
+def test_job_service_transport_channel_mtls_with_adc(transport_class):
+ mock_ssl_cred = mock.Mock()
+ with mock.patch.multiple(
+ "google.auth.transport.grpc.SslCredentials",
+ __init__=mock.Mock(return_value=None),
+ ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
+ ):
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+def test_job_service_grpc_lro_client():
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+ transport = client._transport
+
+ # Ensure that we have a api-core operations client.
+ assert isinstance(transport.operations_client, operations_v1.OperationsClient,)
+
+ # Ensure that subsequent calls to the property send the exact same object.
+ assert transport.operations_client is transport.operations_client
+
+
+def test_job_service_grpc_lro_async_client():
+ client = JobServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc_asyncio",
+ )
+ transport = client._client._transport
+
+ # Ensure that we have a api-core operations client.
+ assert isinstance(transport.operations_client, operations_v1.OperationsAsyncClient,)
+
+ # Ensure that subsequent calls to the property send the exact same object.
+ assert transport.operations_client is transport.operations_client
+
+
+def test_job_path():
+ project = "squid"
+ tenant = "clam"
+ job = "whelk"
+
+ expected = "projects/{project}/tenants/{tenant}/jobs/{job}".format(
+ project=project, tenant=tenant, job=job,
+ )
+ actual = JobServiceClient.job_path(project, tenant, job)
+ assert expected == actual
+
+
+def test_parse_job_path():
+ expected = {
+ "project": "octopus",
+ "tenant": "oyster",
+ "job": "nudibranch",
+ }
+ path = JobServiceClient.job_path(**expected)
+
+ # Check that the path construction is reversible.
+ actual = JobServiceClient.parse_job_path(path)
+ assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.JobServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.JobServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = JobServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4/test_tenant_service.py b/tests/unit/gapic/talent_v4/test_tenant_service.py
new file mode 100644
index 00000000..7e7b35b1
--- /dev/null
+++ b/tests/unit/gapic/talent_v4/test_tenant_service.py
@@ -0,0 +1,1882 @@
+# -*- 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.
+#
+
+import os
+import mock
+
+import grpc
+from grpc.experimental import aio
+import math
+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 gapic_v1
+from google.api_core import grpc_helpers
+from google.api_core import grpc_helpers_async
+from google.auth import credentials
+from google.auth.exceptions import MutualTLSChannelError
+from google.cloud.talent_v4.services.tenant_service import TenantServiceAsyncClient
+from google.cloud.talent_v4.services.tenant_service import TenantServiceClient
+from google.cloud.talent_v4.services.tenant_service import pagers
+from google.cloud.talent_v4.services.tenant_service import transports
+from google.cloud.talent_v4.types import tenant
+from google.cloud.talent_v4.types import tenant as gct_tenant
+from google.cloud.talent_v4.types import tenant_service
+from google.oauth2 import service_account
+from google.protobuf import field_mask_pb2 as field_mask # type: ignore
+
+
+def client_cert_source_callback():
+ return b"cert bytes", b"key bytes"
+
+
+# If default endpoint is localhost, then default mtls endpoint will be the same.
+# This method modifies the default endpoint so the client can produce a different
+# mtls endpoint for endpoint testing purposes.
+def modify_default_endpoint(client):
+ return (
+ "foo.googleapis.com"
+ if ("localhost" in client.DEFAULT_ENDPOINT)
+ else client.DEFAULT_ENDPOINT
+ )
+
+
+def test__get_default_mtls_endpoint():
+ api_endpoint = "example.googleapis.com"
+ api_mtls_endpoint = "example.mtls.googleapis.com"
+ sandbox_endpoint = "example.sandbox.googleapis.com"
+ sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com"
+ non_googleapi = "api.example.com"
+
+ assert TenantServiceClient._get_default_mtls_endpoint(None) is None
+ assert (
+ TenantServiceClient._get_default_mtls_endpoint(api_endpoint)
+ == api_mtls_endpoint
+ )
+ assert (
+ TenantServiceClient._get_default_mtls_endpoint(api_mtls_endpoint)
+ == api_mtls_endpoint
+ )
+ assert (
+ TenantServiceClient._get_default_mtls_endpoint(sandbox_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert (
+ TenantServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint)
+ == sandbox_mtls_endpoint
+ )
+ assert (
+ TenantServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class", [TenantServiceClient, TenantServiceAsyncClient]
+)
+def test_tenant_service_client_from_service_account_file(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_file"
+ ) as factory:
+ factory.return_value = creds
+ client = client_class.from_service_account_file("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ client = client_class.from_service_account_json("dummy/file/path.json")
+ assert client._transport._credentials == creds
+
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_tenant_service_client_get_transport_class():
+ transport = TenantServiceClient.get_transport_class()
+ assert transport == transports.TenantServiceGrpcTransport
+
+ transport = TenantServiceClient.get_transport_class("grpc")
+ assert transport == transports.TenantServiceGrpcTransport
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (TenantServiceClient, transports.TenantServiceGrpcTransport, "grpc"),
+ (
+ TenantServiceAsyncClient,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+@mock.patch.object(
+ TenantServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(TenantServiceClient),
+)
+@mock.patch.object(
+ TenantServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(TenantServiceAsyncClient),
+)
+def test_tenant_service_client_client_options(
+ client_class, transport_class, transport_name
+):
+ # Check that if channel is provided we won't create a new one.
+ with mock.patch.object(TenantServiceClient, "get_transport_class") as gtc:
+ transport = transport_class(credentials=credentials.AnonymousCredentials())
+ client = client_class(transport=transport)
+ gtc.assert_not_called()
+
+ # Check that if channel is provided via str we will create a new one.
+ with mock.patch.object(TenantServiceClient, "get_transport_class") as gtc:
+ client = client_class(transport=transport_name)
+ gtc.assert_called()
+
+ # Check the case api_endpoint is provided.
+ options = client_options.ClientOptions(api_endpoint="squid.clam.whelk")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "never".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
+ # "always".
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_MTLS_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (TenantServiceClient, transports.TenantServiceGrpcTransport, "grpc", "true"),
+ (
+ TenantServiceAsyncClient,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (TenantServiceClient, transports.TenantServiceGrpcTransport, "grpc", "false"),
+ (
+ TenantServiceAsyncClient,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ TenantServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(TenantServiceClient),
+)
+@mock.patch.object(
+ TenantServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(TenantServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_tenant_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ options = client_options.ClientOptions(
+ client_cert_source=client_cert_source_callback
+ )
+ with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
+ with mock.patch(
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
+ ):
+ patched.return_value = None
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (TenantServiceClient, transports.TenantServiceGrpcTransport, "grpc"),
+ (
+ TenantServiceAsyncClient,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_tenant_service_client_client_options_scopes(
+ client_class, transport_class, transport_name
+):
+ # Check the case scopes are provided.
+ options = client_options.ClientOptions(scopes=["1", "2"],)
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=["1", "2"],
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name",
+ [
+ (TenantServiceClient, transports.TenantServiceGrpcTransport, "grpc"),
+ (
+ TenantServiceAsyncClient,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ ),
+ ],
+)
+def test_tenant_service_client_client_options_credentials_file(
+ client_class, transport_class, transport_name
+):
+ # Check the case credentials file is provided.
+ options = client_options.ClientOptions(credentials_file="credentials.json")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file="credentials.json",
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_tenant_service_client_client_options_from_dict():
+ with mock.patch(
+ "google.cloud.talent_v4.services.tenant_service.transports.TenantServiceGrpcTransport.__init__"
+ ) as grpc_transport:
+ grpc_transport.return_value = None
+ client = TenantServiceClient(
+ client_options={"api_endpoint": "squid.clam.whelk"}
+ )
+ grpc_transport.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host="squid.clam.whelk",
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+def test_create_tenant(
+ transport: str = "grpc", request_type=tenant_service.CreateTenantRequest
+):
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_tenant.Tenant(
+ name="name_value", external_id="external_id_value",
+ )
+
+ response = client.create_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == tenant_service.CreateTenantRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_tenant.Tenant)
+
+ assert response.name == "name_value"
+
+ assert response.external_id == "external_id_value"
+
+
+def test_create_tenant_from_dict():
+ test_create_tenant(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_create_tenant_async(transport: str = "grpc_asyncio"):
+ client = TenantServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = tenant_service.CreateTenantRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ gct_tenant.Tenant(name="name_value", external_id="external_id_value",)
+ )
+
+ response = await client.create_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_tenant.Tenant)
+
+ assert response.name == "name_value"
+
+ assert response.external_id == "external_id_value"
+
+
+def test_create_tenant_field_headers():
+ client = TenantServiceClient(credentials=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 = tenant_service.CreateTenantRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_tenant), "__call__") as call:
+ call.return_value = gct_tenant.Tenant()
+
+ client.create_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_create_tenant_field_headers_async():
+ client = TenantServiceAsyncClient(credentials=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 = tenant_service.CreateTenantRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_tenant), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_tenant.Tenant())
+
+ await client.create_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_create_tenant_flattened():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.create_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_tenant.Tenant()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.create_tenant(
+ parent="parent_value", tenant=gct_tenant.Tenant(name="name_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].tenant == gct_tenant.Tenant(name="name_value")
+
+
+def test_create_tenant_flattened_error():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.create_tenant(
+ tenant_service.CreateTenantRequest(),
+ parent="parent_value",
+ tenant=gct_tenant.Tenant(name="name_value"),
+ )
+
+
+@pytest.mark.asyncio
+async def test_create_tenant_flattened_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.create_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_tenant.Tenant()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_tenant.Tenant())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.create_tenant(
+ parent="parent_value", tenant=gct_tenant.Tenant(name="name_value"),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+ assert args[0].tenant == gct_tenant.Tenant(name="name_value")
+
+
+@pytest.mark.asyncio
+async def test_create_tenant_flattened_error_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.create_tenant(
+ tenant_service.CreateTenantRequest(),
+ parent="parent_value",
+ tenant=gct_tenant.Tenant(name="name_value"),
+ )
+
+
+def test_get_tenant(
+ transport: str = "grpc", request_type=tenant_service.GetTenantRequest
+):
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = tenant.Tenant(
+ name="name_value", external_id="external_id_value",
+ )
+
+ response = client.get_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == tenant_service.GetTenantRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, tenant.Tenant)
+
+ assert response.name == "name_value"
+
+ assert response.external_id == "external_id_value"
+
+
+def test_get_tenant_from_dict():
+ test_get_tenant(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_get_tenant_async(transport: str = "grpc_asyncio"):
+ client = TenantServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = tenant_service.GetTenantRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.get_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ tenant.Tenant(name="name_value", external_id="external_id_value",)
+ )
+
+ response = await client.get_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, tenant.Tenant)
+
+ assert response.name == "name_value"
+
+ assert response.external_id == "external_id_value"
+
+
+def test_get_tenant_field_headers():
+ client = TenantServiceClient(credentials=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 = tenant_service.GetTenantRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_tenant), "__call__") as call:
+ call.return_value = tenant.Tenant()
+
+ client.get_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_get_tenant_field_headers_async():
+ client = TenantServiceAsyncClient(credentials=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 = tenant_service.GetTenantRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.get_tenant), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(tenant.Tenant())
+
+ await client.get_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+def test_get_tenant_flattened():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.get_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = tenant.Tenant()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.get_tenant(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].name == "name_value"
+
+
+def test_get_tenant_flattened_error():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.get_tenant(
+ tenant_service.GetTenantRequest(), name="name_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_get_tenant_flattened_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.get_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = tenant.Tenant()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(tenant.Tenant())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.get_tenant(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # 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_get_tenant_flattened_error_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.get_tenant(
+ tenant_service.GetTenantRequest(), name="name_value",
+ )
+
+
+def test_update_tenant(
+ transport: str = "grpc", request_type=tenant_service.UpdateTenantRequest
+):
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_tenant.Tenant(
+ name="name_value", external_id="external_id_value",
+ )
+
+ response = client.update_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == tenant_service.UpdateTenantRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_tenant.Tenant)
+
+ assert response.name == "name_value"
+
+ assert response.external_id == "external_id_value"
+
+
+def test_update_tenant_from_dict():
+ test_update_tenant(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_update_tenant_async(transport: str = "grpc_asyncio"):
+ client = TenantServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = tenant_service.UpdateTenantRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ gct_tenant.Tenant(name="name_value", external_id="external_id_value",)
+ )
+
+ response = await client.update_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, gct_tenant.Tenant)
+
+ assert response.name == "name_value"
+
+ assert response.external_id == "external_id_value"
+
+
+def test_update_tenant_field_headers():
+ client = TenantServiceClient(credentials=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 = tenant_service.UpdateTenantRequest()
+ request.tenant.name = "tenant.name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_tenant), "__call__") as call:
+ call.return_value = gct_tenant.Tenant()
+
+ client.update_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "tenant.name=tenant.name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_update_tenant_field_headers_async():
+ client = TenantServiceAsyncClient(credentials=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 = tenant_service.UpdateTenantRequest()
+ request.tenant.name = "tenant.name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_tenant), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_tenant.Tenant())
+
+ await client.update_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "tenant.name=tenant.name/value",) in kw["metadata"]
+
+
+def test_update_tenant_flattened():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.update_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_tenant.Tenant()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.update_tenant(
+ tenant=gct_tenant.Tenant(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].tenant == gct_tenant.Tenant(name="name_value")
+
+ assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"])
+
+
+def test_update_tenant_flattened_error():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.update_tenant(
+ tenant_service.UpdateTenantRequest(),
+ tenant=gct_tenant.Tenant(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+
+@pytest.mark.asyncio
+async def test_update_tenant_flattened_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.update_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = gct_tenant.Tenant()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gct_tenant.Tenant())
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.update_tenant(
+ tenant=gct_tenant.Tenant(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].tenant == gct_tenant.Tenant(name="name_value")
+
+ assert args[0].update_mask == field_mask.FieldMask(paths=["paths_value"])
+
+
+@pytest.mark.asyncio
+async def test_update_tenant_flattened_error_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.update_tenant(
+ tenant_service.UpdateTenantRequest(),
+ tenant=gct_tenant.Tenant(name="name_value"),
+ update_mask=field_mask.FieldMask(paths=["paths_value"]),
+ )
+
+
+def test_delete_tenant(
+ transport: str = "grpc", request_type=tenant_service.DeleteTenantRequest
+):
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ response = client.delete_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == tenant_service.DeleteTenantRequest()
+
+ # Establish that the response is the type that we expect.
+ assert response is None
+
+
+def test_delete_tenant_from_dict():
+ test_delete_tenant(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_delete_tenant_async(transport: str = "grpc_asyncio"):
+ client = TenantServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = tenant_service.DeleteTenantRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+
+ response = await client.delete_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert response is None
+
+
+def test_delete_tenant_field_headers():
+ client = TenantServiceClient(credentials=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 = tenant_service.DeleteTenantRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_tenant), "__call__") as call:
+ call.return_value = None
+
+ client.delete_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_delete_tenant_field_headers_async():
+ client = TenantServiceAsyncClient(credentials=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 = tenant_service.DeleteTenantRequest()
+ request.name = "name/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_tenant), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+
+ await client.delete_tenant(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "name=name/value",) in kw["metadata"]
+
+
+def test_delete_tenant_flattened():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.delete_tenant), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.delete_tenant(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].name == "name_value"
+
+
+def test_delete_tenant_flattened_error():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.delete_tenant(
+ tenant_service.DeleteTenantRequest(), name="name_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_delete_tenant_flattened_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.delete_tenant), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = None
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None)
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.delete_tenant(name="name_value",)
+
+ # Establish that the underlying call was made with the expected
+ # 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_delete_tenant_flattened_error_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.delete_tenant(
+ tenant_service.DeleteTenantRequest(), name="name_value",
+ )
+
+
+def test_list_tenants(
+ transport: str = "grpc", request_type=tenant_service.ListTenantsRequest
+):
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = request_type()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_tenants), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = tenant_service.ListTenantsResponse(
+ next_page_token="next_page_token_value",
+ )
+
+ response = client.list_tenants(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == tenant_service.ListTenantsRequest()
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, pagers.ListTenantsPager)
+
+ assert response.next_page_token == "next_page_token_value"
+
+
+def test_list_tenants_from_dict():
+ test_list_tenants(request_type=dict)
+
+
+@pytest.mark.asyncio
+async def test_list_tenants_async(transport: str = "grpc_asyncio"):
+ client = TenantServiceAsyncClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # Everything is optional in proto3 as far as the runtime is concerned,
+ # and we are mocking out the actual API, so just send an empty request.
+ request = tenant_service.ListTenantsRequest()
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_tenants), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ tenant_service.ListTenantsResponse(next_page_token="next_page_token_value",)
+ )
+
+ response = await client.list_tenants(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == request
+
+ # Establish that the response is the type that we expect.
+ assert isinstance(response, pagers.ListTenantsAsyncPager)
+
+ assert response.next_page_token == "next_page_token_value"
+
+
+def test_list_tenants_field_headers():
+ client = TenantServiceClient(credentials=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 = tenant_service.ListTenantsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_tenants), "__call__") as call:
+ call.return_value = tenant_service.ListTenantsResponse()
+
+ client.list_tenants(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+@pytest.mark.asyncio
+async def test_list_tenants_field_headers_async():
+ client = TenantServiceAsyncClient(credentials=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 = tenant_service.ListTenantsRequest()
+ request.parent = "parent/value"
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_tenants), "__call__"
+ ) as call:
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ tenant_service.ListTenantsResponse()
+ )
+
+ await client.list_tenants(request)
+
+ # Establish that the underlying gRPC stub method was called.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+ assert args[0] == request
+
+ # Establish that the field header was sent.
+ _, _, kw = call.mock_calls[0]
+ assert ("x-goog-request-params", "parent=parent/value",) in kw["metadata"]
+
+
+def test_list_tenants_flattened():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_tenants), "__call__") as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = tenant_service.ListTenantsResponse()
+
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ client.list_tenants(parent="parent_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls) == 1
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+
+def test_list_tenants_flattened_error():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ client.list_tenants(
+ tenant_service.ListTenantsRequest(), parent="parent_value",
+ )
+
+
+@pytest.mark.asyncio
+async def test_list_tenants_flattened_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_tenants), "__call__"
+ ) as call:
+ # Designate an appropriate return value for the call.
+ call.return_value = tenant_service.ListTenantsResponse()
+
+ call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(
+ tenant_service.ListTenantsResponse()
+ )
+ # Call the method with a truthy value for each flattened field,
+ # using the keyword arguments to the method.
+ response = await client.list_tenants(parent="parent_value",)
+
+ # Establish that the underlying call was made with the expected
+ # request object values.
+ assert len(call.mock_calls)
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0].parent == "parent_value"
+
+
+@pytest.mark.asyncio
+async def test_list_tenants_flattened_error_async():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials(),)
+
+ # Attempting to call a method with both a request object and flattened
+ # fields is an error.
+ with pytest.raises(ValueError):
+ await client.list_tenants(
+ tenant_service.ListTenantsRequest(), parent="parent_value",
+ )
+
+
+def test_list_tenants_pager():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_tenants), "__call__") as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(), tenant.Tenant(),],
+ next_page_token="abc",
+ ),
+ tenant_service.ListTenantsResponse(tenants=[], next_page_token="def",),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(),], next_page_token="ghi",
+ ),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(),],
+ ),
+ RuntimeError,
+ )
+
+ metadata = ()
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)),
+ )
+ pager = client.list_tenants(request={})
+
+ assert pager._metadata == metadata
+
+ results = [i for i in pager]
+ assert len(results) == 6
+ assert all(isinstance(i, tenant.Tenant) for i in results)
+
+
+def test_list_tenants_pages():
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client._transport.list_tenants), "__call__") as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(), tenant.Tenant(),],
+ next_page_token="abc",
+ ),
+ tenant_service.ListTenantsResponse(tenants=[], next_page_token="def",),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(),], next_page_token="ghi",
+ ),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(),],
+ ),
+ RuntimeError,
+ )
+ pages = list(client.list_tenants(request={}).pages)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
+
+
+@pytest.mark.asyncio
+async def test_list_tenants_async_pager():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_tenants),
+ "__call__",
+ new_callable=mock.AsyncMock,
+ ) as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(), tenant.Tenant(),],
+ next_page_token="abc",
+ ),
+ tenant_service.ListTenantsResponse(tenants=[], next_page_token="def",),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(),], next_page_token="ghi",
+ ),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(),],
+ ),
+ RuntimeError,
+ )
+ async_pager = await client.list_tenants(request={},)
+ assert async_pager.next_page_token == "abc"
+ responses = []
+ async for response in async_pager:
+ responses.append(response)
+
+ assert len(responses) == 6
+ assert all(isinstance(i, tenant.Tenant) for i in responses)
+
+
+@pytest.mark.asyncio
+async def test_list_tenants_async_pages():
+ client = TenantServiceAsyncClient(credentials=credentials.AnonymousCredentials,)
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(
+ type(client._client._transport.list_tenants),
+ "__call__",
+ new_callable=mock.AsyncMock,
+ ) as call:
+ # Set the response to a series of pages.
+ call.side_effect = (
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(), tenant.Tenant(),],
+ next_page_token="abc",
+ ),
+ tenant_service.ListTenantsResponse(tenants=[], next_page_token="def",),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(),], next_page_token="ghi",
+ ),
+ tenant_service.ListTenantsResponse(
+ tenants=[tenant.Tenant(), tenant.Tenant(),],
+ ),
+ RuntimeError,
+ )
+ pages = []
+ async for page_ in (await client.list_tenants(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
+
+
+def test_credentials_transport_error():
+ # It is an error to provide credentials and a transport instance.
+ transport = transports.TenantServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport=transport,
+ )
+
+ # It is an error to provide a credentials file and a transport instance.
+ transport = transports.TenantServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = TenantServiceClient(
+ client_options={"credentials_file": "credentials.json"},
+ transport=transport,
+ )
+
+ # It is an error to provide scopes and a transport instance.
+ transport = transports.TenantServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ with pytest.raises(ValueError):
+ client = TenantServiceClient(
+ client_options={"scopes": ["1", "2"]}, transport=transport,
+ )
+
+
+def test_transport_instance():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.TenantServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ client = TenantServiceClient(transport=transport)
+ assert client._transport is transport
+
+
+def test_transport_get_channel():
+ # A client may be instantiated with a custom transport instance.
+ transport = transports.TenantServiceGrpcTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+ transport = transports.TenantServiceGrpcAsyncIOTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+ channel = transport.grpc_channel
+ assert channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.TenantServiceGrpcTransport,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ ],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
+def test_transport_grpc_default():
+ # A client should use the gRPC transport by default.
+ client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
+ assert isinstance(client._transport, transports.TenantServiceGrpcTransport,)
+
+
+def test_tenant_service_base_transport_error():
+ # Passing both a credentials object and credentials_file should raise an error
+ with pytest.raises(exceptions.DuplicateCredentialArgs):
+ transport = transports.TenantServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ credentials_file="credentials.json",
+ )
+
+
+def test_tenant_service_base_transport():
+ # Instantiate the base transport.
+ with mock.patch(
+ "google.cloud.talent_v4.services.tenant_service.transports.TenantServiceTransport.__init__"
+ ) as Transport:
+ Transport.return_value = None
+ transport = transports.TenantServiceTransport(
+ credentials=credentials.AnonymousCredentials(),
+ )
+
+ # Every method on the transport should just blindly
+ # raise NotImplementedError.
+ methods = (
+ "create_tenant",
+ "get_tenant",
+ "update_tenant",
+ "delete_tenant",
+ "list_tenants",
+ )
+ for method in methods:
+ with pytest.raises(NotImplementedError):
+ getattr(transport, method)(request=object())
+
+
+def test_tenant_service_base_transport_with_credentials_file():
+ # Instantiate the base transport with a credentials file
+ with mock.patch.object(
+ auth, "load_credentials_from_file"
+ ) as load_creds, mock.patch(
+ "google.cloud.talent_v4.services.tenant_service.transports.TenantServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ load_creds.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.TenantServiceTransport(
+ credentials_file="credentials.json", quota_project_id="octopus",
+ )
+ load_creds.assert_called_once_with(
+ "credentials.json",
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_tenant_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(
+ "google.cloud.talent_v4.services.tenant_service.transports.TenantServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.TenantServiceTransport()
+ adc.assert_called_once()
+
+
+def test_tenant_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)
+ TenantServiceClient()
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id=None,
+ )
+
+
+def test_tenant_service_transport_auth_adc():
+ # 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.TenantServiceGrpcTransport(
+ host="squid.clam.whelk", quota_project_id="octopus"
+ )
+ adc.assert_called_once_with(
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ quota_project_id="octopus",
+ )
+
+
+def test_tenant_service_host_no_port():
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(api_endpoint="jobs.googleapis.com"),
+ )
+ assert client._transport._host == "jobs.googleapis.com:443"
+
+
+def test_tenant_service_host_with_port():
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(),
+ client_options=client_options.ClientOptions(
+ api_endpoint="jobs.googleapis.com:8000"
+ ),
+ )
+ assert client._transport._host == "jobs.googleapis.com:8000"
+
+
+def test_tenant_service_grpc_transport_channel():
+ channel = grpc.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.TenantServiceGrpcTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+def test_tenant_service_grpc_asyncio_transport_channel():
+ channel = aio.insecure_channel("http://localhost/")
+
+ # Check that channel is used if provided.
+ transport = transports.TenantServiceGrpcAsyncIOTransport(
+ host="squid.clam.whelk", channel=channel,
+ )
+ assert transport.grpc_channel == channel
+ assert transport._host == "squid.clam.whelk:443"
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.TenantServiceGrpcTransport,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_tenant_service_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.TenantServiceGrpcTransport,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_tenant_service_transport_channel_mtls_with_adc(transport_class):
+ mock_ssl_cred = mock.Mock()
+ with mock.patch.multiple(
+ "google.auth.transport.grpc.SslCredentials",
+ __init__=mock.Mock(return_value=None),
+ ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
+ ):
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
+
+
+def test_tenant_path():
+ project = "squid"
+ tenant = "clam"
+
+ expected = "projects/{project}/tenants/{tenant}".format(
+ project=project, tenant=tenant,
+ )
+ actual = TenantServiceClient.tenant_path(project, tenant)
+ assert expected == actual
+
+
+def test_parse_tenant_path():
+ expected = {
+ "project": "whelk",
+ "tenant": "octopus",
+ }
+ path = TenantServiceClient.tenant_path(**expected)
+
+ # Check that the path construction is reversible.
+ actual = TenantServiceClient.parse_tenant_path(path)
+ assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.TenantServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.TenantServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = TenantServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4beta1/test_application_service.py b/tests/unit/gapic/talent_v4beta1/test_application_service.py
index defe6406..904d4543 100644
--- a/tests/unit/gapic/talent_v4beta1/test_application_service.py
+++ b/tests/unit/gapic/talent_v4beta1/test_application_service.py
@@ -167,14 +167,14 @@ def test_application_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "never".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -183,14 +183,14 @@ def test_application_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "always".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -199,90 +199,185 @@ def test_application_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (
+ ApplicationServiceClient,
+ transports.ApplicationServiceGrpcTransport,
+ "grpc",
+ "true",
+ ),
+ (
+ ApplicationServiceAsyncClient,
+ transports.ApplicationServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (
+ ApplicationServiceClient,
+ transports.ApplicationServiceGrpcTransport,
+ "grpc",
+ "false",
+ ),
+ (
+ ApplicationServiceAsyncClient,
+ transports.ApplicationServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ ApplicationServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(ApplicationServiceClient),
+)
+@mock.patch.object(
+ ApplicationServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(ApplicationServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_application_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
options = client_options.ClientOptions(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=client_cert_source_callback,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and default_client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
- with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=True,
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
):
patched.return_value = None
- client = client_class()
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
+ host=expected_host,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", but client_cert_source and default_client_cert_source are None.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=False,
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
):
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has
- # unsupported value.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}):
- with pytest.raises(MutualTLSChannelError):
- client = client_class()
-
- # Check the case quota_project_id is provided
- options = client_options.ClientOptions(quota_project_id="octopus")
- with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id="octopus",
- )
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
@pytest.mark.parametrize(
@@ -309,9 +404,9 @@ def test_application_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -339,9 +434,9 @@ def test_application_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -358,9 +453,9 @@ def test_application_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -1626,8 +1721,8 @@ def test_list_applications_pages():
RuntimeError,
)
pages = list(client.list_applications(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -1707,10 +1802,10 @@ async def test_list_applications_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.list_applications(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.list_applications(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_credentials_transport_error():
@@ -1767,6 +1862,21 @@ def test_transport_get_channel():
assert channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.ApplicationServiceGrpcTransport,
+ transports.ApplicationServiceGrpcAsyncIOTransport,
+ ],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
def test_transport_grpc_default():
# A client should use the gRPC transport by default.
client = ApplicationServiceClient(credentials=credentials.AnonymousCredentials(),)
@@ -1828,6 +1938,17 @@ def test_application_service_base_transport_with_credentials_file():
)
+def test_application_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(
+ "google.cloud.talent_v4beta1.services.application_service.transports.ApplicationServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.ApplicationServiceTransport()
+ adc.assert_called_once()
+
+
def test_application_service_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(auth, "default") as adc:
@@ -1880,191 +2001,116 @@ def test_application_service_host_with_port():
def test_application_service_grpc_transport_channel():
channel = grpc.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.ApplicationServiceGrpcTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
def test_application_service_grpc_asyncio_transport_channel():
channel = aio.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.ApplicationServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_application_service_grpc_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.ApplicationServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_application_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.ApplicationServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.ApplicationServiceGrpcTransport,
+ transports.ApplicationServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_application_service_grpc_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
+def test_application_service_transport_channel_mtls_with_client_cert_source(
+ transport_class,
):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
- mock_ssl_cred = mock.Mock()
- with mock.patch.multiple(
- "google.auth.transport.grpc.SslCredentials",
- __init__=mock.Mock(return_value=None),
- ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
- ):
- mock_cred = mock.Mock()
- transport = transports.ApplicationServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.ApplicationServiceGrpcTransport,
+ transports.ApplicationServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_application_service_grpc_asyncio_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
+def test_application_service_transport_channel_mtls_with_adc(transport_class):
mock_ssl_cred = mock.Mock()
with mock.patch.multiple(
"google.auth.transport.grpc.SslCredentials",
__init__=mock.Mock(return_value=None),
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
- mock_cred = mock.Mock()
- transport = transports.ApplicationServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
def test_application_path():
@@ -2094,3 +2140,24 @@ def test_parse_application_path():
# Check that the path construction is reversible.
actual = ApplicationServiceClient.parse_application_path(path)
assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.ApplicationServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = ApplicationServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.ApplicationServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = ApplicationServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4beta1/test_company_service.py b/tests/unit/gapic/talent_v4beta1/test_company_service.py
index 29ac1a52..317b328f 100644
--- a/tests/unit/gapic/talent_v4beta1/test_company_service.py
+++ b/tests/unit/gapic/talent_v4beta1/test_company_service.py
@@ -163,14 +163,14 @@ def test_company_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "never".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -179,14 +179,14 @@ def test_company_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "always".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -195,90 +195,175 @@ def test_company_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (CompanyServiceClient, transports.CompanyServiceGrpcTransport, "grpc", "true"),
+ (
+ CompanyServiceAsyncClient,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (CompanyServiceClient, transports.CompanyServiceGrpcTransport, "grpc", "false"),
+ (
+ CompanyServiceAsyncClient,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ CompanyServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompanyServiceClient),
+)
+@mock.patch.object(
+ CompanyServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompanyServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_company_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
options = client_options.ClientOptions(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=client_cert_source_callback,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and default_client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
- with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=True,
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
):
patched.return_value = None
- client = client_class()
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
+ host=expected_host,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", but client_cert_source and default_client_cert_source are None.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=False,
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
):
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has
- # unsupported value.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}):
- with pytest.raises(MutualTLSChannelError):
- client = client_class()
-
- # Check the case quota_project_id is provided
- options = client_options.ClientOptions(quota_project_id="octopus")
- with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id="octopus",
- )
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
@pytest.mark.parametrize(
@@ -305,9 +390,9 @@ def test_company_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -335,9 +420,9 @@ def test_company_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -354,9 +439,9 @@ def test_company_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -1596,8 +1681,8 @@ def test_list_companies_pages():
RuntimeError,
)
pages = list(client.list_companies(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -1661,10 +1746,10 @@ async def test_list_companies_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.list_companies(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.list_companies(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_credentials_transport_error():
@@ -1721,6 +1806,21 @@ def test_transport_get_channel():
assert channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.CompanyServiceGrpcTransport,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ ],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
def test_transport_grpc_default():
# A client should use the gRPC transport by default.
client = CompanyServiceClient(credentials=credentials.AnonymousCredentials(),)
@@ -1782,6 +1882,17 @@ def test_company_service_base_transport_with_credentials_file():
)
+def test_company_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(
+ "google.cloud.talent_v4beta1.services.company_service.transports.CompanyServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.CompanyServiceTransport()
+ adc.assert_called_once()
+
+
def test_company_service_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(auth, "default") as adc:
@@ -1834,191 +1945,116 @@ def test_company_service_host_with_port():
def test_company_service_grpc_transport_channel():
channel = grpc.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.CompanyServiceGrpcTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
def test_company_service_grpc_asyncio_transport_channel():
channel = aio.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.CompanyServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_company_service_grpc_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.CompanyServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_company_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.CompanyServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.CompanyServiceGrpcTransport,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_company_service_grpc_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
+def test_company_service_transport_channel_mtls_with_client_cert_source(
+ transport_class,
):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
- mock_ssl_cred = mock.Mock()
- with mock.patch.multiple(
- "google.auth.transport.grpc.SslCredentials",
- __init__=mock.Mock(return_value=None),
- ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
- ):
- mock_cred = mock.Mock()
- transport = transports.CompanyServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.CompanyServiceGrpcTransport,
+ transports.CompanyServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_company_service_grpc_asyncio_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
+def test_company_service_transport_channel_mtls_with_adc(transport_class):
mock_ssl_cred = mock.Mock()
with mock.patch.multiple(
"google.auth.transport.grpc.SslCredentials",
__init__=mock.Mock(return_value=None),
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
- mock_cred = mock.Mock()
- transport = transports.CompanyServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
def test_company_path():
@@ -2044,3 +2080,24 @@ def test_parse_company_path():
# Check that the path construction is reversible.
actual = CompanyServiceClient.parse_company_path(path)
assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.CompanyServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = CompanyServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.CompanyServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = CompanyServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4beta1/test_completion.py b/tests/unit/gapic/talent_v4beta1/test_completion.py
index 5e65aa06..eda690c7 100644
--- a/tests/unit/gapic/talent_v4beta1/test_completion.py
+++ b/tests/unit/gapic/talent_v4beta1/test_completion.py
@@ -27,6 +27,7 @@
from google import auth
from google.api_core import client_options
from google.api_core import exceptions
+from google.api_core import gapic_v1
from google.api_core import grpc_helpers
from google.api_core import grpc_helpers_async
from google.auth import credentials
@@ -147,14 +148,14 @@ def test_completion_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "never".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -163,14 +164,14 @@ def test_completion_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "always".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -179,90 +180,173 @@ def test_completion_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (CompletionClient, transports.CompletionGrpcTransport, "grpc", "true"),
+ (
+ CompletionAsyncClient,
+ transports.CompletionGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (CompletionClient, transports.CompletionGrpcTransport, "grpc", "false"),
+ (
+ CompletionAsyncClient,
+ transports.CompletionGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ CompletionClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionClient)
+)
+@mock.patch.object(
+ CompletionAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(CompletionAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_completion_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
options = client_options.ClientOptions(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=client_cert_source_callback,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and default_client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
- with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=True,
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
):
patched.return_value = None
- client = client_class()
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
+ host=expected_host,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", but client_cert_source and default_client_cert_source are None.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=False,
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
):
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has
- # unsupported value.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}):
- with pytest.raises(MutualTLSChannelError):
- client = client_class()
-
- # Check the case quota_project_id is provided
- options = client_options.ClientOptions(quota_project_id="octopus")
- with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id="octopus",
- )
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
@pytest.mark.parametrize(
@@ -289,9 +373,9 @@ def test_completion_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -319,9 +403,9 @@ def test_completion_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -336,9 +420,9 @@ def test_completion_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -512,6 +596,18 @@ def test_transport_get_channel():
assert channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.CompletionGrpcTransport, transports.CompletionGrpcAsyncIOTransport],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
def test_transport_grpc_default():
# A client should use the gRPC transport by default.
client = CompletionClient(credentials=credentials.AnonymousCredentials(),)
@@ -567,6 +663,17 @@ def test_completion_base_transport_with_credentials_file():
)
+def test_completion_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(
+ "google.cloud.talent_v4beta1.services.completion.transports.CompletionTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.CompletionTransport()
+ adc.assert_called_once()
+
+
def test_completion_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(auth, "default") as adc:
@@ -619,188 +726,126 @@ def test_completion_host_with_port():
def test_completion_grpc_transport_channel():
channel = grpc.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.CompletionGrpcTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
def test_completion_grpc_asyncio_transport_channel():
channel = aio.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.CompletionGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_completion_grpc_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
- transport = transports.CompletionGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_completion_grpc_asyncio_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.CompletionGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.CompletionGrpcTransport, transports.CompletionGrpcAsyncIOTransport],
+)
+def test_completion_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [transports.CompletionGrpcTransport, transports.CompletionGrpcAsyncIOTransport],
)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_completion_grpc_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
+def test_completion_transport_channel_mtls_with_adc(transport_class):
mock_ssl_cred = mock.Mock()
with mock.patch.multiple(
"google.auth.transport.grpc.SslCredentials",
__init__=mock.Mock(return_value=None),
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
- mock_cred = mock.Mock()
- transport = transports.CompletionGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
-@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
-)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_completion_grpc_asyncio_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
- # Mock google.auth.transport.grpc.SslCredentials class.
- mock_ssl_cred = mock.Mock()
- with mock.patch.multiple(
- "google.auth.transport.grpc.SslCredentials",
- __init__=mock.Mock(return_value=None),
- ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
- ):
- mock_cred = mock.Mock()
- transport = transports.CompletionGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.CompletionTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = CompletionClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
)
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.CompletionTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = CompletionClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
)
- assert transport.grpc_channel == mock_grpc_channel
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4beta1/test_event_service.py b/tests/unit/gapic/talent_v4beta1/test_event_service.py
index fea20890..fb617f2d 100644
--- a/tests/unit/gapic/talent_v4beta1/test_event_service.py
+++ b/tests/unit/gapic/talent_v4beta1/test_event_service.py
@@ -27,6 +27,7 @@
from google import auth
from google.api_core import client_options
from google.api_core import exceptions
+from google.api_core import gapic_v1
from google.api_core import grpc_helpers
from google.api_core import grpc_helpers_async
from google.auth import credentials
@@ -148,14 +149,14 @@ def test_event_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "never".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -164,14 +165,14 @@ def test_event_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "always".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -180,90 +181,173 @@ def test_event_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (EventServiceClient, transports.EventServiceGrpcTransport, "grpc", "true"),
+ (
+ EventServiceAsyncClient,
+ transports.EventServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (EventServiceClient, transports.EventServiceGrpcTransport, "grpc", "false"),
+ (
+ EventServiceAsyncClient,
+ transports.EventServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ EventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(EventServiceClient)
+)
+@mock.patch.object(
+ EventServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(EventServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_event_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
options = client_options.ClientOptions(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=client_cert_source_callback,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and default_client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
- with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=True,
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
):
patched.return_value = None
- client = client_class()
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
+ host=expected_host,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", but client_cert_source and default_client_cert_source are None.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=False,
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
):
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has
- # unsupported value.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}):
- with pytest.raises(MutualTLSChannelError):
- client = client_class()
-
- # Check the case quota_project_id is provided
- options = client_options.ClientOptions(quota_project_id="octopus")
- with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id="octopus",
- )
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
@pytest.mark.parametrize(
@@ -290,9 +374,9 @@ def test_event_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -320,9 +404,9 @@ def test_event_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -337,9 +421,9 @@ def test_event_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -363,7 +447,7 @@ def test_create_client_event(
request_id="request_id_value",
event_id="event_id_value",
event_notes="event_notes_value",
- job_event=event.JobEvent(type=event.JobEvent.JobEventType.IMPRESSION),
+ job_event=event.JobEvent(type_=event.JobEvent.JobEventType.IMPRESSION),
)
response = client.create_client_event(request)
@@ -619,6 +703,18 @@ def test_transport_get_channel():
assert channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.EventServiceGrpcTransport, transports.EventServiceGrpcAsyncIOTransport],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
def test_transport_grpc_default():
# A client should use the gRPC transport by default.
client = EventServiceClient(credentials=credentials.AnonymousCredentials(),)
@@ -674,6 +770,17 @@ def test_event_service_base_transport_with_credentials_file():
)
+def test_event_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(
+ "google.cloud.talent_v4beta1.services.event_service.transports.EventServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.EventServiceTransport()
+ adc.assert_called_once()
+
+
def test_event_service_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(auth, "default") as adc:
@@ -726,188 +833,126 @@ def test_event_service_host_with_port():
def test_event_service_grpc_transport_channel():
channel = grpc.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.EventServiceGrpcTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
def test_event_service_grpc_asyncio_transport_channel():
channel = aio.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.EventServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_event_service_grpc_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
- transport = transports.EventServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_event_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.EventServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.EventServiceGrpcTransport, transports.EventServiceGrpcAsyncIOTransport],
+)
+def test_event_service_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [transports.EventServiceGrpcTransport, transports.EventServiceGrpcAsyncIOTransport],
)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_event_service_grpc_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
+def test_event_service_transport_channel_mtls_with_adc(transport_class):
mock_ssl_cred = mock.Mock()
with mock.patch.multiple(
"google.auth.transport.grpc.SslCredentials",
__init__=mock.Mock(return_value=None),
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
- mock_cred = mock.Mock()
- transport = transports.EventServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
-@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
-)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_event_service_grpc_asyncio_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
- # Mock google.auth.transport.grpc.SslCredentials class.
- mock_ssl_cred = mock.Mock()
- with mock.patch.multiple(
- "google.auth.transport.grpc.SslCredentials",
- __init__=mock.Mock(return_value=None),
- ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
- ):
- mock_cred = mock.Mock()
- transport = transports.EventServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.EventServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = EventServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
)
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.EventServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = EventServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
)
- assert transport.grpc_channel == mock_grpc_channel
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4beta1/test_job_service.py b/tests/unit/gapic/talent_v4beta1/test_job_service.py
index b4446d66..9dae40d1 100644
--- a/tests/unit/gapic/talent_v4beta1/test_job_service.py
+++ b/tests/unit/gapic/talent_v4beta1/test_job_service.py
@@ -31,7 +31,7 @@
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
+from google.api_core import operation_async # type: ignore
from google.api_core import operations_v1
from google.auth import credentials
from google.auth.exceptions import MutualTLSChannelError
@@ -165,14 +165,14 @@ def test_job_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "never".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -181,14 +181,14 @@ def test_job_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "always".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -197,90 +197,173 @@ def test_job_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (JobServiceClient, transports.JobServiceGrpcTransport, "grpc", "true"),
+ (
+ JobServiceAsyncClient,
+ transports.JobServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (JobServiceClient, transports.JobServiceGrpcTransport, "grpc", "false"),
+ (
+ JobServiceAsyncClient,
+ transports.JobServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ JobServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(JobServiceClient)
+)
+@mock.patch.object(
+ JobServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(JobServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_job_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
options = client_options.ClientOptions(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=client_cert_source_callback,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and default_client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
- with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=True,
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
):
patched.return_value = None
- client = client_class()
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
+ host=expected_host,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", but client_cert_source and default_client_cert_source are None.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=False,
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
):
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has
- # unsupported value.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}):
- with pytest.raises(MutualTLSChannelError):
- client = client_class()
-
- # Check the case quota_project_id is provided
- options = client_options.ClientOptions(quota_project_id="octopus")
- with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id="octopus",
- )
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
@pytest.mark.parametrize(
@@ -307,9 +390,9 @@ def test_job_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -337,9 +420,9 @@ def test_job_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -354,9 +437,9 @@ def test_job_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -2271,8 +2354,8 @@ def test_list_jobs_pages():
RuntimeError,
)
pages = list(client.list_jobs(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -2326,10 +2409,10 @@ async def test_list_jobs_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.list_jobs(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.list_jobs(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_search_jobs(
@@ -2547,8 +2630,8 @@ def test_search_jobs_pages():
RuntimeError,
)
pages = list(client.search_jobs(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -2630,10 +2713,10 @@ async def test_search_jobs_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.search_jobs(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.search_jobs(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_search_jobs_for_alert(
@@ -2859,8 +2942,8 @@ def test_search_jobs_for_alert_pages():
RuntimeError,
)
pages = list(client.search_jobs_for_alert(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -2942,10 +3025,10 @@ async def test_search_jobs_for_alert_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.search_jobs_for_alert(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.search_jobs_for_alert(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_credentials_transport_error():
@@ -3002,6 +3085,18 @@ def test_transport_get_channel():
assert channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [transports.JobServiceGrpcTransport, transports.JobServiceGrpcAsyncIOTransport],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
def test_transport_grpc_default():
# A client should use the gRPC transport by default.
client = JobServiceClient(credentials=credentials.AnonymousCredentials(),)
@@ -3073,6 +3168,17 @@ def test_job_service_base_transport_with_credentials_file():
)
+def test_job_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(
+ "google.cloud.talent_v4beta1.services.job_service.transports.JobServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.JobServiceTransport()
+ adc.assert_called_once()
+
+
def test_job_service_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(auth, "default") as adc:
@@ -3125,191 +3231,108 @@ def test_job_service_host_with_port():
def test_job_service_grpc_transport_channel():
channel = grpc.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.JobServiceGrpcTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
def test_job_service_grpc_asyncio_transport_channel():
channel = aio.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.JobServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_job_service_grpc_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.JobServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_job_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.JobServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [transports.JobServiceGrpcTransport, transports.JobServiceGrpcAsyncIOTransport],
)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_job_service_grpc_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
- mock_ssl_cred = mock.Mock()
- with mock.patch.multiple(
- "google.auth.transport.grpc.SslCredentials",
- __init__=mock.Mock(return_value=None),
- ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
- ):
- mock_cred = mock.Mock()
- transport = transports.JobServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+def test_job_service_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [transports.JobServiceGrpcTransport, transports.JobServiceGrpcAsyncIOTransport],
)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_job_service_grpc_asyncio_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
+def test_job_service_transport_channel_mtls_with_adc(transport_class):
mock_ssl_cred = mock.Mock()
with mock.patch.multiple(
"google.auth.transport.grpc.SslCredentials",
__init__=mock.Mock(return_value=None),
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
- mock_cred = mock.Mock()
- transport = transports.JobServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
def test_job_service_grpc_lro_client():
@@ -3361,3 +3384,24 @@ def test_parse_job_path():
# Check that the path construction is reversible.
actual = JobServiceClient.parse_job_path(path)
assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.JobServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = JobServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.JobServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = JobServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4beta1/test_profile_service.py b/tests/unit/gapic/talent_v4beta1/test_profile_service.py
index f95669da..53e3dbba 100644
--- a/tests/unit/gapic/talent_v4beta1/test_profile_service.py
+++ b/tests/unit/gapic/talent_v4beta1/test_profile_service.py
@@ -169,14 +169,14 @@ def test_profile_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "never".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -185,14 +185,14 @@ def test_profile_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "always".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -201,90 +201,175 @@ def test_profile_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (ProfileServiceClient, transports.ProfileServiceGrpcTransport, "grpc", "true"),
+ (
+ ProfileServiceAsyncClient,
+ transports.ProfileServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (ProfileServiceClient, transports.ProfileServiceGrpcTransport, "grpc", "false"),
+ (
+ ProfileServiceAsyncClient,
+ transports.ProfileServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ ProfileServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(ProfileServiceClient),
+)
+@mock.patch.object(
+ ProfileServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(ProfileServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_profile_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
options = client_options.ClientOptions(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=client_cert_source_callback,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and default_client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
- with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=True,
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
):
patched.return_value = None
- client = client_class()
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
+ host=expected_host,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", but client_cert_source and default_client_cert_source are None.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=False,
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
):
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has
- # unsupported value.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}):
- with pytest.raises(MutualTLSChannelError):
- client = client_class()
-
- # Check the case quota_project_id is provided
- options = client_options.ClientOptions(quota_project_id="octopus")
- with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id="octopus",
- )
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
@pytest.mark.parametrize(
@@ -311,9 +396,9 @@ def test_profile_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -341,9 +426,9 @@ def test_profile_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -360,9 +445,9 @@ def test_profile_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -614,8 +699,8 @@ def test_list_profiles_pages():
RuntimeError,
)
pages = list(client.list_profiles(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -679,10 +764,10 @@ async def test_list_profiles_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.list_profiles(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.list_profiles(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_create_profile(
@@ -1806,8 +1891,8 @@ def test_search_profiles_pages():
RuntimeError,
)
pages = list(client.search_profiles(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -1891,10 +1976,10 @@ async def test_search_profiles_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.search_profiles(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.search_profiles(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_credentials_transport_error():
@@ -1951,6 +2036,21 @@ def test_transport_get_channel():
assert channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.ProfileServiceGrpcTransport,
+ transports.ProfileServiceGrpcAsyncIOTransport,
+ ],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
def test_transport_grpc_default():
# A client should use the gRPC transport by default.
client = ProfileServiceClient(credentials=credentials.AnonymousCredentials(),)
@@ -2013,6 +2113,17 @@ def test_profile_service_base_transport_with_credentials_file():
)
+def test_profile_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(
+ "google.cloud.talent_v4beta1.services.profile_service.transports.ProfileServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.ProfileServiceTransport()
+ adc.assert_called_once()
+
+
def test_profile_service_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(auth, "default") as adc:
@@ -2065,191 +2176,116 @@ def test_profile_service_host_with_port():
def test_profile_service_grpc_transport_channel():
channel = grpc.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.ProfileServiceGrpcTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
def test_profile_service_grpc_asyncio_transport_channel():
channel = aio.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.ProfileServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_profile_service_grpc_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.ProfileServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_profile_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.ProfileServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.ProfileServiceGrpcTransport,
+ transports.ProfileServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_profile_service_grpc_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
+def test_profile_service_transport_channel_mtls_with_client_cert_source(
+ transport_class,
):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
- mock_ssl_cred = mock.Mock()
- with mock.patch.multiple(
- "google.auth.transport.grpc.SslCredentials",
- __init__=mock.Mock(return_value=None),
- ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
- ):
- mock_cred = mock.Mock()
- transport = transports.ProfileServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.ProfileServiceGrpcTransport,
+ transports.ProfileServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_profile_service_grpc_asyncio_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
+def test_profile_service_transport_channel_mtls_with_adc(transport_class):
mock_ssl_cred = mock.Mock()
with mock.patch.multiple(
"google.auth.transport.grpc.SslCredentials",
__init__=mock.Mock(return_value=None),
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
- mock_cred = mock.Mock()
- transport = transports.ProfileServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
def test_profile_path():
@@ -2275,3 +2311,24 @@ def test_parse_profile_path():
# Check that the path construction is reversible.
actual = ProfileServiceClient.parse_profile_path(path)
assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.ProfileServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = ProfileServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.ProfileServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = ProfileServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
diff --git a/tests/unit/gapic/talent_v4beta1/test_tenant_service.py b/tests/unit/gapic/talent_v4beta1/test_tenant_service.py
index cfbd0058..ecf6be6c 100644
--- a/tests/unit/gapic/talent_v4beta1/test_tenant_service.py
+++ b/tests/unit/gapic/talent_v4beta1/test_tenant_service.py
@@ -158,14 +158,14 @@ def test_tenant_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "never".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "never"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -174,14 +174,14 @@ def test_tenant_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is
# "always".
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "always"}):
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}):
with mock.patch.object(transport_class, "__init__") as patched:
patched.return_value = None
client = client_class()
@@ -190,90 +190,175 @@ def test_tenant_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has
+ # unsupported value.
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}):
+ with pytest.raises(MutualTLSChannelError):
+ client = client_class()
+
+ # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
+ ):
+ with pytest.raises(ValueError):
+ client = client_class()
+
+ # Check the case quota_project_id is provided
+ options = client_options.ClientOptions(quota_project_id="octopus")
+ with mock.patch.object(transport_class, "__init__") as patched:
+ patched.return_value = None
+ client = client_class(client_options=options)
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id="octopus",
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+
+@pytest.mark.parametrize(
+ "client_class,transport_class,transport_name,use_client_cert_env",
+ [
+ (TenantServiceClient, transports.TenantServiceGrpcTransport, "grpc", "true"),
+ (
+ TenantServiceAsyncClient,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "true",
+ ),
+ (TenantServiceClient, transports.TenantServiceGrpcTransport, "grpc", "false"),
+ (
+ TenantServiceAsyncClient,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ "grpc_asyncio",
+ "false",
+ ),
+ ],
+)
+@mock.patch.object(
+ TenantServiceClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(TenantServiceClient),
+)
+@mock.patch.object(
+ TenantServiceAsyncClient,
+ "DEFAULT_ENDPOINT",
+ modify_default_endpoint(TenantServiceAsyncClient),
+)
+@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"})
+def test_tenant_service_client_mtls_env_auto(
+ client_class, transport_class, transport_name, use_client_cert_env
+):
+ # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default
+ # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists.
+
+ # Check the case client_cert_source is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
options = client_options.ClientOptions(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=client_cert_source_callback,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", and default_client_cert_source is provided.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
- with mock.patch.object(transport_class, "__init__") as patched:
+ ssl_channel_creds = mock.Mock()
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=True,
+ "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
):
patched.return_value = None
- client = client_class()
+ client = client_class(client_options=options)
+
+ if use_client_cert_env == "false":
+ expected_ssl_channel_creds = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_ssl_channel_creds = ssl_channel_creds
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_MTLS_ENDPOINT,
+ host=expected_host,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
- # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is
- # "auto", but client_cert_source and default_client_cert_source are None.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "auto"}):
+ # Check the case ADC client cert is provided. Whether client cert is used depends on
+ # GOOGLE_API_USE_CLIENT_CERTIFICATE value.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.mtls.has_default_client_cert_source",
- return_value=False,
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
):
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id=None,
- )
-
- # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has
- # unsupported value.
- with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS": "Unsupported"}):
- with pytest.raises(MutualTLSChannelError):
- client = client_class()
-
- # Check the case quota_project_id is provided
- options = client_options.ClientOptions(quota_project_id="octopus")
- with mock.patch.object(transport_class, "__init__") as patched:
- patched.return_value = None
- client = client_class(client_options=options)
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
- scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
- quota_project_id="octopus",
- )
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.ssl_credentials",
+ new_callable=mock.PropertyMock,
+ ) as ssl_credentials_mock:
+ if use_client_cert_env == "false":
+ is_mtls_mock.return_value = False
+ ssl_credentials_mock.return_value = None
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_ssl_channel_creds = None
+ else:
+ is_mtls_mock.return_value = True
+ ssl_credentials_mock.return_value = mock.Mock()
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_ssl_channel_creds = (
+ ssl_credentials_mock.return_value
+ )
+
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ ssl_channel_credentials=expected_ssl_channel_creds,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ ):
+ with mock.patch(
+ "google.auth.transport.grpc.SslCredentials.is_mtls",
+ new_callable=mock.PropertyMock,
+ ) as is_mtls_mock:
+ is_mtls_mock.return_value = False
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ ssl_channel_credentials=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
@pytest.mark.parametrize(
@@ -300,9 +385,9 @@ def test_tenant_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -330,9 +415,9 @@ def test_tenant_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- api_mtls_endpoint=client.DEFAULT_ENDPOINT,
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -349,9 +434,9 @@ def test_tenant_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- api_mtls_endpoint="squid.clam.whelk",
- client_cert_source=None,
+ ssl_channel_credentials=None,
quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -1441,8 +1526,8 @@ def test_list_tenants_pages():
RuntimeError,
)
pages = list(client.list_tenants(request={}).pages)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
@pytest.mark.asyncio
@@ -1506,10 +1591,10 @@ async def test_list_tenants_async_pages():
RuntimeError,
)
pages = []
- async for page in (await client.list_tenants(request={})).pages:
- pages.append(page)
- for page, token in zip(pages, ["abc", "def", "ghi", ""]):
- assert page.raw_page.next_page_token == token
+ async for page_ in (await client.list_tenants(request={})).pages:
+ pages.append(page_)
+ for page_, token in zip(pages, ["abc", "def", "ghi", ""]):
+ assert page_.raw_page.next_page_token == token
def test_credentials_transport_error():
@@ -1566,6 +1651,21 @@ def test_transport_get_channel():
assert channel
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.TenantServiceGrpcTransport,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ ],
+)
+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)
+ transport_class()
+ adc.assert_called_once()
+
+
def test_transport_grpc_default():
# A client should use the gRPC transport by default.
client = TenantServiceClient(credentials=credentials.AnonymousCredentials(),)
@@ -1627,6 +1727,17 @@ def test_tenant_service_base_transport_with_credentials_file():
)
+def test_tenant_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(
+ "google.cloud.talent_v4beta1.services.tenant_service.transports.TenantServiceTransport._prep_wrapped_messages"
+ ) as Transport:
+ Transport.return_value = None
+ adc.return_value = (credentials.AnonymousCredentials(), None)
+ transport = transports.TenantServiceTransport()
+ adc.assert_called_once()
+
+
def test_tenant_service_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(auth, "default") as adc:
@@ -1679,191 +1790,114 @@ def test_tenant_service_host_with_port():
def test_tenant_service_grpc_transport_channel():
channel = grpc.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.TenantServiceGrpcTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
def test_tenant_service_grpc_asyncio_transport_channel():
channel = aio.insecure_channel("http://localhost/")
- # Check that if channel is provided, mtls endpoint and client_cert_source
- # won't be used.
- callback = mock.MagicMock()
+ # Check that channel is used if provided.
transport = transports.TenantServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- channel=channel,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=callback,
+ host="squid.clam.whelk", channel=channel,
)
assert transport.grpc_channel == channel
assert transport._host == "squid.clam.whelk:443"
- assert not callback.called
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_tenant_service_grpc_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.TenantServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
-
-
-@mock.patch("grpc.ssl_channel_credentials", autospec=True)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_tenant_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source(
- grpc_create_channel, grpc_ssl_channel_cred
-):
- # Check that if channel is None, but api_mtls_endpoint and client_cert_source
- # are provided, then a mTLS channel will be created.
- mock_cred = mock.Mock()
-
- mock_ssl_cred = mock.Mock()
- grpc_ssl_channel_cred.return_value = mock_ssl_cred
-
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- transport = transports.TenantServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint="mtls.squid.clam.whelk",
- client_cert_source=client_cert_source_callback,
- )
- grpc_ssl_channel_cred.assert_called_once_with(
- certificate_chain=b"cert bytes", private_key=b"key bytes"
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.TenantServiceGrpcTransport,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True)
-def test_tenant_service_grpc_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
- mock_ssl_cred = mock.Mock()
- with mock.patch.multiple(
- "google.auth.transport.grpc.SslCredentials",
- __init__=mock.Mock(return_value=None),
- ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
- ):
- mock_cred = mock.Mock()
- transport = transports.TenantServiceGrpcTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+def test_tenant_service_transport_channel_mtls_with_client_cert_source(transport_class):
+ with mock.patch(
+ "grpc.ssl_channel_credentials", autospec=True
+ ) as grpc_ssl_channel_cred:
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_ssl_cred = mock.Mock()
+ grpc_ssl_channel_cred.return_value = mock_ssl_cred
+
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+
+ cred = credentials.AnonymousCredentials()
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.object(auth, "default") as adc:
+ adc.return_value = (cred, None)
+ transport = transport_class(
+ host="squid.clam.whelk",
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=client_cert_source_callback,
+ )
+ adc.assert_called_once()
+
+ grpc_ssl_channel_cred.assert_called_once_with(
+ certificate_chain=b"cert bytes", private_key=b"key bytes"
+ )
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
@pytest.mark.parametrize(
- "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"]
+ "transport_class",
+ [
+ transports.TenantServiceGrpcTransport,
+ transports.TenantServiceGrpcAsyncIOTransport,
+ ],
)
-@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True)
-def test_tenant_service_grpc_asyncio_transport_channel_mtls_with_adc(
- grpc_create_channel, api_mtls_endpoint
-):
- # Check that if channel and client_cert_source are None, but api_mtls_endpoint
- # is provided, then a mTLS channel will be created with SSL ADC.
- mock_grpc_channel = mock.Mock()
- grpc_create_channel.return_value = mock_grpc_channel
-
- # Mock google.auth.transport.grpc.SslCredentials class.
+def test_tenant_service_transport_channel_mtls_with_adc(transport_class):
mock_ssl_cred = mock.Mock()
with mock.patch.multiple(
"google.auth.transport.grpc.SslCredentials",
__init__=mock.Mock(return_value=None),
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
- mock_cred = mock.Mock()
- transport = transports.TenantServiceGrpcAsyncIOTransport(
- host="squid.clam.whelk",
- credentials=mock_cred,
- api_mtls_endpoint=api_mtls_endpoint,
- client_cert_source=None,
- )
- grpc_create_channel.assert_called_once_with(
- "mtls.squid.clam.whelk:443",
- credentials=mock_cred,
- credentials_file=None,
- scopes=(
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/jobs",
- ),
- ssl_credentials=mock_ssl_cred,
- quota_project_id=None,
- )
- assert transport.grpc_channel == mock_grpc_channel
+ with mock.patch.object(
+ transport_class, "create_channel", autospec=True
+ ) as grpc_create_channel:
+ mock_grpc_channel = mock.Mock()
+ grpc_create_channel.return_value = mock_grpc_channel
+ mock_cred = mock.Mock()
+
+ with pytest.warns(DeprecationWarning):
+ transport = transport_class(
+ host="squid.clam.whelk",
+ credentials=mock_cred,
+ api_mtls_endpoint="mtls.squid.clam.whelk",
+ client_cert_source=None,
+ )
+
+ grpc_create_channel.assert_called_once_with(
+ "mtls.squid.clam.whelk:443",
+ credentials=mock_cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/jobs",
+ ),
+ ssl_credentials=mock_ssl_cred,
+ quota_project_id=None,
+ )
+ assert transport.grpc_channel == mock_grpc_channel
def test_tenant_path():
@@ -1887,3 +1921,24 @@ def test_parse_tenant_path():
# Check that the path construction is reversible.
actual = TenantServiceClient.parse_tenant_path(path)
assert expected == actual
+
+
+def test_client_withDEFAULT_CLIENT_INFO():
+ client_info = gapic_v1.client_info.ClientInfo()
+
+ with mock.patch.object(
+ transports.TenantServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ client = TenantServiceClient(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)
+
+ with mock.patch.object(
+ transports.TenantServiceTransport, "_prep_wrapped_messages"
+ ) as prep:
+ transport_class = TenantServiceClient.get_transport_class()
+ transport = transport_class(
+ credentials=credentials.AnonymousCredentials(), client_info=client_info,
+ )
+ prep.assert_called_once_with(client_info)