From a8d54dbd985b28359dcbd4114d77082647eff91f Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 5 Nov 2025 06:11:19 +0000 Subject: [PATCH 01/49] chore: onboard to librarian --- .github/.OwlBot.lock.yaml | 17 - .github/.OwlBot.yaml | 30 -- .github/release-please.yml | 15 - .github/release-trigger.yml | 2 - .../generator-input/.repo-metadata.json | 18 + .librarian/generator-input/owlbot.py | 324 ++++++++++++++++++ .librarian/state.yaml | 18 + .release-please-manifest.json | 3 - noxfile.py | 6 +- owlbot.py | 48 ++- release-please-config.json | 35 -- 11 files changed, 395 insertions(+), 121 deletions(-) delete mode 100644 .github/.OwlBot.lock.yaml delete mode 100644 .github/.OwlBot.yaml delete mode 100644 .github/release-please.yml delete mode 100644 .github/release-trigger.yml create mode 100644 .librarian/generator-input/.repo-metadata.json create mode 100644 .librarian/generator-input/owlbot.py create mode 100644 .librarian/state.yaml delete mode 100644 .release-please-manifest.json delete mode 100644 release-please-config.json diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml deleted file mode 100644 index 0ba6990347..0000000000 --- a/.github/.OwlBot.lock.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -docker: - image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:fbbc8db67afd8b7d71bf694c5081a32da0c528eba166fbcffb3b6e56ddf907d5 -# created: 2025-10-30T00:16:55.473963098Z diff --git a/.github/.OwlBot.yaml b/.github/.OwlBot.yaml deleted file mode 100644 index 5db16e2a9d..0000000000 --- a/.github/.OwlBot.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2021 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -docker: - image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - -deep-remove-regex: - - /owl-bot-staging - -deep-copy-regex: - - source: /google/spanner/(v.*)/.*-py/(.*) - dest: /owl-bot-staging/spanner/$1/$2 - - source: /google/spanner/admin/instance/(v.*)/.*-py/(.*) - dest: /owl-bot-staging/spanner_admin_instance/$1/$2 - - source: /google/spanner/admin/database/(v.*)/.*-py/(.*) - dest: /owl-bot-staging/spanner_admin_database/$1/$2 - -begin-after-commit-hash: b154da710c5c9eedee127c07f74b6158c9c22382 - diff --git a/.github/release-please.yml b/.github/release-please.yml deleted file mode 100644 index dbd2cc9deb..0000000000 --- a/.github/release-please.yml +++ /dev/null @@ -1,15 +0,0 @@ -releaseType: python -handleGHRelease: true -manifest: true -# NOTE: this section is generated by synthtool.languages.python -# See https://github.com/googleapis/synthtool/blob/master/synthtool/languages/python.py -branches: -- branch: v2 - handleGHRelease: true - releaseType: python -- branch: v1 - handleGHRelease: true - releaseType: python -- branch: v0 - handleGHRelease: true - releaseType: python diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml deleted file mode 100644 index 3c0f1bfc7e..0000000000 --- a/.github/release-trigger.yml +++ /dev/null @@ -1,2 +0,0 @@ -enabled: true -multiScmName: python-spanner diff --git a/.librarian/generator-input/.repo-metadata.json b/.librarian/generator-input/.repo-metadata.json new file mode 100644 index 0000000000..9569af6e31 --- /dev/null +++ b/.librarian/generator-input/.repo-metadata.json @@ -0,0 +1,18 @@ +{ + "name": "spanner", + "name_pretty": "Cloud Spanner", + "product_documentation": "https://cloud.google.com/spanner/docs/", + "client_documentation": "https://cloud.google.com/python/docs/reference/spanner/latest", + "issue_tracker": "https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open", + "release_level": "stable", + "language": "python", + "library_type": "GAPIC_COMBO", + "repo": "googleapis/python-spanner", + "distribution_name": "google-cloud-spanner", + "api_id": "spanner.googleapis.com", + "requires_billing": true, + "default_version": "v1", + "codeowner_team": "@googleapis/spanner-client-libraries-python", + "api_shortname": "spanner", + "api_description": "is a fully managed, mission-critical, \nrelational database service that offers transactional consistency at global scale, \nschemas, SQL (ANSI 2011 with extensions), and automatic, synchronous replication \nfor high availability.\n\nBe sure to activate the Cloud Spanner API on the Developer's Console to\nuse Cloud Spanner from your project." +} diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py new file mode 100644 index 0000000000..4547c4d2d0 --- /dev/null +++ b/.librarian/generator-input/owlbot.py @@ -0,0 +1,324 @@ +# Copyright 2018 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. + +"""This script is used to synthesize generated parts of this library.""" + +from pathlib import Path +import shutil +from typing import List, Optional +import re + +import synthtool as s +from synthtool import gcp +from synthtool.languages import python + +common = gcp.CommonTemplates() + + +def get_staging_dirs( + # This is a customized version of the s.get_staging_dirs() function + # from synthtool to # cater for copying 3 different folders from + # googleapis-gen: + # spanner, spanner/admin/instance and spanner/admin/database. + # Source: + # https://github.com/googleapis/synthtool/blob/master/synthtool/transforms.py#L280 + default_version: Optional[str] = None, + sub_directory: Optional[str] = None, +) -> List[Path]: + """Returns the list of directories, one per version, copied from + https://github.com/googleapis/googleapis-gen. Will return in lexical sorting + order with the exception of the default_version which will be last (if specified). + + Args: + default_version (str): the default version of the API. The directory for this version + will be the last item in the returned list if specified. + sub_directory (str): if a `sub_directory` is provided, only the directories within the + specified `sub_directory` will be returned. + + Returns: the empty list if no file were copied. + """ + + staging = Path("owl-bot-staging") + + if sub_directory: + staging /= sub_directory + + if staging.is_dir(): + # Collect the subdirectories of the staging directory. + versions = [v.name for v in staging.iterdir() if v.is_dir()] + # Reorder the versions so the default version always comes last. + versions = [v for v in versions if v != default_version] + versions.sort() + if default_version is not None: + versions += [default_version] + dirs = [staging / v for v in versions] + for dir in dirs: + s._tracked_paths.add(dir) + return dirs + else: + return [] + + +spanner_default_version = "v1" +spanner_admin_instance_default_version = "v1" +spanner_admin_database_default_version = "v1" + +clean_up_generated_samples = True + +for library in get_staging_dirs(spanner_default_version, "spanner"): + if clean_up_generated_samples: + shutil.rmtree("samples/generated_samples", ignore_errors=True) + clean_up_generated_samples = False + + # Customization for MetricsInterceptor + + assert 6 == s.replace( + [ + library / "google/cloud/spanner_v1/services/spanner/transports/*.py", + library / "google/cloud/spanner_v1/services/spanner/client.py", + ], + """from google.cloud.spanner_v1.types import transaction""", + """from google.cloud.spanner_v1.types import transaction +from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor""", + ) + + assert 1 == s.replace( + library / "google/cloud/spanner_v1/services/spanner/transports/*.py", + """api_audience: Optional\[str\] = None, + \*\*kwargs, + \) -> None: + \"\"\"Instantiate the transport.""", +"""api_audience: Optional[str] = None, + metrics_interceptor: Optional[MetricsInterceptor] = None, + **kwargs, + ) -> None: + \"\"\"Instantiate the transport.""" + ) + + assert 4 == s.replace( + library / "google/cloud/spanner_v1/services/spanner/transports/*.py", + """api_audience: Optional\[str\] = None, + \) -> None: + \"\"\"Instantiate the transport.""", +"""api_audience: Optional[str] = None, + metrics_interceptor: Optional[MetricsInterceptor] = None, + ) -> None: + \"\"\"Instantiate the transport.""" + ) + + assert 1 == s.replace( + library / "google/cloud/spanner_v1/services/spanner/transports/grpc.py", + """\)\n\n self._interceptor = _LoggingClientInterceptor\(\)""", + """) + + # Wrap the gRPC channel with the metric interceptor + if metrics_interceptor is not None: + self._metrics_interceptor = metrics_interceptor + self._grpc_channel = grpc.intercept_channel( + self._grpc_channel, metrics_interceptor + ) + + self._interceptor = _LoggingClientInterceptor()""" + ) + + assert 1 == s.replace( + library / "google/cloud/spanner_v1/services/spanner/transports/grpc.py", + """self._stubs: Dict\[str, Callable\] = \{\}\n\n if api_mtls_endpoint:""", + """self._stubs: Dict[str, Callable] = {} + self._metrics_interceptor = None + + if api_mtls_endpoint:""" + ) + + assert 1 == s.replace( + library / "google/cloud/spanner_v1/services/spanner/client.py", + """# initialize with the provided callable or the passed in class + self._transport = transport_init\( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + \)""", + """# initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + always_use_jwt_access=True, + api_audience=self._client_options.api_audience, + metrics_interceptor=MetricsInterceptor(), + )""", + ) + + assert 12 == s.replace( + library / "tests/unit/gapic/spanner_v1/test_spanner.py", + """api_audience=None,\n(\s+)\)""", + """api_audience=None, + metrics_interceptor=mock.ANY, + )""" + ) + + assert 1 == s.replace( + library / "tests/unit/gapic/spanner_v1/test_spanner.py", + """api_audience="https://language.googleapis.com"\n(\s+)\)""", + """api_audience="https://language.googleapis.com", + metrics_interceptor=mock.ANY, + )""" + ) + + count = s.replace( + [ + library / "google/cloud/spanner_v1/services/*/transports/grpc*", + library / "tests/unit/gapic/spanner_v1/*", + ], + "^\s+options=\\[.*?\\]", + """options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ("grpc.keepalive_time_ms", 120000), + ]""", + flags=re.MULTILINE | re.DOTALL, + ) + if count < 1: + raise Exception("Expected replacements for gRPC channel options not made.") + + s.move( + library, + excludes=[ + "google/cloud/spanner/**", + "*.*", + "noxfile.py", + "docs/index.rst", + "google/cloud/spanner_v1/__init__.py", + "**/gapic_version.py", + "testing/constraints-3.7.txt", + ], + ) + +for library in get_staging_dirs( + spanner_admin_instance_default_version, "spanner_admin_instance" +): + count = s.replace( + [ + library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", + library / "tests/unit/gapic/spanner_admin_instance_v1/*", + ], + "^\s+options=\\[.*?\\]", + """options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ("grpc.keepalive_time_ms", 120000), + ]""", + flags=re.MULTILINE | re.DOTALL, + ) + if count < 1: + raise Exception("Expected replacements for gRPC channel options not made.") + s.move( + library, + excludes=["google/cloud/spanner_admin_instance/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], + ) + +for library in get_staging_dirs( + spanner_admin_database_default_version, "spanner_admin_database" +): + count = s.replace( + [ + library / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", + library / "tests/unit/gapic/spanner_admin_database_v1/*", + ], + "^\s+options=\\[.*?\\]", + """options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ("grpc.keepalive_time_ms", 120000), + ]""", + flags=re.MULTILINE | re.DOTALL, + ) + if count < 1: + raise Exception("Expected replacements for gRPC channel options not made.") + s.move( + library, + excludes=["google/cloud/spanner_admin_database/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], + ) + +s.remove_staging_dirs() + +# ---------------------------------------------------------------------------- +# Add templated files +# ---------------------------------------------------------------------------- +templated_files = common.py_library( + microgenerator=True, + samples=True, + cov_level=98, + split_system_tests=True, + system_test_extras=["tracing"], + system_test_python_versions=["3.12"] +) +s.move( + templated_files, + excludes=[ + ".coveragerc", + ".github/workflows", # exclude gh actions as credentials are needed for tests + "README.rst", + ".github/release-please.yml", + ".kokoro/test-samples-impl.sh", + ".kokoro/presubmit/presubmit.cfg", + ".kokoro/samples/python3.7/**", + ".kokoro/samples/python3.8/**", + ], +) + +# Ensure CI runs on a new instance each time +s.replace( + ".kokoro/build.sh", + "# Setup project id.", + """\ +# Set up creating a new instance for each system test run +export GOOGLE_CLOUD_TESTS_CREATE_SPANNER_INSTANCE=true + +# Setup project id.""", +) + +# Update samples folder in CONTRIBUTING.rst +s.replace("CONTRIBUTING.rst", "samples/snippets", "samples/samples") + +# ---------------------------------------------------------------------------- +# Samples templates +# ---------------------------------------------------------------------------- + +python.py_samples() + +s.replace( + "samples/**/noxfile.py", + 'BLACK_VERSION = "black==22.3.0"', + 'BLACK_VERSION = "black==23.7.0"', +) +s.replace( + "samples/**/noxfile.py", + r'ALL_VERSIONS = \["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"\]', + 'ALL_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13"]', +) + +# Use a python runtime which is available in the owlbot post processor here +# https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile +s.shell.run(["nox", "-s", "blacken-3.10"], hide_output=False) diff --git a/.librarian/state.yaml b/.librarian/state.yaml new file mode 100644 index 0000000000..4d4416143e --- /dev/null +++ b/.librarian/state.yaml @@ -0,0 +1,18 @@ +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:27eae7edfe88876a47cbdb89ec6491192706e94ce46ac0e3ff4d202ef3220fed +libraries: + - id: google-cloud-spanner + version: 3.59.0 + last_generated_commit: 53f97391f3451398f7b53c7f86dabd325d205677 + apis: + - path: google/spanner/v1 + service_config: spanner.yaml + - path: google/spanner/admin/database/v1 + service_config: spanner.yaml + - path: google/spanner/admin/instance/v1 + service_config: spanner.yaml + source_roots: + - . + preserve_regex: [] + remove_regex: + - google/spanner_v1 + tag_format: v{version} diff --git a/.release-please-manifest.json b/.release-please-manifest.json deleted file mode 100644 index 6c2193e315..0000000000 --- a/.release-please-manifest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - ".": "3.59.0" -} diff --git a/noxfile.py b/noxfile.py index b101f46b2e..366147e1d0 100644 --- a/noxfile.py +++ b/noxfile.py @@ -32,10 +32,10 @@ ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.12" +DEFAULT_PYTHON_VERSION = "3.14" -DEFAULT_MOCK_SERVER_TESTS_PYTHON_VERSION = "3.12" -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.12"] +DEFAULT_MOCK_SERVER_TESTS_PYTHON_VERSION = "3.14" +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.14"] UNIT_TEST_PYTHON_VERSIONS: List[str] = [ "3.9", diff --git a/owlbot.py b/owlbot.py index 4547c4d2d0..83349b6375 100644 --- a/owlbot.py +++ b/owlbot.py @@ -14,10 +14,10 @@ """This script is used to synthesize generated parts of this library.""" -from pathlib import Path +import re import shutil +from pathlib import Path from typing import List, Optional -import re import synthtool as s from synthtool import gcp @@ -99,11 +99,11 @@ def get_staging_dirs( \*\*kwargs, \) -> None: \"\"\"Instantiate the transport.""", -"""api_audience: Optional[str] = None, + """api_audience: Optional[str] = None, metrics_interceptor: Optional[MetricsInterceptor] = None, **kwargs, ) -> None: - \"\"\"Instantiate the transport.""" + \"\"\"Instantiate the transport.""", ) assert 4 == s.replace( @@ -111,10 +111,10 @@ def get_staging_dirs( """api_audience: Optional\[str\] = None, \) -> None: \"\"\"Instantiate the transport.""", -"""api_audience: Optional[str] = None, + """api_audience: Optional[str] = None, metrics_interceptor: Optional[MetricsInterceptor] = None, ) -> None: - \"\"\"Instantiate the transport.""" + \"\"\"Instantiate the transport.""", ) assert 1 == s.replace( @@ -129,7 +129,7 @@ def get_staging_dirs( self._grpc_channel, metrics_interceptor ) - self._interceptor = _LoggingClientInterceptor()""" + self._interceptor = _LoggingClientInterceptor()""", ) assert 1 == s.replace( @@ -138,7 +138,7 @@ def get_staging_dirs( """self._stubs: Dict[str, Callable] = {} self._metrics_interceptor = None - if api_mtls_endpoint:""" + if api_mtls_endpoint:""", ) assert 1 == s.replace( @@ -155,7 +155,7 @@ def get_staging_dirs( always_use_jwt_access=True, api_audience=self._client_options.api_audience, \)""", - """# initialize with the provided callable or the passed in class + """# initialize with the provided callable or the passed in class self._transport = transport_init( credentials=credentials, credentials_file=self._client_options.credentials_file, @@ -175,7 +175,7 @@ def get_staging_dirs( """api_audience=None,\n(\s+)\)""", """api_audience=None, metrics_interceptor=mock.ANY, - )""" + )""", ) assert 1 == s.replace( @@ -183,7 +183,7 @@ def get_staging_dirs( """api_audience="https://language.googleapis.com"\n(\s+)\)""", """api_audience="https://language.googleapis.com", metrics_interceptor=mock.ANY, - )""" + )""", ) count = s.replace( @@ -220,7 +220,8 @@ def get_staging_dirs( ): count = s.replace( [ - library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", + library + / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", library / "tests/unit/gapic/spanner_admin_instance_v1/*", ], "^\s+options=\\[.*?\\]", @@ -235,7 +236,14 @@ def get_staging_dirs( raise Exception("Expected replacements for gRPC channel options not made.") s.move( library, - excludes=["google/cloud/spanner_admin_instance/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], + excludes=[ + "google/cloud/spanner_admin_instance/**", + "*.*", + "docs/index.rst", + "noxfile.py", + "**/gapic_version.py", + "testing/constraints-3.7.txt", + ], ) for library in get_staging_dirs( @@ -243,7 +251,8 @@ def get_staging_dirs( ): count = s.replace( [ - library / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", + library + / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", library / "tests/unit/gapic/spanner_admin_database_v1/*", ], "^\s+options=\\[.*?\\]", @@ -258,7 +267,14 @@ def get_staging_dirs( raise Exception("Expected replacements for gRPC channel options not made.") s.move( library, - excludes=["google/cloud/spanner_admin_database/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], + excludes=[ + "google/cloud/spanner_admin_database/**", + "*.*", + "docs/index.rst", + "noxfile.py", + "**/gapic_version.py", + "testing/constraints-3.7.txt", + ], ) s.remove_staging_dirs() @@ -272,7 +288,7 @@ def get_staging_dirs( cov_level=98, split_system_tests=True, system_test_extras=["tracing"], - system_test_python_versions=["3.12"] + system_test_python_versions=["3.12"], ) s.move( templated_files, diff --git a/release-please-config.json b/release-please-config.json deleted file mode 100644 index faae5c405c..0000000000 --- a/release-please-config.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", - "packages": { - ".": { - "release-type": "python", - "extra-files": [ - "google/cloud/spanner_admin_instance_v1/gapic_version.py", - "google/cloud/spanner_v1/gapic_version.py", - "google/cloud/spanner_admin_database_v1/gapic_version.py", - { - "type": "json", - "path": "samples/generated_samples/snippet_metadata_google.spanner.v1.json", - "jsonpath": "$.clientLibrary.version" - }, - { - "type": "json", - "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json", - "jsonpath": "$.clientLibrary.version" - }, - { - "type": "json", - "path": "samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json", - "jsonpath": "$.clientLibrary.version" - } - ] - } - }, - "release-type": "python", - "plugins": [ - { - "type": "sentence-case" - } - ], - "initial-version": "0.1.0" -} From a8f9ffa805551d9dd4cbf1ef8379568eb4e56e00 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 5 Nov 2025 09:50:09 +0000 Subject: [PATCH 02/49] add setup file --- .github/release-trigger.yml | 2 + .librarian/generator-input/owlbot.py | 2 +- .librarian/generator-input/setup.py | 103 +++++++++++++++++++++++++++ .release-please-manifest.json | 3 + 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 .github/release-trigger.yml create mode 100644 .librarian/generator-input/setup.py create mode 100644 .release-please-manifest.json diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml new file mode 100644 index 0000000000..3c0f1bfc7e --- /dev/null +++ b/.github/release-trigger.yml @@ -0,0 +1,2 @@ +enabled: true +multiScmName: python-spanner diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py index 4547c4d2d0..c6d8445908 100644 --- a/.librarian/generator-input/owlbot.py +++ b/.librarian/generator-input/owlbot.py @@ -321,4 +321,4 @@ def get_staging_dirs( # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken-3.10"], hide_output=False) +s.shell.run(["nox", "-s", "blacken"], hide_output=False) diff --git a/.librarian/generator-input/setup.py b/.librarian/generator-input/setup.py new file mode 100644 index 0000000000..858982f783 --- /dev/null +++ b/.librarian/generator-input/setup.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# 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 io +import os + +import setuptools # type: ignore + +package_root = os.path.abspath(os.path.dirname(__file__)) + +name = "google-cloud-spanner" + + +description = "Google Cloud Spanner API client library" + +version = {} +with open(os.path.join(package_root, "google/cloud/spanner_v1/gapic_version.py")) as fp: + exec(fp.read(), version) +version = version["__version__"] + +if version[0] == "0": + release_status = "Development Status :: 4 - Beta" +else: + release_status = "Development Status :: 5 - Production/Stable" + +dependencies = [ + "google-api-core[grpc] >= 1.34.0, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*", + "google-cloud-core >= 1.4.4, < 3.0.0", + "grpc-google-iam-v1 >= 0.12.4, <1.0.0", + "proto-plus >= 1.22.0, <2.0.0", + "sqlparse >= 0.4.4", + "proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'", + "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", + "grpc-interceptor >= 0.15.4", +] +extras = { + "tracing": [ + "opentelemetry-api >= 1.22.0", + "opentelemetry-sdk >= 1.22.0", + "opentelemetry-semantic-conventions >= 0.43b0", + "opentelemetry-resourcedetector-gcp >= 1.8.0a0", + "google-cloud-monitoring >= 2.16.0", + "mmh3 >= 4.1.0 ", + ], + "libcst": "libcst >= 0.2.5", +} + +url = "https://github.com/googleapis/python-spanner" + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package + for package in setuptools.find_namespace_packages() + if package.startswith("google") +] + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@google.com", + license="Apache 2.0", + url=url, + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + install_requires=dependencies, + extras_require=extras, + python_requires=">=3.9", + include_package_data=True, + zip_safe=False, +) diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000000..6c2193e315 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "3.59.0" +} From 13e81f66a94aed87db9446e0cf1ddcfffcec3c7e Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 5 Nov 2025 18:38:04 +0000 Subject: [PATCH 03/49] update blacken --- owlbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owlbot.py b/owlbot.py index 83349b6375..e33e3a6f40 100644 --- a/owlbot.py +++ b/owlbot.py @@ -337,4 +337,4 @@ def get_staging_dirs( # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken-3.10"], hide_output=False) +s.shell.run(["nox", "-s", "blacken"], hide_output=False) From 6492d28d1b55efc088a47f3c214fd1a59b749e2e Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 5 Nov 2025 18:41:41 +0000 Subject: [PATCH 04/49] revert system test version to 3.12 --- .librarian/generator-input/noxfile.py | 595 ++++++++++++++++++++++++++ .librarian/state.yaml | 6 +- noxfile.py | 8 +- owlbot.py | 48 +-- 4 files changed, 619 insertions(+), 38 deletions(-) create mode 100644 .librarian/generator-input/noxfile.py diff --git a/.librarian/generator-input/noxfile.py b/.librarian/generator-input/noxfile.py new file mode 100644 index 0000000000..81c522d0d5 --- /dev/null +++ b/.librarian/generator-input/noxfile.py @@ -0,0 +1,595 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2024 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. + +# Generated by synthtool. DO NOT EDIT! + +from __future__ import absolute_import + +import os +import pathlib +import re +import shutil +from typing import Dict, List +import warnings + +import nox + +FLAKE8_VERSION = "flake8==6.1.0" +BLACK_VERSION = "black[jupyter]==23.7.0" +ISORT_VERSION = "isort==5.11.0" +LINT_PATHS = ["google", "tests", "noxfile.py", "setup.py"] + +DEFAULT_PYTHON_VERSION = "3.14" + +DEFAULT_MOCK_SERVER_TESTS_PYTHON_VERSION = "3.12" +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.12"] + +UNIT_TEST_PYTHON_VERSIONS: List[str] = [ + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", +] +UNIT_TEST_STANDARD_DEPENDENCIES = [ + "mock", + "asyncmock", + "pytest", + "pytest-cov", + "pytest-asyncio", +] +MOCK_SERVER_ADDITIONAL_DEPENDENCIES = [ + "google-cloud-testutils", +] +UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = [] +UNIT_TEST_DEPENDENCIES: List[str] = [] +UNIT_TEST_EXTRAS: List[str] = [] +UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [ + "mock", + "pytest", + "google-cloud-testutils", +] +SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_DEPENDENCIES: List[str] = [] +SYSTEM_TEST_EXTRAS: List[str] = [ + "tracing", +] +SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} + +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + +nox.options.sessions = [ + "unit-3.9", + "unit-3.10", + "unit-3.11", + "unit-3.12", + "unit-3.13", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", + "docfx", + "format", +] + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint(session): + """Run linters. + + Returns a failure if the linters find linting errors or sufficiently + serious code quality issues. + """ + session.install(FLAKE8_VERSION, BLACK_VERSION) + session.run( + "black", + "--check", + *LINT_PATHS, + ) + session.run("flake8", "google", "tests") + + +# Use a python runtime which is available in the owlbot post processor here +# https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile +@nox.session(python=DEFAULT_PYTHON_VERSION) +def blacken(session): + """Run black. Format code to uniform standard.""" + session.install(BLACK_VERSION) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run isort to sort imports. Then run black + to format code to uniform standard. + """ + session.install(BLACK_VERSION, ISORT_VERSION) + # 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", + *LINT_PATHS, + ) + session.run( + "black", + *LINT_PATHS, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("docutils", "pygments", "setuptools>=79.0.1") + session.run("python", "setup.py", "check", "--restructuredtext", "--strict") + + +def install_unittest_dependencies(session, *constraints): + standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES + session.install(*standard_deps, *constraints) + + if UNIT_TEST_EXTERNAL_DEPENDENCIES: + warnings.warn( + "'unit_test_external_dependencies' is deprecated. Instead, please " + "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.", + DeprecationWarning, + ) + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_LOCAL_DEPENDENCIES: + session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints) + + if UNIT_TEST_EXTRAS_BY_PYTHON: + extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif UNIT_TEST_EXTRAS: + extras = UNIT_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + # XXX Work around Kokoro image's older pip, which borks the OT install. + session.run("pip", "install", "--upgrade", "pip") + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + session.install("-e", ".[tracing]", "-c", constraints_path) + # XXX: Dump installed versions to debug OT issue + session.run("pip", "list") + + +@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb", "cpp"], +) +def unit(session, protobuf_implementation): + # Install all test dependencies, then install this package in-place. + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + install_unittest_dependencies(session, "-c", constraints_path) + + # TODO(https://github.com/googleapis/synthtool/issues/1976): + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + # Run py.test against the unit tests. + session.run( + "py.test", + "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "unit"), + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) + + +@nox.session(python=DEFAULT_MOCK_SERVER_TESTS_PYTHON_VERSION) +def mockserver(session): + # Install all test dependencies, then install this package in-place. + + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + standard_deps = ( + UNIT_TEST_STANDARD_DEPENDENCIES + + UNIT_TEST_DEPENDENCIES + + MOCK_SERVER_ADDITIONAL_DEPENDENCIES + ) + session.install(*standard_deps, "-c", constraints_path) + session.install("-e", ".", "-c", constraints_path) + + # Run py.test against the mockserver tests. + session.run( + "py.test", + "--quiet", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + os.path.join("tests", "mockserver_tests"), + *session.posargs, + ) + + +def install_systemtest_dependencies(session, *constraints): + # Use pre-release gRPC for system tests. + # Exclude version 1.52.0rc1 which has a known issue. + # See https://github.com/grpc/grpc/issues/32163 + session.install("--pre", "grpcio!=1.52.0rc1") + + session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTERNAL_DEPENDENCIES: + session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_LOCAL_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_DEPENDENCIES: + session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints) + + if SYSTEM_TEST_EXTRAS_BY_PYTHON: + extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, []) + elif SYSTEM_TEST_EXTRAS: + extras = SYSTEM_TEST_EXTRAS + else: + extras = [] + + if extras: + session.install("-e", f".[{','.join(extras)}]", *constraints) + else: + session.install("-e", ".", *constraints) + + +@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) +@nox.parametrize( + "protobuf_implementation,database_dialect", + [ + ("python", "GOOGLE_STANDARD_SQL"), + ("python", "POSTGRESQL"), + ("upb", "GOOGLE_STANDARD_SQL"), + ("upb", "POSTGRESQL"), + ("cpp", "GOOGLE_STANDARD_SQL"), + ("cpp", "POSTGRESQL"), + ], +) +def system(session, protobuf_implementation, database_dialect): + """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. + if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": + session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # Sanity check: Only run tests if the environment variable is set. + if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", "") and not os.environ.get( + "SPANNER_EMULATOR_HOST", "" + ): + session.skip( + "Credentials or emulator host must be set via environment variable" + ) + if not ( + os.environ.get("SPANNER_EMULATOR_HOST") or protobuf_implementation == "python" + ): + session.skip( + "Only run system tests on real Spanner with one protobuf implementation to speed up the build" + ) + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install pyopenssl for mTLS testing. + if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": + session.install("pyopenssl") + + system_test_exists = os.path.exists(system_test_path) + system_test_folder_exists = os.path.exists(system_test_folder_path) + # Sanity check: only run tests if found. + if not system_test_exists and not system_test_folder_exists: + session.skip("System tests were not found") + + install_systemtest_dependencies(session, "-c", constraints_path) + + # TODO(https://github.com/googleapis/synthtool/issues/1976): + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + + # Run py.test against the system tests. + if system_test_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) + elif system_test_folder_exists: + session.run( + "py.test", + "--quiet", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def cover(session): + """Run the final coverage report. + + This outputs the coverage report aggregating coverage from the unit + test runs (not system test runs), and then erases coverage data. + """ + session.install("coverage", "pytest-cov") + session.run("coverage", "report", "--show-missing", "--fail-under=98") + + session.run("coverage", "erase") + + +@nox.session(python="3.10") +def docs(session): + """Build the docs for this library.""" + + session.install("-e", ".[tracing]") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "sphinx==4.5.0", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-W", # warnings as errors + "-T", # show full traceback on exception + "-N", # no colors + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.10") +def docfx(session): + """Build the docfx yaml files for this library.""" + + session.install("-e", ".[tracing]") + session.install( + # We need to pin to specific versions of the `sphinxcontrib-*` packages + # which still support sphinx 4.x. + # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344 + # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345. + "sphinxcontrib-applehelp==1.0.4", + "sphinxcontrib-devhelp==1.0.2", + "sphinxcontrib-htmlhelp==2.0.1", + "sphinxcontrib-qthelp==1.0.3", + "sphinxcontrib-serializinghtml==1.1.5", + "gcp-sphinx-docfx-yaml", + "alabaster", + "recommonmark", + ) + + shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) + session.run( + "sphinx-build", + "-T", # show full traceback on exception + "-N", # no colors + "-D", + ( + "extensions=sphinx.ext.autodoc," + "sphinx.ext.autosummary," + "docfx_yaml.extension," + "sphinx.ext.intersphinx," + "sphinx.ext.coverage," + "sphinx.ext.napoleon," + "sphinx.ext.todo," + "sphinx.ext.viewcode," + "recommonmark" + ), + "-b", + "html", + "-d", + os.path.join("docs", "_build", "doctrees", ""), + os.path.join("docs", ""), + os.path.join("docs", "_build", "html", ""), + ) + + +@nox.session(python="3.13") +@nox.parametrize( + "protobuf_implementation,database_dialect", + [ + ("python", "GOOGLE_STANDARD_SQL"), + ("python", "POSTGRESQL"), + ("upb", "GOOGLE_STANDARD_SQL"), + ("upb", "POSTGRESQL"), + ("cpp", "GOOGLE_STANDARD_SQL"), + ("cpp", "POSTGRESQL"), + ], +) +def prerelease_deps(session, protobuf_implementation, database_dialect): + """Run all tests with prerelease versions of dependencies installed.""" + + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + session.skip("cpp implementation is not supported in python 3.11+") + + # Install all dependencies + session.install("-e", ".[all, tests, tracing]") + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + system_deps_all = ( + SYSTEM_TEST_STANDARD_DEPENDENCIES + SYSTEM_TEST_EXTERNAL_DEPENDENCIES + ) + session.install(*system_deps_all) + + # Because we test minimum dependency versions on the minimum Python + # version, the first version we test with in the unit tests sessions has a + # constraints file containing all dependencies and extras. + with open( + CURRENT_DIRECTORY + / "testing" + / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt", + encoding="utf-8", + ) as constraints_file: + constraints_text = constraints_file.read() + + # Ignore leading whitespace and comment lines. + constraints_deps = [ + match.group(1) + for match in re.finditer( + r"^\s*([a-zA-Z0-9._-]+)", constraints_text, flags=re.MULTILINE + ) + ] + + if constraints_deps: + session.install(*constraints_deps) + + prerel_deps = [ + "protobuf", + # dependency of grpc + "six", + "grpc-google-iam-v1", + "googleapis-common-protos", + "grpcio", + "grpcio-status", + "google-api-core", + "google-auth", + "proto-plus", + "google-cloud-testutils", + # dependencies of google-cloud-testutils" + "click", + ] + + for dep in prerel_deps: + session.install("--pre", "--no-deps", "--upgrade", dep) + + # Remaining dependencies + other_deps = [ + "requests", + ] + session.install(*other_deps) + + # Print out prerelease package versions + session.run( + "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" + ) + session.run("python", "-c", "import grpc; print(grpc.__version__)") + session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) + + system_test_path = os.path.join("tests", "system.py") + system_test_folder_path = os.path.join("tests", "system") + + # Only run system tests for one protobuf implementation on real Spanner to speed up the build. + if os.environ.get("SPANNER_EMULATOR_HOST") or protobuf_implementation == "python": + # Only run system tests if found. + if os.path.exists(system_test_path): + session.run( + "py.test", + "--verbose", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_path, + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) + elif os.path.exists(system_test_folder_path): + session.run( + "py.test", + "--verbose", + f"--junitxml=system_{session.python}_sponge_log.xml", + system_test_folder_path, + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 4d4416143e..32336eb8bf 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-spanner version: 3.59.0 - last_generated_commit: 53f97391f3451398f7b53c7f86dabd325d205677 + last_generated_commit: 3a77bd60b37c086effb39819e9183fbc83e3a693 apis: - path: google/spanner/v1 service_config: spanner.yaml @@ -14,5 +14,7 @@ libraries: - . preserve_regex: [] remove_regex: - - google/spanner_v1 + - google/cloud/spanner_admin_database_v1 + - google/cloud/spanner_admin_instance_v1 + - google/cloud/spanner_v1 tag_format: v{version} diff --git a/noxfile.py b/noxfile.py index 366147e1d0..81c522d0d5 100644 --- a/noxfile.py +++ b/noxfile.py @@ -30,12 +30,12 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" ISORT_VERSION = "isort==5.11.0" -LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] +LINT_PATHS = ["google", "tests", "noxfile.py", "setup.py"] DEFAULT_PYTHON_VERSION = "3.14" -DEFAULT_MOCK_SERVER_TESTS_PYTHON_VERSION = "3.14" -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.14"] +DEFAULT_MOCK_SERVER_TESTS_PYTHON_VERSION = "3.12" +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.12"] UNIT_TEST_PYTHON_VERSIONS: List[str] = [ "3.9", @@ -113,7 +113,7 @@ def lint(session): # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -@nox.session(python=["3.10", DEFAULT_PYTHON_VERSION]) +@nox.session(python=DEFAULT_PYTHON_VERSION) def blacken(session): """Run black. Format code to uniform standard.""" session.install(BLACK_VERSION) diff --git a/owlbot.py b/owlbot.py index e33e3a6f40..c6d8445908 100644 --- a/owlbot.py +++ b/owlbot.py @@ -14,10 +14,10 @@ """This script is used to synthesize generated parts of this library.""" -import re -import shutil from pathlib import Path +import shutil from typing import List, Optional +import re import synthtool as s from synthtool import gcp @@ -99,11 +99,11 @@ def get_staging_dirs( \*\*kwargs, \) -> None: \"\"\"Instantiate the transport.""", - """api_audience: Optional[str] = None, +"""api_audience: Optional[str] = None, metrics_interceptor: Optional[MetricsInterceptor] = None, **kwargs, ) -> None: - \"\"\"Instantiate the transport.""", + \"\"\"Instantiate the transport.""" ) assert 4 == s.replace( @@ -111,10 +111,10 @@ def get_staging_dirs( """api_audience: Optional\[str\] = None, \) -> None: \"\"\"Instantiate the transport.""", - """api_audience: Optional[str] = None, +"""api_audience: Optional[str] = None, metrics_interceptor: Optional[MetricsInterceptor] = None, ) -> None: - \"\"\"Instantiate the transport.""", + \"\"\"Instantiate the transport.""" ) assert 1 == s.replace( @@ -129,7 +129,7 @@ def get_staging_dirs( self._grpc_channel, metrics_interceptor ) - self._interceptor = _LoggingClientInterceptor()""", + self._interceptor = _LoggingClientInterceptor()""" ) assert 1 == s.replace( @@ -138,7 +138,7 @@ def get_staging_dirs( """self._stubs: Dict[str, Callable] = {} self._metrics_interceptor = None - if api_mtls_endpoint:""", + if api_mtls_endpoint:""" ) assert 1 == s.replace( @@ -155,7 +155,7 @@ def get_staging_dirs( always_use_jwt_access=True, api_audience=self._client_options.api_audience, \)""", - """# initialize with the provided callable or the passed in class + """# initialize with the provided callable or the passed in class self._transport = transport_init( credentials=credentials, credentials_file=self._client_options.credentials_file, @@ -175,7 +175,7 @@ def get_staging_dirs( """api_audience=None,\n(\s+)\)""", """api_audience=None, metrics_interceptor=mock.ANY, - )""", + )""" ) assert 1 == s.replace( @@ -183,7 +183,7 @@ def get_staging_dirs( """api_audience="https://language.googleapis.com"\n(\s+)\)""", """api_audience="https://language.googleapis.com", metrics_interceptor=mock.ANY, - )""", + )""" ) count = s.replace( @@ -220,8 +220,7 @@ def get_staging_dirs( ): count = s.replace( [ - library - / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", + library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", library / "tests/unit/gapic/spanner_admin_instance_v1/*", ], "^\s+options=\\[.*?\\]", @@ -236,14 +235,7 @@ def get_staging_dirs( raise Exception("Expected replacements for gRPC channel options not made.") s.move( library, - excludes=[ - "google/cloud/spanner_admin_instance/**", - "*.*", - "docs/index.rst", - "noxfile.py", - "**/gapic_version.py", - "testing/constraints-3.7.txt", - ], + excludes=["google/cloud/spanner_admin_instance/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], ) for library in get_staging_dirs( @@ -251,8 +243,7 @@ def get_staging_dirs( ): count = s.replace( [ - library - / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", + library / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", library / "tests/unit/gapic/spanner_admin_database_v1/*", ], "^\s+options=\\[.*?\\]", @@ -267,14 +258,7 @@ def get_staging_dirs( raise Exception("Expected replacements for gRPC channel options not made.") s.move( library, - excludes=[ - "google/cloud/spanner_admin_database/**", - "*.*", - "docs/index.rst", - "noxfile.py", - "**/gapic_version.py", - "testing/constraints-3.7.txt", - ], + excludes=["google/cloud/spanner_admin_database/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], ) s.remove_staging_dirs() @@ -288,7 +272,7 @@ def get_staging_dirs( cov_level=98, split_system_tests=True, system_test_extras=["tracing"], - system_test_python_versions=["3.12"], + system_test_python_versions=["3.12"] ) s.move( templated_files, From a21d945c6fe7089f79e74c5d08912c4f4d3a7013 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 10:21:32 +0000 Subject: [PATCH 05/49] wip --- .librarian/generator-input/config.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .librarian/generator-input/config.yaml diff --git a/.librarian/generator-input/config.yaml b/.librarian/generator-input/config.yaml new file mode 100644 index 0000000000..8d9022e45b --- /dev/null +++ b/.librarian/generator-input/config.yaml @@ -0,0 +1,6 @@ +global_files_allowlist: + # Allow the container to read and write the root `CHANGELOG.md` + # file during the `release` step to update the latest client library + # versions which are hardcoded in the file. + - path: "CHANGELOG.md" + permissions: "read-write" \ No newline at end of file From bf9caac2872397e7126fe1888145efdecccf1bdb Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 11:25:11 +0000 Subject: [PATCH 06/49] wip --- .librarian/generator-input/owlbot.py | 2 +- .librarian/state.yaml | 5 +---- owlbot.py | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py index c6d8445908..deda1925b4 100644 --- a/.librarian/generator-input/owlbot.py +++ b/.librarian/generator-input/owlbot.py @@ -321,4 +321,4 @@ def get_staging_dirs( # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken"], hide_output=False) +s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 32336eb8bf..028e6d89a4 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -13,8 +13,5 @@ libraries: source_roots: - . preserve_regex: [] - remove_regex: - - google/cloud/spanner_admin_database_v1 - - google/cloud/spanner_admin_instance_v1 - - google/cloud/spanner_v1 + remove_regex: [] tag_format: v{version} diff --git a/owlbot.py b/owlbot.py index c6d8445908..deda1925b4 100644 --- a/owlbot.py +++ b/owlbot.py @@ -321,4 +321,4 @@ def get_staging_dirs( # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken"], hide_output=False) +s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) From 9324cda43af3125a0bf64215b48009e295916abf Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 12:16:54 +0000 Subject: [PATCH 07/49] wip --- .librarian/state.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 028e6d89a4..32336eb8bf 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -13,5 +13,8 @@ libraries: source_roots: - . preserve_regex: [] - remove_regex: [] + remove_regex: + - google/cloud/spanner_admin_database_v1 + - google/cloud/spanner_admin_instance_v1 + - google/cloud/spanner_v1 tag_format: v{version} From dadc2050387bf11c682ead398c8a3d8f864657b5 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 12:17:10 +0000 Subject: [PATCH 08/49] wip --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 32336eb8bf..c2d9c98129 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:27eae7edfe88876a47cbdb89ec6491192706e94ce46ac0e3ff4d202ef3220fed +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:latest libraries: - id: google-cloud-spanner version: 3.59.0 From 382734883b0165b9f7605decf99494e899894af4 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 12:33:11 +0000 Subject: [PATCH 09/49] wip --- .librarian/state.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index c2d9c98129..f25e5e4244 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -17,4 +17,5 @@ libraries: - google/cloud/spanner_admin_database_v1 - google/cloud/spanner_admin_instance_v1 - google/cloud/spanner_v1 + - .coveragerc tag_format: v{version} From 226249205994dc70ebed9ac55b58a412819f1dc7 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 12:37:55 +0000 Subject: [PATCH 10/49] wip --- .librarian/state.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index f25e5e4244..6f79da14e8 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -18,4 +18,5 @@ libraries: - google/cloud/spanner_admin_instance_v1 - google/cloud/spanner_v1 - .coveragerc + - .flake8 tag_format: v{version} From 110d72cb4dc4e5ffe33e11b851be530172e912b6 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 12:41:09 +0000 Subject: [PATCH 11/49] wip --- .librarian/state.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 6f79da14e8..fba286ff59 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -19,4 +19,6 @@ libraries: - google/cloud/spanner_v1 - .coveragerc - .flake8 + - .github + - .gitignore tag_format: v{version} From a8e0f0d111cae8c1c7f6ead453ce15f9a3ab3402 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Thu, 6 Nov 2025 23:19:04 +0000 Subject: [PATCH 12/49] wip --- .librarian/state.yaml | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index fba286ff59..f77a1752a5 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -14,11 +14,28 @@ libraries: - . preserve_regex: [] remove_regex: - - google/cloud/spanner_admin_database_v1 - - google/cloud/spanner_admin_instance_v1 - - google/cloud/spanner_v1 - - .coveragerc - - .flake8 - - .github - - .gitignore + - ^google/pubsub + - ^google/pubsub_v1 + - ^tests/unit/gapic + - ^tests/__init__.py + - ^tests/unit/__init__.py + - ^.coveragerc + - ^.flake8 + - ^.pre-commit-config.yaml + - ^.repo-metadata.json + - ^.trampolinerc + - ^LICENSE + - ^MANIFEST.in + - ^SECURITY.md + - ^mypy.ini + - ^noxfile.py + - ^owlbot.py + - ^renovate.json + - ^samples/AUTHORING_GUIDE.md + - ^samples/CONTRIBUTING.md + - ^samples/generated_samples + - ^scripts/fixup_pubsub_v1_keywords.py + - ^setup.py + - ^testing/constraints-3.9 + - ^testing/constraints-3.1 tag_format: v{version} From 0739b8e28a15d03c7a7314714beeb523279331e0 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 00:18:34 +0000 Subject: [PATCH 13/49] wip --- .librarian/state.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index f77a1752a5..49d9506906 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:latest +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:27eae7edfe88876a47cbdb89ec6491192706e94ce46ac0e3ff4d202ef3220fed libraries: - id: google-cloud-spanner version: 3.59.0 @@ -14,8 +14,9 @@ libraries: - . preserve_regex: [] remove_regex: - - ^google/pubsub - - ^google/pubsub_v1 + - ^google/cloud/spanner_v1 + - ^google/cloud/spanner_admin_database_v1 + - ^google/cloud/spanner_admin_instance_v1 - ^tests/unit/gapic - ^tests/__init__.py - ^tests/unit/__init__.py From fa3971ba52d52da7bc3f29f340900361d6e6cead Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 00:33:14 +0000 Subject: [PATCH 14/49] wip --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 49d9506906..25493fcb8d 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -14,7 +14,7 @@ libraries: - . preserve_regex: [] remove_regex: - - ^google/cloud/spanner_v1 + - ^google/cloud/spanner_v1/services/spanner - ^google/cloud/spanner_admin_database_v1 - ^google/cloud/spanner_admin_instance_v1 - ^tests/unit/gapic From 48d37dd00d155664cf0fc0cdb35852cb74c88a9a Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 01:02:58 +0000 Subject: [PATCH 15/49] wip --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 25493fcb8d..76d6c8dc1a 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:27eae7edfe88876a47cbdb89ec6491192706e94ce46ac0e3ff4d202ef3220fed +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:latest libraries: - id: google-cloud-spanner version: 3.59.0 From 79dd6dc64b6ea4cefdc01224cf267d8f593419a2 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 01:20:09 +0000 Subject: [PATCH 16/49] wip --- owlbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owlbot.py b/owlbot.py index deda1925b4..0abf22c6da 100644 --- a/owlbot.py +++ b/owlbot.py @@ -76,7 +76,7 @@ def get_staging_dirs( clean_up_generated_samples = True -for library in get_staging_dirs(spanner_default_version, "spanner"): +for library in get_staging_dirs("v1"): if clean_up_generated_samples: shutil.rmtree("samples/generated_samples", ignore_errors=True) clean_up_generated_samples = False From 4c459ace29b026ba0079169c1fa1d4a05afeffde Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 01:20:43 +0000 Subject: [PATCH 17/49] wip --- .librarian/generator-input/owlbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py index deda1925b4..0abf22c6da 100644 --- a/.librarian/generator-input/owlbot.py +++ b/.librarian/generator-input/owlbot.py @@ -76,7 +76,7 @@ def get_staging_dirs( clean_up_generated_samples = True -for library in get_staging_dirs(spanner_default_version, "spanner"): +for library in get_staging_dirs("v1"): if clean_up_generated_samples: shutil.rmtree("samples/generated_samples", ignore_errors=True) clean_up_generated_samples = False From 37dff4c16eb4d2b1a7f93764d907d5b1553f83ee Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 01:34:30 +0000 Subject: [PATCH 18/49] wip --- .librarian/generator-input/owlbot.py | 87 +++++----------------------- 1 file changed, 14 insertions(+), 73 deletions(-) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py index 0abf22c6da..be6abc988e 100644 --- a/.librarian/generator-input/owlbot.py +++ b/.librarian/generator-input/owlbot.py @@ -25,58 +25,9 @@ common = gcp.CommonTemplates() - -def get_staging_dirs( - # This is a customized version of the s.get_staging_dirs() function - # from synthtool to # cater for copying 3 different folders from - # googleapis-gen: - # spanner, spanner/admin/instance and spanner/admin/database. - # Source: - # https://github.com/googleapis/synthtool/blob/master/synthtool/transforms.py#L280 - default_version: Optional[str] = None, - sub_directory: Optional[str] = None, -) -> List[Path]: - """Returns the list of directories, one per version, copied from - https://github.com/googleapis/googleapis-gen. Will return in lexical sorting - order with the exception of the default_version which will be last (if specified). - - Args: - default_version (str): the default version of the API. The directory for this version - will be the last item in the returned list if specified. - sub_directory (str): if a `sub_directory` is provided, only the directories within the - specified `sub_directory` will be returned. - - Returns: the empty list if no file were copied. - """ - - staging = Path("owl-bot-staging") - - if sub_directory: - staging /= sub_directory - - if staging.is_dir(): - # Collect the subdirectories of the staging directory. - versions = [v.name for v in staging.iterdir() if v.is_dir()] - # Reorder the versions so the default version always comes last. - versions = [v for v in versions if v != default_version] - versions.sort() - if default_version is not None: - versions += [default_version] - dirs = [staging / v for v in versions] - for dir in dirs: - s._tracked_paths.add(dir) - return dirs - else: - return [] - - -spanner_default_version = "v1" -spanner_admin_instance_default_version = "v1" -spanner_admin_database_default_version = "v1" - clean_up_generated_samples = True -for library in get_staging_dirs("v1"): +for library in "v1": if clean_up_generated_samples: shutil.rmtree("samples/generated_samples", ignore_errors=True) clean_up_generated_samples = False @@ -202,22 +153,7 @@ def get_staging_dirs( if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - s.move( - library, - excludes=[ - "google/cloud/spanner/**", - "*.*", - "noxfile.py", - "docs/index.rst", - "google/cloud/spanner_v1/__init__.py", - "**/gapic_version.py", - "testing/constraints-3.7.txt", - ], - ) -for library in get_staging_dirs( - spanner_admin_instance_default_version, "spanner_admin_instance" -): count = s.replace( [ library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", @@ -233,14 +169,7 @@ def get_staging_dirs( ) if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - s.move( - library, - excludes=["google/cloud/spanner_admin_instance/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], - ) -for library in get_staging_dirs( - spanner_admin_database_default_version, "spanner_admin_database" -): count = s.replace( [ library / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", @@ -256,11 +185,23 @@ def get_staging_dirs( ) if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") + s.move( library, - excludes=["google/cloud/spanner_admin_database/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], + excludes=[ + "google/cloud/spanner/**", + "google/cloud/spanner_admin_instance/**" + "google/cloud/spanner_admin_database/**" + "*.*", + "noxfile.py", + "docs/index.rst", + "google/cloud/spanner_v1/__init__.py", + "**/gapic_version.py", + "testing/constraints-3.7.txt", + ], ) + s.remove_staging_dirs() # ---------------------------------------------------------------------------- From de360eeee947a8f5546bc0b34128d76101d5b744 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 01:40:04 +0000 Subject: [PATCH 19/49] wip --- config.yaml | 6 ++++ owlbot.py | 87 +++++++++-------------------------------------------- 2 files changed, 20 insertions(+), 73 deletions(-) create mode 100644 config.yaml diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000000..8d9022e45b --- /dev/null +++ b/config.yaml @@ -0,0 +1,6 @@ +global_files_allowlist: + # Allow the container to read and write the root `CHANGELOG.md` + # file during the `release` step to update the latest client library + # versions which are hardcoded in the file. + - path: "CHANGELOG.md" + permissions: "read-write" \ No newline at end of file diff --git a/owlbot.py b/owlbot.py index 0abf22c6da..f9ca02c02c 100644 --- a/owlbot.py +++ b/owlbot.py @@ -25,58 +25,9 @@ common = gcp.CommonTemplates() - -def get_staging_dirs( - # This is a customized version of the s.get_staging_dirs() function - # from synthtool to # cater for copying 3 different folders from - # googleapis-gen: - # spanner, spanner/admin/instance and spanner/admin/database. - # Source: - # https://github.com/googleapis/synthtool/blob/master/synthtool/transforms.py#L280 - default_version: Optional[str] = None, - sub_directory: Optional[str] = None, -) -> List[Path]: - """Returns the list of directories, one per version, copied from - https://github.com/googleapis/googleapis-gen. Will return in lexical sorting - order with the exception of the default_version which will be last (if specified). - - Args: - default_version (str): the default version of the API. The directory for this version - will be the last item in the returned list if specified. - sub_directory (str): if a `sub_directory` is provided, only the directories within the - specified `sub_directory` will be returned. - - Returns: the empty list if no file were copied. - """ - - staging = Path("owl-bot-staging") - - if sub_directory: - staging /= sub_directory - - if staging.is_dir(): - # Collect the subdirectories of the staging directory. - versions = [v.name for v in staging.iterdir() if v.is_dir()] - # Reorder the versions so the default version always comes last. - versions = [v for v in versions if v != default_version] - versions.sort() - if default_version is not None: - versions += [default_version] - dirs = [staging / v for v in versions] - for dir in dirs: - s._tracked_paths.add(dir) - return dirs - else: - return [] - - -spanner_default_version = "v1" -spanner_admin_instance_default_version = "v1" -spanner_admin_database_default_version = "v1" - clean_up_generated_samples = True -for library in get_staging_dirs("v1"): +for library in s.get_staging_dirs("v1"): if clean_up_generated_samples: shutil.rmtree("samples/generated_samples", ignore_errors=True) clean_up_generated_samples = False @@ -202,22 +153,7 @@ def get_staging_dirs( if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - s.move( - library, - excludes=[ - "google/cloud/spanner/**", - "*.*", - "noxfile.py", - "docs/index.rst", - "google/cloud/spanner_v1/__init__.py", - "**/gapic_version.py", - "testing/constraints-3.7.txt", - ], - ) -for library in get_staging_dirs( - spanner_admin_instance_default_version, "spanner_admin_instance" -): count = s.replace( [ library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", @@ -233,14 +169,7 @@ def get_staging_dirs( ) if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - s.move( - library, - excludes=["google/cloud/spanner_admin_instance/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], - ) -for library in get_staging_dirs( - spanner_admin_database_default_version, "spanner_admin_database" -): count = s.replace( [ library / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", @@ -256,11 +185,23 @@ def get_staging_dirs( ) if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") + s.move( library, - excludes=["google/cloud/spanner_admin_database/**", "*.*", "docs/index.rst", "noxfile.py", "**/gapic_version.py", "testing/constraints-3.7.txt",], + excludes=[ + "google/cloud/spanner/**", + "google/cloud/spanner_admin_instance/**" + "google/cloud/spanner_admin_database/**" + "*.*", + "noxfile.py", + "docs/index.rst", + "google/cloud/spanner_v1/__init__.py", + "**/gapic_version.py", + "testing/constraints-3.7.txt", + ], ) + s.remove_staging_dirs() # ---------------------------------------------------------------------------- From 59b71381fa304a2d0ce86f7293719b1e295497d2 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 01:42:23 +0000 Subject: [PATCH 20/49] wip --- .librarian/generator-input/owlbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py index be6abc988e..f9ca02c02c 100644 --- a/.librarian/generator-input/owlbot.py +++ b/.librarian/generator-input/owlbot.py @@ -27,7 +27,7 @@ clean_up_generated_samples = True -for library in "v1": +for library in s.get_staging_dirs("v1"): if clean_up_generated_samples: shutil.rmtree("samples/generated_samples", ignore_errors=True) clean_up_generated_samples = False From 0f74181d1d01e65686fe50fe8ad79ccd2cb5dc06 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 01:58:56 +0000 Subject: [PATCH 21/49] wip --- .librarian/state.yaml | 14 +++++++++++++- owlbot.py | 29 +++++------------------------ 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 76d6c8dc1a..fde54f5a1b 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -14,7 +14,10 @@ libraries: - . preserve_regex: [] remove_regex: - - ^google/cloud/spanner_v1/services/spanner + - ^google/cloud/spanner_v1/gapic_metadata.json + - ^google/cloud/spanner_v1/gapic_version.py + - ^google/cloud/spanner_v1/py.typed + - ^google/cloud/spanner_v1/services - ^google/cloud/spanner_admin_database_v1 - ^google/cloud/spanner_admin_instance_v1 - ^tests/unit/gapic @@ -39,4 +42,13 @@ libraries: - ^setup.py - ^testing/constraints-3.9 - ^testing/constraints-3.1 + - ^docs/_static + - ^docs/_templates + - ^docs/spanner_v1 + - ^docs/spanner_admin_database_v1 + - ^docs/spanner_admin_instance_v1 + - ^docs/conf.py + - ^docs/index.rst + - ^docs/multiprocessing.rst + - ^docs/summary_overview.md tag_format: v{version} diff --git a/owlbot.py b/owlbot.py index f9ca02c02c..4f85d064a8 100644 --- a/owlbot.py +++ b/owlbot.py @@ -153,7 +153,6 @@ if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - count = s.replace( [ library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", @@ -185,23 +184,20 @@ ) if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - s.move( library, excludes=[ "google/cloud/spanner/**", - "google/cloud/spanner_admin_instance/**" - "google/cloud/spanner_admin_database/**" "*.*", "noxfile.py", "docs/index.rst", "google/cloud/spanner_v1/__init__.py", - "**/gapic_version.py", "testing/constraints-3.7.txt", + "google/cloud/spanner_admin_instance/**", + "google/cloud/spanner_admin_database/**" ], ) - s.remove_staging_dirs() # ---------------------------------------------------------------------------- @@ -219,27 +215,12 @@ templated_files, excludes=[ ".coveragerc", - ".github/workflows", # exclude gh actions as credentials are needed for tests + ".github/**", + ".kokoro/**", "README.rst", - ".github/release-please.yml", - ".kokoro/test-samples-impl.sh", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/samples/python3.7/**", - ".kokoro/samples/python3.8/**", ], ) -# Ensure CI runs on a new instance each time -s.replace( - ".kokoro/build.sh", - "# Setup project id.", - """\ -# Set up creating a new instance for each system test run -export GOOGLE_CLOUD_TESTS_CREATE_SPANNER_INSTANCE=true - -# Setup project id.""", -) - # Update samples folder in CONTRIBUTING.rst s.replace("CONTRIBUTING.rst", "samples/snippets", "samples/samples") @@ -262,4 +243,4 @@ # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) +s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) \ No newline at end of file From 03c5f47035ac284fcb0fdea5c7cc8ff150d79ff7 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 02:02:48 +0000 Subject: [PATCH 22/49] wip --- .librarian/generator-input/owlbot.py | 29 +++++----------------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py index f9ca02c02c..4f85d064a8 100644 --- a/.librarian/generator-input/owlbot.py +++ b/.librarian/generator-input/owlbot.py @@ -153,7 +153,6 @@ if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - count = s.replace( [ library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", @@ -185,23 +184,20 @@ ) if count < 1: raise Exception("Expected replacements for gRPC channel options not made.") - s.move( library, excludes=[ "google/cloud/spanner/**", - "google/cloud/spanner_admin_instance/**" - "google/cloud/spanner_admin_database/**" "*.*", "noxfile.py", "docs/index.rst", "google/cloud/spanner_v1/__init__.py", - "**/gapic_version.py", "testing/constraints-3.7.txt", + "google/cloud/spanner_admin_instance/**", + "google/cloud/spanner_admin_database/**" ], ) - s.remove_staging_dirs() # ---------------------------------------------------------------------------- @@ -219,27 +215,12 @@ templated_files, excludes=[ ".coveragerc", - ".github/workflows", # exclude gh actions as credentials are needed for tests + ".github/**", + ".kokoro/**", "README.rst", - ".github/release-please.yml", - ".kokoro/test-samples-impl.sh", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/samples/python3.7/**", - ".kokoro/samples/python3.8/**", ], ) -# Ensure CI runs on a new instance each time -s.replace( - ".kokoro/build.sh", - "# Setup project id.", - """\ -# Set up creating a new instance for each system test run -export GOOGLE_CLOUD_TESTS_CREATE_SPANNER_INSTANCE=true - -# Setup project id.""", -) - # Update samples folder in CONTRIBUTING.rst s.replace("CONTRIBUTING.rst", "samples/snippets", "samples/samples") @@ -262,4 +243,4 @@ # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) +s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) \ No newline at end of file From 98003fbc027be4572722271f461f269b19554c62 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 7 Nov 2025 02:20:16 +0000 Subject: [PATCH 23/49] wip --- .librarian/generator-input/config.yaml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .librarian/generator-input/config.yaml diff --git a/.librarian/generator-input/config.yaml b/.librarian/generator-input/config.yaml deleted file mode 100644 index 8d9022e45b..0000000000 --- a/.librarian/generator-input/config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -global_files_allowlist: - # Allow the container to read and write the root `CHANGELOG.md` - # file during the `release` step to update the latest client library - # versions which are hardcoded in the file. - - path: "CHANGELOG.md" - permissions: "read-write" \ No newline at end of file From 3341cfba53045fa415d55b80734e9455fa607901 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Sat, 8 Nov 2025 00:57:48 +0000 Subject: [PATCH 24/49] wip --- .librarian/generator-input/owlbot.py | 2 +- .librarian/state.yaml | 6 ++++-- owlbot.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/owlbot.py index 4f85d064a8..31efb36c92 100644 --- a/.librarian/generator-input/owlbot.py +++ b/.librarian/generator-input/owlbot.py @@ -243,4 +243,4 @@ # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) \ No newline at end of file +s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index fde54f5a1b..118ecc9e0e 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-spanner version: 3.59.0 - last_generated_commit: 3a77bd60b37c086effb39819e9183fbc83e3a693 + last_generated_commit: 9fcfbea0aa5b50fa22e190faceb073d74504172b apis: - path: google/spanner/v1 service_config: spanner.yaml @@ -18,6 +18,7 @@ libraries: - ^google/cloud/spanner_v1/gapic_version.py - ^google/cloud/spanner_v1/py.typed - ^google/cloud/spanner_v1/services + - ^google/cloud/spanner_v1/types - ^google/cloud/spanner_admin_database_v1 - ^google/cloud/spanner_admin_instance_v1 - ^tests/unit/gapic @@ -38,8 +39,9 @@ libraries: - ^samples/AUTHORING_GUIDE.md - ^samples/CONTRIBUTING.md - ^samples/generated_samples - - ^scripts/fixup_pubsub_v1_keywords.py + - ^scripts/fixup_ - ^setup.py + - ^testing/constraints-3.8 - ^testing/constraints-3.9 - ^testing/constraints-3.1 - ^docs/_static diff --git a/owlbot.py b/owlbot.py index 4f85d064a8..31efb36c92 100644 --- a/owlbot.py +++ b/owlbot.py @@ -243,4 +243,4 @@ # Use a python runtime which is available in the owlbot post processor here # https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) \ No newline at end of file +s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) From 8caed48ffde870096ce95782f7ea4d46506caf28 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Sat, 8 Nov 2025 01:09:05 +0000 Subject: [PATCH 25/49] wip --- .librarian/state.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 118ecc9e0e..0a4cfc9c24 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-spanner version: 3.59.0 - last_generated_commit: 9fcfbea0aa5b50fa22e190faceb073d74504172b + last_generated_commit: 1b5f8632487bce889ce05366647addc6ef5ee36d apis: - path: google/spanner/v1 service_config: spanner.yaml @@ -24,7 +24,6 @@ libraries: - ^tests/unit/gapic - ^tests/__init__.py - ^tests/unit/__init__.py - - ^.coveragerc - ^.flake8 - ^.pre-commit-config.yaml - ^.repo-metadata.json From c9d8e403e946c5cd9e9f732087e0dd2bfd526adf Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 10 Nov 2025 05:36:16 +0000 Subject: [PATCH 26/49] update sha --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 0a4cfc9c24..95fb113138 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:latest +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:@sha256:39628f6e89c9cad27973b9a39a50f7052bec0435ee58c7027b4fa6b655943e31 libraries: - id: google-cloud-spanner version: 3.59.0 From c957278faa2b804fa144053ac72c61499b429448 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 10 Nov 2025 05:39:33 +0000 Subject: [PATCH 27/49] update sha --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 95fb113138..e7edc44d15 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:@sha256:39628f6e89c9cad27973b9a39a50f7052bec0435ee58c7027b4fa6b655943e31 +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:39628f6e89c9cad27973b9a39a50f7052bec0435ee58c7027b4fa6b655943e31 libraries: - id: google-cloud-spanner version: 3.59.0 From 6ff03e8bdd0789b8225e2896cccd7857134dd500 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 10 Nov 2025 05:46:25 +0000 Subject: [PATCH 28/49] wip --- .librarian/state.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index e7edc44d15..724f22eecc 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -23,8 +23,7 @@ libraries: - ^google/cloud/spanner_admin_instance_v1 - ^tests/unit/gapic - ^tests/__init__.py - - ^tests/unit/__init__.py - - ^.flake8 + - ^tests/unit/__init__.pyå - ^.pre-commit-config.yaml - ^.repo-metadata.json - ^.trampolinerc From 6cd13c0903a6eef1625e4f3de629cb60024d4af9 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 10 Nov 2025 21:44:14 +0000 Subject: [PATCH 29/49] wip --- .librarian/state.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 724f22eecc..3b06ed2ad8 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -28,6 +28,7 @@ libraries: - ^.repo-metadata.json - ^.trampolinerc - ^LICENSE + - ^.flake8 - ^MANIFEST.in - ^SECURITY.md - ^mypy.ini From 9a6788cb89107fb03ca3ee4169801a6d5ef43396 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 10 Nov 2025 21:54:38 +0000 Subject: [PATCH 30/49] wip --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 3b06ed2ad8..994c4b3a39 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -23,7 +23,7 @@ libraries: - ^google/cloud/spanner_admin_instance_v1 - ^tests/unit/gapic - ^tests/__init__.py - - ^tests/unit/__init__.pyå + - ^tests/unit/__init__.py - ^.pre-commit-config.yaml - ^.repo-metadata.json - ^.trampolinerc From 440652923d54931f1beb449aca9e61bf97fc1d98 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 22:01:47 +0000 Subject: [PATCH 31/49] wip --- .librarian/state.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 994c4b3a39..c13e4099cb 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -28,8 +28,6 @@ libraries: - ^.repo-metadata.json - ^.trampolinerc - ^LICENSE - - ^.flake8 - - ^MANIFEST.in - ^SECURITY.md - ^mypy.ini - ^noxfile.py From 2bcf275062de02ea1de0b849c9ca3b3ff123c037 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 22:11:03 +0000 Subject: [PATCH 32/49] wip --- .librarian/state.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index c13e4099cb..c2ea7714f6 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-spanner version: 3.59.0 - last_generated_commit: 1b5f8632487bce889ce05366647addc6ef5ee36d + last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 apis: - path: google/spanner/v1 service_config: spanner.yaml @@ -43,11 +43,11 @@ libraries: - ^testing/constraints-3.1 - ^docs/_static - ^docs/_templates - - ^docs/spanner_v1 + - ^docs/spanner_v1/services_.rst + - ^docs/spanner_v1/spanner.rst + - ^docs/spanner_v1/types.rst - ^docs/spanner_admin_database_v1 - ^docs/spanner_admin_instance_v1 - - ^docs/conf.py - - ^docs/index.rst - ^docs/multiprocessing.rst - ^docs/summary_overview.md tag_format: v{version} From 77c5cf46d006bf560b475cf30d0178cd6f6e1df8 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 22:21:49 +0000 Subject: [PATCH 33/49] wip --- .librarian/state.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index c2ea7714f6..0de15ef4ff 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -41,6 +41,7 @@ libraries: - ^testing/constraints-3.8 - ^testing/constraints-3.9 - ^testing/constraints-3.1 + - ^docs/conf.py - ^docs/_static - ^docs/_templates - ^docs/spanner_v1/services_.rst From 6961967022bd9220c532b914dc23d581fddb57c7 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 22:47:20 +0000 Subject: [PATCH 34/49] wip --- .librarian/state.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 0de15ef4ff..2e3ea1d9cd 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -43,6 +43,7 @@ libraries: - ^testing/constraints-3.1 - ^docs/conf.py - ^docs/_static + - ^docs/spanner_v1/types_.rst - ^docs/_templates - ^docs/spanner_v1/services_.rst - ^docs/spanner_v1/spanner.rst From 872a5ddae3092e25e6ab5f30915bb6b683b08fed Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 22:50:34 +0000 Subject: [PATCH 35/49] generated changes --- docs/conf.py | 34 ++++++++++++++++++- .../gapic_version.py | 2 +- .../gapic_version.py | 2 +- google/cloud/spanner_v1/gapic_version.py | 2 +- ...data_google.spanner.admin.database.v1.json | 2 +- ...data_google.spanner.admin.instance.v1.json | 2 +- .../snippet_metadata_google.spanner.v1.json | 2 +- setup.py | 19 ++++++----- 8 files changed, 50 insertions(+), 15 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 64058683e8..f4956b9108 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ # limitations under the License. # # -# google-cloud-spanner-admin-database documentation build configuration file +# google-cloud-spanner-admin-instance documentation build configuration file # # This file is execfile()d with the current directory set to its # containing dir. @@ -81,9 +81,15 @@ root_doc = "index" # General information about the project. +<<<<<<< HEAD project = "google-cloud-spanner-admin-database" copyright = "2025, Google, LLC" author = "Google APIs" +======= +project = u"google-cloud-spanner-admin-instance" +copyright = u"2025, Google, LLC" +author = u"Google APIs" +>>>>>>> ea2fb81 (generated changes) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -155,7 +161,11 @@ # further. For a list of options available for each theme, see the # documentation. html_theme_options = { +<<<<<<< HEAD "description": "Google Cloud Client Libraries for google-cloud-spanner-admin-database", +======= + "description": "Google Cloud Client Libraries for google-cloud-spanner-admin-instance", +>>>>>>> ea2fb81 (generated changes) "github_user": "googleapis", "github_repo": "google-cloud-python", "github_banner": True, @@ -249,7 +259,11 @@ # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. +<<<<<<< HEAD htmlhelp_basename = "google-cloud-spanner-admin-database-doc" +======= +htmlhelp_basename = "google-cloud-spanner-admin-instance-doc" +>>>>>>> ea2fb81 (generated changes) # -- Options for warnings ------------------------------------------------------ @@ -282,8 +296,13 @@ latex_documents = [ ( root_doc, +<<<<<<< HEAD "google-cloud-spanner-admin-database.tex", "google-cloud-spanner-admin-database Documentation", +======= + "google-cloud-spanner-admin-instance.tex", + u"google-cloud-spanner-admin-instance Documentation", +>>>>>>> ea2fb81 (generated changes) author, "manual", ) @@ -317,8 +336,13 @@ man_pages = [ ( root_doc, +<<<<<<< HEAD "google-cloud-spanner-admin-database", "google-cloud-spanner-admin-database Documentation", +======= + "google-cloud-spanner-admin-instance", + "google-cloud-spanner-admin-instance Documentation", +>>>>>>> ea2fb81 (generated changes) [author], 1, ) @@ -336,11 +360,19 @@ texinfo_documents = [ ( root_doc, +<<<<<<< HEAD "google-cloud-spanner-admin-database", "google-cloud-spanner-admin-database Documentation", author, "google-cloud-spanner-admin-database", "google-cloud-spanner-admin-database Library", +======= + "google-cloud-spanner-admin-instance", + "google-cloud-spanner-admin-instance Documentation", + author, + "google-cloud-spanner-admin-instance", + "google-cloud-spanner-admin-instance Library", +>>>>>>> ea2fb81 (generated changes) "APIs", ) ] diff --git a/google/cloud/spanner_admin_database_v1/gapic_version.py b/google/cloud/spanner_admin_database_v1/gapic_version.py index 17acb3026a..745f02e051 100644 --- a/google/cloud/spanner_admin_database_v1/gapic_version.py +++ b/google/cloud/spanner_admin_database_v1/gapic_version.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2022 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/google/cloud/spanner_admin_instance_v1/gapic_version.py b/google/cloud/spanner_admin_instance_v1/gapic_version.py index 17acb3026a..745f02e051 100644 --- a/google/cloud/spanner_admin_instance_v1/gapic_version.py +++ b/google/cloud/spanner_admin_instance_v1/gapic_version.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2022 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/google/cloud/spanner_v1/gapic_version.py b/google/cloud/spanner_v1/gapic_version.py index 17acb3026a..745f02e051 100644 --- a/google/cloud/spanner_v1/gapic_version.py +++ b/google/cloud/spanner_v1/gapic_version.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2022 Google LLC +# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json b/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json index e89008727d..e6eeb1f977 100644 --- a/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json +++ b/samples/generated_samples/snippet_metadata_google.spanner.admin.database.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner-admin-database", - "version": "0.0.0" + "version": "3.59.0" }, "snippets": [ { diff --git a/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json b/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json index f58e9794e2..92ae0279ef 100644 --- a/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json +++ b/samples/generated_samples/snippet_metadata_google.spanner.admin.instance.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner-admin-instance", - "version": "0.0.0" + "version": "3.59.0" }, "snippets": [ { diff --git a/samples/generated_samples/snippet_metadata_google.spanner.v1.json b/samples/generated_samples/snippet_metadata_google.spanner.v1.json index f7f33c3d29..4d84b1ab9a 100644 --- a/samples/generated_samples/snippet_metadata_google.spanner.v1.json +++ b/samples/generated_samples/snippet_metadata_google.spanner.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-spanner", - "version": "0.0.0" + "version": "3.59.0" }, "snippets": [ { diff --git a/setup.py b/setup.py index 216b095d0b..858982f783 100644 --- a/setup.py +++ b/setup.py @@ -44,15 +44,18 @@ "proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "grpc-interceptor >= 0.15.4", - # Make OpenTelemetry a core dependency - "opentelemetry-api >= 1.22.0", - "opentelemetry-sdk >= 1.22.0", - "opentelemetry-semantic-conventions >= 0.43b0", - "opentelemetry-resourcedetector-gcp >= 1.8.0a0", - "google-cloud-monitoring >= 2.16.0", - "mmh3 >= 4.1.0 ", ] -extras = {"libcst": "libcst >= 0.2.5"} +extras = { + "tracing": [ + "opentelemetry-api >= 1.22.0", + "opentelemetry-sdk >= 1.22.0", + "opentelemetry-semantic-conventions >= 0.43b0", + "opentelemetry-resourcedetector-gcp >= 1.8.0a0", + "google-cloud-monitoring >= 2.16.0", + "mmh3 >= 4.1.0 ", + ], + "libcst": "libcst >= 0.2.5", +} url = "https://github.com/googleapis/python-spanner" From 8d7d9825e222e0cc284ee5ae043cd2a285834bfc Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 22:51:14 +0000 Subject: [PATCH 36/49] update sha --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 2e3ea1d9cd..7136aadc7c 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:39628f6e89c9cad27973b9a39a50f7052bec0435ee58c7027b4fa6b655943e31 +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:c8612d3fffb3f6a32353b2d1abd16b61e87811866f7ec9d65b59b02eb452a620 libraries: - id: google-cloud-spanner version: 3.59.0 From 7d3fe8d0c835eb70c2ad22952af1d7997af4ebc2 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 22:53:16 +0000 Subject: [PATCH 37/49] remove files --- .github/auto-approve.yml | 3 --- .github/release-trigger.yml | 2 -- .github/snippet-bot.yml | 0 .github/sync-repo-settings.yaml | 15 --------------- 4 files changed, 20 deletions(-) delete mode 100644 .github/auto-approve.yml delete mode 100644 .github/release-trigger.yml delete mode 100644 .github/snippet-bot.yml delete mode 100644 .github/sync-repo-settings.yaml diff --git a/.github/auto-approve.yml b/.github/auto-approve.yml deleted file mode 100644 index 311ebbb853..0000000000 --- a/.github/auto-approve.yml +++ /dev/null @@ -1,3 +0,0 @@ -# https://github.com/googleapis/repo-automation-bots/tree/main/packages/auto-approve -processes: - - "OwlBotTemplateChanges" diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml deleted file mode 100644 index 3c0f1bfc7e..0000000000 --- a/.github/release-trigger.yml +++ /dev/null @@ -1,2 +0,0 @@ -enabled: true -multiScmName: python-spanner diff --git a/.github/snippet-bot.yml b/.github/snippet-bot.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml deleted file mode 100644 index d726d1193d..0000000000 --- a/.github/sync-repo-settings.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# https://github.com/googleapis/repo-automation-bots/tree/main/packages/sync-repo-settings -# Rules for main branch protection -branchProtectionRules: -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `main` -- pattern: main - requiresCodeOwnerReviews: true - requiresStrictStatusChecks: true - requiredStatusCheckContexts: - - 'Kokoro' - - 'Kokoro system-3.12' - - 'cla/google' - - 'Samples - Lint' - - 'Samples - Python 3.9' - - 'Samples - Python 3.12' From 9ed7010c5cbb2cb74f431eb6d50f69c3a77ed4ca Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 12 Nov 2025 02:10:22 +0000 Subject: [PATCH 38/49] update python version for lint --- .github/workflows/presubmit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/presubmit.yaml b/.github/workflows/presubmit.yaml index 67db6136d1..6e5f1af29b 100644 --- a/.github/workflows/presubmit.yaml +++ b/.github/workflows/presubmit.yaml @@ -17,7 +17,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v6 with: - python-version: 3.13 + python-version: 3.14 - name: Install nox run: python -m pip install nox - name: Check formatting From 7233ab133fb2855089a04101188618ee9f17a36c Mon Sep 17 00:00:00 2001 From: ohmayr Date: Fri, 14 Nov 2025 02:36:04 +0000 Subject: [PATCH 39/49] revert setup file to main --- setup.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/setup.py b/setup.py index 858982f783..216b095d0b 100644 --- a/setup.py +++ b/setup.py @@ -44,18 +44,15 @@ "proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", "grpc-interceptor >= 0.15.4", + # Make OpenTelemetry a core dependency + "opentelemetry-api >= 1.22.0", + "opentelemetry-sdk >= 1.22.0", + "opentelemetry-semantic-conventions >= 0.43b0", + "opentelemetry-resourcedetector-gcp >= 1.8.0a0", + "google-cloud-monitoring >= 2.16.0", + "mmh3 >= 4.1.0 ", ] -extras = { - "tracing": [ - "opentelemetry-api >= 1.22.0", - "opentelemetry-sdk >= 1.22.0", - "opentelemetry-semantic-conventions >= 0.43b0", - "opentelemetry-resourcedetector-gcp >= 1.8.0a0", - "google-cloud-monitoring >= 2.16.0", - "mmh3 >= 4.1.0 ", - ], - "libcst": "libcst >= 0.2.5", -} +extras = {"libcst": "libcst >= 0.2.5"} url = "https://github.com/googleapis/python-spanner" From 3d449e6a1dcf5501af0a312839595917e8f585ed Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 17 Nov 2025 23:20:22 +0000 Subject: [PATCH 40/49] reorder apis --- .librarian/state.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 7136aadc7c..e277d77af6 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -4,12 +4,12 @@ libraries: version: 3.59.0 last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 apis: - - path: google/spanner/v1 - service_config: spanner.yaml - path: google/spanner/admin/database/v1 service_config: spanner.yaml - path: google/spanner/admin/instance/v1 service_config: spanner.yaml + - path: google/spanner/v1 + service_config: spanner.yaml source_roots: - . preserve_regex: [] From 1bac37d776f560f26adc73b485f64e4f532761ab Mon Sep 17 00:00:00 2001 From: ohmayr Date: Mon, 17 Nov 2025 23:31:09 +0000 Subject: [PATCH 41/49] fix docs --- .librarian/state.yaml | 2 +- docs/conf.py | 32 -------------------------------- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index e277d77af6..d7f8c76918 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-spanner version: 3.59.0 - last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 + last_generated_commit: 136201b66f70829232b7ec63fa6e35ca765bcacb apis: - path: google/spanner/admin/database/v1 service_config: spanner.yaml diff --git a/docs/conf.py b/docs/conf.py index f4956b9108..4e0af4e74e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -81,15 +81,9 @@ root_doc = "index" # General information about the project. -<<<<<<< HEAD -project = "google-cloud-spanner-admin-database" -copyright = "2025, Google, LLC" -author = "Google APIs" -======= project = u"google-cloud-spanner-admin-instance" copyright = u"2025, Google, LLC" author = u"Google APIs" ->>>>>>> ea2fb81 (generated changes) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -161,11 +155,7 @@ # further. For a list of options available for each theme, see the # documentation. html_theme_options = { -<<<<<<< HEAD - "description": "Google Cloud Client Libraries for google-cloud-spanner-admin-database", -======= "description": "Google Cloud Client Libraries for google-cloud-spanner-admin-instance", ->>>>>>> ea2fb81 (generated changes) "github_user": "googleapis", "github_repo": "google-cloud-python", "github_banner": True, @@ -259,11 +249,7 @@ # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -<<<<<<< HEAD -htmlhelp_basename = "google-cloud-spanner-admin-database-doc" -======= htmlhelp_basename = "google-cloud-spanner-admin-instance-doc" ->>>>>>> ea2fb81 (generated changes) # -- Options for warnings ------------------------------------------------------ @@ -296,13 +282,8 @@ latex_documents = [ ( root_doc, -<<<<<<< HEAD - "google-cloud-spanner-admin-database.tex", - "google-cloud-spanner-admin-database Documentation", -======= "google-cloud-spanner-admin-instance.tex", u"google-cloud-spanner-admin-instance Documentation", ->>>>>>> ea2fb81 (generated changes) author, "manual", ) @@ -336,13 +317,8 @@ man_pages = [ ( root_doc, -<<<<<<< HEAD - "google-cloud-spanner-admin-database", - "google-cloud-spanner-admin-database Documentation", -======= "google-cloud-spanner-admin-instance", "google-cloud-spanner-admin-instance Documentation", ->>>>>>> ea2fb81 (generated changes) [author], 1, ) @@ -360,19 +336,11 @@ texinfo_documents = [ ( root_doc, -<<<<<<< HEAD - "google-cloud-spanner-admin-database", - "google-cloud-spanner-admin-database Documentation", - author, - "google-cloud-spanner-admin-database", - "google-cloud-spanner-admin-database Library", -======= "google-cloud-spanner-admin-instance", "google-cloud-spanner-admin-instance Documentation", author, "google-cloud-spanner-admin-instance", "google-cloud-spanner-admin-instance Library", ->>>>>>> ea2fb81 (generated changes) "APIs", ) ] From 59e266ab6eee1fde72e982138d506fe5d5a2792f Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 18 Nov 2025 22:02:53 +0000 Subject: [PATCH 42/49] address failure --- .librarian/state.yaml | 2 +- google/cloud/spanner_dbapi/version.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index d7f8c76918..e277d77af6 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-spanner version: 3.59.0 - last_generated_commit: 136201b66f70829232b7ec63fa6e35ca765bcacb + last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 apis: - path: google/spanner/admin/database/v1 service_config: spanner.yaml diff --git a/google/cloud/spanner_dbapi/version.py b/google/cloud/spanner_dbapi/version.py index 6fbb80eb90..0ae3005c43 100644 --- a/google/cloud/spanner_dbapi/version.py +++ b/google/cloud/spanner_dbapi/version.py @@ -13,8 +13,8 @@ # limitations under the License. import platform -from google.cloud.spanner_v1 import gapic_version as package_version PY_VERSION = platform.python_version() -VERSION = package_version.__version__ +__version__ = "3.59.0" +VERSION = __version__ DEFAULT_USER_AGENT = "gl-dbapi/" + VERSION From de8fb83eab3a4a4d0402807f9aa39cf4fc4c0df5 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 18 Nov 2025 22:10:09 +0000 Subject: [PATCH 43/49] rename owlbot.py to librarian.py --- .librarian/state.yaml | 2 +- owlbot.py => librarian.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename owlbot.py => librarian.py (100%) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index e277d77af6..4585e16f11 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:c8612d3fffb3f6a32353b2d1abd16b61e87811866f7ec9d65b59b02eb452a620 +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:e601da6e29c993e14c52867f2c088dfb841beae618d2a4f1e0f7970a888ab020 libraries: - id: google-cloud-spanner version: 3.59.0 diff --git a/owlbot.py b/librarian.py similarity index 100% rename from owlbot.py rename to librarian.py From 338d86186b2049f9b3d71915d696f046c3795eb0 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 18 Nov 2025 22:12:58 +0000 Subject: [PATCH 44/49] rename file --- .librarian/generator-input/{owlbot.py => librarian.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .librarian/generator-input/{owlbot.py => librarian.py} (100%) diff --git a/.librarian/generator-input/owlbot.py b/.librarian/generator-input/librarian.py similarity index 100% rename from .librarian/generator-input/owlbot.py rename to .librarian/generator-input/librarian.py From fbfcedf6b87bc43ca356f9ce5f9147aa715083a3 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 19 Nov 2025 00:37:50 +0000 Subject: [PATCH 45/49] remove librarian --- librarian.py | 246 --------------------------------------------------- 1 file changed, 246 deletions(-) delete mode 100644 librarian.py diff --git a/librarian.py b/librarian.py deleted file mode 100644 index 31efb36c92..0000000000 --- a/librarian.py +++ /dev/null @@ -1,246 +0,0 @@ -# Copyright 2018 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. - -"""This script is used to synthesize generated parts of this library.""" - -from pathlib import Path -import shutil -from typing import List, Optional -import re - -import synthtool as s -from synthtool import gcp -from synthtool.languages import python - -common = gcp.CommonTemplates() - -clean_up_generated_samples = True - -for library in s.get_staging_dirs("v1"): - if clean_up_generated_samples: - shutil.rmtree("samples/generated_samples", ignore_errors=True) - clean_up_generated_samples = False - - # Customization for MetricsInterceptor - - assert 6 == s.replace( - [ - library / "google/cloud/spanner_v1/services/spanner/transports/*.py", - library / "google/cloud/spanner_v1/services/spanner/client.py", - ], - """from google.cloud.spanner_v1.types import transaction""", - """from google.cloud.spanner_v1.types import transaction -from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor""", - ) - - assert 1 == s.replace( - library / "google/cloud/spanner_v1/services/spanner/transports/*.py", - """api_audience: Optional\[str\] = None, - \*\*kwargs, - \) -> None: - \"\"\"Instantiate the transport.""", -"""api_audience: Optional[str] = None, - metrics_interceptor: Optional[MetricsInterceptor] = None, - **kwargs, - ) -> None: - \"\"\"Instantiate the transport.""" - ) - - assert 4 == s.replace( - library / "google/cloud/spanner_v1/services/spanner/transports/*.py", - """api_audience: Optional\[str\] = None, - \) -> None: - \"\"\"Instantiate the transport.""", -"""api_audience: Optional[str] = None, - metrics_interceptor: Optional[MetricsInterceptor] = None, - ) -> None: - \"\"\"Instantiate the transport.""" - ) - - assert 1 == s.replace( - library / "google/cloud/spanner_v1/services/spanner/transports/grpc.py", - """\)\n\n self._interceptor = _LoggingClientInterceptor\(\)""", - """) - - # Wrap the gRPC channel with the metric interceptor - if metrics_interceptor is not None: - self._metrics_interceptor = metrics_interceptor - self._grpc_channel = grpc.intercept_channel( - self._grpc_channel, metrics_interceptor - ) - - self._interceptor = _LoggingClientInterceptor()""" - ) - - assert 1 == s.replace( - library / "google/cloud/spanner_v1/services/spanner/transports/grpc.py", - """self._stubs: Dict\[str, Callable\] = \{\}\n\n if api_mtls_endpoint:""", - """self._stubs: Dict[str, Callable] = {} - self._metrics_interceptor = None - - if api_mtls_endpoint:""" - ) - - assert 1 == s.replace( - library / "google/cloud/spanner_v1/services/spanner/client.py", - """# initialize with the provided callable or the passed in class - self._transport = transport_init\( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - \)""", - """# initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - always_use_jwt_access=True, - api_audience=self._client_options.api_audience, - metrics_interceptor=MetricsInterceptor(), - )""", - ) - - assert 12 == s.replace( - library / "tests/unit/gapic/spanner_v1/test_spanner.py", - """api_audience=None,\n(\s+)\)""", - """api_audience=None, - metrics_interceptor=mock.ANY, - )""" - ) - - assert 1 == s.replace( - library / "tests/unit/gapic/spanner_v1/test_spanner.py", - """api_audience="https://language.googleapis.com"\n(\s+)\)""", - """api_audience="https://language.googleapis.com", - metrics_interceptor=mock.ANY, - )""" - ) - - count = s.replace( - [ - library / "google/cloud/spanner_v1/services/*/transports/grpc*", - library / "tests/unit/gapic/spanner_v1/*", - ], - "^\s+options=\\[.*?\\]", - """options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ("grpc.keepalive_time_ms", 120000), - ]""", - flags=re.MULTILINE | re.DOTALL, - ) - if count < 1: - raise Exception("Expected replacements for gRPC channel options not made.") - - count = s.replace( - [ - library / "google/cloud/spanner_admin_instance_v1/services/*/transports/grpc*", - library / "tests/unit/gapic/spanner_admin_instance_v1/*", - ], - "^\s+options=\\[.*?\\]", - """options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ("grpc.keepalive_time_ms", 120000), - ]""", - flags=re.MULTILINE | re.DOTALL, - ) - if count < 1: - raise Exception("Expected replacements for gRPC channel options not made.") - - count = s.replace( - [ - library / "google/cloud/spanner_admin_database_v1/services/*/transports/grpc*", - library / "tests/unit/gapic/spanner_admin_database_v1/*", - ], - "^\s+options=\\[.*?\\]", - """options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ("grpc.keepalive_time_ms", 120000), - ]""", - flags=re.MULTILINE | re.DOTALL, - ) - if count < 1: - raise Exception("Expected replacements for gRPC channel options not made.") - s.move( - library, - excludes=[ - "google/cloud/spanner/**", - "*.*", - "noxfile.py", - "docs/index.rst", - "google/cloud/spanner_v1/__init__.py", - "testing/constraints-3.7.txt", - "google/cloud/spanner_admin_instance/**", - "google/cloud/spanner_admin_database/**" - ], - ) - -s.remove_staging_dirs() - -# ---------------------------------------------------------------------------- -# Add templated files -# ---------------------------------------------------------------------------- -templated_files = common.py_library( - microgenerator=True, - samples=True, - cov_level=98, - split_system_tests=True, - system_test_extras=["tracing"], - system_test_python_versions=["3.12"] -) -s.move( - templated_files, - excludes=[ - ".coveragerc", - ".github/**", - ".kokoro/**", - "README.rst", - ], -) - -# Update samples folder in CONTRIBUTING.rst -s.replace("CONTRIBUTING.rst", "samples/snippets", "samples/samples") - -# ---------------------------------------------------------------------------- -# Samples templates -# ---------------------------------------------------------------------------- - -python.py_samples() - -s.replace( - "samples/**/noxfile.py", - 'BLACK_VERSION = "black==22.3.0"', - 'BLACK_VERSION = "black==23.7.0"', -) -s.replace( - "samples/**/noxfile.py", - r'ALL_VERSIONS = \["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"\]', - 'ALL_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13"]', -) - -# Use a python runtime which is available in the owlbot post processor here -# https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile -s.shell.run(["nox", "-s", "blacken-3.14"], hide_output=False) From da83d8fbd983b70edcd81cf2483a4f33115482c8 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 19 Nov 2025 00:42:24 +0000 Subject: [PATCH 46/49] update sha --- .librarian/state.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 4585e16f11..dab95406eb 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:e601da6e29c993e14c52867f2c088dfb841beae618d2a4f1e0f7970a888ab020 +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:8e2c32496077054105bd06c54a59d6a6694287bc053588e24debe6da6920ad91 libraries: - id: google-cloud-spanner version: 3.59.0 @@ -31,7 +31,6 @@ libraries: - ^SECURITY.md - ^mypy.ini - ^noxfile.py - - ^owlbot.py - ^renovate.json - ^samples/AUTHORING_GUIDE.md - ^samples/CONTRIBUTING.md From 35e316e0b350b4107a2f1e7d540021158a0cf566 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 19 Nov 2025 00:52:03 +0000 Subject: [PATCH 47/49] remove config.yaml --- config.yaml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 config.yaml diff --git a/config.yaml b/config.yaml deleted file mode 100644 index 8d9022e45b..0000000000 --- a/config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -global_files_allowlist: - # Allow the container to read and write the root `CHANGELOG.md` - # file during the `release` step to update the latest client library - # versions which are hardcoded in the file. - - path: "CHANGELOG.md" - permissions: "read-write" \ No newline at end of file From dd132a6d30f17aa73e71488c848de6b73d20c9f2 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 19 Nov 2025 03:31:23 +0000 Subject: [PATCH 48/49] update changes --- .librarian/state.yaml | 4 ++-- docs/conf.py | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index dab95406eb..231fa66eac 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -4,10 +4,10 @@ libraries: version: 3.59.0 last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 apis: - - path: google/spanner/admin/database/v1 - service_config: spanner.yaml - path: google/spanner/admin/instance/v1 service_config: spanner.yaml + - path: google/spanner/admin/database/v1 + service_config: spanner.yaml - path: google/spanner/v1 service_config: spanner.yaml source_roots: diff --git a/docs/conf.py b/docs/conf.py index 4e0af4e74e..64058683e8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ # limitations under the License. # # -# google-cloud-spanner-admin-instance documentation build configuration file +# google-cloud-spanner-admin-database documentation build configuration file # # This file is execfile()d with the current directory set to its # containing dir. @@ -81,9 +81,9 @@ root_doc = "index" # General information about the project. -project = u"google-cloud-spanner-admin-instance" -copyright = u"2025, Google, LLC" -author = u"Google APIs" +project = "google-cloud-spanner-admin-database" +copyright = "2025, Google, LLC" +author = "Google APIs" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -155,7 +155,7 @@ # further. For a list of options available for each theme, see the # documentation. html_theme_options = { - "description": "Google Cloud Client Libraries for google-cloud-spanner-admin-instance", + "description": "Google Cloud Client Libraries for google-cloud-spanner-admin-database", "github_user": "googleapis", "github_repo": "google-cloud-python", "github_banner": True, @@ -249,7 +249,7 @@ # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = "google-cloud-spanner-admin-instance-doc" +htmlhelp_basename = "google-cloud-spanner-admin-database-doc" # -- Options for warnings ------------------------------------------------------ @@ -282,8 +282,8 @@ latex_documents = [ ( root_doc, - "google-cloud-spanner-admin-instance.tex", - u"google-cloud-spanner-admin-instance Documentation", + "google-cloud-spanner-admin-database.tex", + "google-cloud-spanner-admin-database Documentation", author, "manual", ) @@ -317,8 +317,8 @@ man_pages = [ ( root_doc, - "google-cloud-spanner-admin-instance", - "google-cloud-spanner-admin-instance Documentation", + "google-cloud-spanner-admin-database", + "google-cloud-spanner-admin-database Documentation", [author], 1, ) @@ -336,11 +336,11 @@ texinfo_documents = [ ( root_doc, - "google-cloud-spanner-admin-instance", - "google-cloud-spanner-admin-instance Documentation", + "google-cloud-spanner-admin-database", + "google-cloud-spanner-admin-database Documentation", author, - "google-cloud-spanner-admin-instance", - "google-cloud-spanner-admin-instance Library", + "google-cloud-spanner-admin-database", + "google-cloud-spanner-admin-database Library", "APIs", ) ] From 07165db110ea043f365c802468a2d945bc550ee2 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Wed, 19 Nov 2025 03:35:40 +0000 Subject: [PATCH 49/49] minor fixes via generation --- .librarian/state.yaml | 2 +- docs/conf.py | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 231fa66eac..08fd9350c2 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-cloud-spanner version: 3.59.0 - last_generated_commit: cf0434f4bd20618db60ddd16a1e7db2c0dfb9158 + last_generated_commit: a17b84add8318f780fcc8a027815d5fee644b9f7 apis: - path: google/spanner/admin/instance/v1 service_config: spanner.yaml diff --git a/docs/conf.py b/docs/conf.py index 64058683e8..010a6b6cda 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ # limitations under the License. # # -# google-cloud-spanner-admin-database documentation build configuration file +# google-cloud-spanner documentation build configuration file # # This file is execfile()d with the current directory set to its # containing dir. @@ -81,9 +81,9 @@ root_doc = "index" # General information about the project. -project = "google-cloud-spanner-admin-database" -copyright = "2025, Google, LLC" -author = "Google APIs" +project = u"google-cloud-spanner" +copyright = u"2025, Google, LLC" +author = u"Google APIs" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -155,7 +155,7 @@ # further. For a list of options available for each theme, see the # documentation. html_theme_options = { - "description": "Google Cloud Client Libraries for google-cloud-spanner-admin-database", + "description": "Google Cloud Client Libraries for google-cloud-spanner", "github_user": "googleapis", "github_repo": "google-cloud-python", "github_banner": True, @@ -249,7 +249,7 @@ # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = "google-cloud-spanner-admin-database-doc" +htmlhelp_basename = "google-cloud-spanner-doc" # -- Options for warnings ------------------------------------------------------ @@ -282,8 +282,8 @@ latex_documents = [ ( root_doc, - "google-cloud-spanner-admin-database.tex", - "google-cloud-spanner-admin-database Documentation", + "google-cloud-spanner.tex", + u"google-cloud-spanner Documentation", author, "manual", ) @@ -317,8 +317,8 @@ man_pages = [ ( root_doc, - "google-cloud-spanner-admin-database", - "google-cloud-spanner-admin-database Documentation", + "google-cloud-spanner", + "google-cloud-spanner Documentation", [author], 1, ) @@ -336,11 +336,11 @@ texinfo_documents = [ ( root_doc, - "google-cloud-spanner-admin-database", - "google-cloud-spanner-admin-database Documentation", + "google-cloud-spanner", + "google-cloud-spanner Documentation", author, - "google-cloud-spanner-admin-database", - "google-cloud-spanner-admin-database Library", + "google-cloud-spanner", + "google-cloud-spanner Library", "APIs", ) ]