diff --git a/.kokoro/system.sh b/.kokoro/system.sh index b8976b688a2c..7214ff3c664f 100755 --- a/.kokoro/system.sh +++ b/.kokoro/system.sh @@ -101,6 +101,7 @@ packages_with_system_tests=( "google-cloud-logging" "google-cloud-ndb" "google-cloud-pubsub" + "google-cloud-spanner" "google-cloud-testutils" "sqlalchemy-bigquery" "pandas-gbq" diff --git a/.librarian/config.yaml b/.librarian/config.yaml index ced97dc03d44..4e6a62c4c085 100644 --- a/.librarian/config.yaml +++ b/.librarian/config.yaml @@ -16,10 +16,6 @@ libraries: # Allow releases for google-cloud-storage once this bug is fixed. - id: "google-cloud-storage" release_blocked: true -# TODO(https://github.com/googleapis/google-cloud-python/issues/16490): -# Allow generation for google-cloud-spanner once this bug is fixed. - - id: "google-cloud-spanner" - generate_blocked: true # TODO(https://github.com/googleapis/google-cloud-python/issues/16494): # Allow generation for google-cloud-bigtable once this bug is fixed. - id: "google-cloud-bigtable" diff --git a/.librarian/generator-input/client-post-processing/spanner-integration.yaml b/.librarian/generator-input/client-post-processing/spanner-integration.yaml index f60389a386d8..4efd32ccded0 100644 --- a/.librarian/generator-input/client-post-processing/spanner-integration.yaml +++ b/.librarian/generator-input/client-post-processing/spanner-integration.yaml @@ -11,142 +11,1313 @@ # 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. -description: Integrate Google Cloud Spanner customizations for MetricsInterceptor and gRPC options -# TODO(Fill in issue number below to add more context) +description: Integrate Google Cloud Logging Spanner Handwritten code url: https://github.com/googleapis/gapic-generator-python/issues/123 replacements: - - paths: [ - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/base.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest_base.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py", - ] - before: | - from google.cloud.spanner_v1.types import transaction + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py] + before: '(import google\.rpc\.status_pb2 as status_pb2 # type: ignore\n\n)(?!from google\.cloud\.spanner_v1\.metrics)' after: | - from google.cloud.spanner_v1.types import transaction - from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor - count: 6 + \g<1>from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor + count: 1 - - paths: [ - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/base.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest_base.py", - ] - before: | - (?P\s+)api_audience: Optional\[str\] = None,\n\s+\*\*kwargs,\n\s+\) -> None: + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py] + before: '(\s+api_audience=self\._client_options\.api_audience,\n)(?!\s+metrics_interceptor=MetricsInterceptor)' after: | - \gapi_audience: Optional[str] = None, - \g metrics_interceptor: Optional[MetricsInterceptor] = None, - \g **kwargs, - \g) -> None: - count: 1 # Using regex with backreferences for correctness + \g<1> metrics_interceptor=MetricsInterceptor(), + count: 1 - - paths: [ - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py", - ] - before: | - \)\n\n self._interceptor = _LoggingClientInterceptor\(\) + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/base.py] + before: '(from google\.cloud\.spanner_v1 import gapic_version as package_version\n)(?!from google\.cloud\.spanner_v1\.metrics)' after: | - ) + \g<1>from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor + count: 1 - # 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 - ) + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest.py] + before: '(from requests import __version__ as requests_version\n\n)(?!from google\.cloud\.spanner_v1\.metrics)' + after: | + \g<1>from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor + count: 1 + + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py] + before: '(from grpc\.experimental import aio # type: ignore\n\n)(?!from google\.cloud\.spanner_v1\.metrics)' + after: | + \g<1>from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor + count: 1 + + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py] + before: '(from google\.protobuf\.json_format import MessageToJson\n\n)(?!from google\.cloud\.spanner_v1\.metrics)' + after: | + \g<1>from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor + count: 1 + + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest_base.py] + before: '(from google\.protobuf import json_format\n\n)(?!from google\.cloud\.spanner_v1\.metrics)' + after: | + \g<1>from google.cloud.spanner_v1.metrics.metrics_interceptor import MetricsInterceptor + count: 1 + + - paths: + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/base.py + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest.py + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/rest_base.py + before: '(\s+api_audience: Optional\[str\] = None,\n)(?!\s+metrics_interceptor: Optional\[MetricsInterceptor\])' + after: | + \g<1> metrics_interceptor: Optional[MetricsInterceptor] = None, + count: 5 - self._interceptor = _LoggingClientInterceptor() + - paths: + # Source Transports + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py + - packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc.py + - packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc_asyncio.py + - packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc.py + - packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc_asyncio.py + # Test Files + - packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py + - packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py + - packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py + # Group 1 captures exactly the spaces/tabs on that line. + # Group 2 captures the code up to the newline. + before: '([ \t]+)(\("grpc\.max_receive_message_length", -1\),\n)(?![ \t]+\("grpc\.keepalive_time_ms")' + after: | + \g<1>\g<2>\g<1>("grpc.keepalive_time_ms", 120000), + count: 21 + + - paths: + - packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py + before: '(\s+api_audience=\"https\:\/\/language\.googleapis\.com\",\n)(?!\s+metrics_interceptor=mock\.ANY,)' + after: | + \g<1> metrics_interceptor=mock.ANY, count: 1 + + - paths: + - packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py + # Group 1: Captures ONLY the spaces/tabs before the text + # Group 2: Captures the text itself and the newline + before: '([ \t]+)(api_audience=None,\n)(?![ \t]+metrics_interceptor=mock\.ANY,)' + after: | + \g<1>\g<2>\g<1>metrics_interceptor=mock.ANY, + count: 12 - - paths: [ - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py", - ] - before: | - self._stubs: Dict\[str, Callable\] = \{\}\n\n if api_mtls_endpoint: + - paths: + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py + before: '(\s+self\._stubs: Dict\[str, Callable\] = \{\}\n)(?!\s+self\._metrics_interceptor = None)' + after: | + \g<1> self._metrics_interceptor = None + count: 1 + - paths: + - packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py + before: '([ \t]+)(\("grpc\.keepalive_time_ms", 120000\),\n[ \t]+\](?:,\n[ \t]*|\n[ \t]*)\)\n+)([ \t]+)(self\._interceptor = _LoggingClientInterceptor\(\)\n)' after: | - self._stubs: Dict[str, Callable] = {} - self._metrics_interceptor = None + \g<1>\g<2>\g<3># Wrap the gRPC channel with the metric interceptor + \g<3>if metrics_interceptor is not None: + \g<3> self._metrics_interceptor = metrics_interceptor + \g<3> self._grpc_channel = grpc.intercept_channel( + \g<3> self._grpc_channel, metrics_interceptor + \g<3> ) - if api_mtls_endpoint: + \g<3>\g<4> + count: 1 + - paths: [packages/google-cloud-spanner/setup.py] + before: '(?s)dependencies = \[.*?\]\nextras = \{\}' + after: | + 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 >= 4.25.8, < 8.0.0", + "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"} count: 1 + - paths: [packages/google-cloud-spanner/docs/index.rst] + before: '(?s)API Reference\n-------------.*' + after: | + Usage Documentation + ------------------- + .. toctree:: + :maxdepth: 2 - - paths: [ - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py", - ] - before: | - # 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, - \) - after: | - # 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(), - ) + client-usage + table-usage + batch-usage + snapshot-usage + transaction-usage + + database-usage + instance-usage + + API Documentation + ----------------- + .. toctree:: + :maxdepth: 1 + :titlesonly: + + advanced-session-pool-topics + opentelemetry-tracing + + spanner_v1/client + spanner_v1/instance + spanner_v1/database + spanner_v1/table + spanner_v1/session + spanner_v1/keyset + spanner_v1/snapshot + spanner_v1/batch + spanner_v1/transaction + spanner_v1/streamed + + spanner_v1/services_ + spanner_v1/types_ + spanner_admin_database_v1/services_ + spanner_admin_database_v1/types_ + spanner_admin_database_v1/database_admin + spanner_admin_instance_v1/services_ + spanner_admin_instance_v1/types_ + spanner_admin_instance_v1/instance_admin + + + + Changelog + --------- + + For a list of all ``google-cloud-spanner`` releases: + + .. toctree:: + :maxdepth: 2 + + CHANGELOG + + .. toctree:: + :hidden: + + summary_overview.md count: 1 + - paths: [packages/google-cloud-spanner/google/cloud/spanner_v1/__init__.py] + before: '(?s)import sys\n\nimport google\.api_core as api_core.*' + after: | + from __future__ import absolute_import + + from google.cloud.spanner_v1 import gapic_version as package_version + __version__: str = package_version.__version__ + + from google.cloud.spanner_v1 import param_types + from google.cloud.spanner_v1._async.client import Client as AsyncClient + from google.cloud.spanner_v1._async.pool import ( + AbstractSessionPool as AsyncAbstractSessionPool, + ) + from google.cloud.spanner_v1._async.pool import BurstyPool as AsyncBurstyPool + from google.cloud.spanner_v1._async.pool import FixedSizePool as AsyncFixedSizePool + from google.cloud.spanner_v1._async.pool import PingingPool as AsyncPingingPool + from google.cloud.spanner_v1._async.pool import ( + TransactionPingingPool as AsyncTransactionPingingPool, + ) + from google.cloud.spanner_v1.client import Client + from google.cloud.spanner_v1.keyset import KeyRange, KeySet + from google.cloud.spanner_v1.pool import ( + AbstractSessionPool, + BurstyPool, + FixedSizePool, + PingingPool, + TransactionPingingPool, + ) + + from .data_types import Interval, JsonObject + from .exceptions import wrap_with_request_id + from .services.spanner import SpannerAsyncClient, SpannerClient + from .transaction import BatchTransactionId, DefaultTransactionOptions + from .types import RequestOptions + from .types.commit_response import CommitResponse + from .types.keys import KeyRange as KeyRangePB + from .types.keys import KeySet as KeySetPB + from .types.mutation import Mutation + from .types.query_plan import PlanNode, QueryPlan + from .types.result_set import ( + PartialResultSet, + ResultSet, + ResultSetMetadata, + ResultSetStats, + ) + from .types.spanner import ( + BatchCreateSessionsRequest, + BatchCreateSessionsResponse, + BatchWriteRequest, + BatchWriteResponse, + BeginTransactionRequest, + CommitRequest, + CreateSessionRequest, + DeleteSessionRequest, + DirectedReadOptions, + ExecuteBatchDmlRequest, + ExecuteBatchDmlResponse, + ExecuteSqlRequest, + GetSessionRequest, + ListSessionsRequest, + ListSessionsResponse, + Partition, + PartitionOptions, + PartitionQueryRequest, + PartitionReadRequest, + PartitionResponse, + ReadRequest, + RollbackRequest, + Session, + ) + from .types.transaction import Transaction, TransactionOptions, TransactionSelector + from .types.type import StructType, Type, TypeAnnotationCode, TypeCode + + COMMIT_TIMESTAMP = "spanner.commit_timestamp()" + """Placeholder be used to store commit timestamp of a transaction in a column. + This value can only be used for timestamp columns that have set the option + ``(allow_commit_timestamp=true)`` in the schema. + """ + + __all__ = ( + # google.cloud.spanner_v1 + "__version__", + "param_types", + # google.cloud.spanner_v1.exceptions + "wrap_with_request_id", + # google.cloud.spanner_v1.client + "Client", + "AsyncClient", + # google.cloud.spanner_v1.keyset + "KeyRange", + "KeySet", + # google.cloud.spanner_v1.pool + "AbstractSessionPool", + "BurstyPool", + "FixedSizePool", + "PingingPool", + "TransactionPingingPool", + "AsyncAbstractSessionPool", + "AsyncBurstyPool", + "AsyncFixedSizePool", + "AsyncPingingPool", + "AsyncTransactionPingingPool", + # local + "COMMIT_TIMESTAMP", + # google.cloud.spanner_v1.types + "BatchCreateSessionsRequest", + "BatchCreateSessionsResponse", + "BatchWriteRequest", + "BatchWriteResponse", + "BeginTransactionRequest", + "CommitRequest", + "CommitResponse", + "CreateSessionRequest", + "DeleteSessionRequest", + "DirectedReadOptions", + "ExecuteBatchDmlRequest", + "ExecuteBatchDmlResponse", + "ExecuteSqlRequest", + "GetSessionRequest", + "KeyRangePB", + "KeySetPB", + "ListSessionsRequest", + "ListSessionsResponse", + "Mutation", + "PartialResultSet", + "Partition", + "PartitionOptions", + "PartitionQueryRequest", + "PartitionReadRequest", + "PartitionResponse", + "PlanNode", + "QueryPlan", + "ReadRequest", + "RequestOptions", + "ResultSet", + "ResultSetMetadata", + "ResultSetStats", + "RollbackRequest", + "Session", + "StructType", + "Transaction", + "TransactionOptions", + "TransactionSelector", + "Type", + "TypeAnnotationCode", + "TypeCode", + # Custom spanner related data types + "JsonObject", + "Interval", + # google.cloud.spanner_v1.services + "SpannerClient", + "SpannerAsyncClient", + "BatchTransactionId", + "DefaultTransactionOptions", + ) + count: 1 + - paths: [packages/google-cloud-spanner/google/cloud/spanner/__init__.py] + before: '(?s)from google.cloud.spanner import gapic_version as package_version.*' + after: | + from __future__ import absolute_import + + from google.cloud.spanner_v1 import ( + COMMIT_TIMESTAMP, + AbstractSessionPool, + BurstyPool, + Client, + FixedSizePool, + KeyRange, + KeySet, + PingingPool, + TransactionPingingPool, + __version__, + param_types, + ) + + __all__ = ( + # google.cloud.spanner + "__version__", + "param_types", + # google.cloud.spanner_v1.client + "Client", + # google.cloud.spanner_v1.keyset + "KeyRange", + "KeySet", + # google.cloud.spanner_v1.pool + "AbstractSessionPool", + "BurstyPool", + "FixedSizePool", + "PingingPool", + "TransactionPingingPool", + # local + "COMMIT_TIMESTAMP", + ) + count: 1 - paths: [ - "packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py", + packages/google-cloud-spanner/README.rst ] before: | - api_audience=None,\n(\s+)\) + Windows + \^\^\^\^\^\^\^ + [\s\S]*?pip install google-cloud-spanner\n\nNext Steps after: | - api_audience=None, - metrics_interceptor=mock.ANY, + Windows + ^^^^^^^ + + .. code-block:: console + + py -m venv + .\\\\Scripts\\activate + pip install google-cloud-spanner + + + Example Usage + ------------- + + + Executing Arbitrary SQL in a Transaction + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Generally, to work with Cloud Spanner, you will want a transaction. The + preferred mechanism for this is to create a single function, which executes + as a callback to ``database.run_in_transaction``: + + .. code:: python + + # First, define the function that represents a single "unit of work" + # that should be run within the transaction. + def update_anniversary(transaction, person_id, unix_timestamp): + # The query itself is just a string. + # + # The use of @parameters is recommended rather than doing your + # own string interpolation; this provides protections against + # SQL injection attacks. + query = """SELECT anniversary FROM people + WHERE id = @person_id""" + + # When executing the SQL statement, the query and parameters are sent + # as separate arguments. When using parameters, you must specify + # both the parameters themselves and their types. + row = transaction.execute_sql( + query=query, + params={'person_id': person_id}, + param_types={ + 'person_id': types.INT64_PARAM_TYPE, + }, + ).one() + + # Now perform an update on the data. + old_anniversary = row[0] + new_anniversary = _compute_anniversary(old_anniversary, years) + transaction.update( + 'people', + ['person_id', 'anniversary'], + [person_id, new_anniversary], ) - count: 12 + # Actually run the `update_anniversary` function in a transaction. + database.run_in_transaction(update_anniversary, + person_id=42, + unix_timestamp=1335020400, + ) + + + Select records using a Transaction + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Once you have a transaction object (such as the first argument sent to + ``run_in_transaction``), reading data is easy: + + .. code:: python + + # Define a SELECT query. + query = """SELECT e.first_name, e.last_name, p.telephone + FROM employees as e, phones as p + WHERE p.employee_id == e.employee_id""" + + # Execute the query and return results. + result = transaction.execute_sql(query) + for row in result.rows: + print(row) + + + Insert records using Data Manipulation Language (DML) with a Transaction + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Use the ``execute_update()`` method to execute a DML statement: + + .. code:: python + + spanner_client = spanner.Client() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + def insert_singers(transaction): + row_ct = transaction.execute_update( + "INSERT Singers (SingerId, FirstName, LastName) " + " VALUES (10, 'Virginia', 'Watson')" + ) + + print("{} record(s) inserted.".format(row_ct)) + + database.run_in_transaction(insert_singers) + + + Insert records using Mutations with a Transaction + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + To add one or more records to a table, use ``insert``: + + .. code:: python + + transaction.insert( + 'citizens', + columns=['email', 'first_name', 'last_name', 'age'], + values=[ + ['phred@example.com', 'Phred', 'Phlyntstone', 32], + ['bharney@example.com', 'Bharney', 'Rhubble', 31], + ], + ) + + + Update records using Data Manipulation Language (DML) with a Transaction + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + .. code:: python + + spanner_client = spanner.Client() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + def update_albums(transaction): + row_ct = transaction.execute_update( + "UPDATE Albums " + "SET MarketingBudget = MarketingBudget * 2 " + "WHERE SingerId = 1 and AlbumId = 1" + ) + + print("{} record(s) updated.".format(row_ct)) + + database.run_in_transaction(update_albums) + + + Update records using Mutations with a Transaction + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + ``Transaction.update`` updates one or more existing records in a table. Fails + if any of the records does not already exist. + + .. code:: python + + transaction.update( + 'citizens', + columns=['email', 'age'], + values=[ + ['phred@example.com', 33], + ['bharney@example.com', 32], + ], + ) + + + Connection API + -------------- + Connection API represents a wrap-around for Python Spanner API, written in accordance with PEP-249, and provides a simple way of communication with a Spanner database through connection objects: + + .. code:: python + + from google.cloud.spanner_dbapi.connection import connect + + connection = connect("instance-id", "database-id") + connection.autocommit = True + + cursor = connection.cursor() + cursor.execute("SELECT * FROM table_name") + + result = cursor.fetchall() + + + If using [fine-grained access controls](https://cloud.google.com/spanner/docs/access-with-fgac) you can pass a ``database_role`` argument to connect as that role: + + .. code:: python + + connection = connect("instance-id", "database-id", database_role='your-role') + + + Aborted Transactions Retry Mechanism + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + In ``!autocommit`` mode, transactions can be aborted due to transient errors. In most cases retry of an aborted transaction solves the problem. To simplify it, connection tracks SQL statements, executed in the current transaction. In case the transaction aborted, the connection initiates a new one and re-executes all the statements. In the process, the connection checks that retried statements are returning the same results that the original statements did. If results are different, the transaction is dropped, as the underlying data changed, and auto retry is impossible. + + Auto-retry of aborted transactions is enabled only for ``!autocommit`` mode, as in ``autocommit`` mode transactions are never aborted. + + + Next Steps + count: 1 + # Note: noxfile.py is heavily customized so we clobber the whole file. - paths: [ - "packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py", + packages/google-cloud-spanner/noxfile.py ] before: | - api_audience="https://language.googleapis.com"\n(\s+)\) + import os + [\s\S]*?Run all tests with core dependencies installed from source after: | - api_audience="https://language.googleapis.com", - metrics_interceptor=mock.ANY, + import os + import pathlib + import re + import shutil + import warnings + from typing import Dict, List + + import nox + + RUFF_VERSION = "ruff==0.14.14" + 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"] + + ALL_PYTHON: List[str] = [ + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", + "3.14", + ] + 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", + "pytest-asyncio", + "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", + "unit-3.14", + "system", + "cover", + "lint", + "lint_setup_py", + "blacken", + "docs", + "docfx", + "format", + "prerelease_deps", + "core_deps_from_source", + "mypy", + ] + + # 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", RUFF_VERSION) + + # 2. Check formatting + session.run( + "ruff", + "format", + "--check", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *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): + """(Deprecated) Legacy session. Please use 'nox -s format'.""" + session.log( + "WARNING: The 'blacken' session is deprecated and will be removed in a future release. Please use 'nox -s format' in the future." + ) + + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) + session.install(RUFF_VERSION) + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + + @nox.session(python=DEFAULT_PYTHON_VERSION) + def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + # check --select I: Enables strict import sorting + # --fix: Applies the changes automatically + session.run( + "ruff", + "check", + "--select", + "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + + + @nox.session(python=DEFAULT_PYTHON_VERSION) + def lint_setup_py(session): + """Verify that setup.py is valid (including RST check).""" + session.install("setuptools", "docutils", "pygments") + 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, ) - count: 1 + session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints) - - paths: [ - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py", - "packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py", - "packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py", - "packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc.py", - "packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc_asyncio.py", - "packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py", - "packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc.py", - "packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc_asyncio.py", - "packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py", - ] - before: | - ^\s+options=\[[\s\S]*?\] - after: | - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ("grpc.keepalive_time_ms", 120000), - ] - count: 9 # One per file roughly, or adjusts based on regex triggers + 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=ALL_PYTHON) + @nox.parametrize( + "protobuf_implementation", + ["python", "upb", "cpp"], + ) + def unit(session, protobuf_implementation): + # Install all test dependencies, then install this package in-place. + + if session.python in ("3.7",): + session.skip("Python 3.7 is no longer supported") + if protobuf_implementation == "cpp" and session.python in ( + "3.11", + "3.12", + "3.13", + "3.14", + ): + 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. + args = [ + "py.test", + "-s", + f"--junitxml=unit_{session.python}_sponge_log.xml", + "--cov=google", + "--cov=tests/unit", + "--cov-append", + "--cov-config=.coveragerc", + "--cov-report=", + "--cov-fail-under=0", + ] + if not session.posargs: + args.append(os.path.join("tests", "unit")) + args.extend(session.posargs) + + session.run( + *args, + 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", + "3.14", + ): + 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: + args = [ + "py.test", + "--quiet", + "-o", + "asyncio_mode=auto", + f"--junitxml=system_{session.python}_sponge_log.xml", + ] + if not session.posargs: + args.append(system_test_path) + args.extend(session.posargs) + + session.run( + *args, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) + elif system_test_folder_exists: + # Run sync tests + sync_args = [ + "py.test", + "--quiet", + "-o", + "asyncio_mode=auto", + f"--junitxml=system_{session.python}_sync_sponge_log.xml", + ] + if not session.posargs: + sync_args.append(os.path.join("tests", "system")) + sync_args.append("--ignore=tests/system/_async") + else: + sync_args.extend(session.posargs) + + session.run( + *sync_args, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) + + # Run async tests + async_args = [ + "py.test", + "--quiet", + "-o", + "asyncio_mode=auto", + f"--junitxml=system_{session.python}_async_sponge_log.xml", + ] + if not session.posargs: + async_args.append(os.path.join("tests", "system", "_async")) + else: + # If posargs are provided, only run if they match async tests + # or just skip if they were already run in sync. + # For simplicity, we only run async folder if no posargs. + return + + session.run( + *async_args, + 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.14") + @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", + "3.14", + ): + 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-{ALL_PYTHON[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", + # dependency of google-auth + "cffi", + "cryptography", + "cachetools", + ] + + 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") + + if os.environ.get("SPANNER_EMULATOR_HOST"): + # Run tests against the emulator + run_system = True + elif protobuf_implementation == "python": + # Run tests against real Spanner, but check creds first + if os.environ.get("GOOGLE_APPLICATION_CREDENTIALS"): + run_system = True + else: + session.log( + "Skipping system tests because GOOGLE_APPLICATION_CREDENTIALS is not set" + ) + run_system = False + else: + # Skip to speed up build (only run python implementation on real Spanner) + session.log( + f"Skipping system tests for protobuf={protobuf_implementation} on real Spanner to speed up build" + ) + run_system = False + + if run_system: + # Run the tests (deduplicated logic) + test_path = ( + system_test_path + if os.path.exists(system_test_path) + else system_test_folder_path + ) + session.run( + "py.test", + "--verbose", + f"--junitxml=system_{session.python}_sponge_log.xml", + test_path, + *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + "SPANNER_DATABASE_DIALECT": database_dialect, + "SKIP_BACKUP_TESTS": "true", + }, + ) + + + @nox.session(python=ALL_PYTHON) + def mypy(session): + """Run the type checker.""" + session.skip("Mypy is not yet supported") + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2579): + # use the latest version of mypy + session.install( + "mypy<1.16.0", + "types-requests", + "types-protobuf", + ) + session.install(".") + session.run( + "mypy", + "-p", + "google", + # "--check-untyped-defs", + *session.posargs, + ) + + + @nox.session(python=DEFAULT_PYTHON_VERSION) + @nox.parametrize( + "protobuf_implementation", + ["python", "upb"], + ) + def core_deps_from_source(session, protobuf_implementation): + """Run all tests with core dependencies installed from source, + count: 1 \ No newline at end of file diff --git a/.librarian/generator-input/packages/google-cloud-spanner/.repo-metadata.json b/.librarian/generator-input/packages/google-cloud-spanner/.repo-metadata.json new file mode 100644 index 000000000000..9f9f2f0fc02a --- /dev/null +++ b/.librarian/generator-input/packages/google-cloud-spanner/.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/google-cloud-python", + "distribution_name": "google-cloud-spanner", + "api_id": "spanner.googleapis.com", + "requires_billing": true, + "default_version": "v1", + "codeowner_team": "@googleapis/spanner-team", + "api_shortname": "spanner", + "api_description": "is the world's first fully managed relational database service \nto offer both strong consistency and horizontal scalability for \nmission-critical online transaction processing (OLTP) applications. With Cloud \nSpanner you enjoy all the traditional benefits of a relational database; but \nunlike any other relational database service, Cloud Spanner scales horizontally \nto hundreds or thousands of servers to handle the biggest transactional \nworkloads." +} diff --git a/.librarian/state.yaml b/.librarian/state.yaml index f4e53f215001..55dc06277b67 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -3246,7 +3246,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-cloud-spanner version: 3.64.0 - last_generated_commit: 64f1dbf504bab7b58ed96a539a5b26a7ebfc65c7 + last_generated_commit: 3e09ac03bab9dba5b8800248cf10190219938a26 apis: - path: google/spanner/admin/instance/v1 service_config: spanner.yaml @@ -3279,9 +3279,11 @@ libraries: - ^packages/google-cloud-spanner/docs/spanner_v1/spanner.rst - ^packages/google-cloud-spanner/docs/spanner_v1/services_.rst - ^packages/google-cloud-spanner/docs/spanner_v1/types_.rst + - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/database_admin.rst - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/spanner_admin_database.rst - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/services_.rst - ^packages/google-cloud-spanner/docs/spanner_admin_database_v1/types_.rst + - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/instance_admin.rst - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/spanner_admin_instance.rst - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/services_.rst - ^packages/google-cloud-spanner/docs/spanner_admin_instance_v1/types_.rst @@ -3306,10 +3308,22 @@ libraries: - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/py.typed - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/types + - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database/__init__.py + - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py + - ^packages/google-cloud-spanner/google/cloud/spanner_admin_database/py.typed + - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance/__init__.py + - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py + - ^packages/google-cloud-spanner/google/cloud/spanner_admin_instance/py.typed + - ^packages/google-cloud-spanner/google/cloud/spanner/__init__.py + - ^packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py + - ^packages/google-cloud-spanner/google/cloud/spanner/py.typed - ^packages/google-cloud-spanner/testing - ^packages/google-cloud-spanner/tests/__init__.py - ^packages/google-cloud-spanner/tests/unit/__init__.py - - ^packages/google-cloud-spanner/tests/unit/gapic + - ^packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1 + - ^packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1 + - ^packages/google-cloud-spanner/tests/unit/gapic/spanner_v1 + - ^packages/google-cloud-spanner/tests/unit/gapic/__init__.py - ^packages/google-cloud-spanner/samples/generated_samples tag_format: '{id}-v{version}' - id: google-cloud-speech diff --git a/packages/google-cloud-spanner/.coveragerc b/packages/google-cloud-spanner/.coveragerc new file mode 100644 index 000000000000..677a9927999d --- /dev/null +++ b/packages/google-cloud-spanner/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/spanner/__init__.py + google/cloud/spanner/gapic_version.py +exclude_lines = + # Re-enable the standard pragma + pragma: NO COVER + # Ignore debug-only repr + def __repr__ diff --git a/packages/google-cloud-spanner/.flake8 b/packages/google-cloud-spanner/.flake8 index 32986c79287a..90316de21489 100644 --- a/packages/google-cloud-spanner/.flake8 +++ b/packages/google-cloud-spanner/.flake8 @@ -1,28 +1,29 @@ # -*- coding: utf-8 -*- -# -# Copyright 2024 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. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# 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. - -# Generated by synthtool. DO NOT EDIT! +# [flake8] +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): +# Resolve flake8 lint issues ignore = E203, E231, E266, E501, W503 exclude = - # Exclude generated code. - **/proto/** + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2333): + # Ensure that generated code passes flake8 lint **/gapic/** **/services/** **/types/** + # Exclude Protobuf gencode *_pb2.py # Standard linting exemptions. diff --git a/packages/google-cloud-spanner/.repo-metadata.json b/packages/google-cloud-spanner/.repo-metadata.json index 2bb64f929198..9f9f2f0fc02a 100644 --- a/packages/google-cloud-spanner/.repo-metadata.json +++ b/packages/google-cloud-spanner/.repo-metadata.json @@ -14,5 +14,5 @@ "default_version": "v1", "codeowner_team": "@googleapis/spanner-team", "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." + "api_description": "is the world's first fully managed relational database service \nto offer both strong consistency and horizontal scalability for \nmission-critical online transaction processing (OLTP) applications. With Cloud \nSpanner you enjoy all the traditional benefits of a relational database; but \nunlike any other relational database service, Cloud Spanner scales horizontally \nto hundreds or thousands of servers to handle the biggest transactional \nworkloads." } diff --git a/packages/google-cloud-spanner/MANIFEST.in b/packages/google-cloud-spanner/MANIFEST.in index d6814cd60037..dae249ec8976 100644 --- a/packages/google-cloud-spanner/MANIFEST.in +++ b/packages/google-cloud-spanner/MANIFEST.in @@ -1,25 +1,20 @@ # -*- coding: utf-8 -*- -# -# Copyright 2024 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. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# 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. - -# Generated by synthtool. DO NOT EDIT! +# include README.rst LICENSE -recursive-include google *.json *.proto py.typed +recursive-include google *.py *.pyi *.json *.proto py.typed recursive-include tests * global-exclude *.py[co] global-exclude __pycache__ - -# Exclude scripts for samples readmegen -prune scripts/readme-gen diff --git a/packages/google-cloud-spanner/README.rst b/packages/google-cloud-spanner/README.rst index 2b1f7b0acda7..c21e37fd052e 100644 --- a/packages/google-cloud-spanner/README.rst +++ b/packages/google-cloud-spanner/README.rst @@ -1,29 +1,28 @@ Python Client for Cloud Spanner =============================== -|GA| |pypi| |versions| - -`Cloud Spanner`_ is the world's first fully managed relational database service -to offer both strong consistency and horizontal scalability for -mission-critical online transaction processing (OLTP) applications. With Cloud -Spanner you enjoy all the traditional benefits of a relational database; but -unlike any other relational database service, Cloud Spanner scales horizontally -to hundreds or thousands of servers to handle the biggest transactional +|stable| |pypi| |versions| + +`Cloud Spanner`_: is the world's first fully managed relational database service +to offer both strong consistency and horizontal scalability for +mission-critical online transaction processing (OLTP) applications. With Cloud +Spanner you enjoy all the traditional benefits of a relational database; but +unlike any other relational database service, Cloud Spanner scales horizontally +to hundreds or thousands of servers to handle the biggest transactional workloads. - - `Client Library Documentation`_ - `Product Documentation`_ -.. |GA| image:: https://img.shields.io/badge/support-GA-gold.svg - :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#general-availability +.. |stable| image:: https://img.shields.io/badge/support-stable-gold.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels .. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-spanner.svg :target: https://pypi.org/project/google-cloud-spanner/ .. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-spanner.svg :target: https://pypi.org/project/google-cloud-spanner/ -.. _Cloud Spanner: https://cloud.google.com/spanner/ -.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/spanner/latest -.. _Product Documentation: https://cloud.google.com/spanner/docs +.. _Cloud Spanner: https://cloud.google.com/spanner/docs/ +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/spanner/latest/summary_overview +.. _Product Documentation: https://cloud.google.com/spanner/docs/ Quick Start ----------- @@ -32,49 +31,64 @@ In order to use this library, you first need to go through the following steps: 1. `Select or create a Cloud Platform project.`_ 2. `Enable billing for your project.`_ -3. `Enable the Google Cloud Spanner API.`_ -4. `Setup Authentication.`_ +3. `Enable the Cloud Spanner.`_ +4. `Set up Authentication.`_ .. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project .. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project -.. _Enable the Google Cloud Spanner API.: https://cloud.google.com/spanner -.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html +.. _Enable the Cloud Spanner.: https://cloud.google.com/spanner/docs/ +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html Installation ~~~~~~~~~~~~ -Install this library in a `virtualenv`_ using pip. `virtualenv`_ is a tool to -create isolated Python environments. The basic problem it addresses is one of -dependencies and versions, and indirectly permissions. +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. -With `virtualenv`_, it's possible to install this library without needing system +With `venv`_, it's possible to install this library without needing system install permissions, and without clashing with the installed system dependencies. -.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-spanner/samples Supported Python Versions ^^^^^^^^^^^^^^^^^^^^^^^^^ -Python >= 3.9 +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. -Deprecated Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^^ -Python == 2.7. -Python == 3.5. -Python == 3.6. -Python == 3.7. -Python == 3.8. +Python >= 3.9, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.8 + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches Mac/Linux ^^^^^^^^^ .. code-block:: console - pip install virtualenv - virtualenv + python3 -m venv source /bin/activate - /bin/pip install google-cloud-spanner + pip install google-cloud-spanner Windows @@ -82,10 +96,9 @@ Windows .. code-block:: console - pip install virtualenv - virtualenv - \Scripts\activate - \Scripts\pip.exe install google-cloud-spanner + py -m venv + .\\Scripts\activate + pip install google-cloud-spanner Example Usage @@ -191,7 +204,7 @@ To add one or more records to a table, use ``insert``: 'citizens', columns=['email', 'first_name', 'last_name', 'age'], values=[ - ['phred@exammple.com', 'Phred', 'Phlyntstone', 32], + ['phred@example.com', 'Phred', 'Phlyntstone', 32], ['bharney@example.com', 'Bharney', 'Rhubble', 31], ], ) @@ -230,7 +243,7 @@ if any of the records does not already exist. 'citizens', columns=['email', 'age'], values=[ - ['phred@exammple.com', 33], + ['phred@example.com', 33], ['bharney@example.com', 32], ], ) @@ -271,7 +284,101 @@ Auto-retry of aborted transactions is enabled only for ``!autocommit`` mode, as Next Steps ~~~~~~~~~~ -- See the `Client Library Documentation`_ to learn how to connect to Cloud - Spanner using this Client Library. -- Read the `Product documentation`_ to learn - more about the product and see How-to Guides. +- Read the `Client Library Documentation`_ for Cloud Spanner + to see other available methods on the client. +- Read the `Cloud Spanner Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Cloud Spanner Product documentation: https://cloud.google.com/spanner/docs/ +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-cloud-spanner/docs/README.rst b/packages/google-cloud-spanner/docs/README.rst deleted file mode 120000 index 89a0106941ff..000000000000 --- a/packages/google-cloud-spanner/docs/README.rst +++ /dev/null @@ -1 +0,0 @@ -../README.rst \ No newline at end of file diff --git a/packages/google-cloud-spanner/docs/README.rst b/packages/google-cloud-spanner/docs/README.rst new file mode 100644 index 000000000000..c21e37fd052e --- /dev/null +++ b/packages/google-cloud-spanner/docs/README.rst @@ -0,0 +1,384 @@ +Python Client for Cloud Spanner +=============================== + +|stable| |pypi| |versions| + +`Cloud Spanner`_: is the world's first fully managed relational database service +to offer both strong consistency and horizontal scalability for +mission-critical online transaction processing (OLTP) applications. With Cloud +Spanner you enjoy all the traditional benefits of a relational database; but +unlike any other relational database service, Cloud Spanner scales horizontally +to hundreds or thousands of servers to handle the biggest transactional +workloads. + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |stable| image:: https://img.shields.io/badge/support-stable-gold.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/google-cloud-spanner.svg + :target: https://pypi.org/project/google-cloud-spanner/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/google-cloud-spanner.svg + :target: https://pypi.org/project/google-cloud-spanner/ +.. _Cloud Spanner: https://cloud.google.com/spanner/docs/ +.. _Client Library Documentation: https://cloud.google.com/python/docs/reference/spanner/latest/summary_overview +.. _Product Documentation: https://cloud.google.com/spanner/docs/ + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. `Enable the Cloud Spanner.`_ +4. `Set up Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Enable the Cloud Spanner.: https://cloud.google.com/spanner/docs/ +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-spanner/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.9, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.8 + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install google-cloud-spanner + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install google-cloud-spanner + + +Example Usage +------------- + + +Executing Arbitrary SQL in a Transaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Generally, to work with Cloud Spanner, you will want a transaction. The +preferred mechanism for this is to create a single function, which executes +as a callback to ``database.run_in_transaction``: + +.. code:: python + + # First, define the function that represents a single "unit of work" + # that should be run within the transaction. + def update_anniversary(transaction, person_id, unix_timestamp): + # The query itself is just a string. + # + # The use of @parameters is recommended rather than doing your + # own string interpolation; this provides protections against + # SQL injection attacks. + query = """SELECT anniversary FROM people + WHERE id = @person_id""" + + # When executing the SQL statement, the query and parameters are sent + # as separate arguments. When using parameters, you must specify + # both the parameters themselves and their types. + row = transaction.execute_sql( + query=query, + params={'person_id': person_id}, + param_types={ + 'person_id': types.INT64_PARAM_TYPE, + }, + ).one() + + # Now perform an update on the data. + old_anniversary = row[0] + new_anniversary = _compute_anniversary(old_anniversary, years) + transaction.update( + 'people', + ['person_id', 'anniversary'], + [person_id, new_anniversary], + ) + + # Actually run the `update_anniversary` function in a transaction. + database.run_in_transaction(update_anniversary, + person_id=42, + unix_timestamp=1335020400, + ) + + +Select records using a Transaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once you have a transaction object (such as the first argument sent to +``run_in_transaction``), reading data is easy: + +.. code:: python + + # Define a SELECT query. + query = """SELECT e.first_name, e.last_name, p.telephone + FROM employees as e, phones as p + WHERE p.employee_id == e.employee_id""" + + # Execute the query and return results. + result = transaction.execute_sql(query) + for row in result.rows: + print(row) + + +Insert records using Data Manipulation Language (DML) with a Transaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use the ``execute_update()`` method to execute a DML statement: + +.. code:: python + + spanner_client = spanner.Client() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + def insert_singers(transaction): + row_ct = transaction.execute_update( + "INSERT Singers (SingerId, FirstName, LastName) " + " VALUES (10, 'Virginia', 'Watson')" + ) + + print("{} record(s) inserted.".format(row_ct)) + + database.run_in_transaction(insert_singers) + + +Insert records using Mutations with a Transaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To add one or more records to a table, use ``insert``: + +.. code:: python + + transaction.insert( + 'citizens', + columns=['email', 'first_name', 'last_name', 'age'], + values=[ + ['phred@example.com', 'Phred', 'Phlyntstone', 32], + ['bharney@example.com', 'Bharney', 'Rhubble', 31], + ], + ) + + +Update records using Data Manipulation Language (DML) with a Transaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: python + + spanner_client = spanner.Client() + instance = spanner_client.instance(instance_id) + database = instance.database(database_id) + + def update_albums(transaction): + row_ct = transaction.execute_update( + "UPDATE Albums " + "SET MarketingBudget = MarketingBudget * 2 " + "WHERE SingerId = 1 and AlbumId = 1" + ) + + print("{} record(s) updated.".format(row_ct)) + + database.run_in_transaction(update_albums) + + +Update records using Mutations with a Transaction +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``Transaction.update`` updates one or more existing records in a table. Fails +if any of the records does not already exist. + +.. code:: python + + transaction.update( + 'citizens', + columns=['email', 'age'], + values=[ + ['phred@example.com', 33], + ['bharney@example.com', 32], + ], + ) + + +Connection API +-------------- +Connection API represents a wrap-around for Python Spanner API, written in accordance with PEP-249, and provides a simple way of communication with a Spanner database through connection objects: + +.. code:: python + + from google.cloud.spanner_dbapi.connection import connect + + connection = connect("instance-id", "database-id") + connection.autocommit = True + + cursor = connection.cursor() + cursor.execute("SELECT * FROM table_name") + + result = cursor.fetchall() + + +If using [fine-grained access controls](https://cloud.google.com/spanner/docs/access-with-fgac) you can pass a ``database_role`` argument to connect as that role: + +.. code:: python + + connection = connect("instance-id", "database-id", database_role='your-role') + + +Aborted Transactions Retry Mechanism +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In ``!autocommit`` mode, transactions can be aborted due to transient errors. In most cases retry of an aborted transaction solves the problem. To simplify it, connection tracks SQL statements, executed in the current transaction. In case the transaction aborted, the connection initiates a new one and re-executes all the statements. In the process, the connection checks that retried statements are returning the same results that the original statements did. If results are different, the transaction is dropped, as the underlying data changed, and auto retry is impossible. + +Auto-retry of aborted transactions is enabled only for ``!autocommit`` mode, as in ``autocommit`` mode transactions are never aborted. + + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Cloud Spanner + to see other available methods on the client. +- Read the `Cloud Spanner Product documentation`_ to learn + more about the product and see How-to Guides. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _Cloud Spanner Product documentation: https://cloud.google.com/spanner/docs/ +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/packages/google-cloud-spanner/docs/conf.py b/packages/google-cloud-spanner/docs/conf.py index 8956acc1923e..7af5ba74fea1 100644 --- a/packages/google-cloud-spanner/docs/conf.py +++ b/packages/google-cloud-spanner/docs/conf.py @@ -28,7 +28,6 @@ import os import shlex import sys -import logging from typing import Any # If extensions (or modules to document with autodoc) are in another directory, @@ -83,9 +82,9 @@ root_doc = "index" # General information about the project. -project = u"google-cloud-spanner" -copyright = u"2025, Google, LLC" -author = u"Google APIs" +project = "google-cloud-spanner" +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 @@ -285,7 +284,7 @@ ( root_doc, "google-cloud-spanner.tex", - u"google-cloud-spanner Documentation", + "google-cloud-spanner Documentation", author, "manual", ) @@ -386,6 +385,7 @@ napoleon_use_param = True napoleon_use_rtype = True + # Setup for sphinx behaviors such as warning filters. class UnexpectedUnindentFilter(logging.Filter): """Filter out warnings about unexpected unindentation following bullet lists.""" @@ -413,5 +413,5 @@ def setup(app: Any) -> None: """ # Sphinx's logger is hierarchical. Adding a filter to the # root 'sphinx' logger will catch warnings from all sub-loggers. - logger = logging.getLogger('sphinx') + logger = logging.getLogger("sphinx") logger.addFilter(UnexpectedUnindentFilter()) diff --git a/packages/google-cloud-spanner/docs/index.rst b/packages/google-cloud-spanner/docs/index.rst index bbf28d13c077..d6014e28f10c 100644 --- a/packages/google-cloud-spanner/docs/index.rst +++ b/packages/google-cloud-spanner/docs/index.rst @@ -2,6 +2,7 @@ .. include:: multiprocessing.rst + Usage Documentation ------------------- .. toctree:: diff --git a/packages/google-cloud-spanner/google/cloud/spanner.py b/packages/google-cloud-spanner/google/cloud/spanner/__init__.py similarity index 95% rename from packages/google-cloud-spanner/google/cloud/spanner.py rename to packages/google-cloud-spanner/google/cloud/spanner/__init__.py index 2b89bd3e4682..0c3348587df3 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner.py +++ b/packages/google-cloud-spanner/google/cloud/spanner/__init__.py @@ -1,4 +1,5 @@ -# Copyright 2016, Google LLC All rights reserved. +# -*- coding: utf-8 -*- +# 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. @@ -11,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +# from __future__ import absolute_import from google.cloud.spanner_v1 import ( diff --git a/packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py new file mode 100644 index 000000000000..d268b84d6686 --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# 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. +# +__version__ = "3.64.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner/py.typed b/packages/google-cloud-spanner/google/cloud/spanner/py.typed new file mode 100644 index 000000000000..0989eccd0480 --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-spanner package uses inline types. diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/__init__.py new file mode 100644 index 000000000000..a2ee5232c58a --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/__init__.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# 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. +# +from google.cloud.spanner_admin_database import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.spanner_admin_database_v1.services.database_admin.async_client import ( + DatabaseAdminAsyncClient, +) +from google.cloud.spanner_admin_database_v1.services.database_admin.client import ( + DatabaseAdminClient, +) +from google.cloud.spanner_admin_database_v1.types.backup import ( + Backup, + BackupInfo, + BackupInstancePartition, + CopyBackupEncryptionConfig, + CopyBackupMetadata, + CopyBackupRequest, + CreateBackupEncryptionConfig, + CreateBackupMetadata, + CreateBackupRequest, + DeleteBackupRequest, + FullBackupSpec, + GetBackupRequest, + IncrementalBackupSpec, + ListBackupOperationsRequest, + ListBackupOperationsResponse, + ListBackupsRequest, + ListBackupsResponse, + UpdateBackupRequest, +) +from google.cloud.spanner_admin_database_v1.types.backup_schedule import ( + BackupSchedule, + BackupScheduleSpec, + CreateBackupScheduleRequest, + CrontabSpec, + DeleteBackupScheduleRequest, + GetBackupScheduleRequest, + ListBackupSchedulesRequest, + ListBackupSchedulesResponse, + UpdateBackupScheduleRequest, +) +from google.cloud.spanner_admin_database_v1.types.common import ( + DatabaseDialect, + EncryptionConfig, + EncryptionInfo, + OperationProgress, +) +from google.cloud.spanner_admin_database_v1.types.spanner_database_admin import ( + AddSplitPointsRequest, + AddSplitPointsResponse, + CreateDatabaseMetadata, + CreateDatabaseRequest, + Database, + DatabaseRole, + DdlStatementActionInfo, + DropDatabaseRequest, + GetDatabaseDdlRequest, + GetDatabaseDdlResponse, + GetDatabaseRequest, + InternalUpdateGraphOperationRequest, + InternalUpdateGraphOperationResponse, + ListDatabaseOperationsRequest, + ListDatabaseOperationsResponse, + ListDatabaseRolesRequest, + ListDatabaseRolesResponse, + ListDatabasesRequest, + ListDatabasesResponse, + OptimizeRestoredDatabaseMetadata, + RestoreDatabaseEncryptionConfig, + RestoreDatabaseMetadata, + RestoreDatabaseRequest, + RestoreInfo, + RestoreSourceType, + SplitPoints, + UpdateDatabaseDdlMetadata, + UpdateDatabaseDdlRequest, + UpdateDatabaseMetadata, + UpdateDatabaseRequest, +) + +__all__ = ( + "DatabaseAdminClient", + "DatabaseAdminAsyncClient", + "Backup", + "BackupInfo", + "BackupInstancePartition", + "CopyBackupEncryptionConfig", + "CopyBackupMetadata", + "CopyBackupRequest", + "CreateBackupEncryptionConfig", + "CreateBackupMetadata", + "CreateBackupRequest", + "DeleteBackupRequest", + "FullBackupSpec", + "GetBackupRequest", + "IncrementalBackupSpec", + "ListBackupOperationsRequest", + "ListBackupOperationsResponse", + "ListBackupsRequest", + "ListBackupsResponse", + "UpdateBackupRequest", + "BackupSchedule", + "BackupScheduleSpec", + "CreateBackupScheduleRequest", + "CrontabSpec", + "DeleteBackupScheduleRequest", + "GetBackupScheduleRequest", + "ListBackupSchedulesRequest", + "ListBackupSchedulesResponse", + "UpdateBackupScheduleRequest", + "EncryptionConfig", + "EncryptionInfo", + "OperationProgress", + "DatabaseDialect", + "AddSplitPointsRequest", + "AddSplitPointsResponse", + "CreateDatabaseMetadata", + "CreateDatabaseRequest", + "Database", + "DatabaseRole", + "DdlStatementActionInfo", + "DropDatabaseRequest", + "GetDatabaseDdlRequest", + "GetDatabaseDdlResponse", + "GetDatabaseRequest", + "InternalUpdateGraphOperationRequest", + "InternalUpdateGraphOperationResponse", + "ListDatabaseOperationsRequest", + "ListDatabaseOperationsResponse", + "ListDatabaseRolesRequest", + "ListDatabaseRolesResponse", + "ListDatabasesRequest", + "ListDatabasesResponse", + "OptimizeRestoredDatabaseMetadata", + "RestoreDatabaseEncryptionConfig", + "RestoreDatabaseMetadata", + "RestoreDatabaseRequest", + "RestoreInfo", + "SplitPoints", + "UpdateDatabaseDdlMetadata", + "UpdateDatabaseDdlRequest", + "UpdateDatabaseMetadata", + "UpdateDatabaseRequest", + "RestoreSourceType", +) diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py new file mode 100644 index 000000000000..d268b84d6686 --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# 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. +# +__version__ = "3.64.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database/py.typed b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/py.typed new file mode 100644 index 000000000000..29f334aad61b --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-spanner-admin-database package uses inline types. diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/__init__.py index bc3c6d5d5075..d3da77d95793 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/__init__.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/__init__.py @@ -28,6 +28,7 @@ # this code path once we drop support for Python 3.7 import importlib_metadata as metadata + from .services.database_admin import DatabaseAdminAsyncClient, DatabaseAdminClient from .types.backup import ( Backup, diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/client.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/client.py index 4ccc647dab2b..5387fd68a70d 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/client.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/services/database_admin/client.py @@ -810,11 +810,9 @@ def __init__( universe_domain_opt = getattr(self._client_options, "universe_domain", None) - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = DatabaseAdminClient._read_environment_variables() + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + DatabaseAdminClient._read_environment_variables() + ) self._client_cert_source = DatabaseAdminClient._get_client_cert_source( self._client_options.client_cert_source, self._use_client_cert ) diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/types/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/types/__init__.py index 46cd649f68a1..e9df14d23332 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/types/__init__.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/types/__init__.py @@ -44,7 +44,12 @@ ListBackupSchedulesResponse, UpdateBackupScheduleRequest, ) -from .common import DatabaseDialect, EncryptionConfig, EncryptionInfo, OperationProgress +from .common import ( + DatabaseDialect, + EncryptionConfig, + EncryptionInfo, + OperationProgress, +) from .spanner_database_admin import ( AddSplitPointsRequest, AddSplitPointsResponse, diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/__init__.py new file mode 100644 index 000000000000..7ef3cbc3389b --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/__init__.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# 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. +# +from google.cloud.spanner_admin_instance import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.spanner_admin_instance_v1.services.instance_admin.async_client import ( + InstanceAdminAsyncClient, +) +from google.cloud.spanner_admin_instance_v1.services.instance_admin.client import ( + InstanceAdminClient, +) +from google.cloud.spanner_admin_instance_v1.types.common import ( + FulfillmentPeriod, + OperationProgress, + ReplicaSelection, +) +from google.cloud.spanner_admin_instance_v1.types.spanner_instance_admin import ( + AutoscalingConfig, + CreateInstanceConfigMetadata, + CreateInstanceConfigRequest, + CreateInstanceMetadata, + CreateInstancePartitionMetadata, + CreateInstancePartitionRequest, + CreateInstanceRequest, + DeleteInstanceConfigRequest, + DeleteInstancePartitionRequest, + DeleteInstanceRequest, + FreeInstanceMetadata, + GetInstanceConfigRequest, + GetInstancePartitionRequest, + GetInstanceRequest, + Instance, + InstanceConfig, + InstancePartition, + ListInstanceConfigOperationsRequest, + ListInstanceConfigOperationsResponse, + ListInstanceConfigsRequest, + ListInstanceConfigsResponse, + ListInstancePartitionOperationsRequest, + ListInstancePartitionOperationsResponse, + ListInstancePartitionsRequest, + ListInstancePartitionsResponse, + ListInstancesRequest, + ListInstancesResponse, + MoveInstanceMetadata, + MoveInstanceRequest, + MoveInstanceResponse, + ReplicaComputeCapacity, + ReplicaInfo, + UpdateInstanceConfigMetadata, + UpdateInstanceConfigRequest, + UpdateInstanceMetadata, + UpdateInstancePartitionMetadata, + UpdateInstancePartitionRequest, + UpdateInstanceRequest, +) + +__all__ = ( + "InstanceAdminClient", + "InstanceAdminAsyncClient", + "OperationProgress", + "ReplicaSelection", + "FulfillmentPeriod", + "AutoscalingConfig", + "CreateInstanceConfigMetadata", + "CreateInstanceConfigRequest", + "CreateInstanceMetadata", + "CreateInstancePartitionMetadata", + "CreateInstancePartitionRequest", + "CreateInstanceRequest", + "DeleteInstanceConfigRequest", + "DeleteInstancePartitionRequest", + "DeleteInstanceRequest", + "FreeInstanceMetadata", + "GetInstanceConfigRequest", + "GetInstancePartitionRequest", + "GetInstanceRequest", + "Instance", + "InstanceConfig", + "InstancePartition", + "ListInstanceConfigOperationsRequest", + "ListInstanceConfigOperationsResponse", + "ListInstanceConfigsRequest", + "ListInstanceConfigsResponse", + "ListInstancePartitionOperationsRequest", + "ListInstancePartitionOperationsResponse", + "ListInstancePartitionsRequest", + "ListInstancePartitionsResponse", + "ListInstancesRequest", + "ListInstancesResponse", + "MoveInstanceMetadata", + "MoveInstanceRequest", + "MoveInstanceResponse", + "ReplicaComputeCapacity", + "ReplicaInfo", + "UpdateInstanceConfigMetadata", + "UpdateInstanceConfigRequest", + "UpdateInstanceMetadata", + "UpdateInstancePartitionMetadata", + "UpdateInstancePartitionRequest", + "UpdateInstanceRequest", +) diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py new file mode 100644 index 000000000000..d268b84d6686 --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/gapic_version.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# 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. +# +__version__ = "3.64.0" # {x-release-please-version} diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/py.typed b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/py.typed new file mode 100644 index 000000000000..915a8e55e338 --- /dev/null +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-spanner-admin-instance package uses inline types. diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/__init__.py index 367dc9a08aaf..b2f713eae7fb 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/__init__.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/__init__.py @@ -28,6 +28,7 @@ # this code path once we drop support for Python 3.7 import importlib_metadata as metadata + from .services.instance_admin import InstanceAdminAsyncClient, InstanceAdminClient from .types.common import FulfillmentPeriod, OperationProgress, ReplicaSelection from .types.spanner_instance_admin import ( diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py index 78ec1f97c88a..16be461e8610 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py @@ -692,11 +692,9 @@ def __init__( universe_domain_opt = getattr(self._client_options, "universe_domain", None) - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = InstanceAdminClient._read_environment_variables() + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + InstanceAdminClient._read_environment_variables() + ) self._client_cert_source = InstanceAdminClient._get_client_cert_source( self._client_options.client_cert_source, self._use_client_cert ) diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py index ea40b0f38c3f..f79f7a615709 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py @@ -3115,11 +3115,10 @@ def __call__( resp = self._interceptor.post_list_instance_config_operations(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - ( - resp, - _, - ) = self._interceptor.post_list_instance_config_operations_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_instance_config_operations_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG @@ -3358,11 +3357,10 @@ def __call__( http_options = _BaseInstanceAdminRestTransport._BaseListInstancePartitionOperations._get_http_options() - ( - request, - metadata, - ) = self._interceptor.pre_list_instance_partition_operations( - request, metadata + request, metadata = ( + self._interceptor.pre_list_instance_partition_operations( + request, metadata + ) ) transcoded_request = _BaseInstanceAdminRestTransport._BaseListInstancePartitionOperations._get_transcoded_request( http_options, request @@ -3425,11 +3423,10 @@ def __call__( resp = self._interceptor.post_list_instance_partition_operations(resp) response_metadata = [(k, str(v)) for k, v in response.headers.items()] - ( - resp, - _, - ) = self._interceptor.post_list_instance_partition_operations_with_metadata( - resp, response_metadata + resp, _ = ( + self._interceptor.post_list_instance_partition_operations_with_metadata( + resp, response_metadata + ) ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG diff --git a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/types/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/types/__init__.py index aa3f520a98ed..1a7e78931d2a 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/types/__init__.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/types/__init__.py @@ -13,7 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from .common import FulfillmentPeriod, OperationProgress, ReplicaSelection +from .common import ( + FulfillmentPeriod, + OperationProgress, + ReplicaSelection, +) from .spanner_instance_admin import ( AutoscalingConfig, CreateInstanceConfigMetadata, diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/__init__.py index 9d4388332115..936421ab8306 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/__init__.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/__init__.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- - -# Copyright 2020 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. @@ -91,7 +90,6 @@ ``(allow_commit_timestamp=true)`` in the schema. """ - __all__ = ( # google.cloud.spanner_v1 "__version__", diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/async_client.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/async_client.py index bcab528862f2..37a24f17bccc 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/async_client.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/async_client.py @@ -124,7 +124,9 @@ def from_service_account_info(cls, info: dict, *args, **kwargs): Returns: SpannerAsyncClient: The constructed client. """ - sa_info_func = SpannerClient.from_service_account_info.__func__ # type: ignore + sa_info_func = ( + SpannerClient.from_service_account_info.__func__ # type: ignore + ) return sa_info_func(SpannerAsyncClient, info, *args, **kwargs) @classmethod @@ -141,7 +143,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs): Returns: SpannerAsyncClient: The constructed client. """ - sa_file_func = SpannerClient.from_service_account_file.__func__ # type: ignore + sa_file_func = ( + SpannerClient.from_service_account_file.__func__ # type: ignore + ) return sa_file_func(SpannerAsyncClient, filename, *args, **kwargs) from_service_account_json = from_service_account_file diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py index 18a8a63fa0f1..8e58b78b8846 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/client.py @@ -663,11 +663,9 @@ def __init__( universe_domain_opt = getattr(self._client_options, "universe_domain", None) - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = SpannerClient._read_environment_variables() + self._use_client_cert, self._use_mtls_endpoint, self._universe_domain_env = ( + SpannerClient._read_environment_variables() + ) self._client_cert_source = SpannerClient._get_client_cert_source( self._client_options.client_cert_source, self._use_client_cert ) diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py index 9ffc220d3982..2de2524f94bf 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/services/spanner/transports/grpc.py @@ -285,6 +285,7 @@ def __init__( ) self._interceptor = _LoggingClientInterceptor() + self._logged_channel = grpc.intercept_channel( self._grpc_channel, self._interceptor ) diff --git a/packages/google-cloud-spanner/google/cloud/spanner_v1/types/__init__.py b/packages/google-cloud-spanner/google/cloud/spanner_v1/types/__init__.py index 059003b78fe5..5a7ded16ddb6 100644 --- a/packages/google-cloud-spanner/google/cloud/spanner_v1/types/__init__.py +++ b/packages/google-cloud-spanner/google/cloud/spanner_v1/types/__init__.py @@ -13,9 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from .change_stream import ChangeStreamRecord -from .commit_response import CommitResponse -from .keys import KeyRange, KeySet +from .change_stream import ( + ChangeStreamRecord, +) +from .commit_response import ( + CommitResponse, +) +from .keys import ( + KeyRange, + KeySet, +) from .location import ( CacheUpdate, Group, @@ -25,9 +32,20 @@ RoutingHint, Tablet, ) -from .mutation import Mutation -from .query_plan import PlanNode, QueryAdvisorResult, QueryPlan -from .result_set import PartialResultSet, ResultSet, ResultSetMetadata, ResultSetStats +from .mutation import ( + Mutation, +) +from .query_plan import ( + PlanNode, + QueryAdvisorResult, + QueryPlan, +) +from .result_set import ( + PartialResultSet, + ResultSet, + ResultSetMetadata, + ResultSetStats, +) from .spanner import ( BatchCreateSessionsRequest, BatchCreateSessionsResponse, @@ -60,7 +78,12 @@ TransactionOptions, TransactionSelector, ) -from .type import StructType, Type, TypeAnnotationCode, TypeCode +from .type import ( + StructType, + Type, + TypeAnnotationCode, + TypeCode, +) __all__ = ( "ChangeStreamRecord", diff --git a/packages/google-cloud-spanner/mypy.ini b/packages/google-cloud-spanner/mypy.ini new file mode 100644 index 000000000000..e0e0da2e9e40 --- /dev/null +++ b/packages/google-cloud-spanner/mypy.ini @@ -0,0 +1,15 @@ +[mypy] +python_version = 3.14 +namespace_packages = True +ignore_missing_imports = False + +# TODO(https://github.com/googleapis/gapic-generator-python/issues/2563): +# Dependencies that historically lacks py.typed markers +[mypy-google.iam.*] +ignore_missing_imports = True + +# Helps mypy navigate the 'google' namespace more reliably in 3.10+ +explicit_package_bases = True + +# Performance: reuse results from previous runs to speed up 'nox' +incremental = True diff --git a/packages/google-cloud-spanner/noxfile.py b/packages/google-cloud-spanner/noxfile.py index 81685e62c6ef..e208b01edc45 100644 --- a/packages/google-cloud-spanner/noxfile.py +++ b/packages/google-cloud-spanner/noxfile.py @@ -1,27 +1,18 @@ # -*- coding: utf-8 -*- -# -# Copyright 2024 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. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# 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. - -# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` -# The source of truth for this file is `.librarian/generator-input` - - -# Generated by synthtool. DO NOT EDIT! - -from __future__ import absolute_import - +# import os import pathlib import re @@ -122,6 +113,8 @@ def lint(session): *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 @@ -725,10 +718,73 @@ def mypy(session): @nox.session(python=DEFAULT_PYTHON_VERSION) -def core_deps_from_source(session): - """Run all tests with core dependencies installed from source +@nox.parametrize( + "protobuf_implementation", + ["python", "upb"], +) +def core_deps_from_source(session, protobuf_implementation): + """Run all tests with core dependencies installed from source, rather than pulling the dependencies from PyPI. """ - # TODO(https://github.com/googleapis/google-cloud-python/issues/16014): - # Add core deps from source tests - session.skip("Core deps from source tests are not yet supported") + + # Install all dependencies + session.install("-e", ".") + + # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES + session.install(*unit_deps_all) + + # Install dependencies for the system test environment + system_deps_all = ( + SYSTEM_TEST_STANDARD_DEPENDENCIES + + SYSTEM_TEST_EXTERNAL_DEPENDENCIES + + SYSTEM_TEST_EXTRAS + ) + 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-{ALL_PYTHON[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*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE + ) + ] + + # Install dependencies specified in `testing/constraints-X.txt`. + session.install(*constraints_deps) + + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2358): `grpcio` and + # `grpcio-status` should be added to the list below so that they are installed from source, + # rather than PyPI. + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2357): `protobuf` should be + # added to the list below so that it is installed from source, rather than PyPI + # Note: If a dependency is added to the `core_dependencies_from_source` list, + # the `prerel_deps` list in the `prerelease_deps` nox session should also be updated. + core_dependencies_from_source = [ + "googleapis-common-protos @ git+https://github.com/googleapis/google-cloud-python#egg=googleapis-common-protos&subdirectory=packages/googleapis-common-protos", + "google-api-core @ git+https://github.com/googleapis/google-cloud-python#egg=google-api-core&subdirectory=packages/google-api-core", + "google-auth @ git+https://github.com/googleapis/google-cloud-python#egg=google-auth&subdirectory=packages/google-auth", + "grpc-google-iam-v1 @ git+https://github.com/googleapis/google-cloud-python#egg=grpc-google-iam-v1&subdirectory=packages/grpc-google-iam-v1", + "proto-plus @ git+https://github.com/googleapis/google-cloud-python#egg=proto-plus&subdirectory=packages/proto-plus", + ] + + for dep in core_dependencies_from_source: + session.install(dep, "--no-deps", "--ignore-installed") + print(f"Installed {dep}") + + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_async.py index ff6fcfe598fb..4dad83448b0d 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_async.py @@ -49,4 +49,5 @@ async def sample_add_split_points(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_AddSplitPoints_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_sync.py index 3819bbe986cf..f7e51c32aff0 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_add_split_points_sync.py @@ -49,4 +49,5 @@ def sample_add_split_points(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_AddSplitPoints_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_async.py index d885947bb599..05c95465323e 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_async.py @@ -55,4 +55,5 @@ async def sample_copy_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CopyBackup_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_sync.py index a571e058c94e..7c2d28a187ab 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_copy_backup_sync.py @@ -55,4 +55,5 @@ def sample_copy_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CopyBackup_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_async.py index 2ad8881f54da..f00ca943b51f 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_async.py @@ -54,4 +54,5 @@ async def sample_create_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CreateBackup_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_async.py index efdcc2457ed2..d9b8d0f65726 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_async.py @@ -50,4 +50,5 @@ async def sample_create_backup_schedule(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CreateBackupSchedule_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_sync.py index 60d4b50c3b59..59304c5b4187 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_schedule_sync.py @@ -50,4 +50,5 @@ def sample_create_backup_schedule(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CreateBackupSchedule_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_sync.py index 02b9d1f0e712..500170f1fe49 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_backup_sync.py @@ -54,4 +54,5 @@ def sample_create_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CreateBackup_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_async.py index 47399a8d40c5..98bc5ae8743a 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_async.py @@ -54,4 +54,5 @@ async def sample_create_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CreateDatabase_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_sync.py index 6f112cd8a7d2..24daef627df1 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_create_database_sync.py @@ -54,4 +54,5 @@ def sample_create_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_CreateDatabase_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_async.py index 58b93a119ada..efff84b6729b 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_async.py @@ -49,4 +49,5 @@ async def sample_get_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetBackup_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_async.py index 5a37eec97570..922f8077515b 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_async.py @@ -49,4 +49,5 @@ async def sample_get_backup_schedule(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetBackupSchedule_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_sync.py index 4006cac33391..4304dd7418e7 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_schedule_sync.py @@ -49,4 +49,5 @@ def sample_get_backup_schedule(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetBackupSchedule_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_sync.py index 16cffcd78d0f..ce5a0d6647cc 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_backup_sync.py @@ -49,4 +49,5 @@ def sample_get_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetBackup_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_async.py index fd8621c27bd9..35343a040bc6 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_async.py @@ -49,4 +49,5 @@ async def sample_get_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetDatabase_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_async.py index 8e84b21f7834..c00c8388102d 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_async.py @@ -49,4 +49,5 @@ async def sample_get_database_ddl(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetDatabaseDdl_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_sync.py index 495b557a556e..b637a153605b 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_ddl_sync.py @@ -49,4 +49,5 @@ def sample_get_database_ddl(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetDatabaseDdl_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_sync.py index ab729bb9e372..1e6381fee747 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_database_sync.py @@ -49,4 +49,5 @@ def sample_get_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetDatabase_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_async.py index 74324f68280e..934fc9d08e32 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_async.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_database_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_database_v1 + async def sample_get_iam_policy(): # Create a client @@ -50,4 +51,5 @@ async def sample_get_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetIamPolicy_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_sync.py index b8bba92ba366..076d7b12b1d1 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_get_iam_policy_sync.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_database_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_database_v1 + def sample_get_iam_policy(): # Create a client @@ -50,4 +51,5 @@ def sample_get_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_GetIamPolicy_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_async.py index 556205a0aa78..142664940871 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_async.py @@ -51,4 +51,5 @@ async def sample_internal_update_graph_operation(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_InternalUpdateGraphOperation_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_sync.py index 46f1a3c88f8e..ea4101788507 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_internal_update_graph_operation_sync.py @@ -51,4 +51,5 @@ def sample_internal_update_graph_operation(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_InternalUpdateGraphOperation_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_async.py index a56ec9f80e37..c3774f6d5688 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_async.py @@ -50,4 +50,5 @@ async def sample_list_backup_operations(): async for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListBackupOperations_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_sync.py index 6383e1b2476c..4f097608e0f3 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_operations_sync.py @@ -50,4 +50,5 @@ def sample_list_backup_operations(): for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListBackupOperations_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_async.py index 25ac53891a6a..c0c34ce43420 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_async.py @@ -50,4 +50,5 @@ async def sample_list_backup_schedules(): async for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListBackupSchedules_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_sync.py index 89cf82d27884..cc7dd55ae4b6 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backup_schedules_sync.py @@ -50,4 +50,5 @@ def sample_list_backup_schedules(): for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListBackupSchedules_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_async.py index 140e519e07be..0334b6719706 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_async.py @@ -50,4 +50,5 @@ async def sample_list_backups(): async for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListBackups_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_sync.py index 9f04036f7465..31d5b2c4d90d 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_backups_sync.py @@ -50,4 +50,5 @@ def sample_list_backups(): for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListBackups_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_async.py index 3bc614b2327d..8a8795938b7e 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_async.py @@ -50,4 +50,5 @@ async def sample_list_database_operations(): async for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListDatabaseOperations_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_sync.py index 3d4dc965a99c..d3082794d4be 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_operations_sync.py @@ -50,4 +50,5 @@ def sample_list_database_operations(): for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListDatabaseOperations_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_async.py index 46ec91ce8984..ca8fd99822d8 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_async.py @@ -50,4 +50,5 @@ async def sample_list_database_roles(): async for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListDatabaseRoles_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_sync.py index d39e4759dde5..e5efc6577378 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_database_roles_sync.py @@ -50,4 +50,5 @@ def sample_list_database_roles(): for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListDatabaseRoles_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_async.py index 586dfa56f1ed..04591d44e247 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_async.py @@ -50,4 +50,5 @@ async def sample_list_databases(): async for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListDatabases_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_sync.py index e6ef221af667..7126387461ee 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_list_databases_sync.py @@ -50,4 +50,5 @@ def sample_list_databases(): for response in page_result: print(response) + # [END spanner_v1_generated_DatabaseAdmin_ListDatabases_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_async.py index 384c063c61b8..bfffe8c01088 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_async.py @@ -55,4 +55,5 @@ async def sample_restore_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_RestoreDatabase_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_sync.py index a327a8ae1390..bcfde1efca50 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_restore_database_sync.py @@ -55,4 +55,5 @@ def sample_restore_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_RestoreDatabase_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_async.py index d68e7b03be41..fc3e68a6ebbf 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_async.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_database_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_database_v1 + async def sample_set_iam_policy(): # Create a client @@ -50,4 +51,5 @@ async def sample_set_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_SetIamPolicy_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_sync.py index 5dbd42dc3552..7bb1c58c75c1 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_set_iam_policy_sync.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_database_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_database_v1 + def sample_set_iam_policy(): # Create a client @@ -50,4 +51,5 @@ def sample_set_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_SetIamPolicy_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_async.py index da2970bca4d9..0bcc42204691 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_async.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_database_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_database_v1 + async def sample_test_iam_permissions(): # Create a client @@ -42,7 +43,7 @@ async def sample_test_iam_permissions(): # Initialize request argument(s) request = iam_policy_pb2.TestIamPermissionsRequest( resource="resource_value", - permissions=['permissions_value1', 'permissions_value2'], + permissions=["permissions_value1", "permissions_value2"], ) # Make the request @@ -51,4 +52,5 @@ async def sample_test_iam_permissions(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_TestIamPermissions_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_sync.py index 23826355b71e..1408b4deee29 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_test_iam_permissions_sync.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_database_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_database_v1 + def sample_test_iam_permissions(): # Create a client @@ -42,7 +43,7 @@ def sample_test_iam_permissions(): # Initialize request argument(s) request = iam_policy_pb2.TestIamPermissionsRequest( resource="resource_value", - permissions=['permissions_value1', 'permissions_value2'], + permissions=["permissions_value1", "permissions_value2"], ) # Make the request @@ -51,4 +52,5 @@ def sample_test_iam_permissions(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_TestIamPermissions_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_async.py index 95fa2a63f6e6..237d84dddacf 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_async.py @@ -39,8 +39,7 @@ async def sample_update_backup(): client = spanner_admin_database_v1.DatabaseAdminAsyncClient() # Initialize request argument(s) - request = spanner_admin_database_v1.UpdateBackupRequest( - ) + request = spanner_admin_database_v1.UpdateBackupRequest() # Make the request response = await client.update_backup(request=request) @@ -48,4 +47,5 @@ async def sample_update_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateBackup_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_async.py index de17dfc86e8c..1cfd55f869f3 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_async.py @@ -39,8 +39,7 @@ async def sample_update_backup_schedule(): client = spanner_admin_database_v1.DatabaseAdminAsyncClient() # Initialize request argument(s) - request = spanner_admin_database_v1.UpdateBackupScheduleRequest( - ) + request = spanner_admin_database_v1.UpdateBackupScheduleRequest() # Make the request response = await client.update_backup_schedule(request=request) @@ -48,4 +47,5 @@ async def sample_update_backup_schedule(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateBackupSchedule_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_sync.py index 4ef64a067304..7d8c2eac7a70 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_schedule_sync.py @@ -39,8 +39,7 @@ def sample_update_backup_schedule(): client = spanner_admin_database_v1.DatabaseAdminClient() # Initialize request argument(s) - request = spanner_admin_database_v1.UpdateBackupScheduleRequest( - ) + request = spanner_admin_database_v1.UpdateBackupScheduleRequest() # Make the request response = client.update_backup_schedule(request=request) @@ -48,4 +47,5 @@ def sample_update_backup_schedule(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateBackupSchedule_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_sync.py index 9dbb0148dc90..b192bbb81162 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_backup_sync.py @@ -39,8 +39,7 @@ def sample_update_backup(): client = spanner_admin_database_v1.DatabaseAdminClient() # Initialize request argument(s) - request = spanner_admin_database_v1.UpdateBackupRequest( - ) + request = spanner_admin_database_v1.UpdateBackupRequest() # Make the request response = client.update_backup(request=request) @@ -48,4 +47,5 @@ def sample_update_backup(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateBackup_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_async.py index d5588c3036cc..931cf358eed9 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_async.py @@ -56,4 +56,5 @@ async def sample_update_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateDatabase_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_async.py index ad98e2da9c2d..679b93f6badf 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_async.py @@ -41,7 +41,7 @@ async def sample_update_database_ddl(): # Initialize request argument(s) request = spanner_admin_database_v1.UpdateDatabaseDdlRequest( database="database_value", - statements=['statements_value1', 'statements_value2'], + statements=["statements_value1", "statements_value2"], ) # Make the request @@ -54,4 +54,5 @@ async def sample_update_database_ddl(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateDatabaseDdl_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_sync.py index 73297524b9e4..98ebac28f5ab 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_ddl_sync.py @@ -41,7 +41,7 @@ def sample_update_database_ddl(): # Initialize request argument(s) request = spanner_admin_database_v1.UpdateDatabaseDdlRequest( database="database_value", - statements=['statements_value1', 'statements_value2'], + statements=["statements_value1", "statements_value2"], ) # Make the request @@ -54,4 +54,5 @@ def sample_update_database_ddl(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateDatabaseDdl_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_sync.py index 62ed40bc8489..bcea98845344 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_database_admin_update_database_sync.py @@ -56,4 +56,5 @@ def sample_update_database(): # Handle the response print(response) + # [END spanner_v1_generated_DatabaseAdmin_UpdateDatabase_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_async.py index 74bd64004403..184033e3be47 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_async.py @@ -60,4 +60,5 @@ async def sample_create_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_CreateInstance_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_async.py index c3f266e4c4d1..bf797c72ad51 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_async.py @@ -54,4 +54,5 @@ async def sample_create_instance_config(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_CreateInstanceConfig_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_sync.py index c5b7616534da..3e392223c64c 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_config_sync.py @@ -54,4 +54,5 @@ def sample_create_instance_config(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_CreateInstanceConfig_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_async.py index a22765f53ff4..1bf8b6fe88aa 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_async.py @@ -61,4 +61,5 @@ async def sample_create_instance_partition(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_CreateInstancePartition_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_sync.py index 5b5f2e0e26bc..b1496305d62f 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_partition_sync.py @@ -61,4 +61,5 @@ def sample_create_instance_partition(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_CreateInstancePartition_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_sync.py index f43c5016b549..4e9b0aeb001f 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_create_instance_sync.py @@ -60,4 +60,5 @@ def sample_create_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_CreateInstance_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_async.py index 1acc90bcedf5..e3e64f3d34df 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_async.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_instance_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_instance_v1 + async def sample_get_iam_policy(): # Create a client @@ -50,4 +51,5 @@ async def sample_get_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetIamPolicy_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_sync.py index 170cd1fc5407..3c167bda3d42 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_iam_policy_sync.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_instance_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_instance_v1 + def sample_get_iam_policy(): # Create a client @@ -50,4 +51,5 @@ def sample_get_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetIamPolicy_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_async.py index 059eb2a07891..e2d1e538ed82 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_async.py @@ -49,4 +49,5 @@ async def sample_get_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetInstance_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_async.py index 9adfb51c2e36..a66830ee0635 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_async.py @@ -49,4 +49,5 @@ async def sample_get_instance_config(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetInstanceConfig_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_sync.py index 16e9d3c3c805..a00e62710d70 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_config_sync.py @@ -49,4 +49,5 @@ def sample_get_instance_config(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetInstanceConfig_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_async.py index 8e84abcf6ee9..381b070176df 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_async.py @@ -49,4 +49,5 @@ async def sample_get_instance_partition(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetInstancePartition_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_sync.py index d617cbb382f1..650be8fdbefe 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_partition_sync.py @@ -49,4 +49,5 @@ def sample_get_instance_partition(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetInstancePartition_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_sync.py index 4a246a5bf3be..b64b8906af04 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_get_instance_sync.py @@ -49,4 +49,5 @@ def sample_get_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_GetInstance_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_async.py index a0580fef7c28..c58a8efcd332 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_async.py @@ -50,4 +50,5 @@ async def sample_list_instance_config_operations(): async for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstanceConfigOperations_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_sync.py index 89213b3a2ec8..9cbe5c43348c 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_config_operations_sync.py @@ -50,4 +50,5 @@ def sample_list_instance_config_operations(): for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstanceConfigOperations_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_async.py index 651b2f88ae5d..cc569d9af1ff 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_async.py @@ -50,4 +50,5 @@ async def sample_list_instance_configs(): async for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstanceConfigs_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_sync.py index a0f120277abf..f6dab73127b9 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_configs_sync.py @@ -50,4 +50,5 @@ def sample_list_instance_configs(): for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstanceConfigs_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_async.py index 9dedb973f120..b3012a40cb7b 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_async.py @@ -50,4 +50,5 @@ async def sample_list_instance_partition_operations(): async for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstancePartitionOperations_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_sync.py index b2a7549b2941..cdbf8bad3e7e 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partition_operations_sync.py @@ -50,4 +50,5 @@ def sample_list_instance_partition_operations(): for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstancePartitionOperations_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_async.py index 56adc152fec0..1336c7602e0f 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_async.py @@ -50,4 +50,5 @@ async def sample_list_instance_partitions(): async for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstancePartitions_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_sync.py index 1e65552fc1fe..a32f28e25b3f 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instance_partitions_sync.py @@ -50,4 +50,5 @@ def sample_list_instance_partitions(): for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstancePartitions_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_async.py index abe1a1affae4..f140f24347a2 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_async.py @@ -50,4 +50,5 @@ async def sample_list_instances(): async for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstances_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_sync.py index f344baff11b9..6b503ececf07 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_list_instances_sync.py @@ -50,4 +50,5 @@ def sample_list_instances(): for response in page_result: print(response) + # [END spanner_v1_generated_InstanceAdmin_ListInstances_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_async.py index ce62120492a4..3937a192458b 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_async.py @@ -54,4 +54,5 @@ async def sample_move_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_MoveInstance_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_sync.py index 4621200e0c70..9657c7b3b88c 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_move_instance_sync.py @@ -54,4 +54,5 @@ def sample_move_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_MoveInstance_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_async.py index ce7be36a053a..49e90d0563c2 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_async.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_instance_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_instance_v1 + async def sample_set_iam_policy(): # Create a client @@ -50,4 +51,5 @@ async def sample_set_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_SetIamPolicy_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_sync.py index 838f3333abe1..a556d3a98483 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_set_iam_policy_sync.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_instance_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_instance_v1 + def sample_set_iam_policy(): # Create a client @@ -50,4 +51,5 @@ def sample_set_iam_policy(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_SetIamPolicy_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_async.py index ac53ead9b9ca..76002bce214e 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_async.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_instance_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_instance_v1 + async def sample_test_iam_permissions(): # Create a client @@ -42,7 +43,7 @@ async def sample_test_iam_permissions(): # Initialize request argument(s) request = iam_policy_pb2.TestIamPermissionsRequest( resource="resource_value", - permissions=['permissions_value1', 'permissions_value2'], + permissions=["permissions_value1", "permissions_value2"], ) # Make the request @@ -51,4 +52,5 @@ async def sample_test_iam_permissions(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_TestIamPermissions_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_sync.py index e1837144a1ce..2999758440e7 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_test_iam_permissions_sync.py @@ -31,9 +31,10 @@ # - It may require specifying regional endpoints when creating the service # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html -from google.cloud import spanner_admin_instance_v1 import google.iam.v1.iam_policy_pb2 as iam_policy_pb2 # type: ignore +from google.cloud import spanner_admin_instance_v1 + def sample_test_iam_permissions(): # Create a client @@ -42,7 +43,7 @@ def sample_test_iam_permissions(): # Initialize request argument(s) request = iam_policy_pb2.TestIamPermissionsRequest( resource="resource_value", - permissions=['permissions_value1', 'permissions_value2'], + permissions=["permissions_value1", "permissions_value2"], ) # Make the request @@ -51,4 +52,5 @@ def sample_test_iam_permissions(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_TestIamPermissions_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_async.py index ecabbf5191f6..722eff037966 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_async.py @@ -58,4 +58,5 @@ async def sample_update_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_UpdateInstance_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_async.py index f7ea78401c36..659ac4117033 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_async.py @@ -39,8 +39,7 @@ async def sample_update_instance_config(): client = spanner_admin_instance_v1.InstanceAdminAsyncClient() # Initialize request argument(s) - request = spanner_admin_instance_v1.UpdateInstanceConfigRequest( - ) + request = spanner_admin_instance_v1.UpdateInstanceConfigRequest() # Make the request operation = client.update_instance_config(request=request) @@ -52,4 +51,5 @@ async def sample_update_instance_config(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_UpdateInstanceConfig_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_sync.py index 1d184f6c58b4..388847e09379 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_config_sync.py @@ -39,8 +39,7 @@ def sample_update_instance_config(): client = spanner_admin_instance_v1.InstanceAdminClient() # Initialize request argument(s) - request = spanner_admin_instance_v1.UpdateInstanceConfigRequest( - ) + request = spanner_admin_instance_v1.UpdateInstanceConfigRequest() # Make the request operation = client.update_instance_config(request=request) @@ -52,4 +51,5 @@ def sample_update_instance_config(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_UpdateInstanceConfig_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_async.py index 42d3c484f898..6dd3aafce5ce 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_async.py @@ -59,4 +59,5 @@ async def sample_update_instance_partition(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_UpdateInstancePartition_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_sync.py index 56cd2760a1a6..ea12a4162603 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_partition_sync.py @@ -59,4 +59,5 @@ def sample_update_instance_partition(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_UpdateInstancePartition_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_sync.py index 2340e701e159..f061370e5c07 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_instance_admin_update_instance_sync.py @@ -58,4 +58,5 @@ def sample_update_instance(): # Handle the response print(response) + # [END spanner_v1_generated_InstanceAdmin_UpdateInstance_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_async.py index 49e64b4ab8b4..ca3f32e04cbe 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_async.py @@ -50,4 +50,5 @@ async def sample_batch_create_sessions(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_BatchCreateSessions_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_sync.py index ade1da3661ea..716ca0e226a9 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_create_sessions_sync.py @@ -50,4 +50,5 @@ def sample_batch_create_sessions(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_BatchCreateSessions_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_async.py index d1565657e84f..0ed2278c4a1e 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_async.py @@ -54,4 +54,5 @@ async def sample_batch_write(): async for response in stream: print(response) + # [END spanner_v1_generated_Spanner_BatchWrite_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_sync.py index 9b6621def96d..591b0ef9f02e 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_batch_write_sync.py @@ -54,4 +54,5 @@ def sample_batch_write(): for response in stream: print(response) + # [END spanner_v1_generated_Spanner_BatchWrite_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_async.py index efdd16171573..8fc536fb5ab6 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_async.py @@ -49,4 +49,5 @@ async def sample_begin_transaction(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_BeginTransaction_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_sync.py index 764dab8aa244..b154e499975f 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_begin_transaction_sync.py @@ -49,4 +49,5 @@ def sample_begin_transaction(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_BeginTransaction_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_async.py index f61c297d3886..d34e1e610a1c 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_async.py @@ -40,7 +40,7 @@ async def sample_commit(): # Initialize request argument(s) request = spanner_v1.CommitRequest( - transaction_id=b'transaction_id_blob', + transaction_id=b"transaction_id_blob", session="session_value", ) @@ -50,4 +50,5 @@ async def sample_commit(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_Commit_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_sync.py index a945bd223464..8a225a506bc3 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_commit_sync.py @@ -40,7 +40,7 @@ def sample_commit(): # Initialize request argument(s) request = spanner_v1.CommitRequest( - transaction_id=b'transaction_id_blob', + transaction_id=b"transaction_id_blob", session="session_value", ) @@ -50,4 +50,5 @@ def sample_commit(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_Commit_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_async.py index 8cddc00c66f5..76677474f59c 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_async.py @@ -49,4 +49,5 @@ async def sample_create_session(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_CreateSession_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_sync.py index b9de2d34e07b..e8cd23101b89 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_create_session_sync.py @@ -49,4 +49,5 @@ def sample_create_session(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_CreateSession_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_async.py index 8313fd66a09c..ef9c5680c479 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_async.py @@ -54,4 +54,5 @@ async def sample_execute_batch_dml(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_ExecuteBatchDml_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_sync.py index dd4696b6b281..f424188a0b78 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_batch_dml_sync.py @@ -54,4 +54,5 @@ def sample_execute_batch_dml(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_ExecuteBatchDml_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_async.py index a12b20f3e97c..eb03e1fb0fad 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_async.py @@ -50,4 +50,5 @@ async def sample_execute_sql(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_ExecuteSql_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_sync.py index 761d0ca251a6..ab161aa8ff03 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_sql_sync.py @@ -50,4 +50,5 @@ def sample_execute_sql(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_ExecuteSql_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_async.py index 86b8eb910e2d..553b9c7e6467 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_async.py @@ -51,4 +51,5 @@ async def sample_execute_streaming_sql(): async for response in stream: print(response) + # [END spanner_v1_generated_Spanner_ExecuteStreamingSql_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_sync.py index dc7dba43b8bb..defd6211523a 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_execute_streaming_sql_sync.py @@ -51,4 +51,5 @@ def sample_execute_streaming_sql(): for response in stream: print(response) + # [END spanner_v1_generated_Spanner_ExecuteStreamingSql_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_async.py index d2e50f9891e8..1fe021ef0971 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_async.py @@ -49,4 +49,5 @@ async def sample_get_session(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_GetSession_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_sync.py index 36d6436b0497..87234e0ac61a 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_get_session_sync.py @@ -49,4 +49,5 @@ def sample_get_session(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_GetSession_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_async.py index 95aa4bf818a1..c695b6372543 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_async.py @@ -50,4 +50,5 @@ async def sample_list_sessions(): async for response in page_result: print(response) + # [END spanner_v1_generated_Spanner_ListSessions_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_sync.py index a9533fed0d34..cc4dc1c04d41 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_list_sessions_sync.py @@ -50,4 +50,5 @@ def sample_list_sessions(): for response in page_result: print(response) + # [END spanner_v1_generated_Spanner_ListSessions_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_async.py index 200fb2f6a2fb..d766689778d4 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_async.py @@ -50,4 +50,5 @@ async def sample_partition_query(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_PartitionQuery_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_sync.py index d486a3590cf6..9ed3f1106738 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_query_sync.py @@ -50,4 +50,5 @@ def sample_partition_query(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_PartitionQuery_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_async.py index 99055ade8bda..367a26cf108d 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_async.py @@ -50,4 +50,5 @@ async def sample_partition_read(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_PartitionRead_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_sync.py index 0ca01ac42300..8ff7672e0327 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_partition_read_sync.py @@ -50,4 +50,5 @@ def sample_partition_read(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_PartitionRead_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_async.py index e555865245ac..ff5ac5b0b6a6 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_async.py @@ -42,7 +42,7 @@ async def sample_read(): request = spanner_v1.ReadRequest( session="session_value", table="table_value", - columns=['columns_value1', 'columns_value2'], + columns=["columns_value1", "columns_value2"], ) # Make the request @@ -51,4 +51,5 @@ async def sample_read(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_Read_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_sync.py index 8f9ee621f3c7..08434ad361f3 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_read_sync.py @@ -42,7 +42,7 @@ def sample_read(): request = spanner_v1.ReadRequest( session="session_value", table="table_value", - columns=['columns_value1', 'columns_value2'], + columns=["columns_value1", "columns_value2"], ) # Make the request @@ -51,4 +51,5 @@ def sample_read(): # Handle the response print(response) + # [END spanner_v1_generated_Spanner_Read_sync] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_async.py index f99a1b8dd8fb..bc211f6e5a45 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_async.py @@ -41,7 +41,7 @@ async def sample_rollback(): # Initialize request argument(s) request = spanner_v1.RollbackRequest( session="session_value", - transaction_id=b'transaction_id_blob', + transaction_id=b"transaction_id_blob", ) # Make the request diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_sync.py index 00b23b21fc47..3a044c66f11f 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_rollback_sync.py @@ -41,7 +41,7 @@ def sample_rollback(): # Initialize request argument(s) request = spanner_v1.RollbackRequest( session="session_value", - transaction_id=b'transaction_id_blob', + transaction_id=b"transaction_id_blob", ) # Make the request diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_async.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_async.py index f79b9a96a12e..febeb2106225 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_async.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_async.py @@ -42,7 +42,7 @@ async def sample_streaming_read(): request = spanner_v1.ReadRequest( session="session_value", table="table_value", - columns=['columns_value1', 'columns_value2'], + columns=["columns_value1", "columns_value2"], ) # Make the request @@ -52,4 +52,5 @@ async def sample_streaming_read(): async for response in stream: print(response) + # [END spanner_v1_generated_Spanner_StreamingRead_async] diff --git a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_sync.py b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_sync.py index f81ed34b336a..ba4a16877f52 100644 --- a/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_sync.py +++ b/packages/google-cloud-spanner/samples/generated_samples/spanner_v1_generated_spanner_streaming_read_sync.py @@ -42,7 +42,7 @@ def sample_streaming_read(): request = spanner_v1.ReadRequest( session="session_value", table="table_value", - columns=['columns_value1', 'columns_value2'], + columns=["columns_value1", "columns_value2"], ) # Make the request @@ -52,4 +52,5 @@ def sample_streaming_read(): for response in stream: print(response) + # [END spanner_v1_generated_Spanner_StreamingRead_sync] diff --git a/packages/google-cloud-spanner/setup.py b/packages/google-cloud-spanner/setup.py index 61c7fd2036f1..6c076979fbe7 100644 --- a/packages/google-cloud-spanner/setup.py +++ b/packages/google-cloud-spanner/setup.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. @@ -13,12 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -# DO NOT EDIT THIS FILE OUTSIDE OF `.librarian/generator-input` -# The source of truth for this file is `.librarian/generator-input` - import io import os +import re import setuptools # type: ignore @@ -29,10 +26,12 @@ 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__"] +version = None + +with open(os.path.join(package_root, "google/cloud/spanner/gapic_version.py")) as fp: + version_candidates = re.findall(r"(?<=\")\d+.\d+.\d+(?=\")", fp.read()) + assert len(version_candidates) == 1 + version = version_candidates[0] if version[0] == "0": release_status = "Development Status :: 4 - Beta" @@ -46,7 +45,7 @@ "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", + "protobuf >= 4.25.8, < 8.0.0", "grpc-interceptor >= 0.15.4", # Make OpenTelemetry a core dependency "opentelemetry-api >= 1.22.0", @@ -54,7 +53,7 @@ "opentelemetry-semantic-conventions >= 0.43b0", "opentelemetry-resourcedetector-gcp >= 1.8.0a0", "google-cloud-monitoring >= 2.16.0", - "mmh3 >= 4.1.0 ", + "mmh3 >= 4.1.0", ] extras = {"libcst": "libcst >= 0.2.5"} @@ -87,20 +86,20 @@ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Operating System :: OS Independent", "Topic :: Internet", ], platforms="Posix; MacOS X; Windows", packages=packages, + python_requires=">=3.9", install_requires=dependencies, extras_require=extras, - python_requires=">=3.8", include_package_data=True, zip_safe=False, ) diff --git a/packages/google-cloud-spanner/testing/.gitignore b/packages/google-cloud-spanner/testing/.gitignore deleted file mode 100644 index b05fbd630881..000000000000 --- a/packages/google-cloud-spanner/testing/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -test-env.sh -service-account.json -client-secrets.json \ No newline at end of file diff --git a/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py b/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py index feb13c4e4454..849e0b9d3ffc 100644 --- a/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py +++ b/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_database_v1/test_database_admin.py @@ -978,10 +978,9 @@ def test_database_admin_client_get_mtls_endpoint_and_cert_source(client_class): client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint, ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source(options) + ) assert api_endpoint == mock_api_endpoint assert cert_source is expected_cert_source @@ -1026,10 +1025,9 @@ def test_database_admin_client_get_mtls_endpoint_and_cert_source(client_class): client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint, ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source(options) + ) assert api_endpoint == mock_api_endpoint assert cert_source is expected_cert_source @@ -1065,10 +1063,9 @@ def test_database_admin_client_get_mtls_endpoint_and_cert_source(client_class): "google.auth.transport.mtls.default_client_cert_source", return_value=mock_client_cert_source, ): - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source() + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source() + ) assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT assert cert_source == mock_client_cert_source diff --git a/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py b/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py index d6fda5f4092f..42b0b32c6c5f 100644 --- a/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py +++ b/packages/google-cloud-spanner/tests/unit/gapic/spanner_admin_instance_v1/test_instance_admin.py @@ -964,10 +964,9 @@ def test_instance_admin_client_get_mtls_endpoint_and_cert_source(client_class): client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint, ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source(options) + ) assert api_endpoint == mock_api_endpoint assert cert_source is expected_cert_source @@ -1012,10 +1011,9 @@ def test_instance_admin_client_get_mtls_endpoint_and_cert_source(client_class): client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint, ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source(options) + ) assert api_endpoint == mock_api_endpoint assert cert_source is expected_cert_source @@ -1051,10 +1049,9 @@ def test_instance_admin_client_get_mtls_endpoint_and_cert_source(client_class): "google.auth.transport.mtls.default_client_cert_source", return_value=mock_client_cert_source, ): - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source() + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source() + ) assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT assert cert_source == mock_client_cert_source diff --git a/packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py b/packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py index f72497f03918..cbdc96045a7f 100644 --- a/packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py +++ b/packages/google-cloud-spanner/tests/unit/gapic/spanner_v1/test_spanner.py @@ -924,10 +924,9 @@ def test_spanner_client_get_mtls_endpoint_and_cert_source(client_class): client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint, ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source(options) + ) assert api_endpoint == mock_api_endpoint assert cert_source is expected_cert_source @@ -972,10 +971,9 @@ def test_spanner_client_get_mtls_endpoint_and_cert_source(client_class): client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint, ) - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source(options) + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source(options) + ) assert api_endpoint == mock_api_endpoint assert cert_source is expected_cert_source @@ -1011,10 +1009,9 @@ def test_spanner_client_get_mtls_endpoint_and_cert_source(client_class): "google.auth.transport.mtls.default_client_cert_source", return_value=mock_client_cert_source, ): - ( - api_endpoint, - cert_source, - ) = client_class.get_mtls_endpoint_and_cert_source() + api_endpoint, cert_source = ( + client_class.get_mtls_endpoint_and_cert_source() + ) assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT assert cert_source == mock_client_cert_source