From 1654c75a8bb773d54c404b9404e2f33923e24005 Mon Sep 17 00:00:00 2001 From: Mike <45373284+munkhuushmgl@users.noreply.github.com> Date: Wed, 20 May 2020 19:59:47 -0700 Subject: [PATCH 01/57] Talent v4beta1 samples [Restoring deleted branch samples] [(#3273)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3273) * restored deleted samples * fixed lint issues * added tests and formatted code * corrected test req.txt file * made requested changes and added return val for samples * added secrets.txt to bash, script * fixed the lint * moved to requirements-test.txt * delete resources in teardown just in case * restored deleted samples fixed lint issues added tests and formatted code corrected test req.txt file made requested changes and added return val for samples added secrets.txt to bash, script fixed the lint * added some spacing * restored deleted samples fixed lint issues added tests and formatted code corrected test req.txt file made requested changes and added return val for samples added secrets.txt to bash, script fixed the lint restored deleted samples fixed lint issues added tests and formatted code corrected test req.txt file made requested changes and added return val for samples added secrets.txt to bash, script fixed the lint moved to requirements-test.txt delete resources in teardown just in case added some spacing * fixed merge conflicts * added conftest.py and refactored samples with loop * removed talent secret.txt from bash script * fixed the lint issue * removed unnecessary env vars * deleted global random ids, deleted unnecessary setup code from delete tests * removed unused imports * removed pytest * removed unused IDs * deleted unused uuid imports Co-authored-by: Takashi Matsuo --- talent/conftest.py | 87 +++++++++++ talent/job_search_autocomplete_job_title.py | 56 +++++++ .../job_search_autocomplete_job_title_test.py | 25 +++ talent/job_search_batch_create_jobs.py | 133 ++++++++++++++++ talent/job_search_batch_update_jobs.py | 143 ++++++++++++++++++ talent/job_search_commute_search.py | 66 ++++++++ talent/job_search_commute_search_test.py | 25 +++ talent/job_search_create_client_event.py | 77 ++++++++++ talent/job_search_create_company.py | 50 ++++++ talent/job_search_create_company_test.py | 48 ++++++ talent/job_search_create_job.py | 71 +++++++++ ...job_search_create_job_custom_attributes.py | 63 ++++++++ ...earch_create_job_custom_attributes_test.py | 46 ++++++ talent/job_search_create_job_test.py | 47 ++++++ talent/job_search_create_tenant.py | 43 ++++++ talent/job_search_create_tenant_test.py | 48 ++++++ talent/job_search_custom_ranking_search.py | 64 ++++++++ .../job_search_custom_ranking_search_test.py | 25 +++ talent/job_search_delete_company.py | 42 +++++ talent/job_search_delete_company_test.py | 27 ++++ talent/job_search_delete_job.py | 42 +++++ talent/job_search_delete_job_test.py | 25 +++ talent/job_search_delete_tenant.py | 39 +++++ talent/job_search_delete_tenant_test.py | 25 +++ talent/job_search_get_company.py | 43 ++++++ talent/job_search_get_company_test.py | 25 +++ talent/job_search_get_job.py | 52 +++++++ talent/job_search_get_job_test.py | 25 +++ talent/job_search_get_tenant.py | 40 +++++ talent/job_search_get_tenant_test.py | 26 ++++ talent/job_search_histogram_search.py | 65 ++++++++ talent/job_search_histogram_search_test.py | 26 ++++ talent/job_search_list_companies.py | 45 ++++++ talent/job_search_list_companies_test.py | 25 +++ talent/job_search_list_jobs.py | 56 +++++++ talent/job_search_list_jobs_test.py | 26 ++++ talent/job_search_list_tenants.py | 38 +++++ talent/job_search_list_tenants_test.py | 25 +++ talent/requirements-test.txt | 1 + talent/requirements.txt | 1 + 40 files changed, 1836 insertions(+) create mode 100644 talent/conftest.py create mode 100644 talent/job_search_autocomplete_job_title.py create mode 100644 talent/job_search_autocomplete_job_title_test.py create mode 100644 talent/job_search_batch_create_jobs.py create mode 100644 talent/job_search_batch_update_jobs.py create mode 100644 talent/job_search_commute_search.py create mode 100644 talent/job_search_commute_search_test.py create mode 100644 talent/job_search_create_client_event.py create mode 100644 talent/job_search_create_company.py create mode 100644 talent/job_search_create_company_test.py create mode 100644 talent/job_search_create_job.py create mode 100644 talent/job_search_create_job_custom_attributes.py create mode 100644 talent/job_search_create_job_custom_attributes_test.py create mode 100644 talent/job_search_create_job_test.py create mode 100644 talent/job_search_create_tenant.py create mode 100644 talent/job_search_create_tenant_test.py create mode 100644 talent/job_search_custom_ranking_search.py create mode 100644 talent/job_search_custom_ranking_search_test.py create mode 100644 talent/job_search_delete_company.py create mode 100644 talent/job_search_delete_company_test.py create mode 100644 talent/job_search_delete_job.py create mode 100644 talent/job_search_delete_job_test.py create mode 100644 talent/job_search_delete_tenant.py create mode 100644 talent/job_search_delete_tenant_test.py create mode 100644 talent/job_search_get_company.py create mode 100644 talent/job_search_get_company_test.py create mode 100644 talent/job_search_get_job.py create mode 100644 talent/job_search_get_job_test.py create mode 100644 talent/job_search_get_tenant.py create mode 100644 talent/job_search_get_tenant_test.py create mode 100644 talent/job_search_histogram_search.py create mode 100644 talent/job_search_histogram_search_test.py create mode 100644 talent/job_search_list_companies.py create mode 100644 talent/job_search_list_companies_test.py create mode 100644 talent/job_search_list_jobs.py create mode 100644 talent/job_search_list_jobs_test.py create mode 100644 talent/job_search_list_tenants.py create mode 100644 talent/job_search_list_tenants_test.py create mode 100644 talent/requirements-test.txt create mode 100755 talent/requirements.txt diff --git a/talent/conftest.py b/talent/conftest.py new file mode 100644 index 000000000000..169a401bcfb8 --- /dev/null +++ b/talent/conftest.py @@ -0,0 +1,87 @@ +# 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 uuid + +from google.api_core.exceptions import NotFound + +import pytest + +import job_search_create_company +import job_search_create_job +import job_search_create_tenant +import job_search_delete_company +import job_search_delete_job +import job_search_delete_tenant + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +@pytest.fixture(scope="module") +def tenant(): + tenant_ext_unique_id = "TEST_TENANT_{}".format(uuid.uuid4()) + # create a temporary tenant + tenant_name = job_search_create_tenant.create_tenant( + PROJECT_ID, tenant_ext_unique_id + ) + + # extract company id + tenant_id = tenant_name.split("/")[-1] + + yield tenant_id + + try: + job_search_delete_tenant.delete_tenant(PROJECT_ID, tenant_id) + except NotFound as e: + print("Ignoring NotFound upon cleanup, details: {}".format(e)) + + +@pytest.fixture(scope="module") +def company(tenant): + company_ext_id = "COMPANY_EXT_ID_{}".format(uuid.uuid4()) + + # create a temporary company + company_name = job_search_create_company.create_company( + PROJECT_ID, tenant, "Test Company Name", company_ext_id + ) + + # extract company id + company_id = company_name.split("/")[-1] + + yield company_id + + try: + job_search_delete_company.delete_company(PROJECT_ID, tenant, company_id) + except NotFound as e: + print("Ignoring NotFound upon cleanup, details: {}".format(e)) + + +@pytest.fixture(scope="module") +def job(tenant, company): + post_unique_id = "TEST_POST_{}".format(uuid.uuid4().hex)[:20] + # create a temporary job + job_name = job_search_create_job.create_job( + PROJECT_ID, tenant, company, post_unique_id, "www.jobUrl.com" + ) + + # extract company id + job_id = job_name.split("/")[-1] + + yield job_id + + try: + job_search_delete_job.delete_job(PROJECT_ID, tenant, job_id) + except NotFound as e: + print("Ignoring NotFound upon cleanup, details: {}".format(e)) diff --git a/talent/job_search_autocomplete_job_title.py b/talent/job_search_autocomplete_job_title.py new file mode 100644 index 000000000000..af817ec1a7cc --- /dev/null +++ b/talent/job_search_autocomplete_job_title.py @@ -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 +# +# https://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. + +# [START job_search_autocomplete_job_title] + +from google.cloud import talent_v4beta1 +from google.cloud.talent import enums +import six + + +def complete_query(project_id, tenant_id, query): + """Complete job title given partial text (autocomplete)""" + + client = talent_v4beta1.CompletionClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # query = '[partially typed job title]' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(query, six.binary_type): + query = query.decode("utf-8") + + parent = client.tenant_path(project_id, tenant_id) + + response = client.complete_query( + parent, + query, + page_size=5, # limit for number of results + language_codes=["en-US"], # language code + ) + for result in response.completion_results: + print("Suggested title: {}".format(result.suggestion)) + # Suggestion type is JOB_TITLE or COMPANY_TITLE + print( + "Suggestion type: {}".format( + enums.CompleteQueryRequest.CompletionType(result.type).name + ) + ) + + +# [END job_search_autocomplete_job_title] diff --git a/talent/job_search_autocomplete_job_title_test.py b/talent/job_search_autocomplete_job_title_test.py new file mode 100644 index 000000000000..4fe2498481c3 --- /dev/null +++ b/talent/job_search_autocomplete_job_title_test.py @@ -0,0 +1,25 @@ +# 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 job_search_autocomplete_job_title + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_autocomplete_job_title(capsys, tenant): + job_search_autocomplete_job_title.complete_query(PROJECT_ID, tenant, "Software") + out, _ = capsys.readouterr() + assert "Suggested title:" in out diff --git a/talent/job_search_batch_create_jobs.py b/talent/job_search_batch_create_jobs.py new file mode 100644 index 000000000000..a221cc57c9c7 --- /dev/null +++ b/talent/job_search_batch_create_jobs.py @@ -0,0 +1,133 @@ +# 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 +# +# https://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. + +# [START job_search_batch_create_jobs] + +from google.cloud import talent +import six + + +def batch_create_jobs( + project_id, + tenant_id, + company_name_one, + requisition_id_one, + title_one, + description_one, + job_application_url_one, + address_one, + language_code_one, + company_name_two, + requisition_id_two, + title_two, + description_two, + job_application_url_two, + address_two, + language_code_two, +): + """ + Batch Create Jobs + + Args: + project_id Your Google Cloud Project ID + tenant_id Identifier of the Tenant + """ + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # company_name_one = 'Company name, e.g. projects/your-project/companies/company-id' + # requisition_id_one = 'Job requisition ID, aka Posting ID. Unique per job.' + # title_one = 'Software Engineer' + # description_one = 'This is a description of this wonderful job!' + # job_application_url_one = 'https://www.example.org/job-posting/123' + # address_one = '1600 Amphitheatre Parkway, Mountain View, CA 94043' + # language_code_one = 'en-US' + # company_name_two = 'Company name, e.g. projects/your-project/companies/company-id' + # requisition_id_two = 'Job requisition ID, aka Posting ID. Unique per job.' + # title_two = 'Quality Assurance' + # description_two = 'This is a description of this wonderful job!' + # job_application_url_two = 'https://www.example.org/job-posting/123' + # address_two = '111 8th Avenue, New York, NY 10011' + # language_code_two = 'en-US' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(company_name_one, six.binary_type): + company_name_one = company_name_one.decode("utf-8") + if isinstance(requisition_id_one, six.binary_type): + requisition_id_one = requisition_id_one.decode("utf-8") + if isinstance(title_one, six.binary_type): + title_one = title_one.decode("utf-8") + if isinstance(description_one, six.binary_type): + description_one = description_one.decode("utf-8") + if isinstance(job_application_url_one, six.binary_type): + job_application_url_one = job_application_url_one.decode("utf-8") + if isinstance(address_one, six.binary_type): + address_one = address_one.decode("utf-8") + if isinstance(language_code_one, six.binary_type): + language_code_one = language_code_one.decode("utf-8") + if isinstance(company_name_two, six.binary_type): + company_name_two = company_name_two.decode("utf-8") + if isinstance(requisition_id_two, six.binary_type): + requisition_id_two = requisition_id_two.decode("utf-8") + if isinstance(title_two, six.binary_type): + title_two = title_two.decode("utf-8") + if isinstance(description_two, six.binary_type): + description_two = description_two.decode("utf-8") + if isinstance(job_application_url_two, six.binary_type): + job_application_url_two = job_application_url_two.decode("utf-8") + if isinstance(address_two, six.binary_type): + address_two = address_two.decode("utf-8") + if isinstance(language_code_two, six.binary_type): + language_code_two = language_code_two.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + uris = [job_application_url_one] + application_info = {"uris": uris} + addresses = [address_one] + jobs_element = { + "company": company_name_one, + "requisition_id": requisition_id_one, + "title": title_one, + "description": description_one, + "application_info": application_info, + "addresses": addresses, + "language_code": language_code_one, + } + uris_2 = [job_application_url_two] + application_info_2 = {"uris": uris_2} + addresses_2 = [address_two] + jobs_element_2 = { + "company": company_name_two, + "requisition_id": requisition_id_two, + "title": title_two, + "description": description_two, + "application_info": application_info_2, + "addresses": addresses_2, + "language_code": language_code_two, + } + jobs = [jobs_element, jobs_element_2] + + operation = client.batch_create_jobs(parent, jobs) + + print("Waiting for operation to complete...") + response = operation.result(90) + + print("Batch response: {}".format(response)) + + +# [END job_search_batch_create_jobs] diff --git a/talent/job_search_batch_update_jobs.py b/talent/job_search_batch_update_jobs.py new file mode 100644 index 000000000000..bac4232e2ea5 --- /dev/null +++ b/talent/job_search_batch_update_jobs.py @@ -0,0 +1,143 @@ +# 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 +# +# https://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. + +# [START job_search_batch_update_jobs] + +from google.cloud import talent +import six + + +def batch_update_jobs( + project_id, + tenant_id, + job_name_one, + company_name_one, + requisition_id_one, + title_one, + description_one, + job_application_url_one, + address_one, + language_code_one, + job_name_two, + company_name_two, + requisition_id_two, + title_two, + description_two, + job_application_url_two, + address_two, + language_code_two, +): + """ + Batch Update Jobs + + Args: + project_id Your Google Cloud Project ID + tenant_id Identifier of the Tenant + """ + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # job_name_one = 'job name, projects/your-project/tenants/tenant-id/jobs/job-id' + # company_name_one = 'Company name, e.g. projects/your-project/companies/company-id' + # requisition_id_one = 'Job requisition ID, aka Posting ID. Unique per job.' + # title_one = 'Software Engineer' + # description_one = 'This is a description of this wonderful job!' + # job_application_url_one = 'https://www.example.org/job-posting/123' + # address_one = '1600 Amphitheatre Parkway, Mountain View, CA 94043' + # language_code_one = 'en-US' + # job_name_two = 'job name, projects/your-project/tenants/tenant-id/jobs/job-id' + # company_name_two = 'Company name, e.g. projects/your-project/companies/company-id' + # requisition_id_two = 'Job requisition ID, aka Posting ID. Unique per job.' + # title_two = 'Quality Assurance' + # description_two = 'This is a description of this wonderful job!' + # job_application_url_two = 'https://www.example.org/job-posting/123' + # address_two = '111 8th Avenue, New York, NY 10011' + # language_code_two = 'en-US' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(job_name_one, six.binary_type): + job_name_one = job_name_one.decode("utf-8") + if isinstance(company_name_one, six.binary_type): + company_name_one = company_name_one.decode("utf-8") + if isinstance(requisition_id_one, six.binary_type): + requisition_id_one = requisition_id_one.decode("utf-8") + if isinstance(title_one, six.binary_type): + title_one = title_one.decode("utf-8") + if isinstance(description_one, six.binary_type): + description_one = description_one.decode("utf-8") + if isinstance(job_application_url_one, six.binary_type): + job_application_url_one = job_application_url_one.decode("utf-8") + if isinstance(address_one, six.binary_type): + address_one = address_one.decode("utf-8") + if isinstance(language_code_one, six.binary_type): + language_code_one = language_code_one.decode("utf-8") + if isinstance(job_name_two, six.binary_type): + job_name_two = job_name_two.decode("utf-8") + if isinstance(company_name_two, six.binary_type): + company_name_two = company_name_two.decode("utf-8") + if isinstance(requisition_id_two, six.binary_type): + requisition_id_two = requisition_id_two.decode("utf-8") + if isinstance(title_two, six.binary_type): + title_two = title_two.decode("utf-8") + if isinstance(description_two, six.binary_type): + description_two = description_two.decode("utf-8") + if isinstance(job_application_url_two, six.binary_type): + job_application_url_two = job_application_url_two.decode("utf-8") + if isinstance(address_two, six.binary_type): + address_two = address_two.decode("utf-8") + if isinstance(language_code_two, six.binary_type): + language_code_two = language_code_two.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + uris = [job_application_url_one] + application_info = {"uris": uris} + addresses = [address_one] + jobs_element = { + "name": job_name_one, + "company": company_name_one, + "requisition_id": requisition_id_one, + "title": title_one, + "description": description_one, + "application_info": application_info, + "addresses": addresses, + "language_code": language_code_one, + } + uris_2 = [job_application_url_two] + application_info_2 = {"uris": uris_2} + addresses_2 = [address_two] + jobs_element_2 = { + "name": job_name_two, + "company": company_name_two, + "requisition_id": requisition_id_two, + "title": title_two, + "description": description_two, + "application_info": application_info_2, + "addresses": addresses_2, + "language_code": language_code_two, + } + jobs = [jobs_element, jobs_element_2] + + operation = client.batch_update_jobs(parent, jobs) + + print("Waiting for operation to complete...") + response = operation.result(90) + + print("Batch response: {}".format(response)) + + +# [END job_search_batch_update_jobs] diff --git a/talent/job_search_commute_search.py b/talent/job_search_commute_search.py new file mode 100644 index 000000000000..1a5df79f6f3d --- /dev/null +++ b/talent/job_search_commute_search.py @@ -0,0 +1,66 @@ +# 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 +# +# https://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. + +# [START job_search_commute_search] + +from google.cloud import talent +from google.cloud.talent import enums +import six + + +def search_jobs(project_id, tenant_id): + """Search Jobs using commute distance""" + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + domain = "www.example.com" + session_id = "Hashed session identifier" + user_id = "Hashed user identifier" + request_metadata = {"domain": domain, "session_id": session_id, "user_id": user_id} + commute_method = enums.CommuteMethod.TRANSIT + seconds = 1800 + travel_duration = {"seconds": seconds} + latitude = 37.422408 + longitude = -122.084068 + start_coordinates = {"latitude": latitude, "longitude": longitude} + commute_filter = { + "commute_method": commute_method, + "travel_duration": travel_duration, + "start_coordinates": start_coordinates, + } + job_query = {"commute_filter": commute_filter} + + # Iterate over all results + results = [] + for response_item in client.search_jobs( + parent, request_metadata, job_query=job_query + ): + print("Job summary: {}".format(response_item.job_summary)) + print("Job title snippet: {}".format(response_item.job_title_snippet)) + job = response_item.job + results.append(job.name) + print("Job name: {}".format(job.name)) + print("Job title: {}".format(job.title)) + return results + + +# [END job_search_commute_search] diff --git a/talent/job_search_commute_search_test.py b/talent/job_search_commute_search_test.py new file mode 100644 index 000000000000..911875015dce --- /dev/null +++ b/talent/job_search_commute_search_test.py @@ -0,0 +1,25 @@ +# 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 job_search_commute_search + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_commute_search(tenant): + jobs = job_search_commute_search.search_jobs(PROJECT_ID, tenant) + for job in jobs: + assert "projects/" in job diff --git a/talent/job_search_create_client_event.py b/talent/job_search_create_client_event.py new file mode 100644 index 000000000000..c5bb1b48f7da --- /dev/null +++ b/talent/job_search_create_client_event.py @@ -0,0 +1,77 @@ +# 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 +# +# https://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. + +# [START job_search_create_client_event] + +from google.cloud import talent +from google.cloud.talent import enums +import six + + +def create_client_event(project_id, tenant_id, request_id, event_id): + """ + Creates a client event + + Args: + project_id Your Google Cloud Project ID + tenant_id Identifier of the Tenant + request_id A unique ID generated in the API responses. + Value should be set to the request_id from an API response. + event_id A unique identifier, generated by the client application + """ + + client = talent.EventServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # request_id = '[request_id from ResponseMetadata]' + # event_id = '[Set this to a unique identifier]' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(request_id, six.binary_type): + request_id = request_id.decode("utf-8") + if isinstance(event_id, six.binary_type): + event_id = event_id.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + + # The timestamp of the event as seconds of UTC time since Unix epoch + # For more information on how to create google.protobuf.Timestamps + # See: + # https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto + seconds = 0 + create_time = {"seconds": seconds} + + # The type of event attributed to the behavior of the end user + type_ = enums.JobEvent.JobEventType.VIEW + + # List of job names associated with this event + jobs_element = "projects/[Project ID]/tenants/[Tenant ID]/jobs/[Job ID]" + jobs_element_2 = "projects/[Project ID]/tenants/[Tenant ID]/jobs/[Job ID]" + jobs = [jobs_element, jobs_element_2] + job_event = {"type": type_, "jobs": jobs} + client_event = { + "request_id": request_id, + "event_id": event_id, + "create_time": create_time, + "job_event": job_event, + } + + response = client.create_client_event(parent, client_event) + print(response) + + +# [END job_search_create_client_event] diff --git a/talent/job_search_create_company.py b/talent/job_search_create_company.py new file mode 100644 index 000000000000..828fb0e49dbc --- /dev/null +++ b/talent/job_search_create_company.py @@ -0,0 +1,50 @@ +# 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 +# +# https://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. + +# [START job_search_create_company] + +from google.cloud import talent +import six + + +def create_company(project_id, tenant_id, display_name, external_id): + """Create Company""" + + client = talent.CompanyServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # display_name = 'My Company Name' + # external_id = 'Identifier of this company in my system' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(display_name, six.binary_type): + display_name = display_name.decode("utf-8") + if isinstance(external_id, six.binary_type): + external_id = external_id.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + company = {"display_name": display_name, "external_id": external_id} + + response = client.create_company(parent, company) + print("Created Company") + print("Name: {}".format(response.name)) + print("Display Name: {}".format(response.display_name)) + print("External ID: {}".format(response.external_id)) + return response.name + + +# [END job_search_create_company] diff --git a/talent/job_search_create_company_test.py b/talent/job_search_create_company_test.py new file mode 100644 index 000000000000..e78f60903212 --- /dev/null +++ b/talent/job_search_create_company_test.py @@ -0,0 +1,48 @@ +# 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 uuid + +import pytest + +import job_search_create_company +import job_search_delete_company + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] +COMPANY_EXT_ID = "COMPANY_EXT_ID_{}".format(uuid.uuid4()) + + +def test_create_company(capsys, tenant, cleaner): + # create company + company_name = job_search_create_company.create_company( + PROJECT_ID, tenant, "Test Company Name", COMPANY_EXT_ID + ) + out, _ = capsys.readouterr() + assert "Created" in out + assert "Name:" in out + + # extract id + company_id = company_name.split("/")[-1] + cleaner.append(company_id) + + +@pytest.fixture(scope="module") +def cleaner(tenant): + companies = [] + + yield companies + + for company_id in companies: + job_search_delete_company.delete_company(PROJECT_ID, tenant, company_id) diff --git a/talent/job_search_create_job.py b/talent/job_search_create_job.py new file mode 100644 index 000000000000..ed065d24fab6 --- /dev/null +++ b/talent/job_search_create_job.py @@ -0,0 +1,71 @@ +# 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 +# +# https://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. + +# [START job_search_create_job] + +from google.cloud import talent +import six + + +def create_job( + project_id, tenant_id, company_id, requisition_id, job_application_url, +): + """Create Job""" + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # company_id = 'Company name, e.g. projects/your-project/companies/company-id' + # requisition_id = 'Job requisition ID, aka Posting ID. Unique per job.' + # title = 'Software Engineer' + # description = 'This is a description of this wonderful job!' + # job_application_url = 'https://www.example.org/job-posting/123' + # address_one = '1600 Amphitheatre Parkway, Mountain View, CA 94043' + # address_two = '111 8th Avenue, New York, NY 10011' + # language_code = 'en-US' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(company_id, six.binary_type): + company_id = company_id.decode("utf-8") + if isinstance(requisition_id, six.binary_type): + requisition_id = requisition_id.decode("utf-8") + if isinstance(job_application_url, six.binary_type): + job_application_url = job_application_url.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + uris = [job_application_url] + application_info = {"uris": uris} + addresses = [ + "1600 Amphitheatre Parkway, Mountain View, CA 94043", + "111 8th Avenue, New York, NY 10011", + ] + job = { + "company": company_id, + "requisition_id": requisition_id, + "title": "Software Developer", + "description": "Develop, maintain the software solutions.", + "application_info": application_info, + "addresses": addresses, + "language_code": "en-US", + } + + response = client.create_job(parent, job) + print("Created job: {}".format(response.name)) + return response.name + + +# [END job_search_create_job] diff --git a/talent/job_search_create_job_custom_attributes.py b/talent/job_search_create_job_custom_attributes.py new file mode 100644 index 000000000000..de8aa40e999b --- /dev/null +++ b/talent/job_search_create_job_custom_attributes.py @@ -0,0 +1,63 @@ +# 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 +# +# https://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. + +# [START job_search_create_job_custom_attributes] + +from google.cloud import talent +import six + + +def create_job(project_id, tenant_id, company_id, requisition_id): + """Create Job with Custom Attributes""" + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # company_id = 'Company name, e.g. projects/your-project/companies/company-id' + # requisition_id = 'Job requisition ID, aka Posting ID. Unique per job.' + # language_code = 'en-US' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(company_id, six.binary_type): + company_id = company_id.decode("utf-8") + + # Custom attribute can be string or numeric value, + # and can be filtered in search queries. + # https://cloud.google.com/talent-solution/job-search/docs/custom-attributes + custom_attribute = talent.types.CustomAttribute() + custom_attribute.filterable = True + custom_attribute.string_values.append("Intern") + custom_attribute.string_values.append("Apprenticeship") + + parent = client.tenant_path(project_id, tenant_id) + + job = { + "company": company_id, + "title": "Software Engineer", + "requisition_id": requisition_id, + "description": "This is a description of this job", + "language_code": "en-US", + "custom_attributes": {"FOR_STUDENTS": custom_attribute}, + } + + response = client.create_job(parent, job) + print("Created job: {}".format(response.name)) + return response.name + + +# [END job_search_create_job_custom_attributes] diff --git a/talent/job_search_create_job_custom_attributes_test.py b/talent/job_search_create_job_custom_attributes_test.py new file mode 100644 index 000000000000..028fedb7074c --- /dev/null +++ b/talent/job_search_create_job_custom_attributes_test.py @@ -0,0 +1,46 @@ +# 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 uuid + +import pytest + +import job_search_create_job_custom_attributes +import job_search_delete_job + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] +JOB_EXT_UNIQUE_ID = "TEST_JOB_{}".format(uuid.uuid4()) + + +def test_create_job_with_attributes(capsys, tenant, company, cleaner): + job_name = job_search_create_job_custom_attributes.create_job( + PROJECT_ID, tenant, company, JOB_EXT_UNIQUE_ID + ) + out, _ = capsys.readouterr() + assert "Created job:" in out + + # extract job id + job_id = job_name.split("/")[-1] + cleaner.append(job_id) + + +@pytest.fixture(scope="module") +def cleaner(tenant): + jobs = [] + + yield jobs + + for job_id in jobs: + job_search_delete_job.delete_job(PROJECT_ID, tenant, job_id) diff --git a/talent/job_search_create_job_test.py b/talent/job_search_create_job_test.py new file mode 100644 index 000000000000..505d27f6c379 --- /dev/null +++ b/talent/job_search_create_job_test.py @@ -0,0 +1,47 @@ +# 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 uuid + +import pytest + +import job_search_create_job +import job_search_delete_job + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] +JOB_EXT_UNIQUE_ID = "TEST_JOB_{}".format(uuid.uuid4()) + + +def test_create_job(capsys, tenant, company, cleaner): + # create a job + job_name = job_search_create_job.create_job( + PROJECT_ID, tenant, company, JOB_EXT_UNIQUE_ID, "www.example.com" + ) + out, _ = capsys.readouterr() + assert "Created job:" in out + + # extract job id + job_id = job_name.split("/")[-1] + cleaner.append(job_id) + + +@pytest.fixture(scope="module") +def cleaner(tenant): + jobs = [] + + yield jobs + + for job_id in jobs: + job_search_delete_job.delete_job(PROJECT_ID, tenant, job_id) diff --git a/talent/job_search_create_tenant.py b/talent/job_search_create_tenant.py new file mode 100644 index 000000000000..8d4fde32811c --- /dev/null +++ b/talent/job_search_create_tenant.py @@ -0,0 +1,43 @@ +# 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 +# +# https://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. + +# [START job_search_create_tenant] + +from google.cloud import talent +import six + + +def create_tenant(project_id, external_id): + """Create Tenant for scoping resources, e.g. companies and jobs""" + + client = talent.TenantServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # external_id = 'Your Unique Identifier for Tenant' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(external_id, six.binary_type): + external_id = external_id.decode("utf-8") + parent = client.project_path(project_id) + tenant = {"external_id": external_id} + + response = client.create_tenant(parent, tenant) + print("Created Tenant") + print("Name: {}".format(response.name)) + print("External ID: {}".format(response.external_id)) + return response.name + + +# [END job_search_create_tenant] diff --git a/talent/job_search_create_tenant_test.py b/talent/job_search_create_tenant_test.py new file mode 100644 index 000000000000..e8c9c0495fbe --- /dev/null +++ b/talent/job_search_create_tenant_test.py @@ -0,0 +1,48 @@ +# 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 uuid + +import pytest + +import job_search_create_tenant +import job_search_delete_tenant + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] +TENANT_EXT_UNIQUE_ID = "TEST_TENANT_{}".format(uuid.uuid4()) + + +def test_create_tenant(capsys, cleaner): + # create tenant + tenant_name = job_search_create_tenant.create_tenant( + PROJECT_ID, TENANT_EXT_UNIQUE_ID + ) + out, _ = capsys.readouterr() + assert "Created Tenant" in out + assert "Name:" in out + + # extract tenant id + tenant_id = tenant_name.split("/")[-1] + cleaner.append(tenant_id) + + +@pytest.fixture(scope="module") +def cleaner(): + tenants = [] + + yield tenants + + for tenant_id in tenants: + job_search_delete_tenant.delete_tenant(PROJECT_ID, tenant_id) diff --git a/talent/job_search_custom_ranking_search.py b/talent/job_search_custom_ranking_search.py new file mode 100644 index 000000000000..1b33aab36216 --- /dev/null +++ b/talent/job_search_custom_ranking_search.py @@ -0,0 +1,64 @@ +# 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 +# +# https://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. + +# [START job_search_custom_ranking_search] + +from google.cloud import talent +from google.cloud.talent import enums +import six + + +def search_jobs(project_id, tenant_id): + """Search Jobs using custom rankings""" + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + domain = "www.example.com" + session_id = "Hashed session identifier" + user_id = "Hashed user identifier" + request_metadata = {"domain": domain, "session_id": session_id, "user_id": user_id} + importance_level = enums.SearchJobsRequest.CustomRankingInfo.ImportanceLevel.EXTREME + ranking_expression = "(someFieldLong + 25) * 0.25" + custom_ranking_info = { + "importance_level": importance_level, + "ranking_expression": ranking_expression, + } + order_by = "custom_ranking desc" + + # Iterate over all results + results = [] + for response_item in client.search_jobs( + parent, + request_metadata, + custom_ranking_info=custom_ranking_info, + order_by=order_by, + ): + print("Job summary: {}".format(response_item.job_summary)) + print("Job title snippet: {}".format(response_item.job_title_snippet)) + job = response_item.job + results.append(job.name) + print("Job name: {}".format(job.name)) + print("Job title: {}".format(job.title)) + return results + + +# [END job_search_custom_ranking_search] diff --git a/talent/job_search_custom_ranking_search_test.py b/talent/job_search_custom_ranking_search_test.py new file mode 100644 index 000000000000..3a8e80bcbb0a --- /dev/null +++ b/talent/job_search_custom_ranking_search_test.py @@ -0,0 +1,25 @@ +# 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 job_search_custom_ranking_search + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_search_jobs_custom_ranking(tenant): + jobs = job_search_custom_ranking_search.search_jobs(PROJECT_ID, tenant) + for job in jobs: + assert "projects/" in job diff --git a/talent/job_search_delete_company.py b/talent/job_search_delete_company.py new file mode 100644 index 000000000000..1eb1ed19355d --- /dev/null +++ b/talent/job_search_delete_company.py @@ -0,0 +1,42 @@ +# 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 +# +# https://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. + +# [START job_search_delete_company] + +from google.cloud import talent +import six + + +def delete_company(project_id, tenant_id, company_id): + """Delete Company""" + + client = talent.CompanyServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # company_id = 'ID of the company to delete' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(company_id, six.binary_type): + company_id = company_id.decode("utf-8") + name = client.company_path(project_id, tenant_id, company_id) + + client.delete_company(name) + print("Deleted company") + + +# [END job_search_delete_company] diff --git a/talent/job_search_delete_company_test.py b/talent/job_search_delete_company_test.py new file mode 100644 index 000000000000..f581935b0c43 --- /dev/null +++ b/talent/job_search_delete_company_test.py @@ -0,0 +1,27 @@ +# 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 job_search_delete_company + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_delete_company(capsys, tenant, company): + out, _ = capsys.readouterr() + + job_search_delete_company.delete_company(PROJECT_ID, tenant, company) + out, _ = capsys.readouterr() + assert "Deleted" in out diff --git a/talent/job_search_delete_job.py b/talent/job_search_delete_job.py new file mode 100644 index 000000000000..f6dd0cf38e50 --- /dev/null +++ b/talent/job_search_delete_job.py @@ -0,0 +1,42 @@ +# 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 +# +# https://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. + +# [START job_search_delete_job] + +from google.cloud import talent +import six + + +def delete_job(project_id, tenant_id, job_id): + """Delete Job""" + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # job_id = 'Company ID' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(job_id, six.binary_type): + job_id = job_id.decode("utf-8") + name = client.job_path(project_id, tenant_id, job_id) + + client.delete_job(name) + print("Deleted job.") + + +# [END job_search_delete_job] diff --git a/talent/job_search_delete_job_test.py b/talent/job_search_delete_job_test.py new file mode 100644 index 000000000000..ef151a2b53cc --- /dev/null +++ b/talent/job_search_delete_job_test.py @@ -0,0 +1,25 @@ +# 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 job_search_delete_job + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_delete_job(capsys, tenant, job): + job_search_delete_job.delete_job(PROJECT_ID, tenant, job) + out, _ = capsys.readouterr() + assert "Deleted" in out diff --git a/talent/job_search_delete_tenant.py b/talent/job_search_delete_tenant.py new file mode 100644 index 000000000000..9d95498bd44d --- /dev/null +++ b/talent/job_search_delete_tenant.py @@ -0,0 +1,39 @@ +# 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 +# +# https://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. + +# [START job_search_delete_tenant] + +from google.cloud import talent +import six + + +def delete_tenant(project_id, tenant_id): + """Delete Tenant""" + + client = talent.TenantServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID)' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + name = client.tenant_path(project_id, tenant_id) + + client.delete_tenant(name) + print("Deleted Tenant.") + + +# [END job_search_delete_tenant] diff --git a/talent/job_search_delete_tenant_test.py b/talent/job_search_delete_tenant_test.py new file mode 100644 index 000000000000..a2fc490bbbca --- /dev/null +++ b/talent/job_search_delete_tenant_test.py @@ -0,0 +1,25 @@ +# 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 job_search_delete_tenant + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_delete_tenant(capsys, tenant): + job_search_delete_tenant.delete_tenant(PROJECT_ID, tenant) + out, _ = capsys.readouterr() + assert "Deleted" in out diff --git a/talent/job_search_get_company.py b/talent/job_search_get_company.py new file mode 100644 index 000000000000..ceac6e899002 --- /dev/null +++ b/talent/job_search_get_company.py @@ -0,0 +1,43 @@ +# 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 +# +# https://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. + +# [START job_search_get_company] + +from google.cloud import talent +import six + + +def get_company(project_id, tenant_id, company_id): + """Get Company""" + + client = talent.CompanyServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # company_id = 'Company ID' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(company_id, six.binary_type): + company_id = company_id.decode("utf-8") + name = client.company_path(project_id, tenant_id, company_id) + + response = client.get_company(name) + print("Company name: {}".format(response.name)) + print("Display name: {}".format(response.display_name)) + + +# [END job_search_get_company] diff --git a/talent/job_search_get_company_test.py b/talent/job_search_get_company_test.py new file mode 100644 index 000000000000..f11263304da3 --- /dev/null +++ b/talent/job_search_get_company_test.py @@ -0,0 +1,25 @@ +# 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 job_search_get_company + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_job_search_get_company(capsys, tenant, company): + job_search_get_company.get_company(PROJECT_ID, tenant, company) + out, _ = capsys.readouterr() + assert "Company name:" in out diff --git a/talent/job_search_get_job.py b/talent/job_search_get_job.py new file mode 100644 index 000000000000..f311202bcecf --- /dev/null +++ b/talent/job_search_get_job.py @@ -0,0 +1,52 @@ +# 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 +# +# https://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. + +# [START job_search_get_job] + +from google.cloud import talent +import six + + +def get_job(project_id, tenant_id, job_id): + """Get Job""" + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # job_id = 'Job ID' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(job_id, six.binary_type): + job_id = job_id.decode("utf-8") + name = client.job_path(project_id, tenant_id, job_id) + + response = client.get_job(name) + print("Job name: {}".format(response.name)) + print("Requisition ID: {}".format(response.requisition_id)) + print("Title: {}".format(response.title)) + print("Description: {}".format(response.description)) + print("Posting language: {}".format(response.language_code)) + for address in response.addresses: + print("Address: {}".format(address)) + for email in response.application_info.emails: + print("Email: {}".format(email)) + for website_uri in response.application_info.uris: + print("Website: {}".format(website_uri)) + + +# [END job_search_get_job] diff --git a/talent/job_search_get_job_test.py b/talent/job_search_get_job_test.py new file mode 100644 index 000000000000..264c57725e9d --- /dev/null +++ b/talent/job_search_get_job_test.py @@ -0,0 +1,25 @@ +# 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 job_search_get_job + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_job_search_get_job(capsys, tenant, job): + job_search_get_job.get_job(PROJECT_ID, tenant, job) + out, _ = capsys.readouterr() + assert "Job name:" in out diff --git a/talent/job_search_get_tenant.py b/talent/job_search_get_tenant.py new file mode 100644 index 000000000000..484c44d6f035 --- /dev/null +++ b/talent/job_search_get_tenant.py @@ -0,0 +1,40 @@ +# 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 +# +# https://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. + +# [START job_search_get_tenant] + +from google.cloud import talent +import six + + +def get_tenant(project_id, tenant_id): + """Get Tenant by name""" + + client = talent.TenantServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + name = client.tenant_path(project_id, tenant_id) + + response = client.get_tenant(name) + print("Name: {}".format(response.name)) + print("External ID: {}".format(response.external_id)) + + +# [END job_search_get_tenant] diff --git a/talent/job_search_get_tenant_test.py b/talent/job_search_get_tenant_test.py new file mode 100644 index 000000000000..d1f8c1cd8cfa --- /dev/null +++ b/talent/job_search_get_tenant_test.py @@ -0,0 +1,26 @@ +# 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 job_search_get_tenant + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_get_tenant(capsys, tenant): + job_search_get_tenant.get_tenant(PROJECT_ID, tenant) + out, _ = capsys.readouterr() + assert "Name: " in out diff --git a/talent/job_search_histogram_search.py b/talent/job_search_histogram_search.py new file mode 100644 index 000000000000..f238e6a620c9 --- /dev/null +++ b/talent/job_search_histogram_search.py @@ -0,0 +1,65 @@ +# 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 +# +# https://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. + +# [START job_search_histogram_search] + +from google.cloud import talent +import six + + +def search_jobs(project_id, tenant_id, query): + """ + Search Jobs with histogram queries + + Args: + query Histogram query + More info on histogram facets, constants, and built-in functions: + https://godoc.org/google.golang.org/genproto/googleapis/cloud/talent/v4beta1#SearchJobsRequest + """ + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # query = 'count(base_compensation, [bucket(12, 20)])' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(query, six.binary_type): + query = query.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + domain = "www.example.com" + session_id = "Hashed session identifier" + user_id = "Hashed user identifier" + request_metadata = {"domain": domain, "session_id": session_id, "user_id": user_id} + histogram_queries_element = {"histogram_query": query} + histogram_queries = [histogram_queries_element] + + # Iterate over all results + results = [] + for response_item in client.search_jobs( + parent, request_metadata, histogram_queries=histogram_queries + ): + print("Job summary: {}".format(response_item.job_summary)) + print("Job title snippet: {}".format(response_item.job_title_snippet)) + job = response_item.job + results.append(job) + print("Job name: {}".format(job.name)) + print("Job title: {}".format(job.title)) + return results + + +# [END job_search_histogram_search] diff --git a/talent/job_search_histogram_search_test.py b/talent/job_search_histogram_search_test.py new file mode 100644 index 000000000000..1f6594de9d61 --- /dev/null +++ b/talent/job_search_histogram_search_test.py @@ -0,0 +1,26 @@ +# 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 job_search_histogram_search + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_search_jobs_histogram(tenant): + query = "count(base_compensation, [bucket(12, 20)])" + jobs = job_search_histogram_search.search_jobs(PROJECT_ID, tenant, query) + for job in jobs: + assert "projects/" in job diff --git a/talent/job_search_list_companies.py b/talent/job_search_list_companies.py new file mode 100644 index 000000000000..bdef589c150a --- /dev/null +++ b/talent/job_search_list_companies.py @@ -0,0 +1,45 @@ +# 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 +# +# https://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. + +# [START job_search_list_companies] + +from google.cloud import talent +import six + + +def list_companies(project_id, tenant_id): + """List Companies""" + + client = talent.CompanyServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + + # Iterate over all results + results = [] + for company in client.list_companies(parent): + results.append(company.name) + print("Company Name: {}".format(company.name)) + print("Display Name: {}".format(company.display_name)) + print("External ID: {}".format(company.external_id)) + return results + + +# [END job_search_list_companies] diff --git a/talent/job_search_list_companies_test.py b/talent/job_search_list_companies_test.py new file mode 100644 index 000000000000..c8d71a850b7c --- /dev/null +++ b/talent/job_search_list_companies_test.py @@ -0,0 +1,25 @@ +# 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 job_search_list_companies + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_list_companies(tenant): + results = job_search_list_companies.list_companies(PROJECT_ID, tenant) + for company in results: + assert "projects/" in company.name diff --git a/talent/job_search_list_jobs.py b/talent/job_search_list_jobs.py new file mode 100644 index 000000000000..0ae52dc18610 --- /dev/null +++ b/talent/job_search_list_jobs.py @@ -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 +# +# https://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. + +# [START job_search_list_jobs] + +from google.cloud import talent +import six + + +def list_jobs(project_id, tenant_id, filter_): + """List Jobs""" + + client = talent.JobServiceClient() + + # project_id = 'Your Google Cloud Project ID' + # tenant_id = 'Your Tenant ID (using tenancy is optional)' + # filter_ = 'companyName=projects/my-project/companies/company-id' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + if isinstance(tenant_id, six.binary_type): + tenant_id = tenant_id.decode("utf-8") + if isinstance(filter_, six.binary_type): + filter_ = filter_.decode("utf-8") + parent = client.tenant_path(project_id, tenant_id) + + # Iterate over all results + results = [] + for job in client.list_jobs(parent, filter_): + results.append(job.name) + print("Job name: {}".format(job.name)) + print("Job requisition ID: {}".format(job.requisition_id)) + print("Job title: {}".format(job.title)) + print("Job description: {}".format(job.description)) + return results + + +# [END job_search_list_jobs] +list_jobs( + "python-docs-samples-tests", + "b603d325-3fb5-4979-8994-eba4ecf726f4", + 'companyName="projects/{}/companies/{}"'.format( + "python-docs-samples-tests", "4c0b9887-8f69-429b-bc67-a072ef55ec3e" + ), +) diff --git a/talent/job_search_list_jobs_test.py b/talent/job_search_list_jobs_test.py new file mode 100644 index 000000000000..a2187fd97f4b --- /dev/null +++ b/talent/job_search_list_jobs_test.py @@ -0,0 +1,26 @@ +# 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 job_search_list_jobs + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_list_jobs(capsys, tenant, company): + filter = 'companyName="projects/{}/companies/{}"'.format(PROJECT_ID, company) + jobs = job_search_list_jobs.list_jobs(PROJECT_ID, tenant, filter) + for job in jobs: + assert "projects/" in job diff --git a/talent/job_search_list_tenants.py b/talent/job_search_list_tenants.py new file mode 100644 index 000000000000..2045bccac5e6 --- /dev/null +++ b/talent/job_search_list_tenants.py @@ -0,0 +1,38 @@ +# 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 +# +# https://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. + +# [START job_search_list_tenants] + +from google.cloud import talent +import six + + +def list_tenants(project_id): + """List Tenants""" + + client = talent.TenantServiceClient() + + # project_id = 'Your Google Cloud Project ID' + + if isinstance(project_id, six.binary_type): + project_id = project_id.decode("utf-8") + parent = client.project_path(project_id) + + # Iterate over all results + for response_item in client.list_tenants(parent): + print("Tenant Name: {}".format(response_item.name)) + print("External ID: {}".format(response_item.external_id)) + + +# [END job_search_list_tenants] diff --git a/talent/job_search_list_tenants_test.py b/talent/job_search_list_tenants_test.py new file mode 100644 index 000000000000..38d840d564a0 --- /dev/null +++ b/talent/job_search_list_tenants_test.py @@ -0,0 +1,25 @@ +# 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 job_search_list_tenants + +PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] + + +def test_list_tenants(capsys): + job_search_list_tenants.list_tenants(PROJECT_ID) + out, _ = capsys.readouterr() + assert "Tenant Name:" in out diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt new file mode 100644 index 000000000000..10b405fa748e --- /dev/null +++ b/talent/requirements-test.txt @@ -0,0 +1 @@ +pytest==5.4.2 \ No newline at end of file diff --git a/talent/requirements.txt b/talent/requirements.txt new file mode 100755 index 000000000000..d2d6347f5538 --- /dev/null +++ b/talent/requirements.txt @@ -0,0 +1 @@ +google.cloud.talent==0.6.0 \ No newline at end of file From 962393570349292dcfc883b9e22ca0ec5a020087 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Thu, 21 May 2020 19:53:05 +0200 Subject: [PATCH 02/57] chore(deps): update dependency google.cloud.talent to v0.6.1 [(#3851)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3851) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index d2d6347f5538..9db6aba9c65d 100755 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==0.6.0 \ No newline at end of file +google.cloud.talent==0.6.1 \ No newline at end of file From dba46e3a65fc990fbaeddbcdbe15b862b6cb519f Mon Sep 17 00:00:00 2001 From: Takashi Matsuo Date: Fri, 12 Jun 2020 11:54:07 -0700 Subject: [PATCH 03/57] [jobs] testing: use multiple projects [(#4068)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4068) * [jobs] testing: use multiple projects * added README --- talent/README.rst | 6 +++++ talent/job_search_list_tenants_test.py | 19 ++++++++++++- talent/noxfile_config.py | 37 ++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 talent/README.rst create mode 100644 talent/noxfile_config.py diff --git a/talent/README.rst b/talent/README.rst new file mode 100644 index 000000000000..a7bfef3c666b --- /dev/null +++ b/talent/README.rst @@ -0,0 +1,6 @@ +To run the sample, you need to enable the API at: https://console.cloud.google.com/apis/library/jobs.googleapis.com + +To run the sample, you need to have the following roles: + +* `Talent Solution Job Editor` +* `Talent Solution Profile Editor` diff --git a/talent/job_search_list_tenants_test.py b/talent/job_search_list_tenants_test.py index 38d840d564a0..03f2fce7d675 100644 --- a/talent/job_search_list_tenants_test.py +++ b/talent/job_search_list_tenants_test.py @@ -13,13 +13,30 @@ # limitations under the License. import os +import uuid + +from google.cloud import talent +import pytest import job_search_list_tenants PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"] -def test_list_tenants(capsys): +@pytest.fixture(scope="module") +def test_tenant(): + client = talent.TenantServiceClient() + external_id = f'test_tenant_{uuid.uuid4().hex}' + parent = client.project_path(PROJECT_ID) + tenant = {"external_id": external_id} + resp = client.create_tenant(parent, tenant) + + yield resp + + client.delete_tenant(resp.name) + + +def test_list_tenants(capsys, test_tenant): job_search_list_tenants.list_tenants(PROJECT_ID) out, _ = capsys.readouterr() assert "Tenant Name:" in out diff --git a/talent/noxfile_config.py b/talent/noxfile_config.py new file mode 100644 index 000000000000..cfd0d439150c --- /dev/null +++ b/talent/noxfile_config.py @@ -0,0 +1,37 @@ +# 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + # 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} From dc0b61c799ee4c388e6d55e223a387546c4bb850 Mon Sep 17 00:00:00 2001 From: Takashi Matsuo Date: Wed, 8 Jul 2020 16:12:35 -0700 Subject: [PATCH 04/57] cleanup(jobs): remove unnecessary code [(#4257)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4257) Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> --- talent/job_search_list_jobs.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/talent/job_search_list_jobs.py b/talent/job_search_list_jobs.py index 0ae52dc18610..f31884dcd920 100644 --- a/talent/job_search_list_jobs.py +++ b/talent/job_search_list_jobs.py @@ -47,10 +47,3 @@ def list_jobs(project_id, tenant_id, filter_): # [END job_search_list_jobs] -list_jobs( - "python-docs-samples-tests", - "b603d325-3fb5-4979-8994-eba4ecf726f4", - 'companyName="projects/{}/companies/{}"'.format( - "python-docs-samples-tests", "4c0b9887-8f69-429b-bc67-a072ef55ec3e" - ), -) From df31d906531556b38ee5bde80e2d6d68e0178d07 Mon Sep 17 00:00:00 2001 From: Mike <45373284+munkhuushmgl@users.noreply.github.com> Date: Thu, 9 Jul 2020 10:36:53 -0700 Subject: [PATCH 05/57] samples: Automl table batch test [(#4267)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4267) * added rtest req.txt * samples: added automl batch predict test * added missing package * Update tables/automl/batch_predict_test.py Co-authored-by: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Co-authored-by: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 10b405fa748e..bbef4fe11b9a 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==5.4.2 \ No newline at end of file +pytest==5.4.2 From 333208705855bbbdbadbbee14abe1e4137cd3116 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 13 Jul 2020 00:46:30 +0200 Subject: [PATCH 06/57] chore(deps): update dependency pytest to v5.4.3 [(#4279)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4279) * chore(deps): update dependency pytest to v5.4.3 * specify pytest for python 2 in appengine Co-authored-by: Leah Cole --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index bbef4fe11b9a..79738af5f268 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==5.4.2 +pytest==5.4.3 From e8b43eee33718bd65a97e1c614736039edc81dc2 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Sat, 1 Aug 2020 21:51:00 +0200 Subject: [PATCH 07/57] Update dependency pytest to v6 [(#4390)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4390) --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 79738af5f268..7e460c8c866e 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==5.4.3 +pytest==6.0.1 From ffe4a88ab1ecb8c88859dea3793a6cb813fbff7d Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Thu, 24 Sep 2020 22:15:37 +0000 Subject: [PATCH 08/57] chore: update templates --- talent/noxfile.py | 224 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 talent/noxfile.py diff --git a/talent/noxfile.py b/talent/noxfile.py new file mode 100644 index 000000000000..ba55d7ce53ca --- /dev/null +++ b/talent/noxfile.py @@ -0,0 +1,224 @@ +# Copyright 2019 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 __future__ import print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) From 5df7915cca6e8727cecf1f33a2d9f47aef0cdccf Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Thu, 24 Sep 2020 23:24:39 +0000 Subject: [PATCH 09/57] test: fix sample tests --- talent/job_search_autocomplete_job_title.py | 16 +++---- talent/job_search_batch_create_jobs.py | 4 +- talent/job_search_batch_update_jobs.py | 46 ++++++++++--------- talent/job_search_commute_search.py | 40 +++++++++------- talent/job_search_create_client_event.py | 4 +- talent/job_search_create_company.py | 4 +- talent/job_search_create_job.py | 2 +- ...job_search_create_job_custom_attributes.py | 24 +++++----- talent/job_search_create_tenant.py | 10 ++-- talent/job_search_custom_ranking_search.py | 30 ++++++------ talent/job_search_delete_company.py | 2 +- talent/job_search_delete_job.py | 2 +- talent/job_search_delete_tenant.py | 2 +- talent/job_search_get_company.py | 6 +-- talent/job_search_get_job.py | 18 ++++---- talent/job_search_get_tenant.py | 4 +- talent/job_search_histogram_search.py | 19 ++++---- talent/job_search_list_companies.py | 10 ++-- talent/job_search_list_jobs.py | 12 ++--- talent/job_search_list_tenants.py | 8 ++-- 20 files changed, 138 insertions(+), 125 deletions(-) diff --git a/talent/job_search_autocomplete_job_title.py b/talent/job_search_autocomplete_job_title.py index af817ec1a7cc..e9f5286873ad 100644 --- a/talent/job_search_autocomplete_job_title.py +++ b/talent/job_search_autocomplete_job_title.py @@ -15,7 +15,6 @@ # [START job_search_autocomplete_job_title] from google.cloud import talent_v4beta1 -from google.cloud.talent import enums import six @@ -35,21 +34,20 @@ def complete_query(project_id, tenant_id, query): if isinstance(query, six.binary_type): query = query.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" - response = client.complete_query( - parent, - query, + request = talent_v4beta1.CompleteQueryRequest( + parent=parent, + query=query, page_size=5, # limit for number of results language_codes=["en-US"], # language code ) + response = client.complete_query(request=request) for result in response.completion_results: - print("Suggested title: {}".format(result.suggestion)) + print(f"Suggested title: {result.suggestion}") # Suggestion type is JOB_TITLE or COMPANY_TITLE print( - "Suggestion type: {}".format( - enums.CompleteQueryRequest.CompletionType(result.type).name - ) + f"Suggestion type: {talent_v4beta1.CompleteQueryRequest.CompletionType(result.type).name}" ) diff --git a/talent/job_search_batch_create_jobs.py b/talent/job_search_batch_create_jobs.py index a221cc57c9c7..18d48ae9737c 100644 --- a/talent/job_search_batch_create_jobs.py +++ b/talent/job_search_batch_create_jobs.py @@ -95,7 +95,7 @@ def batch_create_jobs( address_two = address_two.decode("utf-8") if isinstance(language_code_two, six.binary_type): language_code_two = language_code_two.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" uris = [job_application_url_one] application_info = {"uris": uris} addresses = [address_one] @@ -122,7 +122,7 @@ def batch_create_jobs( } jobs = [jobs_element, jobs_element_2] - operation = client.batch_create_jobs(parent, jobs) + operation = client.batch_create_jobs(parent=parent, jobs=jobs) print("Waiting for operation to complete...") response = operation.result(90) diff --git a/talent/job_search_batch_update_jobs.py b/talent/job_search_batch_update_jobs.py index bac4232e2ea5..0aa576c49a15 100644 --- a/talent/job_search_batch_update_jobs.py +++ b/talent/job_search_batch_update_jobs.py @@ -103,36 +103,38 @@ def batch_update_jobs( address_two = address_two.decode("utf-8") if isinstance(language_code_two, six.binary_type): language_code_two = language_code_two.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" uris = [job_application_url_one] application_info = {"uris": uris} addresses = [address_one] - jobs_element = { - "name": job_name_one, - "company": company_name_one, - "requisition_id": requisition_id_one, - "title": title_one, - "description": description_one, - "application_info": application_info, - "addresses": addresses, - "language_code": language_code_one, - } + jobs_element = talent.Job( + name=job_name_one, + company=company_name_one, + requisition_id=requisition_id_one, + title=title_one, + description=description_one, + application_info=application_info, + addresses=addresses, + language_code=language_code_one + ) + uris_2 = [job_application_url_two] application_info_2 = {"uris": uris_2} addresses_2 = [address_two] - jobs_element_2 = { - "name": job_name_two, - "company": company_name_two, - "requisition_id": requisition_id_two, - "title": title_two, - "description": description_two, - "application_info": application_info_2, - "addresses": addresses_2, - "language_code": language_code_two, - } + jobs_element_2 = talent.Job( + name=job_name_two, + company=company_name_two, + requisition_id=requisition_id_two, + title=title_two, + description=description_two, + application_info=application_info_2, + addresses=addresses_2, + language_code=language_code_two + ) + jobs = [jobs_element, jobs_element_2] - operation = client.batch_update_jobs(parent, jobs) + operation = client.batch_update_jobs(parent=parent, jobs=jobs) print("Waiting for operation to complete...") response = operation.result(90) diff --git a/talent/job_search_commute_search.py b/talent/job_search_commute_search.py index 1a5df79f6f3d..037bbd0845be 100644 --- a/talent/job_search_commute_search.py +++ b/talent/job_search_commute_search.py @@ -15,7 +15,6 @@ # [START job_search_commute_search] from google.cloud import talent -from google.cloud.talent import enums import six @@ -31,35 +30,42 @@ def search_jobs(project_id, tenant_id): project_id = project_id.decode("utf-8") if isinstance(tenant_id, six.binary_type): tenant_id = tenant_id.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}/" domain = "www.example.com" session_id = "Hashed session identifier" user_id = "Hashed user identifier" - request_metadata = {"domain": domain, "session_id": session_id, "user_id": user_id} - commute_method = enums.CommuteMethod.TRANSIT + request_metadata = talent.RequestMetadata( + domain=domain, + session_id=session_id, + user_id=user_id + ) + commute_method = talent.CommuteMethod.TRANSIT seconds = 1800 travel_duration = {"seconds": seconds} latitude = 37.422408 longitude = -122.084068 start_coordinates = {"latitude": latitude, "longitude": longitude} - commute_filter = { - "commute_method": commute_method, - "travel_duration": travel_duration, - "start_coordinates": start_coordinates, - } - job_query = {"commute_filter": commute_filter} + commute_filter = talent.CommuteFilter( + commute_method=commute_method, + travel_duration=travel_duration, + start_coordinates=start_coordinates, + ) + job_query = talent.JobQuery(commute_filter=commute_filter) # Iterate over all results results = [] - for response_item in client.search_jobs( - parent, request_metadata, job_query=job_query - ): - print("Job summary: {}".format(response_item.job_summary)) - print("Job title snippet: {}".format(response_item.job_title_snippet)) + request = talent.SearchJobsRequest( + parent=parent, + request_metadata=request_metadata, + job_query=job_query, + ) + for response_item in client.search_jobs(request=request): + print(f"Job summary: {response_item.job_summary}") + print(f"Job title snippet: {response_item.job_title_snippet}") job = response_item.job results.append(job.name) - print("Job name: {}".format(job.name)) - print("Job title: {}".format(job.title)) + print(f"Job name: {job.name}") + print(f"Job title: {job.title}") return results diff --git a/talent/job_search_create_client_event.py b/talent/job_search_create_client_event.py index c5bb1b48f7da..5b068570f16d 100644 --- a/talent/job_search_create_client_event.py +++ b/talent/job_search_create_client_event.py @@ -46,7 +46,7 @@ def create_client_event(project_id, tenant_id, request_id, event_id): request_id = request_id.decode("utf-8") if isinstance(event_id, six.binary_type): event_id = event_id.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" # The timestamp of the event as seconds of UTC time since Unix epoch # For more information on how to create google.protobuf.Timestamps @@ -70,7 +70,7 @@ def create_client_event(project_id, tenant_id, request_id, event_id): "job_event": job_event, } - response = client.create_client_event(parent, client_event) + response = client.create_client_event(parent=parent, client_event=client_event) print(response) diff --git a/talent/job_search_create_company.py b/talent/job_search_create_company.py index 828fb0e49dbc..28619a37fa21 100644 --- a/talent/job_search_create_company.py +++ b/talent/job_search_create_company.py @@ -36,10 +36,10 @@ def create_company(project_id, tenant_id, display_name, external_id): display_name = display_name.decode("utf-8") if isinstance(external_id, six.binary_type): external_id = external_id.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" company = {"display_name": display_name, "external_id": external_id} - response = client.create_company(parent, company) + response = client.create_company(parent=parent, company=company) print("Created Company") print("Name: {}".format(response.name)) print("Display Name: {}".format(response.display_name)) diff --git a/talent/job_search_create_job.py b/talent/job_search_create_job.py index ed065d24fab6..d48c962cc4ea 100644 --- a/talent/job_search_create_job.py +++ b/talent/job_search_create_job.py @@ -46,7 +46,7 @@ def create_job( requisition_id = requisition_id.decode("utf-8") if isinstance(job_application_url, six.binary_type): job_application_url = job_application_url.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" uris = [job_application_url] application_info = {"uris": uris} addresses = [ diff --git a/talent/job_search_create_job_custom_attributes.py b/talent/job_search_create_job_custom_attributes.py index de8aa40e999b..1ae10f2c28ae 100644 --- a/talent/job_search_create_job_custom_attributes.py +++ b/talent/job_search_create_job_custom_attributes.py @@ -39,24 +39,24 @@ def create_job(project_id, tenant_id, company_id, requisition_id): # Custom attribute can be string or numeric value, # and can be filtered in search queries. # https://cloud.google.com/talent-solution/job-search/docs/custom-attributes - custom_attribute = talent.types.CustomAttribute() + custom_attribute = talent.CustomAttribute() custom_attribute.filterable = True custom_attribute.string_values.append("Intern") custom_attribute.string_values.append("Apprenticeship") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" - job = { - "company": company_id, - "title": "Software Engineer", - "requisition_id": requisition_id, - "description": "This is a description of this job", - "language_code": "en-US", - "custom_attributes": {"FOR_STUDENTS": custom_attribute}, - } + job = talent.Job( + company=company_id, + title="Software Engineer", + requisition_id=requisition_id, + description="This is a description of this job", + language_code="en-us", + custom_attributes={"FOR_STUDENTS": custom_attribute} + ) - response = client.create_job(parent, job) - print("Created job: {}".format(response.name)) + response = client.create_job(parent=parent, job=job) + print(f"Created job: {response.name}") return response.name diff --git a/talent/job_search_create_tenant.py b/talent/job_search_create_tenant.py index 8d4fde32811c..4d9760e00490 100644 --- a/talent/job_search_create_tenant.py +++ b/talent/job_search_create_tenant.py @@ -30,13 +30,13 @@ def create_tenant(project_id, external_id): project_id = project_id.decode("utf-8") if isinstance(external_id, six.binary_type): external_id = external_id.decode("utf-8") - parent = client.project_path(project_id) - tenant = {"external_id": external_id} + parent = f"projects/{project_id}" + tenant = talent.Tenant(external_id=external_id) - response = client.create_tenant(parent, tenant) + response = client.create_tenant(parent=parent, tenant=tenant) print("Created Tenant") - print("Name: {}".format(response.name)) - print("External ID: {}".format(response.external_id)) + print(f"Name: {response.name}") + print(f"External ID: {response.external_id}") return response.name diff --git a/talent/job_search_custom_ranking_search.py b/talent/job_search_custom_ranking_search.py index 1b33aab36216..015291e48372 100644 --- a/talent/job_search_custom_ranking_search.py +++ b/talent/job_search_custom_ranking_search.py @@ -15,7 +15,6 @@ # [START job_search_custom_ranking_search] from google.cloud import talent -from google.cloud.talent import enums import six @@ -31,12 +30,16 @@ def search_jobs(project_id, tenant_id): project_id = project_id.decode("utf-8") if isinstance(tenant_id, six.binary_type): tenant_id = tenant_id.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" domain = "www.example.com" session_id = "Hashed session identifier" user_id = "Hashed user identifier" - request_metadata = {"domain": domain, "session_id": session_id, "user_id": user_id} - importance_level = enums.SearchJobsRequest.CustomRankingInfo.ImportanceLevel.EXTREME + request_metadata = talent.RequestMetadata( + domain=domain, + session_id=session_id, + user_id=user_id + ) + importance_level = talent.SearchJobsRequest.CustomRankingInfo.ImportanceLevel.EXTREME ranking_expression = "(someFieldLong + 25) * 0.25" custom_ranking_info = { "importance_level": importance_level, @@ -46,18 +49,19 @@ def search_jobs(project_id, tenant_id): # Iterate over all results results = [] - for response_item in client.search_jobs( - parent, - request_metadata, + request = talent.SearchJobsRequest( + parent=parent, + request_metadata=request_metadata, custom_ranking_info=custom_ranking_info, - order_by=order_by, - ): - print("Job summary: {}".format(response_item.job_summary)) - print("Job title snippet: {}".format(response_item.job_title_snippet)) + order_by=order_by + ) + for response_item in client.search_jobs(request=request): + print(f"Job summary: {response_item.job_summary}") + print(f"Job title snippet: {response_item.job_title_snippet}") job = response_item.job results.append(job.name) - print("Job name: {}".format(job.name)) - print("Job title: {}".format(job.title)) + print(f"Job name: {job.name}") + print(f"Job title: {job.title}") return results diff --git a/talent/job_search_delete_company.py b/talent/job_search_delete_company.py index 1eb1ed19355d..98174db5e713 100644 --- a/talent/job_search_delete_company.py +++ b/talent/job_search_delete_company.py @@ -35,7 +35,7 @@ def delete_company(project_id, tenant_id, company_id): company_id = company_id.decode("utf-8") name = client.company_path(project_id, tenant_id, company_id) - client.delete_company(name) + client.delete_company(name=name) print("Deleted company") diff --git a/talent/job_search_delete_job.py b/talent/job_search_delete_job.py index f6dd0cf38e50..ba165590bf82 100644 --- a/talent/job_search_delete_job.py +++ b/talent/job_search_delete_job.py @@ -35,7 +35,7 @@ def delete_job(project_id, tenant_id, job_id): job_id = job_id.decode("utf-8") name = client.job_path(project_id, tenant_id, job_id) - client.delete_job(name) + client.delete_job(name=name) print("Deleted job.") diff --git a/talent/job_search_delete_tenant.py b/talent/job_search_delete_tenant.py index 9d95498bd44d..5db49c1cce7d 100644 --- a/talent/job_search_delete_tenant.py +++ b/talent/job_search_delete_tenant.py @@ -32,7 +32,7 @@ def delete_tenant(project_id, tenant_id): tenant_id = tenant_id.decode("utf-8") name = client.tenant_path(project_id, tenant_id) - client.delete_tenant(name) + client.delete_tenant(name=name) print("Deleted Tenant.") diff --git a/talent/job_search_get_company.py b/talent/job_search_get_company.py index ceac6e899002..f597da899394 100644 --- a/talent/job_search_get_company.py +++ b/talent/job_search_get_company.py @@ -35,9 +35,9 @@ def get_company(project_id, tenant_id, company_id): company_id = company_id.decode("utf-8") name = client.company_path(project_id, tenant_id, company_id) - response = client.get_company(name) - print("Company name: {}".format(response.name)) - print("Display name: {}".format(response.display_name)) + response = client.get_company(name=name) + print(f"Company name: {response.name}") + print(f"Display name: {response.display_name}") # [END job_search_get_company] diff --git a/talent/job_search_get_job.py b/talent/job_search_get_job.py index f311202bcecf..cef60889eebb 100644 --- a/talent/job_search_get_job.py +++ b/talent/job_search_get_job.py @@ -35,18 +35,18 @@ def get_job(project_id, tenant_id, job_id): job_id = job_id.decode("utf-8") name = client.job_path(project_id, tenant_id, job_id) - response = client.get_job(name) - print("Job name: {}".format(response.name)) - print("Requisition ID: {}".format(response.requisition_id)) - print("Title: {}".format(response.title)) - print("Description: {}".format(response.description)) - print("Posting language: {}".format(response.language_code)) + response = client.get_job(name=name) + print(f"Job name: {response.name}") + print(f"Requisition ID: {response.requisition_id}") + print(f"Title: {response.title}") + print(f"Description: {response.description}") + print(f"Posting language: {response.language_code}") for address in response.addresses: - print("Address: {}".format(address)) + print(f"Address: {address}") for email in response.application_info.emails: - print("Email: {}".format(email)) + print(f"Email: {email}") for website_uri in response.application_info.uris: - print("Website: {}".format(website_uri)) + print(f"Website: {website_uri}") # [END job_search_get_job] diff --git a/talent/job_search_get_tenant.py b/talent/job_search_get_tenant.py index 484c44d6f035..84f8d7001063 100644 --- a/talent/job_search_get_tenant.py +++ b/talent/job_search_get_tenant.py @@ -33,8 +33,8 @@ def get_tenant(project_id, tenant_id): name = client.tenant_path(project_id, tenant_id) response = client.get_tenant(name) - print("Name: {}".format(response.name)) - print("External ID: {}".format(response.external_id)) + print(f"Name: {response.name}") + print(f"External ID: {response.external_id}") # [END job_search_get_tenant] diff --git a/talent/job_search_histogram_search.py b/talent/job_search_histogram_search.py index f238e6a620c9..73bbc974f18d 100644 --- a/talent/job_search_histogram_search.py +++ b/talent/job_search_histogram_search.py @@ -40,7 +40,7 @@ def search_jobs(project_id, tenant_id, query): tenant_id = tenant_id.decode("utf-8") if isinstance(query, six.binary_type): query = query.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" domain = "www.example.com" session_id = "Hashed session identifier" user_id = "Hashed user identifier" @@ -50,15 +50,18 @@ def search_jobs(project_id, tenant_id, query): # Iterate over all results results = [] - for response_item in client.search_jobs( - parent, request_metadata, histogram_queries=histogram_queries - ): - print("Job summary: {}".format(response_item.job_summary)) - print("Job title snippet: {}".format(response_item.job_title_snippet)) + request = talent.SearchJobsRequest( + parent=parent, + request_metadata=request_metadata, + histogram_queries=histogram_queries, + ) + for response_item in client.search_jobs(request=request): + print("Job summary: {response_item.job_summary}") + print("Job title snippet: {response_item.job_title_snippet}") job = response_item.job results.append(job) - print("Job name: {}".format(job.name)) - print("Job title: {}".format(job.title)) + print("Job name: {job.name}") + print("Job title: {job.title}") return results diff --git a/talent/job_search_list_companies.py b/talent/job_search_list_companies.py index bdef589c150a..4cad5a4d1750 100644 --- a/talent/job_search_list_companies.py +++ b/talent/job_search_list_companies.py @@ -30,15 +30,15 @@ def list_companies(project_id, tenant_id): project_id = project_id.decode("utf-8") if isinstance(tenant_id, six.binary_type): tenant_id = tenant_id.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" # Iterate over all results results = [] - for company in client.list_companies(parent): + for company in client.list_companies(parent=parent): results.append(company.name) - print("Company Name: {}".format(company.name)) - print("Display Name: {}".format(company.display_name)) - print("External ID: {}".format(company.external_id)) + print(f"Company Name: {company.name}") + print(f"Display Name: {company.display_name}") + print(f"External ID: {company.external_id}") return results diff --git a/talent/job_search_list_jobs.py b/talent/job_search_list_jobs.py index f31884dcd920..fd164bf7460f 100644 --- a/talent/job_search_list_jobs.py +++ b/talent/job_search_list_jobs.py @@ -33,16 +33,16 @@ def list_jobs(project_id, tenant_id, filter_): tenant_id = tenant_id.decode("utf-8") if isinstance(filter_, six.binary_type): filter_ = filter_.decode("utf-8") - parent = client.tenant_path(project_id, tenant_id) + parent = f"projects/{project_id}/tenants/{tenant_id}" # Iterate over all results results = [] - for job in client.list_jobs(parent, filter_): + for job in client.list_jobs(parent=parent, filter=filter_): results.append(job.name) - print("Job name: {}".format(job.name)) - print("Job requisition ID: {}".format(job.requisition_id)) - print("Job title: {}".format(job.title)) - print("Job description: {}".format(job.description)) + print("Job name: {job.name}") + print("Job requisition ID: {job.requisition_id}") + print("Job title: {job.title}") + print("Job description: {job.description}") return results diff --git a/talent/job_search_list_tenants.py b/talent/job_search_list_tenants.py index 2045bccac5e6..11fe45503e03 100644 --- a/talent/job_search_list_tenants.py +++ b/talent/job_search_list_tenants.py @@ -27,12 +27,12 @@ def list_tenants(project_id): if isinstance(project_id, six.binary_type): project_id = project_id.decode("utf-8") - parent = client.project_path(project_id) + parent = "projects/{project_id}" # Iterate over all results - for response_item in client.list_tenants(parent): - print("Tenant Name: {}".format(response_item.name)) - print("External ID: {}".format(response_item.external_id)) + for response_item in client.list_tenants(parent=parent): + print(f"Tenant Name: {response_item.name}") + print(f"External ID: {response_item.external_id}") # [END job_search_list_tenants] From 7d3ab015c7a700c503cdf570995166503a70ba6b Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Thu, 24 Sep 2020 23:45:38 +0000 Subject: [PATCH 10/57] test: fix samples --- talent/job_search_create_job.py | 2 +- talent/job_search_get_tenant.py | 2 +- talent/job_search_list_tenants.py | 2 +- talent/job_search_list_tenants_test.py | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/talent/job_search_create_job.py b/talent/job_search_create_job.py index d48c962cc4ea..0252a3e0154f 100644 --- a/talent/job_search_create_job.py +++ b/talent/job_search_create_job.py @@ -63,7 +63,7 @@ def create_job( "language_code": "en-US", } - response = client.create_job(parent, job) + response = client.create_job(parent=parent, job=job) print("Created job: {}".format(response.name)) return response.name diff --git a/talent/job_search_get_tenant.py b/talent/job_search_get_tenant.py index 84f8d7001063..1799c556a69a 100644 --- a/talent/job_search_get_tenant.py +++ b/talent/job_search_get_tenant.py @@ -32,7 +32,7 @@ def get_tenant(project_id, tenant_id): tenant_id = tenant_id.decode("utf-8") name = client.tenant_path(project_id, tenant_id) - response = client.get_tenant(name) + response = client.get_tenant(name=name) print(f"Name: {response.name}") print(f"External ID: {response.external_id}") diff --git a/talent/job_search_list_tenants.py b/talent/job_search_list_tenants.py index 11fe45503e03..652398552bf1 100644 --- a/talent/job_search_list_tenants.py +++ b/talent/job_search_list_tenants.py @@ -27,7 +27,7 @@ def list_tenants(project_id): if isinstance(project_id, six.binary_type): project_id = project_id.decode("utf-8") - parent = "projects/{project_id}" + parent = f"projects/{project_id}" # Iterate over all results for response_item in client.list_tenants(parent=parent): diff --git a/talent/job_search_list_tenants_test.py b/talent/job_search_list_tenants_test.py index 03f2fce7d675..b12f26054119 100644 --- a/talent/job_search_list_tenants_test.py +++ b/talent/job_search_list_tenants_test.py @@ -27,13 +27,13 @@ def test_tenant(): client = talent.TenantServiceClient() external_id = f'test_tenant_{uuid.uuid4().hex}' - parent = client.project_path(PROJECT_ID) + parent = f"projects/{PROJECT_ID}" tenant = {"external_id": external_id} - resp = client.create_tenant(parent, tenant) + resp = client.create_tenant(parent=parent, tenant=tenant) yield resp - client.delete_tenant(resp.name) + client.delete_tenant(name=resp.name) def test_list_tenants(capsys, test_tenant): From a20ccd81ed877e604c86251195c0beddcd55fe46 Mon Sep 17 00:00:00 2001 From: Bu Sun Kim Date: Thu, 24 Sep 2020 23:52:57 +0000 Subject: [PATCH 11/57] sample: fix parent path --- talent/job_search_commute_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/job_search_commute_search.py b/talent/job_search_commute_search.py index 037bbd0845be..0b7684416c9c 100644 --- a/talent/job_search_commute_search.py +++ b/talent/job_search_commute_search.py @@ -30,7 +30,7 @@ def search_jobs(project_id, tenant_id): project_id = project_id.decode("utf-8") if isinstance(tenant_id, six.binary_type): tenant_id = tenant_id.decode("utf-8") - parent = f"projects/{project_id}/tenants/{tenant_id}/" + parent = f"projects/{project_id}/tenants/{tenant_id}" domain = "www.example.com" session_id = "Hashed session identifier" user_id = "Hashed user identifier" From 3b5afeecef57b59da079f00b3582bdbb4c4d82ad 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 12/57] feat: add v4 (#29) --- talent/job_search_autocomplete_job_title.py | 2 +- talent/job_search_commute_search.py | 2 +- talent/job_search_custom_ranking_search.py | 2 +- talent/job_search_histogram_search.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/talent/job_search_autocomplete_job_title.py b/talent/job_search_autocomplete_job_title.py index e9f5286873ad..782517c15746 100644 --- a/talent/job_search_autocomplete_job_title.py +++ b/talent/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/talent/job_search_commute_search.py b/talent/job_search_commute_search.py index 0b7684416c9c..d38a0ae4be8d 100644 --- a/talent/job_search_commute_search.py +++ b/talent/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/talent/job_search_custom_ranking_search.py b/talent/job_search_custom_ranking_search.py index 015291e48372..6f1addc97a5f 100644 --- a/talent/job_search_custom_ranking_search.py +++ b/talent/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/talent/job_search_histogram_search.py b/talent/job_search_histogram_search.py index 73bbc974f18d..5a6a91454244 100644 --- a/talent/job_search_histogram_search.py +++ b/talent/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 From 62d5fcc786544bd214cdf907d77c56407a6c02c9 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 2 Oct 2020 02:06:22 +0200 Subject: [PATCH 13/57] chore(deps): update dependency google.cloud.talent to v1 (#34) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 9db6aba9c65d..7c4d22836911 100755 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==0.6.1 \ No newline at end of file +google.cloud.talent==1.0.0 \ No newline at end of file From a6bdca40f9b477ab7f4f26b0ce0d216692c0be86 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 2 Oct 2020 17:26:05 +0200 Subject: [PATCH 14/57] chore(deps): update dependency google.cloud.talent to v2 (#39) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 7c4d22836911..41bc20603e38 100755 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==1.0.0 \ No newline at end of file +google.cloud.talent==2.0.0 \ No newline at end of file From 662e92ce57ca43caf81ca34b78adcfafc50184c4 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Wed, 23 Dec 2020 16:16:50 -0800 Subject: [PATCH 15/57] chore: update templates (#58) --- talent/noxfile.py | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index ba55d7ce53ca..bca0522ec4d9 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -17,6 +17,7 @@ import os from pathlib import Path import sys +from typing import Callable, Dict, List, Optional import nox @@ -39,6 +40,10 @@ # You can opt out from the test for specific Python versions. 'ignored_versions': ["2.7"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + 'enforce_type_hints': False, + # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string @@ -64,7 +69,7 @@ TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) -def get_pytest_env_vars(): +def get_pytest_env_vars() -> Dict[str, str]: """Returns a dict for pytest invocation.""" ret = {} @@ -93,7 +98,7 @@ def get_pytest_env_vars(): # -def _determine_local_import_names(start_dir): +def _determine_local_import_names(start_dir: str) -> List[str]: """Determines all import names that should be considered "local". This is used when running the linter to insure that import order is @@ -131,8 +136,11 @@ def _determine_local_import_names(start_dir): @nox.session -def lint(session): - session.install("flake8", "flake8-import-order") +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG['enforce_type_hints']: + session.install("flake8", "flake8-import-order") + else: + session.install("flake8", "flake8-import-order", "flake8-annotations") local_names = _determine_local_import_names(".") args = FLAKE8_COMMON_ARGS + [ @@ -141,8 +149,18 @@ def lint(session): "." ] session.run("flake8", *args) +# +# Black +# +@nox.session +def blacken(session: nox.sessions.Session) -> None: + session.install("black") + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + # # Sample Tests # @@ -151,7 +169,7 @@ def lint(session): PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] -def _session_tests(session, post_install=None): +def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: """Runs py.test for a particular project.""" if os.path.exists("requirements.txt"): session.install("-r", "requirements.txt") @@ -177,7 +195,7 @@ def _session_tests(session, post_install=None): @nox.session(python=ALL_VERSIONS) -def py(session): +def py(session: nox.sessions.Session) -> None: """Runs py.test for a sample using the specified version of Python.""" if session.python in TESTED_VERSIONS: _session_tests(session) @@ -192,7 +210,7 @@ def py(session): # -def _get_repo_root(): +def _get_repo_root() -> Optional[str]: """ Returns the root folder of the project. """ # Get root of this repository. Assume we don't have directories nested deeper than 10 items. p = Path(os.getcwd()) @@ -201,6 +219,11 @@ def _get_repo_root(): break if Path(p / ".git").exists(): return str(p) + # .git is not available in repos cloned via Cloud Build + # setup.py is always in the library's root, so use that instead + # https://github.com/googleapis/synthtool/issues/792 + if Path(p / "setup.py").exists(): + return str(p) p = p.parent raise Exception("Unable to detect repository root.") @@ -210,7 +233,7 @@ def _get_repo_root(): @nox.session @nox.parametrize("path", GENERATED_READMES) -def readmegen(session, path): +def readmegen(session: nox.sessions.Session, path: str) -> None: """(Re-)generates the readme for a sample.""" session.install("jinja2", "pyyaml") dir_ = os.path.dirname(path) From aef3b92a96db3ee576d06b2b90fec79486304d4f Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 5 Mar 2021 03:42:16 +0100 Subject: [PATCH 16/57] chore(deps): update dependency google.cloud.talent to v2.1.0 (#69) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 41bc20603e38..4eb2e4f95734 100755 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.0.0 \ No newline at end of file +google.cloud.talent==2.1.0 \ No newline at end of file From d835d0cdbf93f94ee22a0aaeb201a5338b5b233c Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Tue, 30 Mar 2021 12:33:23 -0700 Subject: [PATCH 17/57] fix: fix retry deadlines (#73) feat: add `from_service_account_info` --- talent/noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index bca0522ec4d9..97bf7da80e39 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -85,7 +85,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] From f15df5f494210df8bb7a650884baa28ffca428a5 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Sun, 9 May 2021 21:08:02 -0400 Subject: [PATCH 18/57] chore: migrate to owl bot (#87) This PR migrates from autosynth to [owl bot](https://github.com/googleapis/repo-automation-bots/tree/master/packages/owl-bot). owl bot will save time for maintainers as it will automatically open PRs when there are updates in [googleapis-gen](https://github.com/googleapis/googleapis-gen/tree/master/google) without requiring maintainers to run `synthtool` to build the client from protos. Additionally, similar to autosynth, PRs will be automatically opened when there are template updates. With owl bot, on every PR, a post-processor image will run so that we won't have to ask contributors to run [blacken](https://github.com/googleapis/python-talent/blob/master/synth.py#L65). --- talent/noxfile.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 97bf7da80e39..956cdf4f9250 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -172,10 +172,16 @@ def blacken(session: nox.sessions.Session) -> None: def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: """Runs py.test for a particular project.""" if os.path.exists("requirements.txt"): - session.install("-r", "requirements.txt") + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") if os.path.exists("requirements-test.txt"): - session.install("-r", "requirements-test.txt") + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") if INSTALL_LIBRARY_FROM_SOURCE: session.install("-e", _get_repo_root()) From e2fce3ad74003cdeacc576f5436aa5bec2e7cf76 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Sat, 22 May 2021 09:18:24 +0000 Subject: [PATCH 19/57] chore: new owl bot post processor docker image (#104) gcr.io/repo-automation-bots/owlbot-python:latest@sha256:3c3a445b3ddc99ccd5d31edc4b4519729635d20693900db32c4f587ed51f7479 --- talent/noxfile.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 956cdf4f9250..5ff9e1db5808 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -50,7 +50,10 @@ # to use your own Cloud project. 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', - + # If you need to use a specific version of pip, + # change pip_version_override to the string representation + # of the version number, for example, "20.2.4" + "pip_version_override": None, # A dictionary you want to inject into your test. Don't put any # secrets here. These values will override predefined values. 'envs': {}, @@ -170,6 +173,9 @@ def blacken(session: nox.sessions.Session) -> None: def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") """Runs py.test for a particular project.""" if os.path.exists("requirements.txt"): if os.path.exists("constraints.txt"): From bc8ad2b918af5f6c0dd04db59c3163bf749d0671 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 16 Jun 2021 15:14:02 +0200 Subject: [PATCH 20/57] chore(deps): update dependency pytest to v6.2.4 (#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [pytest](https://docs.pytest.org/en/latest/) ([source](https://togithub.com/pytest-dev/pytest), [changelog](https://docs.pytest.org/en/stable/changelog.html)) | `==6.0.1` -> `==6.2.4` | [![age](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/compatibility-slim/6.0.1)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/pypi/pytest/6.2.4/confidence-slim/6.0.1)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
pytest-dev/pytest ### [`v6.2.4`](https://togithub.com/pytest-dev/pytest/releases/6.2.4) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.3...6.2.4) # pytest 6.2.4 (2021-05-04) ## Bug Fixes - [#​8539](https://togithub.com/pytest-dev/pytest/issues/8539): Fixed assertion rewriting on Python 3.10. ### [`v6.2.3`](https://togithub.com/pytest-dev/pytest/releases/6.2.3) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.2...6.2.3) # pytest 6.2.3 (2021-04-03) ## Bug Fixes - [#​8414](https://togithub.com/pytest-dev/pytest/issues/8414): pytest used to create directories under `/tmp` with world-readable permissions. This means that any user in the system was able to read information written by tests in temporary directories (such as those created by the `tmp_path`/`tmpdir` fixture). Now the directories are created with private permissions. pytest used silenty use a pre-existing `/tmp/pytest-of-` directory, even if owned by another user. This means another user could pre-create such a directory and gain control of another user's temporary directory. Now such a condition results in an error. ### [`v6.2.2`](https://togithub.com/pytest-dev/pytest/releases/6.2.2) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.1...6.2.2) # pytest 6.2.2 (2021-01-25) ## Bug Fixes - [#​8152](https://togithub.com/pytest-dev/pytest/issues/8152): Fixed "(\)" being shown as a skip reason in the verbose test summary line when the reason is empty. - [#​8249](https://togithub.com/pytest-dev/pytest/issues/8249): Fix the `faulthandler` plugin for occasions when running with `twisted.logger` and using `pytest --capture=no`. ### [`v6.2.1`](https://togithub.com/pytest-dev/pytest/releases/6.2.1) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.2.0...6.2.1) # pytest 6.2.1 (2020-12-15) ## Bug Fixes - [#​7678](https://togithub.com/pytest-dev/pytest/issues/7678): Fixed bug where `ImportPathMismatchError` would be raised for files compiled in the host and loaded later from an UNC mounted path (Windows). - [#​8132](https://togithub.com/pytest-dev/pytest/issues/8132): Fixed regression in `approx`: in 6.2.0 `approx` no longer raises `TypeError` when dealing with non-numeric types, falling back to normal comparison. Before 6.2.0, array types like tf.DeviceArray fell through to the scalar case, and happened to compare correctly to a scalar if they had only one element. After 6.2.0, these types began failing, because they inherited neither from standard Python number hierarchy nor from `numpy.ndarray`. `approx` now converts arguments to `numpy.ndarray` if they expose the array protocol and are not scalars. This treats array-like objects like numpy arrays, regardless of size. ### [`v6.2.0`](https://togithub.com/pytest-dev/pytest/releases/6.2.0) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.1.2...6.2.0) # pytest 6.2.0 (2020-12-12) ## Breaking Changes - [#​7808](https://togithub.com/pytest-dev/pytest/issues/7808): pytest now supports python3.6+ only. ## Deprecations - [#​7469](https://togithub.com/pytest-dev/pytest/issues/7469): Directly constructing/calling the following classes/functions is now deprecated: - `_pytest.cacheprovider.Cache` - `_pytest.cacheprovider.Cache.for_config()` - `_pytest.cacheprovider.Cache.clear_cache()` - `_pytest.cacheprovider.Cache.cache_dir_from_config()` - `_pytest.capture.CaptureFixture` - `_pytest.fixtures.FixtureRequest` - `_pytest.fixtures.SubRequest` - `_pytest.logging.LogCaptureFixture` - `_pytest.pytester.Pytester` - `_pytest.pytester.Testdir` - `_pytest.recwarn.WarningsRecorder` - `_pytest.recwarn.WarningsChecker` - `_pytest.tmpdir.TempPathFactory` - `_pytest.tmpdir.TempdirFactory` These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0. - [#​7530](https://togithub.com/pytest-dev/pytest/issues/7530): The `--strict` command-line option has been deprecated, use `--strict-markers` instead. We have plans to maybe in the future to reintroduce `--strict` and make it an encompassing flag for all strictness related options (`--strict-markers` and `--strict-config` at the moment, more might be introduced in the future). - [#​7988](https://togithub.com/pytest-dev/pytest/issues/7988): The `@pytest.yield_fixture` decorator/function is now deprecated. Use pytest.fixture instead. `yield_fixture` has been an alias for `fixture` for a very long time, so can be search/replaced safely. ## Features - [#​5299](https://togithub.com/pytest-dev/pytest/issues/5299): pytest now warns about unraisable exceptions and unhandled thread exceptions that occur in tests on Python>=3.8. See unraisable for more information. - [#​7425](https://togithub.com/pytest-dev/pytest/issues/7425): New pytester fixture, which is identical to testdir but its methods return pathlib.Path when appropriate instead of `py.path.local`. This is part of the movement to use pathlib.Path objects internally, in order to remove the dependency to `py` in the future. Internally, the old Testdir <\_pytest.pytester.Testdir> is now a thin wrapper around Pytester <\_pytest.pytester.Pytester>, preserving the old interface. - [#​7695](https://togithub.com/pytest-dev/pytest/issues/7695): A new hook was added, pytest_markeval_namespace which should return a dictionary. This dictionary will be used to augment the "global" variables available to evaluate skipif/xfail/xpass markers. Pseudo example `conftest.py`: ```{.sourceCode .python} def pytest_markeval_namespace(): return {"color": "red"} ``` `test_func.py`: ```{.sourceCode .python} @​pytest.mark.skipif("color == 'blue'", reason="Color is not red") def test_func(): assert False ``` - [#​8006](https://togithub.com/pytest-dev/pytest/issues/8006): It is now possible to construct a ~pytest.MonkeyPatch object directly as `pytest.MonkeyPatch()`, in cases when the monkeypatch fixture cannot be used. Previously some users imported it from the private \_pytest.monkeypatch.MonkeyPatch namespace. Additionally, MonkeyPatch.context \ is now a classmethod, and can be used as `with MonkeyPatch.context() as mp: ...`. This is the recommended way to use `MonkeyPatch` directly, since unlike the `monkeypatch` fixture, an instance created directly is not `undo()`-ed automatically. ## Improvements - [#​1265](https://togithub.com/pytest-dev/pytest/issues/1265): Added an `__str__` implementation to the ~pytest.pytester.LineMatcher class which is returned from `pytester.run_pytest().stdout` and similar. It returns the entire output, like the existing `str()` method. - [#​2044](https://togithub.com/pytest-dev/pytest/issues/2044): Verbose mode now shows the reason that a test was skipped in the test's terminal line after the "SKIPPED", "XFAIL" or "XPASS". - [#​7469](https://togithub.com/pytest-dev/pytest/issues/7469) The types of builtin pytest fixtures are now exported so they may be used in type annotations of test functions. The newly-exported types are: - `pytest.FixtureRequest` for the request fixture. - `pytest.Cache` for the cache fixture. - `pytest.CaptureFixture[str]` for the capfd and capsys fixtures. - `pytest.CaptureFixture[bytes]` for the capfdbinary and capsysbinary fixtures. - `pytest.LogCaptureFixture` for the caplog fixture. - `pytest.Pytester` for the pytester fixture. - `pytest.Testdir` for the testdir fixture. - `pytest.TempdirFactory` for the tmpdir_factory fixture. - `pytest.TempPathFactory` for the tmp_path_factory fixture. - `pytest.MonkeyPatch` for the monkeypatch fixture. - `pytest.WarningsRecorder` for the recwarn fixture. Constructing them is not supported (except for MonkeyPatch); they are only meant for use in type annotations. Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0. Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy. - [#​7527](https://togithub.com/pytest-dev/pytest/issues/7527): When a comparison between namedtuple \ instances of the same type fails, pytest now shows the differing field names (possibly nested) instead of their indexes. - [#​7615](https://togithub.com/pytest-dev/pytest/issues/7615): Node.warn <\_pytest.nodes.Node.warn> now permits any subclass of Warning, not just PytestWarning \. - [#​7701](https://togithub.com/pytest-dev/pytest/issues/7701): Improved reporting when using `--collected-only`. It will now show the number of collected tests in the summary stats. - [#​7710](https://togithub.com/pytest-dev/pytest/issues/7710): Use strict equality comparison for non-numeric types in pytest.approx instead of raising TypeError. This was the undocumented behavior before 3.7, but is now officially a supported feature. - [#​7938](https://togithub.com/pytest-dev/pytest/issues/7938): New `--sw-skip` argument which is a shorthand for `--stepwise-skip`. - [#​8023](https://togithub.com/pytest-dev/pytest/issues/8023): Added `'node_modules'` to default value for norecursedirs. - [#​8032](https://togithub.com/pytest-dev/pytest/issues/8032): doClassCleanups \ (introduced in unittest in Python and 3.8) is now called appropriately. ## Bug Fixes - [#​4824](https://togithub.com/pytest-dev/pytest/issues/4824): Fixed quadratic behavior and improved performance of collection of items using autouse fixtures and xunit fixtures. - [#​7758](https://togithub.com/pytest-dev/pytest/issues/7758): Fixed an issue where some files in packages are getting lost from `--lf` even though they contain tests that failed. Regressed in pytest 5.4.0. - [#​7911](https://togithub.com/pytest-dev/pytest/issues/7911): Directories created by by tmp_path and tmpdir are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites. - [#​7913](https://togithub.com/pytest-dev/pytest/issues/7913): Fixed a crash or hang in pytester.spawn <\_pytest.pytester.Pytester.spawn> when the readline module is involved. - [#​7951](https://togithub.com/pytest-dev/pytest/issues/7951): Fixed handling of recursive symlinks when collecting tests. - [#​7981](https://togithub.com/pytest-dev/pytest/issues/7981): Fixed symlinked directories not being followed during collection. Regressed in pytest 6.1.0. - [#​8016](https://togithub.com/pytest-dev/pytest/issues/8016): Fixed only one doctest being collected when using `pytest --doctest-modules path/to/an/__init__.py`. ## Improved Documentation - [#​7429](https://togithub.com/pytest-dev/pytest/issues/7429): Add more information and use cases about skipping doctests. - [#​7780](https://togithub.com/pytest-dev/pytest/issues/7780): Classes which should not be inherited from are now marked `final class` in the API reference. - [#​7872](https://togithub.com/pytest-dev/pytest/issues/7872): `_pytest.config.argparsing.Parser.addini()` accepts explicit `None` and `"string"`. - [#​7878](https://togithub.com/pytest-dev/pytest/issues/7878): In pull request section, ask to commit after editing changelog and authors file. ## Trivial/Internal Changes - [#​7802](https://togithub.com/pytest-dev/pytest/issues/7802): The `attrs` dependency requirement is now >=19.2.0 instead of >=17.4.0. - [#​8014](https://togithub.com/pytest-dev/pytest/issues/8014): .pyc files created by pytest's assertion rewriting now conform to the newer PEP-552 format on Python>=3.7. (These files are internal and only interpreted by pytest itself.) ### [`v6.1.2`](https://togithub.com/pytest-dev/pytest/releases/6.1.2) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.1.1...6.1.2) # pytest 6.1.2 (2020-10-28) ## Bug Fixes - [#​7758](https://togithub.com/pytest-dev/pytest/issues/7758): Fixed an issue where some files in packages are getting lost from `--lf` even though they contain tests that failed. Regressed in pytest 5.4.0. - [#​7911](https://togithub.com/pytest-dev/pytest/issues/7911): Directories created by tmpdir are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites. ## Improved Documentation - [#​7815](https://togithub.com/pytest-dev/pytest/issues/7815): Improve deprecation warning message for `pytest._fillfuncargs()`. ### [`v6.1.1`](https://togithub.com/pytest-dev/pytest/releases/6.1.1) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.1.0...6.1.1) # pytest 6.1.1 (2020-10-03) ## Bug Fixes - [#​7807](https://togithub.com/pytest-dev/pytest/issues/7807): Fixed regression in pytest 6.1.0 causing incorrect rootdir to be determined in some non-trivial cases where parent directories have config files as well. - [#​7814](https://togithub.com/pytest-dev/pytest/issues/7814): Fixed crash in header reporting when testpaths is used and contains absolute paths (regression in 6.1.0). ### [`v6.1.0`](https://togithub.com/pytest-dev/pytest/releases/6.1.0) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.0.2...6.1.0) # pytest 6.1.0 (2020-09-26) ## Breaking Changes - [#​5585](https://togithub.com/pytest-dev/pytest/issues/5585): As per our policy, the following features which have been deprecated in the 5.X series are now removed: - The `funcargnames` read-only property of `FixtureRequest`, `Metafunc`, and `Function` classes. Use `fixturenames` attribute. - `@pytest.fixture` no longer supports positional arguments, pass all arguments by keyword instead. - Direct construction of `Node` subclasses now raise an error, use `from_parent` instead. - The default value for `junit_family` has changed to `xunit2`. If you require the old format, add `junit_family=xunit1` to your configuration file. - The `TerminalReporter` no longer has a `writer` attribute. Plugin authors may use the public functions of the `TerminalReporter` instead of accessing the `TerminalWriter` object directly. - The `--result-log` option has been removed. Users are recommended to use the [pytest-reportlog](https://togithub.com/pytest-dev/pytest-reportlog) plugin instead. For more information consult [Deprecations and Removals](https://docs.pytest.org/en/stable/deprecations.html) in the docs. ## Deprecations - [#​6981](https://togithub.com/pytest-dev/pytest/issues/6981): The `pytest.collect` module is deprecated: all its names can be imported from `pytest` directly. - [#​7097](https://togithub.com/pytest-dev/pytest/issues/7097): The `pytest._fillfuncargs` function is deprecated. This function was kept for backward compatibility with an older plugin. It's functionality is not meant to be used directly, but if you must replace it, use function.\_request.\_fillfixtures() instead, though note this is not a public API and may break in the future. - [#​7210](https://togithub.com/pytest-dev/pytest/issues/7210): The special `-k '-expr'` syntax to `-k` is deprecated. Use `-k 'not expr'` instead. The special `-k 'expr:'` syntax to `-k` is deprecated. Please open an issue if you use this and want a replacement. - [#​7255](https://togithub.com/pytest-dev/pytest/issues/7255): The pytest_warning_captured <\_pytest.hookspec.pytest_warning_captured> hook is deprecated in favor of pytest_warning_recorded <\_pytest.hookspec.pytest_warning_recorded>, and will be removed in a future version. - [#​7648](https://togithub.com/pytest-dev/pytest/issues/7648): The `gethookproxy()` and `isinitpath()` methods of `FSCollector` and `Package` are deprecated; use `self.session.gethookproxy()` and `self.session.isinitpath()` instead. This should work on all pytest versions. ## Features - [#​7667](https://togithub.com/pytest-dev/pytest/issues/7667): New `--durations-min` command-line flag controls the minimal duration for inclusion in the slowest list of tests shown by `--durations`. Previously this was hard-coded to `0.005s`. ## Improvements - [#​6681](https://togithub.com/pytest-dev/pytest/issues/6681): Internal pytest warnings issued during the early stages of initialization are now properly handled and can filtered through filterwarnings or `--pythonwarnings/-W`. This also fixes a number of long standing issues: [#​2891](https://togithub.com/pytest-dev/pytest/issues/2891), [#​7620](https://togithub.com/pytest-dev/pytest/issues/7620), [#​7426](https://togithub.com/pytest-dev/pytest/issues/7426). - [#​7572](https://togithub.com/pytest-dev/pytest/issues/7572): When a plugin listed in `required_plugins` is missing or an unknown config key is used with `--strict-config`, a simple error message is now shown instead of a stacktrace. - [#​7685](https://togithub.com/pytest-dev/pytest/issues/7685): Added two new attributes rootpath <\_pytest.config.Config.rootpath> and inipath <\_pytest.config.Config.inipath> to Config <\_pytest.config.Config>. These attributes are pathlib.Path versions of the existing rootdir <\_pytest.config.Config.rootdir> and inifile <\_pytest.config.Config.inifile> attributes, and should be preferred over them when possible. - [#​7780](https://togithub.com/pytest-dev/pytest/issues/7780): Public classes which are not designed to be inherited from are now marked [@​final](https://docs.python.org/3/library/typing.html#typing.final). Code which inherits from these classes will trigger a type-checking (e.g. mypy) error, but will still work in runtime. Currently the `final` designation does not appear in the API Reference but hopefully will in the future. ## Bug Fixes - [#​1953](https://togithub.com/pytest-dev/pytest/issues/1953): Fixed error when overwriting a parametrized fixture, while also reusing the super fixture value. ```{.sourceCode .python} ``` ### conftest.py import pytest @​pytest.fixture(params=[1, 2]) def foo(request): return request.param ### test_foo.py import pytest @​pytest.fixture def foo(foo): return foo * 2 ``` - [#​4984](https://togithub.com/pytest-dev/pytest/issues/4984): Fixed an internal error crash with `IndexError: list index out of range` when collecting a module which starts with a decorated function, the decorator raises, and assertion rewriting is enabled. - [#​7591](https://togithub.com/pytest-dev/pytest/issues/7591): pylint shouldn't complain anymore about unimplemented abstract methods when inheriting from File \. - [#​7628](https://togithub.com/pytest-dev/pytest/issues/7628): Fixed test collection when a full path without a drive letter was passed to pytest on Windows (for example `\projects\tests\test.py` instead of `c:\projects\tests\pytest.py`). - [#​7638](https://togithub.com/pytest-dev/pytest/issues/7638): Fix handling of command-line options that appear as paths but trigger an OS-level syntax error on Windows, such as the options used internally by `pytest-xdist`. - [#​7742](https://togithub.com/pytest-dev/pytest/issues/7742): Fixed INTERNALERROR when accessing locals / globals with faulty `exec`. ## Improved Documentation - [#​1477](https://togithub.com/pytest-dev/pytest/issues/1477): Removed faq.rst and its reference in contents.rst. ## Trivial/Internal Changes - [#​7536](https://togithub.com/pytest-dev/pytest/issues/7536): The internal `junitxml` plugin has rewritten to use `xml.etree.ElementTree`. The order of attributes in XML elements might differ. Some unneeded escaping is no longer performed. - [#​7587](https://togithub.com/pytest-dev/pytest/issues/7587): The dependency on the `more-itertools` package has been removed. - [#​7631](https://togithub.com/pytest-dev/pytest/issues/7631): The result type of capfd.readouterr() <\_pytest.capture.CaptureFixture.readouterr> (and similar) is no longer a namedtuple, but should behave like one in all respects. This was done for technical reasons. - [#​7671](https://togithub.com/pytest-dev/pytest/issues/7671): When collecting tests, pytest finds test classes and functions by examining the attributes of python objects (modules, classes and instances). To speed up this process, pytest now ignores builtin attributes (like `__class__`, `__delattr__` and `__new__`) without consulting the python_classes and python_functions configuration options and without passing them to plugins using the pytest_pycollect_makeitem <\_pytest.hookspec.pytest_pycollect_makeitem> hook. ### [`v6.0.2`](https://togithub.com/pytest-dev/pytest/releases/6.0.2) [Compare Source](https://togithub.com/pytest-dev/pytest/compare/6.0.1...6.0.2) # pytest 6.0.2 (2020-09-04) ## Bug Fixes - [#​7148](https://togithub.com/pytest-dev/pytest/issues/7148): Fixed `--log-cli` potentially causing unrelated `print` output to be swallowed. - [#​7672](https://togithub.com/pytest-dev/pytest/issues/7672): Fixed log-capturing level restored incorrectly if `caplog.set_level` is called more than once. - [#​7686](https://togithub.com/pytest-dev/pytest/issues/7686): Fixed NotSetType.token being used as the parameter ID when the parametrization list is empty. Regressed in pytest 6.0.0. - [#​7707](https://togithub.com/pytest-dev/pytest/issues/7707): Fix internal error when handling some exceptions that contain multiple lines or the style uses multiple lines (`--tb=line` for example).
--- ### Configuration 📅 **Schedule**: At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻️ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/python-talent). --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 7e460c8c866e..95ea1e6a02b0 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==6.0.1 +pytest==6.2.4 From 1b724029134bbe903fb5e848618c0597a8b4f492 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 22 Jul 2021 13:48:16 +0000 Subject: [PATCH 21/57] feat: add Samples section to CONTRIBUTING.rst (#134) Source-Link: https://github.com/googleapis/synthtool/commit/52e4e46eff2a0b70e3ff5506a02929d089d077d4 Post-Processor: gcr.io/repo-automation-bots/owlbot-python:latest@sha256:6186535cbdbf6b9fe61f00294929221d060634dae4a0795c1cefdbc995b2d605 --- talent/noxfile.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 5ff9e1db5808..6a8ccdae22c9 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -28,8 +28,9 @@ # WARNING - WARNING - WARNING - WARNING - WARNING # WARNING - WARNING - WARNING - WARNING - WARNING -# Copy `noxfile_config.py` to your directory and modify it instead. +BLACK_VERSION = "black==19.10b0" +# Copy `noxfile_config.py` to your directory and modify it instead. # `TEST_CONFIG` dict is a configuration hook that allows users to # modify the test configurations. The values here should be in sync @@ -159,7 +160,7 @@ def lint(session: nox.sessions.Session) -> None: @nox.session def blacken(session: nox.sessions.Session) -> None: - session.install("black") + session.install(BLACK_VERSION) python_files = [path for path in os.listdir(".") if path.endswith(".py")] session.run("black", *python_files) From 9d74ba9e4cce69bb5c3c3da73d3e22248133f8ff Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 28 Jul 2021 12:26:35 -0400 Subject: [PATCH 22/57] chore: 'requirements.txt' is not a script (#131) --- talent/requirements.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 talent/requirements.txt diff --git a/talent/requirements.txt b/talent/requirements.txt old mode 100755 new mode 100644 From 8669806482a8aadb840fb6f96b37718e2a5d26a3 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 28 Jul 2021 18:59:19 +0200 Subject: [PATCH 23/57] chore(deps): update dependency google.cloud.talent to v2.2.0 (#117) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 4eb2e4f95734..797b486f155b 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.1.0 \ No newline at end of file +google.cloud.talent==2.2.0 \ No newline at end of file From 2604be55e5fbe7de1eba7f4e9fbe0d7d3d8bd697 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Thu, 29 Jul 2021 13:07:38 +0200 Subject: [PATCH 24/57] chore(deps): update dependency google.cloud.talent to v2.2.1 (#141) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 797b486f155b..4b1bcaa5801d 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.2.0 \ No newline at end of file +google.cloud.talent==2.2.1 \ No newline at end of file From fa03a8a6de6c66ad907401509a6c0303978c291e Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 10 Aug 2021 16:58:24 +0200 Subject: [PATCH 25/57] chore(deps): update dependency google.cloud.talent to v2.3.0 (#144) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 4b1bcaa5801d..4a509405d0a7 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.2.1 \ No newline at end of file +google.cloud.talent==2.3.0 \ No newline at end of file From d84d3368d05eb167fbdb67fd816b9eff2b49f515 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 11 Aug 2021 16:32:39 +0000 Subject: [PATCH 26/57] chore: fix INSTALL_LIBRARY_FROM_SOURCE in noxfile.py (#145) Source-Link: https://github.com/googleapis/synthtool/commit/6252f2cd074c38f37b44abe5e96d128733eb1b61 Post-Processor: gcr.io/repo-automation-bots/owlbot-python:latest@sha256:50e35228649c47b6ca82aa0be3ff9eb2afce51c82b66c4a03fe4afeb5ff6c0fc --- talent/noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 6a8ccdae22c9..125bb619cc49 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -96,7 +96,7 @@ def get_pytest_env_vars() -> Dict[str, str]: TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) -INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ("True", "true") # # Style Checks # From a4fa5822f95d486c54f981e013edb1d344838419 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 13 Aug 2021 11:56:11 -0400 Subject: [PATCH 27/57] chore: drop mention of Python 2.7 from templates (#147) Source-Link: https://github.com/googleapis/synthtool/commit/facee4cc1ea096cd8bcc008bb85929daa7c414c0 Post-Processor: gcr.io/repo-automation-bots/owlbot-python:latest@sha256:9743664022bd63a8084be67f144898314c7ca12f0a03e422ac17c733c129d803 Co-authored-by: Owl Bot --- talent/noxfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 125bb619cc49..e73436a15626 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -39,7 +39,7 @@ TEST_CONFIG = { # You can opt out from the test for specific Python versions. - 'ignored_versions': ["2.7"], + 'ignored_versions': [], # Old samples are opted out of enforcing Python type hints # All new samples should feature them @@ -88,8 +88,8 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. -# All versions used to tested samples. -ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] +# All versions used to test samples. +ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] From fd3fa1ef7616e55ceea27c6405e0ed94c844d75c Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 17 Sep 2021 15:36:56 +0000 Subject: [PATCH 28/57] chore: blacken samples noxfile template (#160) --- talent/noxfile.py | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index e73436a15626..b008613f03ff 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -39,17 +39,15 @@ TEST_CONFIG = { # You can opt out from the test for specific Python versions. - 'ignored_versions': [], - + "ignored_versions": [], # Old samples are opted out of enforcing Python type hints # All new samples should feature them - 'enforce_type_hints': False, - + "enforce_type_hints": False, # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string # to use your own Cloud project. - 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', # If you need to use a specific version of pip, # change pip_version_override to the string representation @@ -57,13 +55,13 @@ "pip_version_override": None, # A dictionary you want to inject into your test. Don't put any # secrets here. These values will override predefined values. - 'envs': {}, + "envs": {}, } try: # Ensure we can import noxfile_config in the project's directory. - sys.path.append('.') + sys.path.append(".") from noxfile_config import TEST_CONFIG_OVERRIDE except ImportError as e: print("No user noxfile_config found: detail: {}".format(e)) @@ -78,12 +76,12 @@ def get_pytest_env_vars() -> Dict[str, str]: ret = {} # Override the GCLOUD_PROJECT and the alias. - env_key = TEST_CONFIG['gcloud_project_env'] + env_key = TEST_CONFIG["gcloud_project_env"] # This should error out if not set. - ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] # Apply user supplied envs. - ret.update(TEST_CONFIG['envs']) + ret.update(TEST_CONFIG["envs"]) return ret @@ -92,11 +90,14 @@ def get_pytest_env_vars() -> Dict[str, str]: ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] # Any default versions that should be ignored. -IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] +IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) -INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ("True", "true") +INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( + "True", + "true", +) # # Style Checks # @@ -141,7 +142,7 @@ def _determine_local_import_names(start_dir: str) -> List[str]: @nox.session def lint(session: nox.sessions.Session) -> None: - if not TEST_CONFIG['enforce_type_hints']: + if not TEST_CONFIG["enforce_type_hints"]: session.install("flake8", "flake8-import-order") else: session.install("flake8", "flake8-import-order", "flake8-annotations") @@ -150,9 +151,11 @@ def lint(session: nox.sessions.Session) -> None: args = FLAKE8_COMMON_ARGS + [ "--application-import-names", ",".join(local_names), - "." + ".", ] session.run("flake8", *args) + + # # Black # @@ -165,6 +168,7 @@ def blacken(session: nox.sessions.Session) -> None: session.run("black", *python_files) + # # Sample Tests # @@ -173,7 +177,9 @@ def blacken(session: nox.sessions.Session) -> None: PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] -def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: +def _session_tests( + session: nox.sessions.Session, post_install: Callable = None +) -> None: if TEST_CONFIG["pip_version_override"]: pip_version = TEST_CONFIG["pip_version_override"] session.install(f"pip=={pip_version}") @@ -203,7 +209,7 @@ def _session_tests(session: nox.sessions.Session, post_install: Callable = None) # on travis where slow and flaky tests are excluded. # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html success_codes=[0, 5], - env=get_pytest_env_vars() + env=get_pytest_env_vars(), ) @@ -213,9 +219,9 @@ def py(session: nox.sessions.Session) -> None: if session.python in TESTED_VERSIONS: _session_tests(session) else: - session.skip("SKIPPED: {} tests are disabled for this sample.".format( - session.python - )) + session.skip( + "SKIPPED: {} tests are disabled for this sample.".format(session.python) + ) # From 8a5c9413db65cb7057d21636d6950c40f8ec0a05 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Thu, 30 Sep 2021 15:44:38 +0000 Subject: [PATCH 29/57] chore: fail samples nox session if python version is missing (#165) --- talent/noxfile.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/talent/noxfile.py b/talent/noxfile.py index b008613f03ff..1fd8956fbf01 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -98,6 +98,10 @@ def get_pytest_env_vars() -> Dict[str, str]: "True", "true", ) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + # # Style Checks # From 5ffc89895b599c05b8999bd255b442fba6a9e1cf Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 8 Oct 2021 17:16:39 +0000 Subject: [PATCH 30/57] chore(python): Add kokoro configs for python 3.10 samples testing (#170) --- talent/noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 1fd8956fbf01..93a9122cc457 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -87,7 +87,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to test samples. -ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] From 9088d2e3b999e7c3c0b4deaf37d705fcf5f5e248 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 25 Oct 2021 13:18:16 +0200 Subject: [PATCH 31/57] chore(deps): update dependency pytest to v6.2.5 (#156) Co-authored-by: Anthonios Partheniou --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 95ea1e6a02b0..927094516e65 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==6.2.4 +pytest==6.2.5 From 72dbf673c33ad74823bf8bfd989498de31a0f4a2 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 10 Nov 2021 01:09:36 +0100 Subject: [PATCH 32/57] chore(deps): update dependency google.cloud.talent to v2.4.0 (#178) Co-authored-by: Anthonios Partheniou --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 4a509405d0a7..62f5dcdde3b8 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.3.0 \ No newline at end of file +google.cloud.talent==2.4.0 \ No newline at end of file From e1560d3fcb03118527453841784e50f29f9e52e4 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 10 Nov 2021 20:37:32 -0500 Subject: [PATCH 33/57] chore(python): run blacken session for all directories with a noxfile (#180) Source-Link: https://github.com/googleapis/synthtool/commit/bc0de6ee2489da6fb8eafd021a8c58b5cc30c947 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:39ad8c0570e4f5d2d3124a509de4fe975e799e2b97e0f58aed88f8880d5a8b60 Co-authored-by: Owl Bot --- talent/job_search_batch_update_jobs.py | 4 ++-- talent/job_search_commute_search.py | 8 ++------ talent/job_search_create_job_custom_attributes.py | 2 +- talent/job_search_custom_ranking_search.py | 10 +++++----- talent/job_search_list_tenants_test.py | 2 +- talent/noxfile_config.py | 8 +++----- 6 files changed, 14 insertions(+), 20 deletions(-) diff --git a/talent/job_search_batch_update_jobs.py b/talent/job_search_batch_update_jobs.py index 0aa576c49a15..cd5713cffdb5 100644 --- a/talent/job_search_batch_update_jobs.py +++ b/talent/job_search_batch_update_jobs.py @@ -115,7 +115,7 @@ def batch_update_jobs( description=description_one, application_info=application_info, addresses=addresses, - language_code=language_code_one + language_code=language_code_one, ) uris_2 = [job_application_url_two] @@ -129,7 +129,7 @@ def batch_update_jobs( description=description_two, application_info=application_info_2, addresses=addresses_2, - language_code=language_code_two + language_code=language_code_two, ) jobs = [jobs_element, jobs_element_2] diff --git a/talent/job_search_commute_search.py b/talent/job_search_commute_search.py index d38a0ae4be8d..704043c11f0e 100644 --- a/talent/job_search_commute_search.py +++ b/talent/job_search_commute_search.py @@ -35,9 +35,7 @@ def search_jobs(project_id, tenant_id): session_id = "Hashed session identifier" user_id = "Hashed user identifier" request_metadata = talent.RequestMetadata( - domain=domain, - session_id=session_id, - user_id=user_id + domain=domain, session_id=session_id, user_id=user_id ) commute_method = talent.CommuteMethod.TRANSIT seconds = 1800 @@ -55,9 +53,7 @@ def search_jobs(project_id, tenant_id): # Iterate over all results results = [] request = talent.SearchJobsRequest( - parent=parent, - request_metadata=request_metadata, - job_query=job_query, + parent=parent, request_metadata=request_metadata, job_query=job_query, ) for response_item in client.search_jobs(request=request).matching_jobs: print(f"Job summary: {response_item.job_summary}") diff --git a/talent/job_search_create_job_custom_attributes.py b/talent/job_search_create_job_custom_attributes.py index 1ae10f2c28ae..0f2ae5513dc2 100644 --- a/talent/job_search_create_job_custom_attributes.py +++ b/talent/job_search_create_job_custom_attributes.py @@ -52,7 +52,7 @@ def create_job(project_id, tenant_id, company_id, requisition_id): requisition_id=requisition_id, description="This is a description of this job", language_code="en-us", - custom_attributes={"FOR_STUDENTS": custom_attribute} + custom_attributes={"FOR_STUDENTS": custom_attribute}, ) response = client.create_job(parent=parent, job=job) diff --git a/talent/job_search_custom_ranking_search.py b/talent/job_search_custom_ranking_search.py index 6f1addc97a5f..00cbd6d8de3a 100644 --- a/talent/job_search_custom_ranking_search.py +++ b/talent/job_search_custom_ranking_search.py @@ -35,11 +35,11 @@ def search_jobs(project_id, tenant_id): session_id = "Hashed session identifier" user_id = "Hashed user identifier" request_metadata = talent.RequestMetadata( - domain=domain, - session_id=session_id, - user_id=user_id + domain=domain, session_id=session_id, user_id=user_id + ) + importance_level = ( + talent.SearchJobsRequest.CustomRankingInfo.ImportanceLevel.EXTREME ) - importance_level = talent.SearchJobsRequest.CustomRankingInfo.ImportanceLevel.EXTREME ranking_expression = "(someFieldLong + 25) * 0.25" custom_ranking_info = { "importance_level": importance_level, @@ -53,7 +53,7 @@ def search_jobs(project_id, tenant_id): parent=parent, request_metadata=request_metadata, custom_ranking_info=custom_ranking_info, - order_by=order_by + order_by=order_by, ) for response_item in client.search_jobs(request=request).matching_jobs: print(f"Job summary: {response_item.job_summary}") diff --git a/talent/job_search_list_tenants_test.py b/talent/job_search_list_tenants_test.py index b12f26054119..2ba14350ff52 100644 --- a/talent/job_search_list_tenants_test.py +++ b/talent/job_search_list_tenants_test.py @@ -26,7 +26,7 @@ @pytest.fixture(scope="module") def test_tenant(): client = talent.TenantServiceClient() - external_id = f'test_tenant_{uuid.uuid4().hex}' + external_id = f"test_tenant_{uuid.uuid4().hex}" parent = f"projects/{PROJECT_ID}" tenant = {"external_id": external_id} resp = client.create_tenant(parent=parent, tenant=tenant) diff --git a/talent/noxfile_config.py b/talent/noxfile_config.py index cfd0d439150c..6ecfa40e0b8f 100644 --- a/talent/noxfile_config.py +++ b/talent/noxfile_config.py @@ -22,16 +22,14 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - 'ignored_versions': ["2.7"], - + "ignored_versions": ["2.7"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string # to use your own Cloud project. # 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', - 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', - + "gcloud_project_env": "BUILD_SPECIFIC_GCLOUD_PROJECT", # A dictionary you want to inject into your test. Don't put any # secrets here. These values will override predefined values. - 'envs': {}, + "envs": {}, } From a4df0b1b0eb3643d055a341d4d195b67e2e7120b Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 11 Jan 2022 10:08:18 -0500 Subject: [PATCH 34/57] chore(samples): Add check for tests in directory (#189) Source-Link: https://github.com/googleapis/synthtool/commit/52aef91f8d25223d9dbdb4aebd94ba8eea2101f3 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:36a95b8f494e4674dc9eee9af98961293b51b86b3649942aac800ae6c1f796d4 Co-authored-by: Owl Bot --- talent/noxfile.py | 70 ++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 93a9122cc457..3bbef5d54f44 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -14,6 +14,7 @@ from __future__ import print_function +import glob import os from pathlib import Path import sys @@ -184,37 +185,44 @@ def blacken(session: nox.sessions.Session) -> None: def _session_tests( session: nox.sessions.Session, post_install: Callable = None ) -> None: - if TEST_CONFIG["pip_version_override"]: - pip_version = TEST_CONFIG["pip_version_override"] - session.install(f"pip=={pip_version}") - """Runs py.test for a particular project.""" - if os.path.exists("requirements.txt"): - if os.path.exists("constraints.txt"): - session.install("-r", "requirements.txt", "-c", "constraints.txt") - else: - session.install("-r", "requirements.txt") - - if os.path.exists("requirements-test.txt"): - if os.path.exists("constraints-test.txt"): - session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") - else: - session.install("-r", "requirements-test.txt") - - if INSTALL_LIBRARY_FROM_SOURCE: - session.install("-e", _get_repo_root()) - - if post_install: - post_install(session) - - session.run( - "pytest", - *(PYTEST_COMMON_ARGS + session.posargs), - # Pytest will return 5 when no tests are collected. This can happen - # on travis where slow and flaky tests are excluded. - # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html - success_codes=[0, 5], - env=get_pytest_env_vars(), - ) + # check for presence of tests + test_list = glob.glob("*_test.py") + glob.glob("test_*.py") + if len(test_list) == 0: + print("No tests found, skipping directory.") + else: + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install( + "-r", "requirements-test.txt", "-c", "constraints-test.txt" + ) + else: + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) @nox.session(python=ALL_VERSIONS) From 01c721cea6884149bff614d9b5a6b01d80331116 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 18 Jan 2022 21:05:44 -0500 Subject: [PATCH 35/57] chore(python): Noxfile recognizes that tests can live in a folder (#194) Source-Link: https://github.com/googleapis/synthtool/commit/4760d8dce1351d93658cb11d02a1b7ceb23ae5d7 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:f0e4b51deef56bed74d3e2359c583fc104a8d6367da3984fc5c66938db738828 Co-authored-by: Owl Bot --- talent/noxfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/talent/noxfile.py b/talent/noxfile.py index 3bbef5d54f44..20cdfc620138 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -187,6 +187,7 @@ def _session_tests( ) -> None: # check for presence of tests test_list = glob.glob("*_test.py") + glob.glob("test_*.py") + test_list.extend(glob.glob("tests")) if len(test_list) == 0: print("No tests found, skipping directory.") else: From 4a0d0b102c6d0f0e50bc7b3ed9d9876273d4709f Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 9 Feb 2022 13:07:55 +0100 Subject: [PATCH 36/57] chore(deps): update dependency pytest to v7 (#202) --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 927094516e65..4a46ff600804 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==6.2.5 +pytest==7.0.0 From d85a3b7356cef71d38843dfd33553177207294f7 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Sat, 26 Feb 2022 19:42:03 +0100 Subject: [PATCH 37/57] chore(deps): update all dependencies (#204) * chore(deps): update all dependencies * fix api_shortname in repo-metadata.json Co-authored-by: Anthonios Partheniou --- talent/requirements-test.txt | 2 +- talent/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 4a46ff600804..c2845bffbe89 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.0 +pytest==7.0.1 diff --git a/talent/requirements.txt b/talent/requirements.txt index 62f5dcdde3b8..053efd011bf1 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.4.0 \ No newline at end of file +google.cloud.talent==2.5.0 \ No newline at end of file From 0b56b84980e00cc41bc44016c963dceab02073a4 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Fri, 4 Mar 2022 13:20:42 -0500 Subject: [PATCH 38/57] chore: Adding support for pytest-xdist and pytest-parallel (#214) Source-Link: https://github.com/googleapis/synthtool/commit/82f5cb283efffe96e1b6cd634738e0e7de2cd90a Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:5d8da01438ece4021d135433f2cf3227aa39ef0eaccc941d62aa35e6902832ae Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- talent/noxfile.py | 78 ++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 20cdfc620138..85f5836dba3a 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -188,42 +188,52 @@ def _session_tests( # check for presence of tests test_list = glob.glob("*_test.py") + glob.glob("test_*.py") test_list.extend(glob.glob("tests")) + if len(test_list) == 0: print("No tests found, skipping directory.") - else: - if TEST_CONFIG["pip_version_override"]: - pip_version = TEST_CONFIG["pip_version_override"] - session.install(f"pip=={pip_version}") - """Runs py.test for a particular project.""" - if os.path.exists("requirements.txt"): - if os.path.exists("constraints.txt"): - session.install("-r", "requirements.txt", "-c", "constraints.txt") - else: - session.install("-r", "requirements.txt") - - if os.path.exists("requirements-test.txt"): - if os.path.exists("constraints-test.txt"): - session.install( - "-r", "requirements-test.txt", "-c", "constraints-test.txt" - ) - else: - session.install("-r", "requirements-test.txt") - - if INSTALL_LIBRARY_FROM_SOURCE: - session.install("-e", _get_repo_root()) - - if post_install: - post_install(session) - - session.run( - "pytest", - *(PYTEST_COMMON_ARGS + session.posargs), - # Pytest will return 5 when no tests are collected. This can happen - # on travis where slow and flaky tests are excluded. - # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html - success_codes=[0, 5], - env=get_pytest_env_vars(), - ) + return + + if TEST_CONFIG["pip_version_override"]: + pip_version = TEST_CONFIG["pip_version_override"] + session.install(f"pip=={pip_version}") + """Runs py.test for a particular project.""" + concurrent_args = [] + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + with open("requirements.txt") as rfile: + packages = rfile.read() + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + with open("requirements-test.txt") as rtfile: + packages += rtfile.read() + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + if "pytest-parallel" in packages: + concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) + elif "pytest-xdist" in packages: + concurrent_args.extend(["-n", "auto"]) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars(), + ) @nox.session(python=ALL_VERSIONS) From 355f5b5ad5a7d812745601505b77af0d919b1ce5 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 8 Mar 2022 02:43:17 +0100 Subject: [PATCH 39/57] chore(deps): update dependency google.cloud.talent to v2.5.1 (#217) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 053efd011bf1..8504b2568709 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.5.0 \ No newline at end of file +google.cloud.talent==2.5.1 \ No newline at end of file From 495d3694b904b352fac085b862061e0d316f5932 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Sun, 13 Mar 2022 21:03:00 +0100 Subject: [PATCH 40/57] chore(deps): update dependency pytest to v7.1.0 (#220) --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index c2845bffbe89..824a8a7a0ce6 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==7.1.0 From 852854127356c616cde4b5ab7234c879c1fafd1b Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 23 Mar 2022 09:57:50 +0100 Subject: [PATCH 41/57] chore(deps): update dependency pytest to v7.1.1 (#222) Co-authored-by: Anthonios Partheniou --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 824a8a7a0ce6..4f6bf643fc5e 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==7.1.0 +pytest==7.1.1 From 29ef2b6ab807336f63eefe27d11653ef4aadd80c Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 29 Mar 2022 00:04:26 +0000 Subject: [PATCH 42/57] chore(python): use black==22.3.0 (#229) Source-Link: https://github.com/googleapis/synthtool/commit/6fab84af09f2cf89a031fd8671d1def6b2931b11 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:7cffbc10910c3ab1b852c05114a08d374c195a81cdec1d4a67a1d129331d0bfe --- talent/job_search_commute_search.py | 4 +++- talent/job_search_create_job.py | 6 +++++- talent/noxfile.py | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/talent/job_search_commute_search.py b/talent/job_search_commute_search.py index 704043c11f0e..1cba53db4531 100644 --- a/talent/job_search_commute_search.py +++ b/talent/job_search_commute_search.py @@ -53,7 +53,9 @@ def search_jobs(project_id, tenant_id): # Iterate over all results results = [] request = talent.SearchJobsRequest( - parent=parent, request_metadata=request_metadata, job_query=job_query, + parent=parent, + request_metadata=request_metadata, + job_query=job_query, ) for response_item in client.search_jobs(request=request).matching_jobs: print(f"Job summary: {response_item.job_summary}") diff --git a/talent/job_search_create_job.py b/talent/job_search_create_job.py index 0252a3e0154f..83c83ea67979 100644 --- a/talent/job_search_create_job.py +++ b/talent/job_search_create_job.py @@ -19,7 +19,11 @@ def create_job( - project_id, tenant_id, company_id, requisition_id, job_application_url, + project_id, + tenant_id, + company_id, + requisition_id, + job_application_url, ): """Create Job""" diff --git a/talent/noxfile.py b/talent/noxfile.py index 85f5836dba3a..25f87a215d4c 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -29,7 +29,7 @@ # WARNING - WARNING - WARNING - WARNING - WARNING # WARNING - WARNING - WARNING - WARNING - WARNING -BLACK_VERSION = "black==19.10b0" +BLACK_VERSION = "black==22.3.0" # Copy `noxfile_config.py` to your directory and modify it instead. @@ -253,7 +253,7 @@ def py(session: nox.sessions.Session) -> None: def _get_repo_root() -> Optional[str]: - """ Returns the root folder of the project. """ + """Returns the root folder of the project.""" # Get root of this repository. Assume we don't have directories nested deeper than 10 items. p = Path(os.getcwd()) for i in range(10): From ba1dca09cffbabf1c8af010f86145492160657b8 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 1 Apr 2022 12:29:54 +0200 Subject: [PATCH 43/57] chore(deps): update dependency google.cloud.talent to v2.5.2 (#232) * chore(deps): update dependency google.cloud.talent to v2.5.2 * use dashes instead of dots Co-authored-by: Anthonios Partheniou --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 8504b2568709..4023f7753e38 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google.cloud.talent==2.5.1 \ No newline at end of file +google-cloud-talent==2.5.2 From ebca065ad99aa7142931164c5188dbe37f33b02a Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Wed, 20 Apr 2022 21:10:10 -0400 Subject: [PATCH 44/57] chore(python): add nox session to sort python imports (#240) Source-Link: https://github.com/googleapis/synthtool/commit/1b71c10e20de7ed3f97f692f99a0e3399b67049f Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:00c9d764fd1cd56265f12a5ef4b99a0c9e87cf261018099141e2ca5158890416 Co-authored-by: Owl Bot --- talent/conftest.py | 1 - talent/noxfile.py | 23 ++++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/talent/conftest.py b/talent/conftest.py index 169a401bcfb8..3b75da54c80f 100644 --- a/talent/conftest.py +++ b/talent/conftest.py @@ -16,7 +16,6 @@ import uuid from google.api_core.exceptions import NotFound - import pytest import job_search_create_company diff --git a/talent/noxfile.py b/talent/noxfile.py index 25f87a215d4c..3b3ffa5d2b0f 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -22,7 +22,6 @@ import nox - # WARNING - WARNING - WARNING - WARNING - WARNING # WARNING - WARNING - WARNING - WARNING - WARNING # DO NOT EDIT THIS FILE EVER! @@ -30,6 +29,7 @@ # WARNING - WARNING - WARNING - WARNING - WARNING BLACK_VERSION = "black==22.3.0" +ISORT_VERSION = "isort==5.10.1" # Copy `noxfile_config.py` to your directory and modify it instead. @@ -168,12 +168,33 @@ def lint(session: nox.sessions.Session) -> None: @nox.session def blacken(session: nox.sessions.Session) -> None: + """Run black. Format code to uniform standard.""" session.install(BLACK_VERSION) python_files = [path for path in os.listdir(".") if path.endswith(".py")] session.run("black", *python_files) +# +# format = isort + black +# + + +@nox.session +def format(session: nox.sessions.Session) -> None: + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + # Use the --fss option to sort imports using strict alphabetical order. + # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + session.run("isort", "--fss", *python_files) + session.run("black", *python_files) + + # # Sample Tests # From 6000b9a4370acf429f75ac742e7781f8fe7f25a6 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 25 Apr 2022 17:00:42 +0200 Subject: [PATCH 45/57] chore(deps): update dependency pytest to v7.1.2 (#243) --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index 4f6bf643fc5e..d00689e0623a 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==7.1.1 +pytest==7.1.2 From e077e05d1b1665cd9aa91237ad4594d1ab13c976 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Sat, 9 Jul 2022 14:42:35 -0400 Subject: [PATCH 46/57] fix: require python 3.7+ (#264) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(python): drop python 3.6 Source-Link: https://github.com/googleapis/synthtool/commit/4f89b13af10d086458f9b379e56a614f9d6dab7b Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:e7bb19d47c13839fe8c147e50e02e8b6cf5da8edd1af8b82208cd6f66cc2829c * add api_description to .repo-metadata.json * require python 3.7+ in setup.py * remove python 3.6 sample configs * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * trigger ci * update name_pretty in .repo-metadata.json * update api_description in .repo-metadata.json * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- talent/noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index 3b3ffa5d2b0f..e9eb1cbfa5db 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -88,7 +88,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to test samples. -ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10"] +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] From 9c1cebd7fff44efe54c8ca57934d6f85c79f848f Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 19 Jul 2022 14:29:25 +0200 Subject: [PATCH 47/57] chore(deps): update all dependencies (#255) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update all dependencies * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * revert Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 4023f7753e38..7f24a3cc237f 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google-cloud-talent==2.5.2 +google-cloud-talent==2.6.0 From eaf5a33a5de301d3329379d31d0f0b69a6019fdc Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 2 Aug 2022 16:15:17 +0200 Subject: [PATCH 48/57] chore(deps): update all dependencies (#270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(deps): update all dependencies * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * revert Co-authored-by: Owl Bot Co-authored-by: Anthonios Partheniou --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 7f24a3cc237f..de29ad393046 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google-cloud-talent==2.6.0 +google-cloud-talent==2.7.0 From 0e54475374c4b81186e2c93700ecf7f0763cedc3 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Fri, 19 Aug 2022 18:31:32 +0200 Subject: [PATCH 49/57] chore(deps): update dependency google-cloud-talent to v2.7.1 (#277) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index de29ad393046..43e44504bdd4 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google-cloud-talent==2.7.0 +google-cloud-talent==2.7.1 From b0e0bc8226ab31ed4330fbcdf93b7e36d579452f Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 6 Sep 2022 17:18:31 +0200 Subject: [PATCH 50/57] chore(deps): update dependency pytest to v7.1.3 (#288) * chore(deps): update all dependencies * revert Co-authored-by: Anthonios Partheniou --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index d00689e0623a..e07168502ea9 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==7.1.2 +pytest==7.1.3 From 50eb826f6cfdda17b4bb3a61a865e6466c45ed64 Mon Sep 17 00:00:00 2001 From: "gcf-owl-bot[bot]" <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Date: Tue, 13 Sep 2022 16:14:24 +0000 Subject: [PATCH 51/57] chore: detect samples tests in nested directories (#292) Source-Link: https://github.com/googleapis/synthtool/commit/50db768f450a50d7c1fd62513c113c9bb96fd434 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-python:latest@sha256:e09366bdf0fd9c8976592988390b24d53583dd9f002d476934da43725adbb978 --- talent/noxfile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/talent/noxfile.py b/talent/noxfile.py index e9eb1cbfa5db..c1715136d645 100644 --- a/talent/noxfile.py +++ b/talent/noxfile.py @@ -207,8 +207,10 @@ def _session_tests( session: nox.sessions.Session, post_install: Callable = None ) -> None: # check for presence of tests - test_list = glob.glob("*_test.py") + glob.glob("test_*.py") - test_list.extend(glob.glob("tests")) + test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( + "**/test_*.py", recursive=True + ) + test_list.extend(glob.glob("**/tests", recursive=True)) if len(test_list) == 0: print("No tests found, skipping directory.") From 8bbb86279521a50e4620e546a57b8ef766eab26d Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 4 Oct 2022 15:32:45 +0200 Subject: [PATCH 52/57] chore(deps): update dependency google-cloud-talent to v2.7.2 (#296) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 43e44504bdd4..10e049e25c80 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google-cloud-talent==2.7.1 +google-cloud-talent==2.7.2 From e9c3dd819302a3c41d5e98e9f4b8f5d8fcd9da8f Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Tue, 18 Oct 2022 15:23:08 +0200 Subject: [PATCH 53/57] chore(deps): update dependency google-cloud-talent to v2.7.3 (#299) --- talent/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements.txt b/talent/requirements.txt index 10e049e25c80..980ec38dd37c 100644 --- a/talent/requirements.txt +++ b/talent/requirements.txt @@ -1 +1 @@ -google-cloud-talent==2.7.2 +google-cloud-talent==2.7.3 From 60882d36a461c9c363ae05ef0dedb3e764308d7e Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 26 Oct 2022 12:46:22 +0200 Subject: [PATCH 54/57] chore(deps): update dependency pytest to v7.2.0 (#300) --- talent/requirements-test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/talent/requirements-test.txt b/talent/requirements-test.txt index e07168502ea9..49780e035690 100644 --- a/talent/requirements-test.txt +++ b/talent/requirements-test.txt @@ -1 +1 @@ -pytest==7.1.3 +pytest==7.2.0 From 198cc16d8d6f2180047dc35a520ec347d4078b92 Mon Sep 17 00:00:00 2001 From: ckim328 Date: Mon, 14 Nov 2022 14:33:43 -0500 Subject: [PATCH 55/57] Added fields to codeowners and blunderbuss --- .github/CODEOWNERS | 1 + .github/blunderbuss.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5cf115a2a35e..9ae122b8e7bc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -68,4 +68,5 @@ /storagetransfer/**/* @GoogleCloudPlatform/cloud-storage-dpes @GoogleCloudPlatform/python-samples-reviewers /trace/**/* @ymotongpoo @GoogleCloudPlatform/python-samples-reviewers /translate/**/* @nicain @GoogleCloudPlatform/python-samples-reviewers +/talent/**/* @GoogleCloudPlatform/python-samples-reviewers /workflows/**/* @GoogleCloudPlatform/python-samples-reviewers diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 97e0b4b04893..6af96fc9cd87 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -119,6 +119,7 @@ assign_issues_by: - nicain - labels: - 'api: datalabeling' + - 'api: talent' to: - GoogleCloudPlatform/python-samples-reviewers - ivanmkc From 86d51ecd4b4166380601a2d477a494a935a98ae2 Mon Sep 17 00:00:00 2001 From: ckim328 Date: Mon, 14 Nov 2022 14:43:17 -0500 Subject: [PATCH 56/57] Remove noxfile --- talent/noxfile.py | 312 ---------------------------------------------- 1 file changed, 312 deletions(-) delete mode 100644 talent/noxfile.py diff --git a/talent/noxfile.py b/talent/noxfile.py deleted file mode 100644 index c1715136d645..000000000000 --- a/talent/noxfile.py +++ /dev/null @@ -1,312 +0,0 @@ -# Copyright 2019 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 __future__ import print_function - -import glob -import os -from pathlib import Path -import sys -from typing import Callable, Dict, List, Optional - -import nox - -# WARNING - WARNING - WARNING - WARNING - WARNING -# WARNING - WARNING - WARNING - WARNING - WARNING -# DO NOT EDIT THIS FILE EVER! -# WARNING - WARNING - WARNING - WARNING - WARNING -# WARNING - WARNING - WARNING - WARNING - WARNING - -BLACK_VERSION = "black==22.3.0" -ISORT_VERSION = "isort==5.10.1" - -# Copy `noxfile_config.py` to your directory and modify it instead. - -# `TEST_CONFIG` dict is a configuration hook that allows users to -# modify the test configurations. The values here should be in sync -# with `noxfile_config.py`. Users will copy `noxfile_config.py` into -# their directory and modify it. - -TEST_CONFIG = { - # You can opt out from the test for specific Python versions. - "ignored_versions": [], - # Old samples are opted out of enforcing Python type hints - # All new samples should feature them - "enforce_type_hints": False, - # An envvar key for determining the project id to use. Change it - # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a - # build specific Cloud project. You can also use your own string - # to use your own Cloud project. - "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", - # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', - # If you need to use a specific version of pip, - # change pip_version_override to the string representation - # of the version number, for example, "20.2.4" - "pip_version_override": None, - # A dictionary you want to inject into your test. Don't put any - # secrets here. These values will override predefined values. - "envs": {}, -} - - -try: - # Ensure we can import noxfile_config in the project's directory. - sys.path.append(".") - from noxfile_config import TEST_CONFIG_OVERRIDE -except ImportError as e: - print("No user noxfile_config found: detail: {}".format(e)) - TEST_CONFIG_OVERRIDE = {} - -# Update the TEST_CONFIG with the user supplied values. -TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) - - -def get_pytest_env_vars() -> Dict[str, str]: - """Returns a dict for pytest invocation.""" - ret = {} - - # Override the GCLOUD_PROJECT and the alias. - env_key = TEST_CONFIG["gcloud_project_env"] - # This should error out if not set. - ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key] - - # Apply user supplied envs. - ret.update(TEST_CONFIG["envs"]) - return ret - - -# DO NOT EDIT - automatically generated. -# All versions used to test samples. -ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10"] - -# Any default versions that should be ignored. -IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] - -TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) - -INSTALL_LIBRARY_FROM_SOURCE = os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False) in ( - "True", - "true", -) - -# Error if a python version is missing -nox.options.error_on_missing_interpreters = True - -# -# Style Checks -# - - -def _determine_local_import_names(start_dir: str) -> List[str]: - """Determines all import names that should be considered "local". - - This is used when running the linter to insure that import order is - properly checked. - """ - file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] - return [ - basename - for basename, extension in file_ext_pairs - if extension == ".py" - or os.path.isdir(os.path.join(start_dir, basename)) - and basename not in ("__pycache__") - ] - - -# Linting with flake8. -# -# We ignore the following rules: -# E203: whitespace before ‘:’ -# E266: too many leading ‘#’ for block comment -# E501: line too long -# I202: Additional newline in a section of imports -# -# We also need to specify the rules which are ignored by default: -# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] -FLAKE8_COMMON_ARGS = [ - "--show-source", - "--builtin=gettext", - "--max-complexity=20", - "--import-order-style=google", - "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", - "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", - "--max-line-length=88", -] - - -@nox.session -def lint(session: nox.sessions.Session) -> None: - if not TEST_CONFIG["enforce_type_hints"]: - session.install("flake8", "flake8-import-order") - else: - session.install("flake8", "flake8-import-order", "flake8-annotations") - - local_names = _determine_local_import_names(".") - args = FLAKE8_COMMON_ARGS + [ - "--application-import-names", - ",".join(local_names), - ".", - ] - session.run("flake8", *args) - - -# -# Black -# - - -@nox.session -def blacken(session: nox.sessions.Session) -> None: - """Run black. Format code to uniform standard.""" - session.install(BLACK_VERSION) - python_files = [path for path in os.listdir(".") if path.endswith(".py")] - - session.run("black", *python_files) - - -# -# format = isort + black -# - - -@nox.session -def format(session: nox.sessions.Session) -> None: - """ - Run isort to sort imports. Then run black - to format code to uniform standard. - """ - session.install(BLACK_VERSION, ISORT_VERSION) - python_files = [path for path in os.listdir(".") if path.endswith(".py")] - - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections - session.run("isort", "--fss", *python_files) - session.run("black", *python_files) - - -# -# Sample Tests -# - - -PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] - - -def _session_tests( - session: nox.sessions.Session, post_install: Callable = None -) -> None: - # check for presence of tests - test_list = glob.glob("**/*_test.py", recursive=True) + glob.glob( - "**/test_*.py", recursive=True - ) - test_list.extend(glob.glob("**/tests", recursive=True)) - - if len(test_list) == 0: - print("No tests found, skipping directory.") - return - - if TEST_CONFIG["pip_version_override"]: - pip_version = TEST_CONFIG["pip_version_override"] - session.install(f"pip=={pip_version}") - """Runs py.test for a particular project.""" - concurrent_args = [] - if os.path.exists("requirements.txt"): - if os.path.exists("constraints.txt"): - session.install("-r", "requirements.txt", "-c", "constraints.txt") - else: - session.install("-r", "requirements.txt") - with open("requirements.txt") as rfile: - packages = rfile.read() - - if os.path.exists("requirements-test.txt"): - if os.path.exists("constraints-test.txt"): - session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") - else: - session.install("-r", "requirements-test.txt") - with open("requirements-test.txt") as rtfile: - packages += rtfile.read() - - if INSTALL_LIBRARY_FROM_SOURCE: - session.install("-e", _get_repo_root()) - - if post_install: - post_install(session) - - if "pytest-parallel" in packages: - concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"]) - elif "pytest-xdist" in packages: - concurrent_args.extend(["-n", "auto"]) - - session.run( - "pytest", - *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args), - # Pytest will return 5 when no tests are collected. This can happen - # on travis where slow and flaky tests are excluded. - # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html - success_codes=[0, 5], - env=get_pytest_env_vars(), - ) - - -@nox.session(python=ALL_VERSIONS) -def py(session: nox.sessions.Session) -> None: - """Runs py.test for a sample using the specified version of Python.""" - if session.python in TESTED_VERSIONS: - _session_tests(session) - else: - session.skip( - "SKIPPED: {} tests are disabled for this sample.".format(session.python) - ) - - -# -# Readmegen -# - - -def _get_repo_root() -> Optional[str]: - """Returns the root folder of the project.""" - # Get root of this repository. Assume we don't have directories nested deeper than 10 items. - p = Path(os.getcwd()) - for i in range(10): - if p is None: - break - if Path(p / ".git").exists(): - return str(p) - # .git is not available in repos cloned via Cloud Build - # setup.py is always in the library's root, so use that instead - # https://github.com/googleapis/synthtool/issues/792 - if Path(p / "setup.py").exists(): - return str(p) - p = p.parent - raise Exception("Unable to detect repository root.") - - -GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) - - -@nox.session -@nox.parametrize("path", GENERATED_READMES) -def readmegen(session: nox.sessions.Session, path: str) -> None: - """(Re-)generates the readme for a sample.""" - session.install("jinja2", "pyyaml") - dir_ = os.path.dirname(path) - - if os.path.exists(os.path.join(dir_, "requirements.txt")): - session.install("-r", os.path.join(dir_, "requirements.txt")) - - in_file = os.path.join(dir_, "README.rst.in") - session.run( - "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file - ) From 36d64f999c56dd65335f32289552884f924ed216 Mon Sep 17 00:00:00 2001 From: ckim328 Date: Mon, 14 Nov 2022 15:07:12 -0500 Subject: [PATCH 57/57] Blunderbuss edit --- .github/blunderbuss.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 6af96fc9cd87..3f9451e1cc6d 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -119,7 +119,6 @@ assign_issues_by: - nicain - labels: - 'api: datalabeling' - - 'api: talent' to: - GoogleCloudPlatform/python-samples-reviewers - ivanmkc @@ -144,7 +143,10 @@ assign_prs_by: - 'api: iot' to: - GoogleCloudPlatform/api-iot - +- labels: + - 'api: talent' + to: + - GoogleCloudPlatform/python-samples-reviewers assign_issues: - GoogleCloudPlatform/python-samples-owners