From c4441cbf76088cbaad7e61ba064e44535a68794f Mon Sep 17 00:00:00 2001 From: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com> Date: Tue, 20 Dec 2022 14:47:09 -0600 Subject: [PATCH 1/5] test: add retries to monitoring tests (#8825) * test: add retries to monitoring tests * linting * limit retries to ServiceUnailable * remove semicolon --- monitoring/snippets/v3/cloud-client/snippets_test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/monitoring/snippets/v3/cloud-client/snippets_test.py b/monitoring/snippets/v3/cloud-client/snippets_test.py index 9a2b44c633be..bc7cc84dbc4e 100644 --- a/monitoring/snippets/v3/cloud-client/snippets_test.py +++ b/monitoring/snippets/v3/cloud-client/snippets_test.py @@ -18,6 +18,7 @@ import backoff from google.api_core.exceptions import InternalServerError from google.api_core.exceptions import NotFound +from google.api_core.exceptions import ServiceUnavailable import pytest import snippets @@ -67,36 +68,42 @@ def eventually_consistent_test(): assert "Deleted metric" in out +@backoff.on_exception(backoff.expo, (ServiceUnavailable), max_tries=3) def test_list_metric_descriptors(capsys): snippets.list_metric_descriptors(PROJECT_ID) out, _ = capsys.readouterr() assert "logging.googleapis.com/byte_count" in out +@backoff.on_exception(backoff.expo, (ServiceUnavailable), max_tries=3) def test_list_resources(capsys): snippets.list_monitored_resources(PROJECT_ID) out, _ = capsys.readouterr() assert "pubsub_topic" in out +@backoff.on_exception(backoff.expo, (ServiceUnavailable), max_tries=3) def test_get_resources(capsys): snippets.get_monitored_resource_descriptor(PROJECT_ID, "pubsub_topic") out, _ = capsys.readouterr() assert "A topic in Google Cloud Pub/Sub" in out +@backoff.on_exception(backoff.expo, (ServiceUnavailable), max_tries=3) def test_list_time_series(capsys, write_time_series): snippets.list_time_series(PROJECT_ID) out, _ = capsys.readouterr() assert "gce_instance" in out +@backoff.on_exception(backoff.expo, (ServiceUnavailable), max_tries=3) def test_list_time_series_header(capsys, write_time_series): snippets.list_time_series_header(PROJECT_ID) out, _ = capsys.readouterr() assert "gce_instance" in out +@backoff.on_exception(backoff.expo, (ServiceUnavailable), max_tries=3) def test_list_time_series_aggregate(capsys, write_time_series): snippets.list_time_series_aggregate(PROJECT_ID) out, _ = capsys.readouterr() @@ -106,6 +113,7 @@ def test_list_time_series_aggregate(capsys, write_time_series): assert "end_time" in out +@backoff.on_exception(backoff.expo, (ServiceUnavailable), max_tries=3) def test_list_time_series_reduce(capsys, write_time_series): snippets.list_time_series_reduce(PROJECT_ID) out, _ = capsys.readouterr() From c0af5fa0754c30973ddbd15d341c2d57afc8b72a Mon Sep 17 00:00:00 2001 From: Sita Lakshmi Sangameswaran Date: Wed, 21 Dec 2022 04:51:57 +0530 Subject: [PATCH 2/5] docs(webrisk-samples): init add samples and tests (#8810) * docs(webrisk-samples): init add samples and tests * added pytest to requirements * added test and fixed lint errors * modified acc to review comments * modified acc to review comments * modified acc to review comments * deleted commented out code --- webrisk/snippets/__init__.py | 13 ++++ webrisk/snippets/compute_threatlist_diff.py | 81 +++++++++++++++++++++ webrisk/snippets/noxfile_config.py | 42 +++++++++++ webrisk/snippets/requirements-test.txt | 1 + webrisk/snippets/requirements.txt | 1 + webrisk/snippets/search_hashes.py | 59 +++++++++++++++ webrisk/snippets/search_uri.py | 45 ++++++++++++ webrisk/snippets/submit_uri.py | 44 +++++++++++ webrisk/snippets/test_basic_samples.py | 57 +++++++++++++++ 9 files changed, 343 insertions(+) create mode 100644 webrisk/snippets/__init__.py create mode 100644 webrisk/snippets/compute_threatlist_diff.py create mode 100644 webrisk/snippets/noxfile_config.py create mode 100644 webrisk/snippets/requirements-test.txt create mode 100644 webrisk/snippets/requirements.txt create mode 100644 webrisk/snippets/search_hashes.py create mode 100644 webrisk/snippets/search_uri.py create mode 100644 webrisk/snippets/submit_uri.py create mode 100644 webrisk/snippets/test_basic_samples.py diff --git a/webrisk/snippets/__init__.py b/webrisk/snippets/__init__.py new file mode 100644 index 000000000000..4bbe0ffdb061 --- /dev/null +++ b/webrisk/snippets/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/webrisk/snippets/compute_threatlist_diff.py b/webrisk/snippets/compute_threatlist_diff.py new file mode 100644 index 000000000000..877360806751 --- /dev/null +++ b/webrisk/snippets/compute_threatlist_diff.py @@ -0,0 +1,81 @@ +# Copyright 2022 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. + +# [START webrisk_compute_threatlist_diff] +from google.cloud import webrisk_v1 + + +def compute_threatlist_diff( + threat_type: webrisk_v1.ThreatType, + version_token: bytes, + max_diff_entries: int, + max_database_entries: int, + compression_type: webrisk_v1.CompressionType, +) -> None: + """Gets the most recent threat list diffs. These diffs should be applied to a local database of + hashes to keep it up-to-date. + + If the local database is empty or excessively out-of-date, + a complete snapshot of the database will be returned. This Method only updates a + single ThreatList at a time. To update multiple ThreatList databases, this method needs to be + called once for each list. + + Args: + threat_type: The threat list to update. Only a single ThreatType should be specified per request. + threat_type = webrisk_v1.ThreatType.MALWARE + + version_token: The current version token of the client for the requested list. If the + client does not have a version token (this is the first time calling ComputeThreatListDiff), + this may be left empty and a full database snapshot will be returned. + + max_diff_entries: The maximum size in number of entries. The diff will not contain more entries + than this value. This should be a power of 2 between 2**10 and 2**20. + If zero, no diff size limit is set. + max_diff_entries = 1024 + + max_database_entries: Sets the maximum number of entries that the client is willing to have in the local database. + This should be a power of 2 between 2**10 and 2**20. If zero, no database size limit is set. + max_database_entries = 1024 + + compression_type: The compression type supported by the client. + compression_type = webrisk_v1.CompressionType.RAW + """ + + webrisk_client = webrisk_v1.WebRiskServiceClient() + + constraints = webrisk_v1.ComputeThreatListDiffRequest.Constraints() + constraints.max_diff_entries = max_diff_entries + constraints.max_database_entries = max_database_entries + constraints.supported_compressions = [compression_type] + + request = webrisk_v1.ComputeThreatListDiffRequest() + request.threat_type = threat_type + request.version_token = version_token + request.constraints = constraints + + response = webrisk_client.compute_threat_list_diff(request) + + # The returned response contains the following information: + # https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#computethreatlistdiffresponse + # Type of response: DIFF/ RESET/ RESPONSE_TYPE_UNSPECIFIED + print(response.response_type) + + # New version token to be used the next time when querying. + print(response.new_version_token) + + # Recommended next diff timestamp. + print(response.recommended_next_diff) + + print("Obtained threat list diff.") +# [END webrisk_compute_threatlist_diff] diff --git a/webrisk/snippets/noxfile_config.py b/webrisk/snippets/noxfile_config.py new file mode 100644 index 000000000000..96fbfe15d322 --- /dev/null +++ b/webrisk/snippets/noxfile_config.py @@ -0,0 +1,42 @@ +# Copyright 2022 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 imported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7", "3.6"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": True, + # 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": {}, +} diff --git a/webrisk/snippets/requirements-test.txt b/webrisk/snippets/requirements-test.txt new file mode 100644 index 000000000000..89cb815c988e --- /dev/null +++ b/webrisk/snippets/requirements-test.txt @@ -0,0 +1 @@ +pytest==7.2.0 \ No newline at end of file diff --git a/webrisk/snippets/requirements.txt b/webrisk/snippets/requirements.txt new file mode 100644 index 000000000000..11417183406a --- /dev/null +++ b/webrisk/snippets/requirements.txt @@ -0,0 +1 @@ +google-cloud-webrisk==1.9.0 \ No newline at end of file diff --git a/webrisk/snippets/search_hashes.py b/webrisk/snippets/search_hashes.py new file mode 100644 index 000000000000..ed3a7880afcd --- /dev/null +++ b/webrisk/snippets/search_hashes.py @@ -0,0 +1,59 @@ +# Copyright 2022 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. + +# [START webrisk_search_hash] +from google.cloud import webrisk_v1 + + +def search_hashes(hash_prefix: bytes, threat_type: webrisk_v1.ThreatType) -> None: + """Gets the full hashes that match the requested hash prefix. + + This is used after a hash prefix is looked up in a threatList and there is a match. + The client side threatList only holds partial hashes so the client must query this method + to determine if there is a full hash match of a threat. + + Args: + hash_prefix: A hash prefix, consisting of the most significant 4-32 bytes of a SHA256 hash. + For JSON requests, this field is base64-encoded. Note that if this parameter is provided + by a URI, it must be encoded using the web safe base64 variant (RFC 4648). + Example: + uri = "http://example.com" + sha256 = sha256() + sha256.update(base64.urlsafe_b64encode(bytes(uri, "utf-8"))) + hex_string = sha256.digest() + + threat_type: The ThreatLists to search in. Multiple ThreatLists may be specified. + For the list on threat types, see: + https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threattype + threat_type = [webrisk_v1.ThreatType.MALWARE, webrisk_v1.ThreatType.SOCIAL_ENGINEERING] + """ + webrisk_client = webrisk_v1.WebRiskServiceClient() + + # Set the hashPrefix and the threat types to search in. + request = webrisk_v1.SearchHashesRequest() + request.hash_prefix = hash_prefix + request.threat_types = [threat_type] + + response = webrisk_client.search_hashes(request) + + # Get all the hashes that match the prefix. Cache the returned hashes until the time + # specified in threat_hash.expire_time + # For more information on response type, see: + # https://cloud.google.com/web-risk/docs/reference/rpc/google.cloud.webrisk.v1#threathash + for threat_hash in response.threats: + print(threat_hash.hash) + + print("Completed searching threat hashes.") + +# [END webrisk_search_hash] diff --git a/webrisk/snippets/search_uri.py b/webrisk/snippets/search_uri.py new file mode 100644 index 000000000000..ab0d8ca1b312 --- /dev/null +++ b/webrisk/snippets/search_uri.py @@ -0,0 +1,45 @@ +# Copyright 2022 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. + +# [START webrisk_search_uri] +from google.cloud import webrisk_v1 + + +def search_uri(uri: str, threat_type: webrisk_v1.ThreatType.MALWARE) -> None: + """Checks whether a URI is on a given threatList. + + Multiple threatLists may be searched in a single query. The response will list all + requested threatLists the URI was found to match. If the URI is not + found on any of the requested ThreatList an empty response will be returned. + + Args: + uri: The URI to be checked for matches + Example: "http://testsafebrowsing.appspot.com/s/malware.html" + + threat_type: The ThreatLists to search in. Multiple ThreatLists may be specified. + Example: threat_type = webrisk_v1.ThreatType.MALWARE + """ + webrisk_client = webrisk_v1.WebRiskServiceClient() + + request = webrisk_v1.SearchUrisRequest() + request.threat_types = [threat_type] + request.uri = uri + + response = webrisk_client.search_uris(request) + if response.threat.threat_types: + print(f"The URI has the following threat: {response}") + return + + print("The URL is safe!") +# [END webrisk_search_uri] diff --git a/webrisk/snippets/submit_uri.py b/webrisk/snippets/submit_uri.py new file mode 100644 index 000000000000..7911b41c03f4 --- /dev/null +++ b/webrisk/snippets/submit_uri.py @@ -0,0 +1,44 @@ +# Copyright 2022 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. + +# [START webrisk_submit_uri] +from google.cloud import webrisk_v1 + + +def submit_uri(project_id: str, uri: str) -> None: + """Submits a URI suspected of containing malicious content to be reviewed. + + Returns a google.longrunning.Operation which, once the review is complete, is updated with its result. + If the result verifies the existence of malicious content, the site will be added to the + Google's Social Engineering lists in order to protect users that could get exposed to this + threat in the future. Only allow-listed projects can use this method during Early Access. + + Args: + project_id: The name of the project that is making the submission. + uri: The URI that is being reported for malicious content to be analyzed. + uri = "http://testsafebrowsing.appspot.com/s/malware.html" + """ + webrisk_client = webrisk_v1.WebRiskServiceClient() + + submission = webrisk_v1.Submission() + submission.uri = uri + + request = webrisk_v1.CreateSubmissionRequest() + request.parent = f"projects/{project_id}" + request.submission = submission + + response = webrisk_client.create_submission(request) + print(f"Submission response: {response}") + +# [END webrisk_submit_uri] diff --git a/webrisk/snippets/test_basic_samples.py b/webrisk/snippets/test_basic_samples.py new file mode 100644 index 000000000000..9a33ef0118e9 --- /dev/null +++ b/webrisk/snippets/test_basic_samples.py @@ -0,0 +1,57 @@ +# Copyright 2022 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 base64 +import hashlib +import re + +from _pytest.capture import CaptureFixture +import google +from google.cloud import webrisk_v1 + +from .compute_threatlist_diff import compute_threatlist_diff +from .search_hashes import search_hashes +from .search_uri import search_uri +from .submit_uri import submit_uri + +PROJECT = google.auth.default()[1] + + +def test_search_uri_with_threat(capsys: CaptureFixture) -> None: + search_uri("http://testsafebrowsing.appspot.com/s/malware.html", webrisk_v1.ThreatType.MALWARE) + assert re.search("The URI has the following threat: ", capsys.readouterr().out) + + +def test_search_uri_without_threat(capsys: CaptureFixture) -> None: + search_uri("http://testsafebrowsing.appspot.com/malware.html", webrisk_v1.ThreatType.MALWARE) + assert re.search("The URL is safe!", capsys.readouterr().out) + + +def test_submit_uri(capsys: CaptureFixture) -> None: + submit_uri(PROJECT, "http://testsafebrowsing.appspot.com/s/malware.html") + assert re.search("Submission response: ", capsys.readouterr().out) + + +def test_search_hashes(capsys: CaptureFixture) -> None: + uri = "http://example.com" + sha256 = hashlib.sha256() + sha256.update(base64.urlsafe_b64encode(bytes(uri, "utf-8"))) + hex_string = sha256.digest() + + search_hashes(hex_string, webrisk_v1.ThreatType.MALWARE) + assert re.search("Completed searching threat hashes.", capsys.readouterr().out) + + +def test_compute_threatdiff_list(capsys: CaptureFixture) -> None: + compute_threatlist_diff(webrisk_v1.ThreatType.MALWARE, b'', 1024, 1024, webrisk_v1.CompressionType.RAW) + assert re.search("Obtained threat list diff.", capsys.readouterr().out) From 8b5ae7701edf9d5902c22307e2950e19de64e720 Mon Sep 17 00:00:00 2001 From: Jack Wotherspoon Date: Fri, 30 Dec 2022 12:26:26 -0500 Subject: [PATCH 3/5] chore(cloudsql): format comments into doc strings (#8803) * chore: format comments into doc strings * chore: lint * chore: lint Co-authored-by: nicain --- cloud-sql/mysql/sqlalchemy/connect_connector.py | 7 +++++-- .../mysql/sqlalchemy/connect_connector_auto_iam_authn.py | 8 +++++--- cloud-sql/mysql/sqlalchemy/connect_tcp.py | 3 +-- cloud-sql/mysql/sqlalchemy/connect_unix.py | 3 +-- cloud-sql/postgres/sqlalchemy/connect_connector.py | 7 +++++-- .../sqlalchemy/connect_connector_auto_iam_authn.py | 8 +++++--- cloud-sql/postgres/sqlalchemy/connect_tcp.py | 3 +-- cloud-sql/postgres/sqlalchemy/connect_unix.py | 3 +-- cloud-sql/sql-server/sqlalchemy/connect_connector.py | 7 +++++-- cloud-sql/sql-server/sqlalchemy/connect_tcp.py | 3 +-- 10 files changed, 30 insertions(+), 22 deletions(-) diff --git a/cloud-sql/mysql/sqlalchemy/connect_connector.py b/cloud-sql/mysql/sqlalchemy/connect_connector.py index c003cd84c65b..3b02ba8f01a7 100644 --- a/cloud-sql/mysql/sqlalchemy/connect_connector.py +++ b/cloud-sql/mysql/sqlalchemy/connect_connector.py @@ -21,9 +21,12 @@ import sqlalchemy -# connect_with_connector initializes a connection pool for a -# Cloud SQL instance of MySQL using the Cloud SQL Python Connector. def connect_with_connector() -> sqlalchemy.engine.base.Engine: + """ + Initializes a connection pool for a Cloud SQL instance of MySQL. + + Uses the Cloud SQL Python Connector package. + """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/mysql/sqlalchemy/connect_connector_auto_iam_authn.py b/cloud-sql/mysql/sqlalchemy/connect_connector_auto_iam_authn.py index cc02182e7824..84ec49a9a143 100644 --- a/cloud-sql/mysql/sqlalchemy/connect_connector_auto_iam_authn.py +++ b/cloud-sql/mysql/sqlalchemy/connect_connector_auto_iam_authn.py @@ -21,10 +21,12 @@ import sqlalchemy -# connect_with_connector_auto_iam_authn initializes a connection pool for -# a Cloud SQL instance of MySQL using the Cloud SQL Python Connector -# with Automatic IAM Database Authentication. def connect_with_connector_auto_iam_authn() -> sqlalchemy.engine.base.Engine: + """ + Initializes a connection pool for a Cloud SQL instance of MySQL. + + Uses the Cloud SQL Python Connector with Automatic IAM Database Authentication. + """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/mysql/sqlalchemy/connect_tcp.py b/cloud-sql/mysql/sqlalchemy/connect_tcp.py index cf9520546602..4398fc97d5ae 100644 --- a/cloud-sql/mysql/sqlalchemy/connect_tcp.py +++ b/cloud-sql/mysql/sqlalchemy/connect_tcp.py @@ -21,9 +21,8 @@ import sqlalchemy -# connect_tcp_socket initializes a TCP connection pool -# for a Cloud SQL instance of MySQL. def connect_tcp_socket() -> sqlalchemy.engine.base.Engine: + """ Initializes a TCP connection pool for a Cloud SQL instance of MySQL. """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/mysql/sqlalchemy/connect_unix.py b/cloud-sql/mysql/sqlalchemy/connect_unix.py index fed63c25ff74..d0cca0beba6a 100644 --- a/cloud-sql/mysql/sqlalchemy/connect_unix.py +++ b/cloud-sql/mysql/sqlalchemy/connect_unix.py @@ -18,9 +18,8 @@ import sqlalchemy -# connect_unix_socket initializes a Unix socket connection pool for -# a Cloud SQL instance of MySQL. def connect_unix_socket() -> sqlalchemy.engine.base.Engine: + """ Initializes a Unix socket connection pool for a Cloud SQL instance of MySQL. """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/postgres/sqlalchemy/connect_connector.py b/cloud-sql/postgres/sqlalchemy/connect_connector.py index 44d0c7163d21..f281ff5f5ac5 100644 --- a/cloud-sql/postgres/sqlalchemy/connect_connector.py +++ b/cloud-sql/postgres/sqlalchemy/connect_connector.py @@ -21,9 +21,12 @@ import sqlalchemy -# connect_with_connector initializes a connection pool for a -# Cloud SQL instance of Postgres using the Cloud SQL Python Connector. def connect_with_connector() -> sqlalchemy.engine.base.Engine: + """ + Initializes a connection pool for a Cloud SQL instance of Postgres. + + Uses the Cloud SQL Python Connector package. + """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/postgres/sqlalchemy/connect_connector_auto_iam_authn.py b/cloud-sql/postgres/sqlalchemy/connect_connector_auto_iam_authn.py index ed5c46205033..e1748fc6ae35 100644 --- a/cloud-sql/postgres/sqlalchemy/connect_connector_auto_iam_authn.py +++ b/cloud-sql/postgres/sqlalchemy/connect_connector_auto_iam_authn.py @@ -21,10 +21,12 @@ import sqlalchemy -# connect_with_connector_auto_iam_authn initializes a connection pool for -# a Cloud SQL instance of Postgres using the Cloud SQL Python Connector -# with Automatic IAM Database Authentication. def connect_with_connector_auto_iam_authn() -> sqlalchemy.engine.base.Engine: + """ + Initializes a connection pool for a Cloud SQL instance of Postgres. + + Uses the Cloud SQL Python Connector with Automatic IAM Database Authentication. + """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/postgres/sqlalchemy/connect_tcp.py b/cloud-sql/postgres/sqlalchemy/connect_tcp.py index 3c22165d9803..808b1fad2c8d 100644 --- a/cloud-sql/postgres/sqlalchemy/connect_tcp.py +++ b/cloud-sql/postgres/sqlalchemy/connect_tcp.py @@ -22,9 +22,8 @@ import sqlalchemy -# connect_tcp_socket initializes a TCP connection pool -# for a Cloud SQL instance of Postgres. def connect_tcp_socket() -> sqlalchemy.engine.base.Engine: + """ Initializes a TCP connection pool for a Cloud SQL instance of Postgres. """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/postgres/sqlalchemy/connect_unix.py b/cloud-sql/postgres/sqlalchemy/connect_unix.py index 183062eef22a..278be1c0d4d8 100644 --- a/cloud-sql/postgres/sqlalchemy/connect_unix.py +++ b/cloud-sql/postgres/sqlalchemy/connect_unix.py @@ -18,9 +18,8 @@ import sqlalchemy -# connect_unix_socket initializes a Unix socket connection pool for -# a Cloud SQL instance of Postgres. def connect_unix_socket() -> sqlalchemy.engine.base.Engine: + """ Initializes a Unix socket connection pool for a Cloud SQL instance of Postgres. """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/sql-server/sqlalchemy/connect_connector.py b/cloud-sql/sql-server/sqlalchemy/connect_connector.py index d63a6939fae0..54c66a7ddfe3 100644 --- a/cloud-sql/sql-server/sqlalchemy/connect_connector.py +++ b/cloud-sql/sql-server/sqlalchemy/connect_connector.py @@ -21,9 +21,12 @@ import sqlalchemy -# connect_with_connector initializes a connection pool for a -# Cloud SQL instance of SQL Server using the Cloud SQL Python Connector. def connect_with_connector() -> sqlalchemy.engine.base.Engine: + """ + Initializes a connection pool for a Cloud SQL instance of SQL Server. + + Uses the Cloud SQL Python Connector package. + """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help diff --git a/cloud-sql/sql-server/sqlalchemy/connect_tcp.py b/cloud-sql/sql-server/sqlalchemy/connect_tcp.py index dd1d10780259..d8421e1d770f 100644 --- a/cloud-sql/sql-server/sqlalchemy/connect_tcp.py +++ b/cloud-sql/sql-server/sqlalchemy/connect_tcp.py @@ -21,9 +21,8 @@ import sqlalchemy -# connect_tcp_socket initializes a TCP connection pool -# for a Cloud SQL instance of SQL Server. def connect_tcp_socket() -> sqlalchemy.engine.base.Engine: + """ Initializes a TCP connection pool for a Cloud SQL instance of SQL Server. """ # Note: Saving credentials in environment variables is convenient, but not # secure - consider a more secure solution such as # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help From 726699b11309eac8f9c6d6ed2be3399f08a157b1 Mon Sep 17 00:00:00 2001 From: Viet Nguyen <19592926+v-ngu@users.noreply.github.com> Date: Mon, 2 Jan 2023 19:03:29 -0500 Subject: [PATCH 4/5] Fix typo on contributing document (#8850) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 28474593053c..b78fcc382a30 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ please open an issue for discussion first. 1. Submit an issue describing your proposed change to this repository. 2. A repo owner will respond to your issue promptly. If you don't see a response within - a few days, please ping the owner assignd to your issue. + a few days, please ping the owner assigned to your issue. 3. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above). 4. Fork this repo, develop and test your code changes. Tests are required for all From 4207f09cfae69e8cd1ab1305f303717fe445e044 Mon Sep 17 00:00:00 2001 From: chengzi Date: Tue, 3 Jan 2023 08:09:22 +0800 Subject: [PATCH 5/5] fix arg type (#8844) fix default arg type string to int Co-authored-by: nicain --- vision/snippets/face_detection/faces.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vision/snippets/face_detection/faces.py b/vision/snippets/face_detection/faces.py index 25014048a790..7b1a90f509a5 100755 --- a/vision/snippets/face_detection/faces.py +++ b/vision/snippets/face_detection/faces.py @@ -97,7 +97,7 @@ def main(input_filename, output_filename, max_results): '--out', dest='output', default='out.jpg', help='the name of the output file.') parser.add_argument( - '--max-results', dest='max_results', default=4, + '--max-results', dest='max_results', default=4, type=int, help='the max results of face detection.') args = parser.parse_args()