diff --git a/.kokoro/samples/lint/common.cfg b/.kokoro/samples/lint/common.cfg new file mode 100644 index 0000000000..28beef0844 --- /dev/null +++ b/.kokoro/samples/lint/common.cfg @@ -0,0 +1,34 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "lint" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-spanner/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-spanner/.kokoro/trampoline.sh" \ No newline at end of file diff --git a/.kokoro/samples/lint/continuous.cfg b/.kokoro/samples/lint/continuous.cfg new file mode 100644 index 0000000000..a1c8d9759c --- /dev/null +++ b/.kokoro/samples/lint/continuous.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/lint/periodic.cfg b/.kokoro/samples/lint/periodic.cfg new file mode 100644 index 0000000000..50fec96497 --- /dev/null +++ b/.kokoro/samples/lint/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} \ No newline at end of file diff --git a/.kokoro/samples/lint/presubmit.cfg b/.kokoro/samples/lint/presubmit.cfg new file mode 100644 index 0000000000..a1c8d9759c --- /dev/null +++ b/.kokoro/samples/lint/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.6/common.cfg b/.kokoro/samples/python3.6/common.cfg new file mode 100644 index 0000000000..093647288c --- /dev/null +++ b/.kokoro/samples/python3.6/common.cfg @@ -0,0 +1,34 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "py-3.6" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-spanner/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-spanner/.kokoro/trampoline.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.6/continuous.cfg b/.kokoro/samples/python3.6/continuous.cfg new file mode 100644 index 0000000000..7218af1499 --- /dev/null +++ b/.kokoro/samples/python3.6/continuous.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + diff --git a/.kokoro/samples/python3.6/periodic.cfg b/.kokoro/samples/python3.6/periodic.cfg new file mode 100644 index 0000000000..50fec96497 --- /dev/null +++ b/.kokoro/samples/python3.6/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.6/presubmit.cfg b/.kokoro/samples/python3.6/presubmit.cfg new file mode 100644 index 0000000000..a1c8d9759c --- /dev/null +++ b/.kokoro/samples/python3.6/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.7/common.cfg b/.kokoro/samples/python3.7/common.cfg new file mode 100644 index 0000000000..cc54c52285 --- /dev/null +++ b/.kokoro/samples/python3.7/common.cfg @@ -0,0 +1,34 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "py-3.7" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-spanner/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-spanner/.kokoro/trampoline.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.7/continuous.cfg b/.kokoro/samples/python3.7/continuous.cfg new file mode 100644 index 0000000000..a1c8d9759c --- /dev/null +++ b/.kokoro/samples/python3.7/continuous.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.7/periodic.cfg b/.kokoro/samples/python3.7/periodic.cfg new file mode 100644 index 0000000000..50fec96497 --- /dev/null +++ b/.kokoro/samples/python3.7/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.7/presubmit.cfg b/.kokoro/samples/python3.7/presubmit.cfg new file mode 100644 index 0000000000..a1c8d9759c --- /dev/null +++ b/.kokoro/samples/python3.7/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.8/common.cfg b/.kokoro/samples/python3.8/common.cfg new file mode 100644 index 0000000000..04da5ee7ef --- /dev/null +++ b/.kokoro/samples/python3.8/common.cfg @@ -0,0 +1,34 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "py-3.8" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-spanner/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-spanner/.kokoro/trampoline.sh" \ No newline at end of file diff --git a/.kokoro/samples/python3.8/continuous.cfg b/.kokoro/samples/python3.8/continuous.cfg new file mode 100644 index 0000000000..a1c8d9759c --- /dev/null +++ b/.kokoro/samples/python3.8/continuous.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.8/periodic.cfg b/.kokoro/samples/python3.8/periodic.cfg new file mode 100644 index 0000000000..50fec96497 --- /dev/null +++ b/.kokoro/samples/python3.8/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.8/presubmit.cfg b/.kokoro/samples/python3.8/presubmit.cfg new file mode 100644 index 0000000000..a1c8d9759c --- /dev/null +++ b/.kokoro/samples/python3.8/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh new file mode 100755 index 0000000000..77a94bb6d7 --- /dev/null +++ b/.kokoro/test-samples.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +cd github/python-spanner + +# Run periodic samples tests at latest release +if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + LATEST_RELEASE=$(git describe --abbrev=0 --tags) + git checkout $LATEST_RELEASE +fi + +# Disable buffering, so that the logs stream through. +export PYTHONUNBUFFERED=1 + +# Debug: show build environment +env | grep KOKORO + +# Install nox +python3.6 -m pip install --upgrade --quiet nox + +# Use secrets acessor service account to get secrets +if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then + gcloud auth activate-service-account \ + --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ + --project="cloud-devrel-kokoro-resources" +fi + +# This script will create 3 files: +# - testing/test-env.sh +# - testing/service-account.json +# - testing/client-secrets.json +./scripts/decrypt-secrets.sh + +source ./testing/test-env.sh +export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json + +# For cloud-run session, we activate the service account for gcloud sdk. +gcloud auth activate-service-account \ + --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" + +export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json + +echo -e "\n******************** TESTING PROJECTS ********************" + +# Switch to 'fail at end' to allow all tests to complete before exiting. +set +e +# Use RTN to return a non-zero value if the test fails. +RTN=0 +ROOT=$(pwd) +# Find all requirements.txt in the samples directory (may break on whitespace). +for file in samples/**/requirements.txt; do + cd "$ROOT" + # Navigate to the project folder. + file=$(dirname "$file") + cd "$file" + + echo "------------------------------------------------------------" + echo "- testing $file" + echo "------------------------------------------------------------" + + # Use nox to execute the tests for the project. + python3.6 -m nox -s "$RUN_TESTS_SESSION" + EXIT=$? + + # If this is a periodic build, send the test log to the Build Cop Bot. + # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/buildcop. + if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + chmod +x $KOKORO_GFILE_DIR/linux_amd64/buildcop + $KOKORO_GFILE_DIR/linux_amd64/buildcop + fi + + if [[ $EXIT -ne 0 ]]; then + RTN=1 + echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" + else + echo -e "\n Testing completed.\n" + fi + +done +cd "$ROOT" + +# Workaround for Kokoro permissions issue: delete secrets +rm testing/{test-env.sh,client-secrets.json,service-account.json} + +exit "$RTN" \ No newline at end of file diff --git a/google/cloud/spanner_admin_database_v1/gapic/database_admin_client.py b/google/cloud/spanner_admin_database_v1/gapic/database_admin_client.py index b208696307..dc11cb0283 100644 --- a/google/cloud/spanner_admin_database_v1/gapic/database_admin_client.py +++ b/google/cloud/spanner_admin_database_v1/gapic/database_admin_client.py @@ -232,16 +232,22 @@ def __init__( self._inner_api_calls = {} # Service calls - def list_databases( + def create_database( self, parent, - page_size=None, + create_statement, + extra_statements=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Lists Cloud Spanner databases. + Creates a new Cloud Spanner database and starts to prepare it for + serving. The returned ``long-running operation`` will have a name of the + format ``/operations/`` and can be used to + track preparation of the database. The ``metadata`` field type is + ``CreateDatabaseMetadata``. The ``response`` field type is ``Database``, + if successful. Example: >>> from google.cloud import spanner_admin_database_v1 @@ -250,28 +256,32 @@ def list_databases( >>> >>> parent = client.instance_path('[PROJECT]', '[INSTANCE]') >>> - >>> # Iterate over all results - >>> for element in client.list_databases(parent): - ... # process element - ... pass + >>> # TODO: Initialize `create_statement`: + >>> create_statement = '' >>> + >>> response = client.create_database(parent, create_statement) >>> - >>> # Alternatively: + >>> def callback(operation_future): + ... # Handle result. + ... result = operation_future.result() >>> - >>> # Iterate over results one page at a time - >>> for page in client.list_databases(parent).pages: - ... for element in page: - ... # process element - ... pass + >>> response.add_done_callback(callback) + >>> + >>> # Handle metadata. + >>> metadata = response.metadata() Args: - parent (str): Required. The instance whose databases should be listed. Values are - of the form ``projects//instances/``. - page_size (int): The maximum number of resources contained in the - underlying API response. If page streaming is performed per- - resource, this parameter does not affect the return value. If page - streaming is performed per-page, this determines the maximum number - of resources in a page. + parent (str): Required. The name of the instance that will serve the new database. + Values are of the form ``projects//instances/``. + create_statement (str): Required. A ``CREATE DATABASE`` statement, which specifies the ID of + the new database. The database ID must conform to the regular expression + ``[a-z][a-z0-9_\-]*[a-z0-9]`` and be between 2 and 30 characters in + length. If the database ID is a reserved word or if it contains a + hyphen, the database ID must be enclosed in backticks (:literal:`\``). + extra_statements (list[str]): Optional. A list of DDL statements to run inside the newly created + database. Statements can create tables, indexes, etc. These + statements execute atomically with the creation of the database: + if there is an error in any statement, the database is not created. retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -282,10 +292,7 @@ def list_databases( that is provided to the method. Returns: - A :class:`~google.api_core.page_iterator.PageIterator` instance. - An iterable of :class:`~google.cloud.spanner_admin_database_v1.types.Database` instances. - You can also iterate over the pages of the response - using its `pages` property. + A :class:`~google.api_core.operation.Operation` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -295,18 +302,20 @@ def list_databases( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "list_databases" not in self._inner_api_calls: + if "create_database" not in self._inner_api_calls: self._inner_api_calls[ - "list_databases" + "create_database" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.list_databases, - default_retry=self._method_configs["ListDatabases"].retry, - default_timeout=self._method_configs["ListDatabases"].timeout, + self.transport.create_database, + default_retry=self._method_configs["CreateDatabase"].retry, + default_timeout=self._method_configs["CreateDatabase"].timeout, client_info=self._client_info, ) - request = spanner_database_admin_pb2.ListDatabasesRequest( - parent=parent, page_size=page_size + request = spanner_database_admin_pb2.CreateDatabaseRequest( + parent=parent, + create_statement=create_statement, + extra_statements=extra_statements, ) if metadata is None: metadata = [] @@ -321,49 +330,44 @@ def list_databases( ) metadata.append(routing_metadata) - iterator = google.api_core.page_iterator.GRPCIterator( - client=None, - method=functools.partial( - self._inner_api_calls["list_databases"], - retry=retry, - timeout=timeout, - metadata=metadata, - ), - request=request, - items_field="databases", - request_token_field="page_token", - response_token_field="next_page_token", + operation = self._inner_api_calls["create_database"]( + request, retry=retry, timeout=timeout, metadata=metadata + ) + return google.api_core.operation.from_gapic( + operation, + self.transport._operations_client, + spanner_database_admin_pb2.Database, + metadata_type=spanner_database_admin_pb2.CreateDatabaseMetadata, ) - return iterator - def create_database( + def update_database_ddl( self, - parent, - create_statement, - extra_statements=None, + database, + statements, + operation_id=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Creates a new Cloud Spanner database and starts to prepare it for - serving. The returned ``long-running operation`` will have a name of the - format ``/operations/`` and can be used to - track preparation of the database. The ``metadata`` field type is - ``CreateDatabaseMetadata``. The ``response`` field type is ``Database``, - if successful. + Updates the schema of a Cloud Spanner database by + creating/altering/dropping tables, columns, indexes, etc. The returned + ``long-running operation`` will have a name of the format + ``/operations/`` and can be used to track + execution of the schema change(s). The ``metadata`` field type is + ``UpdateDatabaseDdlMetadata``. The operation has no response. Example: >>> from google.cloud import spanner_admin_database_v1 >>> >>> client = spanner_admin_database_v1.DatabaseAdminClient() >>> - >>> parent = client.instance_path('[PROJECT]', '[INSTANCE]') + >>> database = client.database_path('[PROJECT]', '[INSTANCE]', '[DATABASE]') >>> - >>> # TODO: Initialize `create_statement`: - >>> create_statement = '' + >>> # TODO: Initialize `statements`: + >>> statements = [] >>> - >>> response = client.create_database(parent, create_statement) + >>> response = client.update_database_ddl(database, statements) >>> >>> def callback(operation_future): ... # Handle result. @@ -375,17 +379,23 @@ def create_database( >>> metadata = response.metadata() Args: - parent (str): Required. The name of the instance that will serve the new database. - Values are of the form ``projects//instances/``. - create_statement (str): Required. A ``CREATE DATABASE`` statement, which specifies the ID of - the new database. The database ID must conform to the regular expression - ``[a-z][a-z0-9_\-]*[a-z0-9]`` and be between 2 and 30 characters in - length. If the database ID is a reserved word or if it contains a - hyphen, the database ID must be enclosed in backticks (:literal:`\``). - extra_statements (list[str]): Optional. A list of DDL statements to run inside the newly created - database. Statements can create tables, indexes, etc. These - statements execute atomically with the creation of the database: - if there is an error in any statement, the database is not created. + database (str): Required. The database to update. + statements (list[str]): Required. DDL statements to be applied to the database. + operation_id (str): If empty, the new update request is assigned an + automatically-generated operation ID. Otherwise, ``operation_id`` is + used to construct the name of the resulting ``Operation``. + + Specifying an explicit operation ID simplifies determining whether the + statements were executed in the event that the ``UpdateDatabaseDdl`` + call is replayed, or the return value is otherwise lost: the + ``database`` and ``operation_id`` fields can be combined to form the + ``name`` of the resulting ``longrunning.Operation``: + ``/operations/``. + + ``operation_id`` should be unique within the database, and must be a + valid identifier: ``[a-z][a-z0-9_]*``. Note that automatically-generated + operation IDs always begin with an underscore. If the named operation + already exists, ``UpdateDatabaseDdl`` returns ``ALREADY_EXISTS``. retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -406,26 +416,24 @@ def create_database( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "create_database" not in self._inner_api_calls: + if "update_database_ddl" not in self._inner_api_calls: self._inner_api_calls[ - "create_database" + "update_database_ddl" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.create_database, - default_retry=self._method_configs["CreateDatabase"].retry, - default_timeout=self._method_configs["CreateDatabase"].timeout, + self.transport.update_database_ddl, + default_retry=self._method_configs["UpdateDatabaseDdl"].retry, + default_timeout=self._method_configs["UpdateDatabaseDdl"].timeout, client_info=self._client_info, ) - request = spanner_database_admin_pb2.CreateDatabaseRequest( - parent=parent, - create_statement=create_statement, - extra_statements=extra_statements, + request = spanner_database_admin_pb2.UpdateDatabaseDdlRequest( + database=database, statements=statements, operation_id=operation_id ) if metadata is None: metadata = [] metadata = list(metadata) try: - routing_header = [("parent", parent)] + routing_header = [("database", database)] except AttributeError: pass else: @@ -434,38 +442,73 @@ def create_database( ) metadata.append(routing_metadata) - operation = self._inner_api_calls["create_database"]( + operation = self._inner_api_calls["update_database_ddl"]( request, retry=retry, timeout=timeout, metadata=metadata ) return google.api_core.operation.from_gapic( operation, self.transport._operations_client, - spanner_database_admin_pb2.Database, - metadata_type=spanner_database_admin_pb2.CreateDatabaseMetadata, + empty_pb2.Empty, + metadata_type=spanner_database_admin_pb2.UpdateDatabaseDdlMetadata, ) - def get_database( + def create_backup( self, - name, + parent, + backup_id, + backup, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Gets the state of a Cloud Spanner database. + Starts creating a new Cloud Spanner Backup. The returned backup + ``long-running operation`` will have a name of the format + ``projects//instances//backups//operations/`` + and can be used to track creation of the backup. The ``metadata`` field + type is ``CreateBackupMetadata``. The ``response`` field type is + ``Backup``, if successful. Cancelling the returned operation will stop + the creation and delete the backup. There can be only one pending backup + creation per database. Backup creation of different databases can run + concurrently. Example: >>> from google.cloud import spanner_admin_database_v1 >>> >>> client = spanner_admin_database_v1.DatabaseAdminClient() >>> - >>> name = client.database_path('[PROJECT]', '[INSTANCE]', '[DATABASE]') + >>> parent = client.instance_path('[PROJECT]', '[INSTANCE]') >>> - >>> response = client.get_database(name) + >>> # TODO: Initialize `backup_id`: + >>> backup_id = '' + >>> + >>> # TODO: Initialize `backup`: + >>> backup = {} + >>> + >>> response = client.create_backup(parent, backup_id, backup) + >>> + >>> def callback(operation_future): + ... # Handle result. + ... result = operation_future.result() + >>> + >>> response.add_done_callback(callback) + >>> + >>> # Handle metadata. + >>> metadata = response.metadata() Args: - name (str): Required. The name of the requested database. Values are of the form - ``projects//instances//databases/``. + parent (str): Required. The name of the instance in which the backup will be + created. This must be the same instance that contains the database the + backup will be created from. The backup will be stored in the + location(s) specified in the instance configuration of this instance. + Values are of the form ``projects//instances/``. + backup_id (str): Required. The id of the backup to be created. The ``backup_id`` + appended to ``parent`` forms the full backup name of the form + ``projects//instances//backups/``. + backup (Union[dict, ~google.cloud.spanner_admin_database_v1.types.Backup]): Required. The backup to create. + + If a dict is provided, it must be of the same form as the protobuf + message :class:`~google.cloud.spanner_admin_database_v1.types.Backup` retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -476,7 +519,7 @@ def get_database( that is provided to the method. Returns: - A :class:`~google.cloud.spanner_admin_database_v1.types.Database` instance. + A :class:`~google.api_core.operation.Operation` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -486,22 +529,24 @@ def get_database( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "get_database" not in self._inner_api_calls: + if "create_backup" not in self._inner_api_calls: self._inner_api_calls[ - "get_database" + "create_backup" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.get_database, - default_retry=self._method_configs["GetDatabase"].retry, - default_timeout=self._method_configs["GetDatabase"].timeout, + self.transport.create_backup, + default_retry=self._method_configs["CreateBackup"].retry, + default_timeout=self._method_configs["CreateBackup"].timeout, client_info=self._client_info, ) - request = spanner_database_admin_pb2.GetDatabaseRequest(name=name) + request = backup_pb2.CreateBackupRequest( + parent=parent, backup_id=backup_id, backup=backup + ) if metadata is None: metadata = [] metadata = list(metadata) try: - routing_header = [("name", name)] + routing_header = [("parent", parent)] except AttributeError: pass else: @@ -510,38 +555,51 @@ def get_database( ) metadata.append(routing_metadata) - return self._inner_api_calls["get_database"]( + operation = self._inner_api_calls["create_backup"]( request, retry=retry, timeout=timeout, metadata=metadata ) + return google.api_core.operation.from_gapic( + operation, + self.transport._operations_client, + backup_pb2.Backup, + metadata_type=backup_pb2.CreateBackupMetadata, + ) - def update_database_ddl( + def restore_database( self, - database, - statements, - operation_id=None, + parent, + database_id, + backup=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Updates the schema of a Cloud Spanner database by - creating/altering/dropping tables, columns, indexes, etc. The returned - ``long-running operation`` will have a name of the format - ``/operations/`` and can be used to track - execution of the schema change(s). The ``metadata`` field type is - ``UpdateDatabaseDdlMetadata``. The operation has no response. + Create a new database by restoring from a completed backup. The new + database must be in the same project and in an instance with the same + instance configuration as the instance containing the backup. The + returned database ``long-running operation`` has a name of the format + ``projects//instances//databases//operations/``, + and can be used to track the progress of the operation, and to cancel + it. The ``metadata`` field type is ``RestoreDatabaseMetadata``. The + ``response`` type is ``Database``, if successful. Cancelling the + returned operation will stop the restore and delete the database. There + can be only one database being restored into an instance at a time. Once + the restore operation completes, a new restore operation can be + initiated, without waiting for the optimize operation associated with + the first restore to complete. Example: >>> from google.cloud import spanner_admin_database_v1 >>> >>> client = spanner_admin_database_v1.DatabaseAdminClient() >>> - >>> database = client.database_path('[PROJECT]', '[INSTANCE]', '[DATABASE]') + >>> parent = client.instance_path('[PROJECT]', '[INSTANCE]') >>> - >>> # TODO: Initialize `statements`: - >>> statements = [] + >>> # TODO: Initialize `database_id`: + >>> database_id = '' >>> - >>> response = client.update_database_ddl(database, statements) + >>> response = client.restore_database(parent, database_id) >>> >>> def callback(operation_future): ... # Handle result. @@ -553,23 +611,202 @@ def update_database_ddl( >>> metadata = response.metadata() Args: - database (str): Required. The database to update. - statements (list[str]): Required. DDL statements to be applied to the database. - operation_id (str): If empty, the new update request is assigned an - automatically-generated operation ID. Otherwise, ``operation_id`` is - used to construct the name of the resulting ``Operation``. + parent (str): Required. The name of the instance in which to create the restored + database. This instance must be in the same project and have the same + instance configuration as the instance containing the source backup. + Values are of the form ``projects//instances/``. + database_id (str): Required. The id of the database to create and restore to. This + database must not already exist. The ``database_id`` appended to + ``parent`` forms the full database name of the form + ``projects//instances//databases/``. + backup (str): Name of the backup from which to restore. Values are of the form + ``projects//instances//backups/``. + retry (Optional[google.api_core.retry.Retry]): A retry object used + to retry requests. If ``None`` is specified, requests will + be retried using a default configuration. + timeout (Optional[float]): The amount of time, in seconds, to wait + for the request to complete. Note that if ``retry`` is + specified, the timeout applies to each individual attempt. + metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata + that is provided to the method. - Specifying an explicit operation ID simplifies determining whether the - statements were executed in the event that the ``UpdateDatabaseDdl`` - call is replayed, or the return value is otherwise lost: the - ``database`` and ``operation_id`` fields can be combined to form the - ``name`` of the resulting ``longrunning.Operation``: - ``/operations/``. + Returns: + A :class:`~google.api_core.operation.Operation` instance. - ``operation_id`` should be unique within the database, and must be a - valid identifier: ``[a-z][a-z0-9_]*``. Note that automatically-generated - operation IDs always begin with an underscore. If the named operation - already exists, ``UpdateDatabaseDdl`` returns ``ALREADY_EXISTS``. + Raises: + google.api_core.exceptions.GoogleAPICallError: If the request + failed for any reason. + google.api_core.exceptions.RetryError: If the request failed due + to a retryable error and retry attempts failed. + ValueError: If the parameters are invalid. + """ + # Wrap the transport method to add retry and timeout logic. + if "restore_database" not in self._inner_api_calls: + self._inner_api_calls[ + "restore_database" + ] = google.api_core.gapic_v1.method.wrap_method( + self.transport.restore_database, + default_retry=self._method_configs["RestoreDatabase"].retry, + default_timeout=self._method_configs["RestoreDatabase"].timeout, + client_info=self._client_info, + ) + + # Sanity check: We have some fields which are mutually exclusive; + # raise ValueError if more than one is sent. + google.api_core.protobuf_helpers.check_oneof(backup=backup) + + request = spanner_database_admin_pb2.RestoreDatabaseRequest( + parent=parent, database_id=database_id, backup=backup + ) + if metadata is None: + metadata = [] + metadata = list(metadata) + try: + routing_header = [("parent", parent)] + except AttributeError: + pass + else: + routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( + routing_header + ) + metadata.append(routing_metadata) + + operation = self._inner_api_calls["restore_database"]( + request, retry=retry, timeout=timeout, metadata=metadata + ) + return google.api_core.operation.from_gapic( + operation, + self.transport._operations_client, + spanner_database_admin_pb2.Database, + metadata_type=spanner_database_admin_pb2.RestoreDatabaseMetadata, + ) + + def list_databases( + self, + parent, + page_size=None, + retry=google.api_core.gapic_v1.method.DEFAULT, + timeout=google.api_core.gapic_v1.method.DEFAULT, + metadata=None, + ): + """ + Lists Cloud Spanner databases. + + Example: + >>> from google.cloud import spanner_admin_database_v1 + >>> + >>> client = spanner_admin_database_v1.DatabaseAdminClient() + >>> + >>> parent = client.instance_path('[PROJECT]', '[INSTANCE]') + >>> + >>> # Iterate over all results + >>> for element in client.list_databases(parent): + ... # process element + ... pass + >>> + >>> + >>> # Alternatively: + >>> + >>> # Iterate over results one page at a time + >>> for page in client.list_databases(parent).pages: + ... for element in page: + ... # process element + ... pass + + Args: + parent (str): Required. The instance whose databases should be listed. Values are + of the form ``projects//instances/``. + page_size (int): The maximum number of resources contained in the + underlying API response. If page streaming is performed per- + resource, this parameter does not affect the return value. If page + streaming is performed per-page, this determines the maximum number + of resources in a page. + retry (Optional[google.api_core.retry.Retry]): A retry object used + to retry requests. If ``None`` is specified, requests will + be retried using a default configuration. + timeout (Optional[float]): The amount of time, in seconds, to wait + for the request to complete. Note that if ``retry`` is + specified, the timeout applies to each individual attempt. + metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata + that is provided to the method. + + Returns: + A :class:`~google.api_core.page_iterator.PageIterator` instance. + An iterable of :class:`~google.cloud.spanner_admin_database_v1.types.Database` instances. + You can also iterate over the pages of the response + using its `pages` property. + + Raises: + google.api_core.exceptions.GoogleAPICallError: If the request + failed for any reason. + google.api_core.exceptions.RetryError: If the request failed due + to a retryable error and retry attempts failed. + ValueError: If the parameters are invalid. + """ + # Wrap the transport method to add retry and timeout logic. + if "list_databases" not in self._inner_api_calls: + self._inner_api_calls[ + "list_databases" + ] = google.api_core.gapic_v1.method.wrap_method( + self.transport.list_databases, + default_retry=self._method_configs["ListDatabases"].retry, + default_timeout=self._method_configs["ListDatabases"].timeout, + client_info=self._client_info, + ) + + request = spanner_database_admin_pb2.ListDatabasesRequest( + parent=parent, page_size=page_size + ) + if metadata is None: + metadata = [] + metadata = list(metadata) + try: + routing_header = [("parent", parent)] + except AttributeError: + pass + else: + routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( + routing_header + ) + metadata.append(routing_metadata) + + iterator = google.api_core.page_iterator.GRPCIterator( + client=None, + method=functools.partial( + self._inner_api_calls["list_databases"], + retry=retry, + timeout=timeout, + metadata=metadata, + ), + request=request, + items_field="databases", + request_token_field="page_token", + response_token_field="next_page_token", + ) + return iterator + + def get_database( + self, + name, + retry=google.api_core.gapic_v1.method.DEFAULT, + timeout=google.api_core.gapic_v1.method.DEFAULT, + metadata=None, + ): + """ + Gets the state of a Cloud Spanner database. + + Example: + >>> from google.cloud import spanner_admin_database_v1 + >>> + >>> client = spanner_admin_database_v1.DatabaseAdminClient() + >>> + >>> name = client.database_path('[PROJECT]', '[INSTANCE]', '[DATABASE]') + >>> + >>> response = client.get_database(name) + + Args: + name (str): Required. The name of the requested database. Values are of the form + ``projects//instances//databases/``. retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -580,7 +817,7 @@ def update_database_ddl( that is provided to the method. Returns: - A :class:`~google.api_core.operation.Operation` instance. + A :class:`~google.cloud.spanner_admin_database_v1.types.Database` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -590,24 +827,22 @@ def update_database_ddl( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "update_database_ddl" not in self._inner_api_calls: + if "get_database" not in self._inner_api_calls: self._inner_api_calls[ - "update_database_ddl" + "get_database" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.update_database_ddl, - default_retry=self._method_configs["UpdateDatabaseDdl"].retry, - default_timeout=self._method_configs["UpdateDatabaseDdl"].timeout, + self.transport.get_database, + default_retry=self._method_configs["GetDatabase"].retry, + default_timeout=self._method_configs["GetDatabase"].timeout, client_info=self._client_info, ) - request = spanner_database_admin_pb2.UpdateDatabaseDdlRequest( - database=database, statements=statements, operation_id=operation_id - ) + request = spanner_database_admin_pb2.GetDatabaseRequest(name=name) if metadata is None: metadata = [] metadata = list(metadata) try: - routing_header = [("database", database)] + routing_header = [("name", name)] except AttributeError: pass else: @@ -616,15 +851,9 @@ def update_database_ddl( ) metadata.append(routing_metadata) - operation = self._inner_api_calls["update_database_ddl"]( + return self._inner_api_calls["get_database"]( request, retry=retry, timeout=timeout, metadata=metadata ) - return google.api_core.operation.from_gapic( - operation, - self.transport._operations_client, - empty_pb2.Empty, - metadata_type=spanner_database_admin_pb2.UpdateDatabaseDdlMetadata, - ) def drop_database( self, @@ -1025,119 +1254,6 @@ def test_iam_permissions( request, retry=retry, timeout=timeout, metadata=metadata ) - def create_backup( - self, - parent, - backup_id, - backup, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Starts creating a new Cloud Spanner Backup. The returned backup - ``long-running operation`` will have a name of the format - ``projects//instances//backups//operations/`` - and can be used to track creation of the backup. The ``metadata`` field - type is ``CreateBackupMetadata``. The ``response`` field type is - ``Backup``, if successful. Cancelling the returned operation will stop - the creation and delete the backup. There can be only one pending backup - creation per database. Backup creation of different databases can run - concurrently. - - Example: - >>> from google.cloud import spanner_admin_database_v1 - >>> - >>> client = spanner_admin_database_v1.DatabaseAdminClient() - >>> - >>> parent = client.instance_path('[PROJECT]', '[INSTANCE]') - >>> - >>> # TODO: Initialize `backup_id`: - >>> backup_id = '' - >>> - >>> # TODO: Initialize `backup`: - >>> backup = {} - >>> - >>> response = client.create_backup(parent, backup_id, backup) - >>> - >>> def callback(operation_future): - ... # Handle result. - ... result = operation_future.result() - >>> - >>> response.add_done_callback(callback) - >>> - >>> # Handle metadata. - >>> metadata = response.metadata() - - Args: - parent (str): Required. The name of the instance in which the backup will be - created. This must be the same instance that contains the database the - backup will be created from. The backup will be stored in the - location(s) specified in the instance configuration of this instance. - Values are of the form ``projects//instances/``. - backup_id (str): Required. The id of the backup to be created. The ``backup_id`` - appended to ``parent`` forms the full backup name of the form - ``projects//instances//backups/``. - backup (Union[dict, ~google.cloud.spanner_admin_database_v1.types.Backup]): Required. The backup to create. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.spanner_admin_database_v1.types.Backup` - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.api_core.operation.Operation` instance. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "create_backup" not in self._inner_api_calls: - self._inner_api_calls[ - "create_backup" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.create_backup, - default_retry=self._method_configs["CreateBackup"].retry, - default_timeout=self._method_configs["CreateBackup"].timeout, - client_info=self._client_info, - ) - - request = backup_pb2.CreateBackupRequest( - parent=parent, backup_id=backup_id, backup=backup - ) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("parent", parent)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - operation = self._inner_api_calls["create_backup"]( - request, retry=retry, timeout=timeout, metadata=metadata - ) - return google.api_core.operation.from_gapic( - operation, - self.transport._operations_client, - backup_pb2.Backup, - metadata_type=backup_pb2.CreateBackupMetadata, - ) - def get_backup( self, name, @@ -1504,122 +1620,6 @@ def list_backups( ) return iterator - def restore_database( - self, - parent, - database_id, - backup=None, - retry=google.api_core.gapic_v1.method.DEFAULT, - timeout=google.api_core.gapic_v1.method.DEFAULT, - metadata=None, - ): - """ - Create a new database by restoring from a completed backup. The new - database must be in the same project and in an instance with the same - instance configuration as the instance containing the backup. The - returned database ``long-running operation`` has a name of the format - ``projects//instances//databases//operations/``, - and can be used to track the progress of the operation, and to cancel - it. The ``metadata`` field type is ``RestoreDatabaseMetadata``. The - ``response`` type is ``Database``, if successful. Cancelling the - returned operation will stop the restore and delete the database. There - can be only one database being restored into an instance at a time. Once - the restore operation completes, a new restore operation can be - initiated, without waiting for the optimize operation associated with - the first restore to complete. - - Example: - >>> from google.cloud import spanner_admin_database_v1 - >>> - >>> client = spanner_admin_database_v1.DatabaseAdminClient() - >>> - >>> parent = client.instance_path('[PROJECT]', '[INSTANCE]') - >>> - >>> # TODO: Initialize `database_id`: - >>> database_id = '' - >>> - >>> response = client.restore_database(parent, database_id) - >>> - >>> def callback(operation_future): - ... # Handle result. - ... result = operation_future.result() - >>> - >>> response.add_done_callback(callback) - >>> - >>> # Handle metadata. - >>> metadata = response.metadata() - - Args: - parent (str): Required. The name of the instance in which to create the restored - database. This instance must be in the same project and have the same - instance configuration as the instance containing the source backup. - Values are of the form ``projects//instances/``. - database_id (str): Required. The id of the database to create and restore to. This - database must not already exist. The ``database_id`` appended to - ``parent`` forms the full database name of the form - ``projects//instances//databases/``. - backup (str): Name of the backup from which to restore. Values are of the form - ``projects//instances//backups/``. - retry (Optional[google.api_core.retry.Retry]): A retry object used - to retry requests. If ``None`` is specified, requests will - be retried using a default configuration. - timeout (Optional[float]): The amount of time, in seconds, to wait - for the request to complete. Note that if ``retry`` is - specified, the timeout applies to each individual attempt. - metadata (Optional[Sequence[Tuple[str, str]]]): Additional metadata - that is provided to the method. - - Returns: - A :class:`~google.api_core.operation.Operation` instance. - - Raises: - google.api_core.exceptions.GoogleAPICallError: If the request - failed for any reason. - google.api_core.exceptions.RetryError: If the request failed due - to a retryable error and retry attempts failed. - ValueError: If the parameters are invalid. - """ - # Wrap the transport method to add retry and timeout logic. - if "restore_database" not in self._inner_api_calls: - self._inner_api_calls[ - "restore_database" - ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.restore_database, - default_retry=self._method_configs["RestoreDatabase"].retry, - default_timeout=self._method_configs["RestoreDatabase"].timeout, - client_info=self._client_info, - ) - - # Sanity check: We have some fields which are mutually exclusive; - # raise ValueError if more than one is sent. - google.api_core.protobuf_helpers.check_oneof(backup=backup) - - request = spanner_database_admin_pb2.RestoreDatabaseRequest( - parent=parent, database_id=database_id, backup=backup - ) - if metadata is None: - metadata = [] - metadata = list(metadata) - try: - routing_header = [("parent", parent)] - except AttributeError: - pass - else: - routing_metadata = google.api_core.gapic_v1.routing_header.to_grpc_metadata( - routing_header - ) - metadata.append(routing_metadata) - - operation = self._inner_api_calls["restore_database"]( - request, retry=retry, timeout=timeout, metadata=metadata - ) - return google.api_core.operation.from_gapic( - operation, - self.transport._operations_client, - spanner_database_admin_pb2.Database, - metadata_type=spanner_database_admin_pb2.RestoreDatabaseMetadata, - ) - def list_database_operations( self, parent, diff --git a/google/cloud/spanner_admin_database_v1/gapic/database_admin_client_config.py b/google/cloud/spanner_admin_database_v1/gapic/database_admin_client_config.py index ef12ea5496..ca3fa3cbe8 100644 --- a/google/cloud/spanner_admin_database_v1/gapic/database_admin_client_config.py +++ b/google/cloud/spanner_admin_database_v1/gapic/database_admin_client_config.py @@ -2,105 +2,144 @@ "interfaces": { "google.spanner.admin.database.v1.DatabaseAdmin": { "retry_codes": { - "idempotent": ["DEADLINE_EXCEEDED", "UNAVAILABLE"], - "non_idempotent": [], + "retry_policy_1_codes": ["UNAVAILABLE", "DEADLINE_EXCEEDED"], + "no_retry_2_codes": [], + "no_retry_codes": [], + "retry_policy_2_codes": ["UNAVAILABLE", "DEADLINE_EXCEEDED"], + "no_retry_1_codes": [], }, "retry_params": { - "default": { + "retry_policy_1_params": { "initial_retry_delay_millis": 1000, "retry_delay_multiplier": 1.3, "max_retry_delay_millis": 32000, - "initial_rpc_timeout_millis": 60000, + "initial_rpc_timeout_millis": 3600000, "rpc_timeout_multiplier": 1.0, - "max_rpc_timeout_millis": 60000, - "total_timeout_millis": 600000, - } + "max_rpc_timeout_millis": 3600000, + "total_timeout_millis": 3600000, + }, + "retry_policy_2_params": { + "initial_retry_delay_millis": 1000, + "retry_delay_multiplier": 1.3, + "max_retry_delay_millis": 32000, + "initial_rpc_timeout_millis": 30000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 30000, + "total_timeout_millis": 30000, + }, + "no_retry_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, + "initial_rpc_timeout_millis": 0, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 0, + "total_timeout_millis": 0, + }, + "no_retry_1_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, + "initial_rpc_timeout_millis": 3600000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 3600000, + "total_timeout_millis": 3600000, + }, + "no_retry_2_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, + "initial_rpc_timeout_millis": 30000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 30000, + "total_timeout_millis": 30000, + }, }, "methods": { - "ListDatabases": { + "CreateDatabase": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", }, - "CreateDatabase": { + "UpdateDatabaseDdl": { "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, - "GetDatabase": { + "CreateBackup": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", }, - "UpdateDatabaseDdl": { + "RestoreDatabase": { + "timeout_millis": 3600000, + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", + }, + "ListDatabases": { + "timeout_millis": 3600000, + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", + }, + "GetDatabase": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "DropDatabase": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "GetDatabaseDdl": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "SetIamPolicy": { "timeout_millis": 30000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_2_codes", + "retry_params_name": "no_retry_2_params", }, "GetIamPolicy": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_2_codes", + "retry_params_name": "retry_policy_2_params", }, "TestIamPermissions": { "timeout_millis": 30000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", - }, - "CreateBackup": { - "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_2_codes", + "retry_params_name": "no_retry_2_params", }, "GetBackup": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "UpdateBackup": { "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", }, "DeleteBackup": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "ListBackups": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", - }, - "RestoreDatabase": { - "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "ListDatabaseOperations": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "ListBackupOperations": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, }, } diff --git a/google/cloud/spanner_admin_database_v1/gapic/transports/database_admin_grpc_transport.py b/google/cloud/spanner_admin_database_v1/gapic/transports/database_admin_grpc_transport.py index 66c4fd6e3d..f2fb755668 100644 --- a/google/cloud/spanner_admin_database_v1/gapic/transports/database_admin_grpc_transport.py +++ b/google/cloud/spanner_admin_database_v1/gapic/transports/database_admin_grpc_transport.py @@ -120,19 +120,6 @@ def channel(self): """ return self._channel - @property - def list_databases(self): - """Return the gRPC stub for :meth:`DatabaseAdminClient.list_databases`. - - Lists Cloud Spanner databases. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["database_admin_stub"].ListDatabases - @property def create_database(self): """Return the gRPC stub for :meth:`DatabaseAdminClient.create_database`. @@ -152,35 +139,94 @@ def create_database(self): return self._stubs["database_admin_stub"].CreateDatabase @property - def get_database(self): - """Return the gRPC stub for :meth:`DatabaseAdminClient.get_database`. + def update_database_ddl(self): + """Return the gRPC stub for :meth:`DatabaseAdminClient.update_database_ddl`. - Gets the state of a Cloud Spanner database. + Updates the schema of a Cloud Spanner database by + creating/altering/dropping tables, columns, indexes, etc. The returned + ``long-running operation`` will have a name of the format + ``/operations/`` and can be used to track + execution of the schema change(s). The ``metadata`` field type is + ``UpdateDatabaseDdlMetadata``. The operation has no response. Returns: Callable: A callable which accepts the appropriate deserialized request object and returns a deserialized response object. """ - return self._stubs["database_admin_stub"].GetDatabase + return self._stubs["database_admin_stub"].UpdateDatabaseDdl @property - def update_database_ddl(self): - """Return the gRPC stub for :meth:`DatabaseAdminClient.update_database_ddl`. + def create_backup(self): + """Return the gRPC stub for :meth:`DatabaseAdminClient.create_backup`. - Updates the schema of a Cloud Spanner database by - creating/altering/dropping tables, columns, indexes, etc. The returned + Starts creating a new Cloud Spanner Backup. The returned backup ``long-running operation`` will have a name of the format - ``/operations/`` and can be used to track - execution of the schema change(s). The ``metadata`` field type is - ``UpdateDatabaseDdlMetadata``. The operation has no response. + ``projects//instances//backups//operations/`` + and can be used to track creation of the backup. The ``metadata`` field + type is ``CreateBackupMetadata``. The ``response`` field type is + ``Backup``, if successful. Cancelling the returned operation will stop + the creation and delete the backup. There can be only one pending backup + creation per database. Backup creation of different databases can run + concurrently. Returns: Callable: A callable which accepts the appropriate deserialized request object and returns a deserialized response object. """ - return self._stubs["database_admin_stub"].UpdateDatabaseDdl + return self._stubs["database_admin_stub"].CreateBackup + + @property + def restore_database(self): + """Return the gRPC stub for :meth:`DatabaseAdminClient.restore_database`. + + Create a new database by restoring from a completed backup. The new + database must be in the same project and in an instance with the same + instance configuration as the instance containing the backup. The + returned database ``long-running operation`` has a name of the format + ``projects//instances//databases//operations/``, + and can be used to track the progress of the operation, and to cancel + it. The ``metadata`` field type is ``RestoreDatabaseMetadata``. The + ``response`` type is ``Database``, if successful. Cancelling the + returned operation will stop the restore and delete the database. There + can be only one database being restored into an instance at a time. Once + the restore operation completes, a new restore operation can be + initiated, without waiting for the optimize operation associated with + the first restore to complete. + + Returns: + Callable: A callable which accepts the appropriate + deserialized request object and returns a + deserialized response object. + """ + return self._stubs["database_admin_stub"].RestoreDatabase + + @property + def list_databases(self): + """Return the gRPC stub for :meth:`DatabaseAdminClient.list_databases`. + + Lists Cloud Spanner databases. + + Returns: + Callable: A callable which accepts the appropriate + deserialized request object and returns a + deserialized response object. + """ + return self._stubs["database_admin_stub"].ListDatabases + + @property + def get_database(self): + """Return the gRPC stub for :meth:`DatabaseAdminClient.get_database`. + + Gets the state of a Cloud Spanner database. + + Returns: + Callable: A callable which accepts the appropriate + deserialized request object and returns a + deserialized response object. + """ + return self._stubs["database_admin_stub"].GetDatabase @property def drop_database(self): @@ -269,27 +315,6 @@ def test_iam_permissions(self): """ return self._stubs["database_admin_stub"].TestIamPermissions - @property - def create_backup(self): - """Return the gRPC stub for :meth:`DatabaseAdminClient.create_backup`. - - Starts creating a new Cloud Spanner Backup. The returned backup - ``long-running operation`` will have a name of the format - ``projects//instances//backups//operations/`` - and can be used to track creation of the backup. The ``metadata`` field - type is ``CreateBackupMetadata``. The ``response`` field type is - ``Backup``, if successful. Cancelling the returned operation will stop - the creation and delete the backup. There can be only one pending backup - creation per database. Backup creation of different databases can run - concurrently. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["database_admin_stub"].CreateBackup - @property def get_backup(self): """Return the gRPC stub for :meth:`DatabaseAdminClient.get_backup`. @@ -344,31 +369,6 @@ def list_backups(self): """ return self._stubs["database_admin_stub"].ListBackups - @property - def restore_database(self): - """Return the gRPC stub for :meth:`DatabaseAdminClient.restore_database`. - - Create a new database by restoring from a completed backup. The new - database must be in the same project and in an instance with the same - instance configuration as the instance containing the backup. The - returned database ``long-running operation`` has a name of the format - ``projects//instances//databases//operations/``, - and can be used to track the progress of the operation, and to cancel - it. The ``metadata`` field type is ``RestoreDatabaseMetadata``. The - ``response`` type is ``Database``, if successful. Cancelling the - returned operation will stop the restore and delete the database. There - can be only one database being restored into an instance at a time. Once - the restore operation completes, a new restore operation can be - initiated, without waiting for the optimize operation associated with - the first restore to complete. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["database_admin_stub"].RestoreDatabase - @property def list_database_operations(self): """Return the gRPC stub for :meth:`DatabaseAdminClient.list_database_operations`. diff --git a/google/cloud/spanner_admin_database_v1/proto/backup_pb2_grpc.py b/google/cloud/spanner_admin_database_v1/proto/backup_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_admin_database_v1/proto/backup_pb2_grpc.py +++ b/google/cloud/spanner_admin_database_v1/proto/backup_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/google/cloud/spanner_admin_database_v1/proto/common_pb2_grpc.py b/google/cloud/spanner_admin_database_v1/proto/common_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_admin_database_v1/proto/common_pb2_grpc.py +++ b/google/cloud/spanner_admin_database_v1/proto/common_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto b/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto index e51f178a3a..af440c1a36 100644 --- a/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto +++ b/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto @@ -207,7 +207,7 @@ service DatabaseAdmin { }; option (google.api.method_signature) = "parent,backup,backup_id"; option (google.longrunning.operation_info) = { - response_type: "Backup" + response_type: "google.spanner.admin.database.v1.Backup" metadata_type: "google.spanner.admin.database.v1.CreateBackupMetadata" }; } diff --git a/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2.py b/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2.py index 10ada3aa29..f0accdbecd 100644 --- a/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2.py +++ b/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2.py @@ -38,7 +38,7 @@ syntax="proto3", serialized_options=b"\n$com.google.spanner.admin.database.v1B\031SpannerDatabaseAdminProtoP\001ZHgoogle.golang.org/genproto/googleapis/spanner/admin/database/v1;database\252\002&Google.Cloud.Spanner.Admin.Database.V1\312\002&Google\\Cloud\\Spanner\\Admin\\Database\\V1\352\002+Google::Cloud::Spanner::Admin::Database::V1\352AJ\n\037spanner.googleapis.com/Instance\022'projects/{project}/instances/{instance}", create_key=_descriptor._internal_create_key, - serialized_pb=b'\nIgoogle/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto\x12 google.spanner.admin.database.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1egoogle/iam/v1/iam_policy.proto\x1a\x1agoogle/iam/v1/policy.proto\x1a#google/longrunning/operations.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x39google/cloud/spanner_admin_database_v1/proto/backup.proto\x1a\x39google/cloud/spanner_admin_database_v1/proto/common.proto"\xab\x01\n\x0bRestoreInfo\x12H\n\x0bsource_type\x18\x01 \x01(\x0e\x32\x33.google.spanner.admin.database.v1.RestoreSourceType\x12\x43\n\x0b\x62\x61\x63kup_info\x18\x02 \x01(\x0b\x32,.google.spanner.admin.database.v1.BackupInfoH\x00\x42\r\n\x0bsource_info"\x96\x03\n\x08\x44\x61tabase\x12\x11\n\x04name\x18\x01 \x01(\tB\x03\xe0\x41\x02\x12\x44\n\x05state\x18\x02 \x01(\x0e\x32\x30.google.spanner.admin.database.v1.Database.StateB\x03\xe0\x41\x03\x12\x34\n\x0b\x63reate_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x03\x12H\n\x0crestore_info\x18\x04 \x01(\x0b\x32-.google.spanner.admin.database.v1.RestoreInfoB\x03\xe0\x41\x03"M\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x0c\n\x08\x43REATING\x10\x01\x12\t\n\x05READY\x10\x02\x12\x14\n\x10READY_OPTIMIZING\x10\x03:b\xea\x41_\n\x1fspanner.googleapis.com/Database\x12\x82\xd3\xe4\x93\x02/\x12-/v1/{parent=projects/*/instances/*}/databases\xda\x41\x06parent\x12\xa4\x02\n\x0e\x43reateDatabase\x12\x37.google.spanner.admin.database.v1.CreateDatabaseRequest\x1a\x1d.google.longrunning.Operation"\xb9\x01\x82\xd3\xe4\x93\x02\x32"-/v1/{parent=projects/*/instances/*}/databases:\x01*\xda\x41\x17parent,create_statement\xca\x41\x64\n)google.spanner.admin.database.v1.Database\x12\x37google.spanner.admin.database.v1.CreateDatabaseMetadata\x12\xad\x01\n\x0bGetDatabase\x12\x34.google.spanner.admin.database.v1.GetDatabaseRequest\x1a*.google.spanner.admin.database.v1.Database"<\x82\xd3\xe4\x93\x02/\x12-/v1/{name=projects/*/instances/*/databases/*}\xda\x41\x04name\x12\x9d\x02\n\x11UpdateDatabaseDdl\x12:.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest\x1a\x1d.google.longrunning.Operation"\xac\x01\x82\xd3\xe4\x93\x02:25/v1/{database=projects/*/instances/*/databases/*}/ddl:\x01*\xda\x41\x13\x64\x61tabase,statements\xca\x41S\n\x15google.protobuf.Empty\x12:google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata\x12\xa3\x01\n\x0c\x44ropDatabase\x12\x35.google.spanner.admin.database.v1.DropDatabaseRequest\x1a\x16.google.protobuf.Empty"D\x82\xd3\xe4\x93\x02\x33*1/v1/{database=projects/*/instances/*/databases/*}\xda\x41\x08\x64\x61tabase\x12\xcd\x01\n\x0eGetDatabaseDdl\x12\x37.google.spanner.admin.database.v1.GetDatabaseDdlRequest\x1a\x38.google.spanner.admin.database.v1.GetDatabaseDdlResponse"H\x82\xd3\xe4\x93\x02\x37\x12\x35/v1/{database=projects/*/instances/*/databases/*}/ddl\xda\x41\x08\x64\x61tabase\x12\xeb\x01\n\x0cSetIamPolicy\x12".google.iam.v1.SetIamPolicyRequest\x1a\x15.google.iam.v1.Policy"\x9f\x01\x82\xd3\xe4\x93\x02\x86\x01">/v1/{resource=projects/*/instances/*/databases/*}:setIamPolicy:\x01*ZA"/v1/{resource=projects/*/instances/*/databases/*}:getIamPolicy:\x01*ZA".google.spanner.admin.database.v1.ListBackupOperationsResponse"E\x82\xd3\xe4\x93\x02\x36\x12\x34/v1/{parent=projects/*/instances/*}/backupOperations\xda\x41\x06parent\x1ax\xca\x41\x16spanner.googleapis.com\xd2\x41\\https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/spanner.adminB\xda\x02\n$com.google.spanner.admin.database.v1B\x19SpannerDatabaseAdminProtoP\x01ZHgoogle.golang.org/genproto/googleapis/spanner/admin/database/v1;database\xaa\x02&Google.Cloud.Spanner.Admin.Database.V1\xca\x02&Google\\Cloud\\Spanner\\Admin\\Database\\V1\xea\x02+Google::Cloud::Spanner::Admin::Database::V1\xea\x41J\n\x1fspanner.googleapis.com/Instance\x12\'projects/{project}/instances/{instance}b\x06proto3', + serialized_pb=b'\nIgoogle/cloud/spanner_admin_database_v1/proto/spanner_database_admin.proto\x12 google.spanner.admin.database.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a\x1egoogle/iam/v1/iam_policy.proto\x1a\x1agoogle/iam/v1/policy.proto\x1a#google/longrunning/operations.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x39google/cloud/spanner_admin_database_v1/proto/backup.proto\x1a\x39google/cloud/spanner_admin_database_v1/proto/common.proto"\xab\x01\n\x0bRestoreInfo\x12H\n\x0bsource_type\x18\x01 \x01(\x0e\x32\x33.google.spanner.admin.database.v1.RestoreSourceType\x12\x43\n\x0b\x62\x61\x63kup_info\x18\x02 \x01(\x0b\x32,.google.spanner.admin.database.v1.BackupInfoH\x00\x42\r\n\x0bsource_info"\x96\x03\n\x08\x44\x61tabase\x12\x11\n\x04name\x18\x01 \x01(\tB\x03\xe0\x41\x02\x12\x44\n\x05state\x18\x02 \x01(\x0e\x32\x30.google.spanner.admin.database.v1.Database.StateB\x03\xe0\x41\x03\x12\x34\n\x0b\x63reate_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x03\x12H\n\x0crestore_info\x18\x04 \x01(\x0b\x32-.google.spanner.admin.database.v1.RestoreInfoB\x03\xe0\x41\x03"M\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x0c\n\x08\x43REATING\x10\x01\x12\t\n\x05READY\x10\x02\x12\x14\n\x10READY_OPTIMIZING\x10\x03:b\xea\x41_\n\x1fspanner.googleapis.com/Database\x12\x82\xd3\xe4\x93\x02/\x12-/v1/{parent=projects/*/instances/*}/databases\xda\x41\x06parent\x12\xa4\x02\n\x0e\x43reateDatabase\x12\x37.google.spanner.admin.database.v1.CreateDatabaseRequest\x1a\x1d.google.longrunning.Operation"\xb9\x01\x82\xd3\xe4\x93\x02\x32"-/v1/{parent=projects/*/instances/*}/databases:\x01*\xda\x41\x17parent,create_statement\xca\x41\x64\n)google.spanner.admin.database.v1.Database\x12\x37google.spanner.admin.database.v1.CreateDatabaseMetadata\x12\xad\x01\n\x0bGetDatabase\x12\x34.google.spanner.admin.database.v1.GetDatabaseRequest\x1a*.google.spanner.admin.database.v1.Database"<\x82\xd3\xe4\x93\x02/\x12-/v1/{name=projects/*/instances/*/databases/*}\xda\x41\x04name\x12\x9d\x02\n\x11UpdateDatabaseDdl\x12:.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest\x1a\x1d.google.longrunning.Operation"\xac\x01\x82\xd3\xe4\x93\x02:25/v1/{database=projects/*/instances/*/databases/*}/ddl:\x01*\xda\x41\x13\x64\x61tabase,statements\xca\x41S\n\x15google.protobuf.Empty\x12:google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata\x12\xa3\x01\n\x0c\x44ropDatabase\x12\x35.google.spanner.admin.database.v1.DropDatabaseRequest\x1a\x16.google.protobuf.Empty"D\x82\xd3\xe4\x93\x02\x33*1/v1/{database=projects/*/instances/*/databases/*}\xda\x41\x08\x64\x61tabase\x12\xcd\x01\n\x0eGetDatabaseDdl\x12\x37.google.spanner.admin.database.v1.GetDatabaseDdlRequest\x1a\x38.google.spanner.admin.database.v1.GetDatabaseDdlResponse"H\x82\xd3\xe4\x93\x02\x37\x12\x35/v1/{database=projects/*/instances/*/databases/*}/ddl\xda\x41\x08\x64\x61tabase\x12\xeb\x01\n\x0cSetIamPolicy\x12".google.iam.v1.SetIamPolicyRequest\x1a\x15.google.iam.v1.Policy"\x9f\x01\x82\xd3\xe4\x93\x02\x86\x01">/v1/{resource=projects/*/instances/*/databases/*}:setIamPolicy:\x01*ZA"/v1/{resource=projects/*/instances/*/databases/*}:getIamPolicy:\x01*ZA".google.spanner.admin.database.v1.ListBackupOperationsResponse"E\x82\xd3\xe4\x93\x02\x36\x12\x34/v1/{parent=projects/*/instances/*}/backupOperations\xda\x41\x06parent\x1ax\xca\x41\x16spanner.googleapis.com\xd2\x41\\https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/spanner.adminB\xda\x02\n$com.google.spanner.admin.database.v1B\x19SpannerDatabaseAdminProtoP\x01ZHgoogle.golang.org/genproto/googleapis/spanner/admin/database/v1;database\xaa\x02&Google.Cloud.Spanner.Admin.Database.V1\xca\x02&Google\\Cloud\\Spanner\\Admin\\Database\\V1\xea\x02+Google::Cloud::Spanner::Admin::Database::V1\xea\x41J\n\x1fspanner.googleapis.com/Instance\x12\'projects/{project}/instances/{instance}b\x06proto3', dependencies=[ google_dot_api_dot_annotations__pb2.DESCRIPTOR, google_dot_api_dot_client__pb2.DESCRIPTOR, @@ -1964,7 +1964,7 @@ serialized_options=b"\312A\026spanner.googleapis.com\322A\\https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/spanner.admin", create_key=_descriptor._internal_create_key, serialized_start=3100, - serialized_end=7054, + serialized_end=7087, methods=[ _descriptor.MethodDescriptor( name="ListDatabases", @@ -2063,7 +2063,7 @@ containing_service=None, input_type=google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2._CREATEBACKUPREQUEST, output_type=google_dot_longrunning_dot_operations__pb2._OPERATION, - serialized_options=b'\202\323\344\223\0025"+/v1/{parent=projects/*/instances/*}/backups:\006backup\332A\027parent,backup,backup_id\312A?\n\006Backup\0225google.spanner.admin.database.v1.CreateBackupMetadata', + serialized_options=b"\202\323\344\223\0025\"+/v1/{parent=projects/*/instances/*}/backups:\006backup\332A\027parent,backup,backup_id\312A`\n'google.spanner.admin.database.v1.Backup\0225google.spanner.admin.database.v1.CreateBackupMetadata", create_key=_descriptor._internal_create_key, ), _descriptor.MethodDescriptor( diff --git a/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2_grpc.py b/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2_grpc.py index 042dcc1548..42542ff9a7 100644 --- a/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2_grpc.py +++ b/google/cloud/spanner_admin_database_v1/proto/spanner_database_admin_pb2_grpc.py @@ -1,4 +1,5 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc from google.cloud.spanner_admin_database_v1.proto import ( @@ -18,18 +19,18 @@ class DatabaseAdminStub(object): """Cloud Spanner Database Admin API - The Cloud Spanner Database Admin API can be used to create, drop, and - list databases. It also enables updating the schema of pre-existing - databases. It can be also used to create, delete and list backups for a - database and to restore from an existing backup. - """ + The Cloud Spanner Database Admin API can be used to create, drop, and + list databases. It also enables updating the schema of pre-existing + databases. It can be also used to create, delete and list backups for a + database and to restore from an existing backup. + """ def __init__(self, channel): """Constructor. - Args: - channel: A grpc.Channel. - """ + Args: + channel: A grpc.Channel. + """ self.ListDatabases = channel.unary_unary( "/google.spanner.admin.database.v1.DatabaseAdmin/ListDatabases", request_serializer=google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.ListDatabasesRequest.SerializeToString, @@ -120,211 +121,211 @@ def __init__(self, channel): class DatabaseAdminServicer(object): """Cloud Spanner Database Admin API - The Cloud Spanner Database Admin API can be used to create, drop, and - list databases. It also enables updating the schema of pre-existing - databases. It can be also used to create, delete and list backups for a - database and to restore from an existing backup. - """ + The Cloud Spanner Database Admin API can be used to create, drop, and + list databases. It also enables updating the schema of pre-existing + databases. It can be also used to create, delete and list backups for a + database and to restore from an existing backup. + """ def ListDatabases(self, request, context): """Lists Cloud Spanner databases. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def CreateDatabase(self, request, context): """Creates a new Cloud Spanner database and starts to prepare it for serving. - The returned [long-running operation][google.longrunning.Operation] will - have a name of the format `/operations/` and - can be used to track preparation of the database. The - [metadata][google.longrunning.Operation.metadata] field type is - [CreateDatabaseMetadata][google.spanner.admin.database.v1.CreateDatabaseMetadata]. The - [response][google.longrunning.Operation.response] field type is - [Database][google.spanner.admin.database.v1.Database], if successful. - """ + The returned [long-running operation][google.longrunning.Operation] will + have a name of the format `/operations/` and + can be used to track preparation of the database. The + [metadata][google.longrunning.Operation.metadata] field type is + [CreateDatabaseMetadata][google.spanner.admin.database.v1.CreateDatabaseMetadata]. The + [response][google.longrunning.Operation.response] field type is + [Database][google.spanner.admin.database.v1.Database], if successful. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetDatabase(self, request, context): """Gets the state of a Cloud Spanner database. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def UpdateDatabaseDdl(self, request, context): """Updates the schema of a Cloud Spanner database by - creating/altering/dropping tables, columns, indexes, etc. The returned - [long-running operation][google.longrunning.Operation] will have a name of - the format `/operations/` and can be used to - track execution of the schema change(s). The - [metadata][google.longrunning.Operation.metadata] field type is - [UpdateDatabaseDdlMetadata][google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata]. The operation has no response. - """ + creating/altering/dropping tables, columns, indexes, etc. The returned + [long-running operation][google.longrunning.Operation] will have a name of + the format `/operations/` and can be used to + track execution of the schema change(s). The + [metadata][google.longrunning.Operation.metadata] field type is + [UpdateDatabaseDdlMetadata][google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata]. The operation has no response. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def DropDatabase(self, request, context): """Drops (aka deletes) a Cloud Spanner database. - Completed backups for the database will be retained according to their - `expire_time`. - """ + Completed backups for the database will be retained according to their + `expire_time`. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetDatabaseDdl(self, request, context): """Returns the schema of a Cloud Spanner database as a list of formatted - DDL statements. This method does not show pending schema updates, those may - be queried using the [Operations][google.longrunning.Operations] API. - """ + DDL statements. This method does not show pending schema updates, those may + be queried using the [Operations][google.longrunning.Operations] API. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def SetIamPolicy(self, request, context): """Sets the access control policy on a database or backup resource. - Replaces any existing policy. + Replaces any existing policy. - Authorization requires `spanner.databases.setIamPolicy` - permission on [resource][google.iam.v1.SetIamPolicyRequest.resource]. - For backups, authorization requires `spanner.backups.setIamPolicy` - permission on [resource][google.iam.v1.SetIamPolicyRequest.resource]. - """ + Authorization requires `spanner.databases.setIamPolicy` + permission on [resource][google.iam.v1.SetIamPolicyRequest.resource]. + For backups, authorization requires `spanner.backups.setIamPolicy` + permission on [resource][google.iam.v1.SetIamPolicyRequest.resource]. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetIamPolicy(self, request, context): """Gets the access control policy for a database or backup resource. - Returns an empty policy if a database or backup exists but does not have a - policy set. + Returns an empty policy if a database or backup exists but does not have a + policy set. - Authorization requires `spanner.databases.getIamPolicy` permission on - [resource][google.iam.v1.GetIamPolicyRequest.resource]. - For backups, authorization requires `spanner.backups.getIamPolicy` - permission on [resource][google.iam.v1.GetIamPolicyRequest.resource]. - """ + Authorization requires `spanner.databases.getIamPolicy` permission on + [resource][google.iam.v1.GetIamPolicyRequest.resource]. + For backups, authorization requires `spanner.backups.getIamPolicy` + permission on [resource][google.iam.v1.GetIamPolicyRequest.resource]. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def TestIamPermissions(self, request, context): """Returns permissions that the caller has on the specified database or backup - resource. - - Attempting this RPC on a non-existent Cloud Spanner database will - result in a NOT_FOUND error if the user has - `spanner.databases.list` permission on the containing Cloud - Spanner instance. Otherwise returns an empty set of permissions. - Calling this method on a backup that does not exist will - result in a NOT_FOUND error if the user has - `spanner.backups.list` permission on the containing instance. - """ + resource. + + Attempting this RPC on a non-existent Cloud Spanner database will + result in a NOT_FOUND error if the user has + `spanner.databases.list` permission on the containing Cloud + Spanner instance. Otherwise returns an empty set of permissions. + Calling this method on a backup that does not exist will + result in a NOT_FOUND error if the user has + `spanner.backups.list` permission on the containing instance. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def CreateBackup(self, request, context): """Starts creating a new Cloud Spanner Backup. - The returned backup [long-running operation][google.longrunning.Operation] - will have a name of the format - `projects//instances//backups//operations/` - and can be used to track creation of the backup. The - [metadata][google.longrunning.Operation.metadata] field type is - [CreateBackupMetadata][google.spanner.admin.database.v1.CreateBackupMetadata]. The - [response][google.longrunning.Operation.response] field type is - [Backup][google.spanner.admin.database.v1.Backup], if successful. Cancelling the returned operation will stop the - creation and delete the backup. - There can be only one pending backup creation per database. Backup creation - of different databases can run concurrently. - """ + The returned backup [long-running operation][google.longrunning.Operation] + will have a name of the format + `projects//instances//backups//operations/` + and can be used to track creation of the backup. The + [metadata][google.longrunning.Operation.metadata] field type is + [CreateBackupMetadata][google.spanner.admin.database.v1.CreateBackupMetadata]. The + [response][google.longrunning.Operation.response] field type is + [Backup][google.spanner.admin.database.v1.Backup], if successful. Cancelling the returned operation will stop the + creation and delete the backup. + There can be only one pending backup creation per database. Backup creation + of different databases can run concurrently. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetBackup(self, request, context): """Gets metadata on a pending or completed [Backup][google.spanner.admin.database.v1.Backup]. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def UpdateBackup(self, request, context): """Updates a pending or completed [Backup][google.spanner.admin.database.v1.Backup]. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def DeleteBackup(self, request, context): """Deletes a pending or completed [Backup][google.spanner.admin.database.v1.Backup]. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ListBackups(self, request, context): """Lists completed and pending backups. - Backups returned are ordered by `create_time` in descending order, - starting from the most recent `create_time`. - """ + Backups returned are ordered by `create_time` in descending order, + starting from the most recent `create_time`. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def RestoreDatabase(self, request, context): """Create a new database by restoring from a completed backup. The new - database must be in the same project and in an instance with the same - instance configuration as the instance containing - the backup. The returned database [long-running - operation][google.longrunning.Operation] has a name of the format - `projects//instances//databases//operations/`, - and can be used to track the progress of the operation, and to cancel it. - The [metadata][google.longrunning.Operation.metadata] field type is - [RestoreDatabaseMetadata][google.spanner.admin.database.v1.RestoreDatabaseMetadata]. - The [response][google.longrunning.Operation.response] type - is [Database][google.spanner.admin.database.v1.Database], if - successful. Cancelling the returned operation will stop the restore and - delete the database. - There can be only one database being restored into an instance at a time. - Once the restore operation completes, a new restore operation can be - initiated, without waiting for the optimize operation associated with the - first restore to complete. - """ + database must be in the same project and in an instance with the same + instance configuration as the instance containing + the backup. The returned database [long-running + operation][google.longrunning.Operation] has a name of the format + `projects//instances//databases//operations/`, + and can be used to track the progress of the operation, and to cancel it. + The [metadata][google.longrunning.Operation.metadata] field type is + [RestoreDatabaseMetadata][google.spanner.admin.database.v1.RestoreDatabaseMetadata]. + The [response][google.longrunning.Operation.response] type + is [Database][google.spanner.admin.database.v1.Database], if + successful. Cancelling the returned operation will stop the restore and + delete the database. + There can be only one database being restored into an instance at a time. + Once the restore operation completes, a new restore operation can be + initiated, without waiting for the optimize operation associated with the + first restore to complete. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ListDatabaseOperations(self, request, context): """Lists database [longrunning-operations][google.longrunning.Operation]. - A database operation has a name of the form - `projects//instances//databases//operations/`. - The long-running operation - [metadata][google.longrunning.Operation.metadata] field type - `metadata.type_url` describes the type of the metadata. Operations returned - include those that have completed/failed/canceled within the last 7 days, - and pending operations. - """ + A database operation has a name of the form + `projects//instances//databases//operations/`. + The long-running operation + [metadata][google.longrunning.Operation.metadata] field type + `metadata.type_url` describes the type of the metadata. Operations returned + include those that have completed/failed/canceled within the last 7 days, + and pending operations. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ListBackupOperations(self, request, context): """Lists the backup [long-running operations][google.longrunning.Operation] in - the given instance. A backup operation has a name of the form - `projects//instances//backups//operations/`. - The long-running operation - [metadata][google.longrunning.Operation.metadata] field type - `metadata.type_url` describes the type of the metadata. Operations returned - include those that have completed/failed/canceled within the last 7 days, - and pending operations. Operations returned are ordered by - `operation.metadata.value.progress.start_time` in descending order starting - from the most recently started operation. - """ + the given instance. A backup operation has a name of the form + `projects//instances//backups//operations/`. + The long-running operation + [metadata][google.longrunning.Operation.metadata] field type + `metadata.type_url` describes the type of the metadata. Operations returned + include those that have completed/failed/canceled within the last 7 days, + and pending operations. Operations returned are ordered by + `operation.metadata.value.progress.start_time` in descending order starting + from the most recently started operation. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") @@ -422,3 +423,473 @@ def add_DatabaseAdminServicer_to_server(servicer, server): "google.spanner.admin.database.v1.DatabaseAdmin", rpc_method_handlers ) server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class DatabaseAdmin(object): + """Cloud Spanner Database Admin API + + The Cloud Spanner Database Admin API can be used to create, drop, and + list databases. It also enables updating the schema of pre-existing + databases. It can be also used to create, delete and list backups for a + database and to restore from an existing backup. + """ + + @staticmethod + def ListDatabases( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/ListDatabases", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.ListDatabasesRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.ListDatabasesResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CreateDatabase( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/CreateDatabase", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.CreateDatabaseRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.Operation.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetDatabase( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/GetDatabase", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.GetDatabaseRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.Database.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def UpdateDatabaseDdl( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/UpdateDatabaseDdl", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.UpdateDatabaseDdlRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.Operation.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DropDatabase( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/DropDatabase", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.DropDatabaseRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetDatabaseDdl( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/GetDatabaseDdl", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.GetDatabaseDdlRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.GetDatabaseDdlResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def SetIamPolicy( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/SetIamPolicy", + google_dot_iam_dot_v1_dot_iam__policy__pb2.SetIamPolicyRequest.SerializeToString, + google_dot_iam_dot_v1_dot_policy__pb2.Policy.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetIamPolicy( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/GetIamPolicy", + google_dot_iam_dot_v1_dot_iam__policy__pb2.GetIamPolicyRequest.SerializeToString, + google_dot_iam_dot_v1_dot_policy__pb2.Policy.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def TestIamPermissions( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/TestIamPermissions", + google_dot_iam_dot_v1_dot_iam__policy__pb2.TestIamPermissionsRequest.SerializeToString, + google_dot_iam_dot_v1_dot_iam__policy__pb2.TestIamPermissionsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CreateBackup( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/CreateBackup", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.CreateBackupRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.Operation.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetBackup( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/GetBackup", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.GetBackupRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.Backup.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def UpdateBackup( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/UpdateBackup", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.UpdateBackupRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.Backup.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DeleteBackup( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/DeleteBackup", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.DeleteBackupRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListBackups( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/ListBackups", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.ListBackupsRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.ListBackupsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def RestoreDatabase( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/RestoreDatabase", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.RestoreDatabaseRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.Operation.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListDatabaseOperations( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/ListDatabaseOperations", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.ListDatabaseOperationsRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_spanner__database__admin__pb2.ListDatabaseOperationsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListBackupOperations( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.database.v1.DatabaseAdmin/ListBackupOperations", + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.ListBackupOperationsRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__database__v1_dot_proto_dot_backup__pb2.ListBackupOperationsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client.py b/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client.py index ae9e6a7e3e..bc6934a711 100644 --- a/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client.py +++ b/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client.py @@ -241,16 +241,47 @@ def __init__( self._inner_api_calls = {} # Service calls - def list_instance_configs( + def create_instance( self, parent, - page_size=None, + instance_id, + instance, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Lists the supported instance configurations for a given project. + Creates an instance and begins preparing it to begin serving. The + returned ``long-running operation`` can be used to track the progress of + preparing the new instance. The instance name is assigned by the caller. + If the named instance already exists, ``CreateInstance`` returns + ``ALREADY_EXISTS``. + + Immediately upon completion of this request: + + - The instance is readable via the API, with all requested attributes + but no allocated resources. Its state is ``CREATING``. + + Until completion of the returned operation: + + - Cancelling the operation renders the instance immediately unreadable + via the API. + - The instance can be deleted. + - All other attempts to modify the instance are rejected. + + Upon completion of the returned operation: + + - Billing for all successfully-allocated resources begins (some types + may have lower than the requested levels). + - Databases can be created in the instance. + - The instance's allocated resource levels are readable via the API. + - The instance's state becomes ``READY``. + + The returned ``long-running operation`` will have a name of the format + ``/operations/`` and can be used to track + creation of the instance. The ``metadata`` field type is + ``CreateInstanceMetadata``. The ``response`` field type is ``Instance``, + if successful. Example: >>> from google.cloud import spanner_admin_instance_v1 @@ -259,29 +290,34 @@ def list_instance_configs( >>> >>> parent = client.project_path('[PROJECT]') >>> - >>> # Iterate over all results - >>> for element in client.list_instance_configs(parent): - ... # process element - ... pass + >>> # TODO: Initialize `instance_id`: + >>> instance_id = '' >>> + >>> # TODO: Initialize `instance`: + >>> instance = {} >>> - >>> # Alternatively: + >>> response = client.create_instance(parent, instance_id, instance) >>> - >>> # Iterate over results one page at a time - >>> for page in client.list_instance_configs(parent).pages: - ... for element in page: - ... # process element - ... pass + >>> def callback(operation_future): + ... # Handle result. + ... result = operation_future.result() + >>> + >>> response.add_done_callback(callback) + >>> + >>> # Handle metadata. + >>> metadata = response.metadata() Args: - parent (str): Required. The name of the project for which a list of supported - instance configurations is requested. Values are of the form - ``projects/``. - page_size (int): The maximum number of resources contained in the - underlying API response. If page streaming is performed per- - resource, this parameter does not affect the return value. If page - streaming is performed per-page, this determines the maximum number - of resources in a page. + parent (str): Required. The name of the project in which to create the instance. + Values are of the form ``projects/``. + instance_id (str): Required. The ID of the instance to create. Valid identifiers are of + the form ``[a-z][-a-z0-9]*[a-z0-9]`` and must be between 2 and 64 + characters in length. + instance (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.Instance]): Required. The instance to create. The name may be omitted, but if + specified must be ``/instances/``. + + If a dict is provided, it must be of the same form as the protobuf + message :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -292,10 +328,7 @@ def list_instance_configs( that is provided to the method. Returns: - A :class:`~google.api_core.page_iterator.PageIterator` instance. - An iterable of :class:`~google.cloud.spanner_admin_instance_v1.types.InstanceConfig` instances. - You can also iterate over the pages of the response - using its `pages` property. + A :class:`~google.api_core.operation.Operation` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -305,18 +338,18 @@ def list_instance_configs( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "list_instance_configs" not in self._inner_api_calls: + if "create_instance" not in self._inner_api_calls: self._inner_api_calls[ - "list_instance_configs" + "create_instance" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.list_instance_configs, - default_retry=self._method_configs["ListInstanceConfigs"].retry, - default_timeout=self._method_configs["ListInstanceConfigs"].timeout, + self.transport.create_instance, + default_retry=self._method_configs["CreateInstance"].retry, + default_timeout=self._method_configs["CreateInstance"].timeout, client_info=self._client_info, ) - request = spanner_instance_admin_pb2.ListInstanceConfigsRequest( - parent=parent, page_size=page_size + request = spanner_instance_admin_pb2.CreateInstanceRequest( + parent=parent, instance_id=instance_id, instance=instance ) if metadata is None: metadata = [] @@ -331,43 +364,98 @@ def list_instance_configs( ) metadata.append(routing_metadata) - iterator = google.api_core.page_iterator.GRPCIterator( - client=None, - method=functools.partial( - self._inner_api_calls["list_instance_configs"], - retry=retry, - timeout=timeout, - metadata=metadata, - ), - request=request, - items_field="instance_configs", - request_token_field="page_token", - response_token_field="next_page_token", + operation = self._inner_api_calls["create_instance"]( + request, retry=retry, timeout=timeout, metadata=metadata + ) + return google.api_core.operation.from_gapic( + operation, + self.transport._operations_client, + spanner_instance_admin_pb2.Instance, + metadata_type=spanner_instance_admin_pb2.CreateInstanceMetadata, ) - return iterator - def get_instance_config( + def update_instance( self, - name, + instance, + field_mask, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Gets information about a particular instance configuration. + Updates an instance, and begins allocating or releasing resources as + requested. The returned ``long-running operation`` can be used to track + the progress of updating the instance. If the named instance does not + exist, returns ``NOT_FOUND``. + + Immediately upon completion of this request: + + - For resource types for which a decrease in the instance's allocation + has been requested, billing is based on the newly-requested level. + + Until completion of the returned operation: + + - Cancelling the operation sets its metadata's ``cancel_time``, and + begins restoring resources to their pre-request values. The operation + is guaranteed to succeed at undoing all resource changes, after which + point it terminates with a ``CANCELLED`` status. + - All other attempts to modify the instance are rejected. + - Reading the instance via the API continues to give the pre-request + resource levels. + + Upon completion of the returned operation: + + - Billing begins for all successfully-allocated resources (some types + may have lower than the requested levels). + - All newly-reserved resources are available for serving the instance's + tables. + - The instance's new resource levels are readable via the API. + + The returned ``long-running operation`` will have a name of the format + ``/operations/`` and can be used to track + the instance modification. The ``metadata`` field type is + ``UpdateInstanceMetadata``. The ``response`` field type is ``Instance``, + if successful. + + Authorization requires ``spanner.instances.update`` permission on + resource ``name``. Example: >>> from google.cloud import spanner_admin_instance_v1 >>> >>> client = spanner_admin_instance_v1.InstanceAdminClient() >>> - >>> name = client.instance_config_path('[PROJECT]', '[INSTANCE_CONFIG]') + >>> # TODO: Initialize `instance`: + >>> instance = {} >>> - >>> response = client.get_instance_config(name) + >>> # TODO: Initialize `field_mask`: + >>> field_mask = {} + >>> + >>> response = client.update_instance(instance, field_mask) + >>> + >>> def callback(operation_future): + ... # Handle result. + ... result = operation_future.result() + >>> + >>> response.add_done_callback(callback) + >>> + >>> # Handle metadata. + >>> metadata = response.metadata() Args: - name (str): Required. The name of the requested instance configuration. Values - are of the form ``projects//instanceConfigs/``. + instance (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.Instance]): Required. The instance to update, which must always include the + instance name. Otherwise, only fields mentioned in ``field_mask`` need + be included. + + If a dict is provided, it must be of the same form as the protobuf + message :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` + field_mask (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.FieldMask]): Required. A mask specifying which fields in ``Instance`` should be + updated. The field mask must always be specified; this prevents any + future fields in ``Instance`` from being erased accidentally by clients + that do not know about them. + + If a dict is provided, it must be of the same form as the protobuf + message :class:`~google.cloud.spanner_admin_instance_v1.types.FieldMask` retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -378,7 +466,7 @@ def get_instance_config( that is provided to the method. Returns: - A :class:`~google.cloud.spanner_admin_instance_v1.types.InstanceConfig` instance. + A :class:`~google.api_core.operation.Operation` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -388,22 +476,24 @@ def get_instance_config( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "get_instance_config" not in self._inner_api_calls: + if "update_instance" not in self._inner_api_calls: self._inner_api_calls[ - "get_instance_config" + "update_instance" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.get_instance_config, - default_retry=self._method_configs["GetInstanceConfig"].retry, - default_timeout=self._method_configs["GetInstanceConfig"].timeout, + self.transport.update_instance, + default_retry=self._method_configs["UpdateInstance"].retry, + default_timeout=self._method_configs["UpdateInstance"].timeout, client_info=self._client_info, ) - request = spanner_instance_admin_pb2.GetInstanceConfigRequest(name=name) + request = spanner_instance_admin_pb2.UpdateInstanceRequest( + instance=instance, field_mask=field_mask + ) if metadata is None: metadata = [] metadata = list(metadata) try: - routing_header = [("name", name)] + routing_header = [("instance.name", instance.name)] except AttributeError: pass else: @@ -412,21 +502,26 @@ def get_instance_config( ) metadata.append(routing_metadata) - return self._inner_api_calls["get_instance_config"]( + operation = self._inner_api_calls["update_instance"]( request, retry=retry, timeout=timeout, metadata=metadata ) + return google.api_core.operation.from_gapic( + operation, + self.transport._operations_client, + spanner_instance_admin_pb2.Instance, + metadata_type=spanner_instance_admin_pb2.UpdateInstanceMetadata, + ) - def list_instances( + def list_instance_configs( self, parent, page_size=None, - filter_=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Lists all instances in the given project. + Lists the supported instance configurations for a given project. Example: >>> from google.cloud import spanner_admin_instance_v1 @@ -436,7 +531,7 @@ def list_instances( >>> parent = client.project_path('[PROJECT]') >>> >>> # Iterate over all results - >>> for element in client.list_instances(parent): + >>> for element in client.list_instance_configs(parent): ... # process element ... pass >>> @@ -444,37 +539,20 @@ def list_instances( >>> # Alternatively: >>> >>> # Iterate over results one page at a time - >>> for page in client.list_instances(parent).pages: + >>> for page in client.list_instance_configs(parent).pages: ... for element in page: ... # process element ... pass Args: - parent (str): Required. The name of the project for which a list of instances is - requested. Values are of the form ``projects/``. + parent (str): Required. The name of the project for which a list of supported + instance configurations is requested. Values are of the form + ``projects/``. page_size (int): The maximum number of resources contained in the underlying API response. If page streaming is performed per- resource, this parameter does not affect the return value. If page streaming is performed per-page, this determines the maximum number of resources in a page. - filter_ (str): An expression for filtering the results of the request. Filter rules - are case insensitive. The fields eligible for filtering are: - - - ``name`` - - ``display_name`` - - ``labels.key`` where key is the name of a label - - Some examples of using filters are: - - - ``name:*`` --> The instance has a name. - - ``name:Howl`` --> The instance's name contains the string "howl". - - ``name:HOWL`` --> Equivalent to above. - - ``NAME:howl`` --> Equivalent to above. - - ``labels.env:*`` --> The instance has the label "env". - - ``labels.env:dev`` --> The instance has the label "env" and the value - of the label contains the string "dev". - - ``name:howl labels.env:dev`` --> The instance's name contains "howl" - and it has the label "env" with its value containing "dev". retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -486,7 +564,7 @@ def list_instances( Returns: A :class:`~google.api_core.page_iterator.PageIterator` instance. - An iterable of :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` instances. + An iterable of :class:`~google.cloud.spanner_admin_instance_v1.types.InstanceConfig` instances. You can also iterate over the pages of the response using its `pages` property. @@ -498,18 +576,18 @@ def list_instances( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "list_instances" not in self._inner_api_calls: + if "list_instance_configs" not in self._inner_api_calls: self._inner_api_calls[ - "list_instances" + "list_instance_configs" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.list_instances, - default_retry=self._method_configs["ListInstances"].retry, - default_timeout=self._method_configs["ListInstances"].timeout, + self.transport.list_instance_configs, + default_retry=self._method_configs["ListInstanceConfigs"].retry, + default_timeout=self._method_configs["ListInstanceConfigs"].timeout, client_info=self._client_info, ) - request = spanner_instance_admin_pb2.ListInstancesRequest( - parent=parent, page_size=page_size, filter=filter_ + request = spanner_instance_admin_pb2.ListInstanceConfigsRequest( + parent=parent, page_size=page_size ) if metadata is None: metadata = [] @@ -527,47 +605,40 @@ def list_instances( iterator = google.api_core.page_iterator.GRPCIterator( client=None, method=functools.partial( - self._inner_api_calls["list_instances"], + self._inner_api_calls["list_instance_configs"], retry=retry, timeout=timeout, metadata=metadata, ), request=request, - items_field="instances", + items_field="instance_configs", request_token_field="page_token", response_token_field="next_page_token", ) return iterator - def get_instance( + def get_instance_config( self, name, - field_mask=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Gets information about a particular instance. + Gets information about a particular instance configuration. Example: >>> from google.cloud import spanner_admin_instance_v1 >>> >>> client = spanner_admin_instance_v1.InstanceAdminClient() >>> - >>> name = client.instance_path('[PROJECT]', '[INSTANCE]') + >>> name = client.instance_config_path('[PROJECT]', '[INSTANCE_CONFIG]') >>> - >>> response = client.get_instance(name) + >>> response = client.get_instance_config(name) Args: - name (str): Required. The name of the requested instance. Values are of the form - ``projects//instances/``. - field_mask (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.FieldMask]): If field_mask is present, specifies the subset of ``Instance`` - fields that should be returned. If absent, all ``Instance`` fields are - returned. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.spanner_admin_instance_v1.types.FieldMask` + name (str): Required. The name of the requested instance configuration. Values + are of the form ``projects//instanceConfigs/``. retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -578,7 +649,7 @@ def get_instance( that is provided to the method. Returns: - A :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` instance. + A :class:`~google.cloud.spanner_admin_instance_v1.types.InstanceConfig` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -588,19 +659,17 @@ def get_instance( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "get_instance" not in self._inner_api_calls: + if "get_instance_config" not in self._inner_api_calls: self._inner_api_calls[ - "get_instance" + "get_instance_config" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.get_instance, - default_retry=self._method_configs["GetInstance"].retry, - default_timeout=self._method_configs["GetInstance"].timeout, + self.transport.get_instance_config, + default_retry=self._method_configs["GetInstanceConfig"].retry, + default_timeout=self._method_configs["GetInstanceConfig"].timeout, client_info=self._client_info, ) - request = spanner_instance_admin_pb2.GetInstanceRequest( - name=name, field_mask=field_mask - ) + request = spanner_instance_admin_pb2.GetInstanceConfigRequest(name=name) if metadata is None: metadata = [] metadata = list(metadata) @@ -614,51 +683,21 @@ def get_instance( ) metadata.append(routing_metadata) - return self._inner_api_calls["get_instance"]( + return self._inner_api_calls["get_instance_config"]( request, retry=retry, timeout=timeout, metadata=metadata ) - def create_instance( + def list_instances( self, parent, - instance_id, - instance, + page_size=None, + filter_=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Creates an instance and begins preparing it to begin serving. The - returned ``long-running operation`` can be used to track the progress of - preparing the new instance. The instance name is assigned by the caller. - If the named instance already exists, ``CreateInstance`` returns - ``ALREADY_EXISTS``. - - Immediately upon completion of this request: - - - The instance is readable via the API, with all requested attributes - but no allocated resources. Its state is ``CREATING``. - - Until completion of the returned operation: - - - Cancelling the operation renders the instance immediately unreadable - via the API. - - The instance can be deleted. - - All other attempts to modify the instance are rejected. - - Upon completion of the returned operation: - - - Billing for all successfully-allocated resources begins (some types - may have lower than the requested levels). - - Databases can be created in the instance. - - The instance's allocated resource levels are readable via the API. - - The instance's state becomes ``READY``. - - The returned ``long-running operation`` will have a name of the format - ``/operations/`` and can be used to track - creation of the instance. The ``metadata`` field type is - ``CreateInstanceMetadata``. The ``response`` field type is ``Instance``, - if successful. + Lists all instances in the given project. Example: >>> from google.cloud import spanner_admin_instance_v1 @@ -667,34 +706,46 @@ def create_instance( >>> >>> parent = client.project_path('[PROJECT]') >>> - >>> # TODO: Initialize `instance_id`: - >>> instance_id = '' - >>> - >>> # TODO: Initialize `instance`: - >>> instance = {} - >>> - >>> response = client.create_instance(parent, instance_id, instance) + >>> # Iterate over all results + >>> for element in client.list_instances(parent): + ... # process element + ... pass >>> - >>> def callback(operation_future): - ... # Handle result. - ... result = operation_future.result() >>> - >>> response.add_done_callback(callback) + >>> # Alternatively: >>> - >>> # Handle metadata. - >>> metadata = response.metadata() + >>> # Iterate over results one page at a time + >>> for page in client.list_instances(parent).pages: + ... for element in page: + ... # process element + ... pass Args: - parent (str): Required. The name of the project in which to create the instance. - Values are of the form ``projects/``. - instance_id (str): Required. The ID of the instance to create. Valid identifiers are of - the form ``[a-z][-a-z0-9]*[a-z0-9]`` and must be between 2 and 64 - characters in length. - instance (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.Instance]): Required. The instance to create. The name may be omitted, but if - specified must be ``/instances/``. + parent (str): Required. The name of the project for which a list of instances is + requested. Values are of the form ``projects/``. + page_size (int): The maximum number of resources contained in the + underlying API response. If page streaming is performed per- + resource, this parameter does not affect the return value. If page + streaming is performed per-page, this determines the maximum number + of resources in a page. + filter_ (str): An expression for filtering the results of the request. Filter rules + are case insensitive. The fields eligible for filtering are: - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` + - ``name`` + - ``display_name`` + - ``labels.key`` where key is the name of a label + + Some examples of using filters are: + + - ``name:*`` --> The instance has a name. + - ``name:Howl`` --> The instance's name contains the string "howl". + - ``name:HOWL`` --> Equivalent to above. + - ``NAME:howl`` --> Equivalent to above. + - ``labels.env:*`` --> The instance has the label "env". + - ``labels.env:dev`` --> The instance has the label "env" and the value + of the label contains the string "dev". + - ``name:howl labels.env:dev`` --> The instance's name contains "howl" + and it has the label "env" with its value containing "dev". retry (Optional[google.api_core.retry.Retry]): A retry object used to retry requests. If ``None`` is specified, requests will be retried using a default configuration. @@ -705,7 +756,10 @@ def create_instance( that is provided to the method. Returns: - A :class:`~google.api_core.operation.Operation` instance. + A :class:`~google.api_core.page_iterator.PageIterator` instance. + An iterable of :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` instances. + You can also iterate over the pages of the response + using its `pages` property. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -715,18 +769,18 @@ def create_instance( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "create_instance" not in self._inner_api_calls: + if "list_instances" not in self._inner_api_calls: self._inner_api_calls[ - "create_instance" + "list_instances" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.create_instance, - default_retry=self._method_configs["CreateInstance"].retry, - default_timeout=self._method_configs["CreateInstance"].timeout, + self.transport.list_instances, + default_retry=self._method_configs["ListInstances"].retry, + default_timeout=self._method_configs["ListInstances"].timeout, client_info=self._client_info, ) - request = spanner_instance_admin_pb2.CreateInstanceRequest( - parent=parent, instance_id=instance_id, instance=instance + request = spanner_instance_admin_pb2.ListInstancesRequest( + parent=parent, page_size=page_size, filter=filter_ ) if metadata is None: metadata = [] @@ -741,95 +795,47 @@ def create_instance( ) metadata.append(routing_metadata) - operation = self._inner_api_calls["create_instance"]( - request, retry=retry, timeout=timeout, metadata=metadata - ) - return google.api_core.operation.from_gapic( - operation, - self.transport._operations_client, - spanner_instance_admin_pb2.Instance, - metadata_type=spanner_instance_admin_pb2.CreateInstanceMetadata, + iterator = google.api_core.page_iterator.GRPCIterator( + client=None, + method=functools.partial( + self._inner_api_calls["list_instances"], + retry=retry, + timeout=timeout, + metadata=metadata, + ), + request=request, + items_field="instances", + request_token_field="page_token", + response_token_field="next_page_token", ) + return iterator - def update_instance( + def get_instance( self, - instance, - field_mask, + name, + field_mask=None, retry=google.api_core.gapic_v1.method.DEFAULT, timeout=google.api_core.gapic_v1.method.DEFAULT, metadata=None, ): """ - Updates an instance, and begins allocating or releasing resources as - requested. The returned ``long-running operation`` can be used to track - the progress of updating the instance. If the named instance does not - exist, returns ``NOT_FOUND``. - - Immediately upon completion of this request: - - - For resource types for which a decrease in the instance's allocation - has been requested, billing is based on the newly-requested level. - - Until completion of the returned operation: - - - Cancelling the operation sets its metadata's ``cancel_time``, and - begins restoring resources to their pre-request values. The operation - is guaranteed to succeed at undoing all resource changes, after which - point it terminates with a ``CANCELLED`` status. - - All other attempts to modify the instance are rejected. - - Reading the instance via the API continues to give the pre-request - resource levels. - - Upon completion of the returned operation: - - - Billing begins for all successfully-allocated resources (some types - may have lower than the requested levels). - - All newly-reserved resources are available for serving the instance's - tables. - - The instance's new resource levels are readable via the API. - - The returned ``long-running operation`` will have a name of the format - ``/operations/`` and can be used to track - the instance modification. The ``metadata`` field type is - ``UpdateInstanceMetadata``. The ``response`` field type is ``Instance``, - if successful. - - Authorization requires ``spanner.instances.update`` permission on - resource ``name``. + Gets information about a particular instance. Example: >>> from google.cloud import spanner_admin_instance_v1 >>> >>> client = spanner_admin_instance_v1.InstanceAdminClient() >>> - >>> # TODO: Initialize `instance`: - >>> instance = {} - >>> - >>> # TODO: Initialize `field_mask`: - >>> field_mask = {} - >>> - >>> response = client.update_instance(instance, field_mask) - >>> - >>> def callback(operation_future): - ... # Handle result. - ... result = operation_future.result() - >>> - >>> response.add_done_callback(callback) + >>> name = client.instance_path('[PROJECT]', '[INSTANCE]') >>> - >>> # Handle metadata. - >>> metadata = response.metadata() + >>> response = client.get_instance(name) Args: - instance (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.Instance]): Required. The instance to update, which must always include the - instance name. Otherwise, only fields mentioned in ``field_mask`` need - be included. - - If a dict is provided, it must be of the same form as the protobuf - message :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` - field_mask (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.FieldMask]): Required. A mask specifying which fields in ``Instance`` should be - updated. The field mask must always be specified; this prevents any - future fields in ``Instance`` from being erased accidentally by clients - that do not know about them. + name (str): Required. The name of the requested instance. Values are of the form + ``projects//instances/``. + field_mask (Union[dict, ~google.cloud.spanner_admin_instance_v1.types.FieldMask]): If field_mask is present, specifies the subset of ``Instance`` + fields that should be returned. If absent, all ``Instance`` fields are + returned. If a dict is provided, it must be of the same form as the protobuf message :class:`~google.cloud.spanner_admin_instance_v1.types.FieldMask` @@ -843,7 +849,7 @@ def update_instance( that is provided to the method. Returns: - A :class:`~google.api_core.operation.Operation` instance. + A :class:`~google.cloud.spanner_admin_instance_v1.types.Instance` instance. Raises: google.api_core.exceptions.GoogleAPICallError: If the request @@ -853,24 +859,24 @@ def update_instance( ValueError: If the parameters are invalid. """ # Wrap the transport method to add retry and timeout logic. - if "update_instance" not in self._inner_api_calls: + if "get_instance" not in self._inner_api_calls: self._inner_api_calls[ - "update_instance" + "get_instance" ] = google.api_core.gapic_v1.method.wrap_method( - self.transport.update_instance, - default_retry=self._method_configs["UpdateInstance"].retry, - default_timeout=self._method_configs["UpdateInstance"].timeout, + self.transport.get_instance, + default_retry=self._method_configs["GetInstance"].retry, + default_timeout=self._method_configs["GetInstance"].timeout, client_info=self._client_info, ) - request = spanner_instance_admin_pb2.UpdateInstanceRequest( - instance=instance, field_mask=field_mask + request = spanner_instance_admin_pb2.GetInstanceRequest( + name=name, field_mask=field_mask ) if metadata is None: metadata = [] metadata = list(metadata) try: - routing_header = [("instance.name", instance.name)] + routing_header = [("name", name)] except AttributeError: pass else: @@ -879,15 +885,9 @@ def update_instance( ) metadata.append(routing_metadata) - operation = self._inner_api_calls["update_instance"]( + return self._inner_api_calls["get_instance"]( request, retry=retry, timeout=timeout, metadata=metadata ) - return google.api_core.operation.from_gapic( - operation, - self.transport._operations_client, - spanner_instance_admin_pb2.Instance, - metadata_type=spanner_instance_admin_pb2.UpdateInstanceMetadata, - ) def delete_instance( self, diff --git a/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client_config.py b/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client_config.py index f181a299bf..cb18900f9e 100644 --- a/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client_config.py +++ b/google/cloud/spanner_admin_instance_v1/gapic/instance_admin_client_config.py @@ -2,70 +2,109 @@ "interfaces": { "google.spanner.admin.instance.v1.InstanceAdmin": { "retry_codes": { - "idempotent": ["DEADLINE_EXCEEDED", "UNAVAILABLE"], - "non_idempotent": [], + "retry_policy_1_codes": ["UNAVAILABLE", "DEADLINE_EXCEEDED"], + "no_retry_2_codes": [], + "no_retry_codes": [], + "retry_policy_2_codes": ["UNAVAILABLE", "DEADLINE_EXCEEDED"], + "no_retry_1_codes": [], }, "retry_params": { - "default": { + "retry_policy_1_params": { "initial_retry_delay_millis": 1000, "retry_delay_multiplier": 1.3, "max_retry_delay_millis": 32000, - "initial_rpc_timeout_millis": 60000, + "initial_rpc_timeout_millis": 3600000, "rpc_timeout_multiplier": 1.0, - "max_rpc_timeout_millis": 60000, - "total_timeout_millis": 600000, - } + "max_rpc_timeout_millis": 3600000, + "total_timeout_millis": 3600000, + }, + "retry_policy_2_params": { + "initial_retry_delay_millis": 1000, + "retry_delay_multiplier": 1.3, + "max_retry_delay_millis": 32000, + "initial_rpc_timeout_millis": 30000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 30000, + "total_timeout_millis": 30000, + }, + "no_retry_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, + "initial_rpc_timeout_millis": 0, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 0, + "total_timeout_millis": 0, + }, + "no_retry_1_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, + "initial_rpc_timeout_millis": 3600000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 3600000, + "total_timeout_millis": 3600000, + }, + "no_retry_2_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, + "initial_rpc_timeout_millis": 30000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 30000, + "total_timeout_millis": 30000, + }, }, "methods": { - "ListInstanceConfigs": { + "CreateInstance": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", }, - "GetInstanceConfig": { + "UpdateInstance": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", }, - "ListInstances": { + "ListInstanceConfigs": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, - "GetInstance": { + "GetInstanceConfig": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, - "CreateInstance": { + "ListInstances": { "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, - "UpdateInstance": { + "GetInstance": { "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "DeleteInstance": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "SetIamPolicy": { "timeout_millis": 30000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_2_codes", + "retry_params_name": "no_retry_2_params", }, "GetIamPolicy": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_2_codes", + "retry_params_name": "retry_policy_2_params", }, "TestIamPermissions": { "timeout_millis": 30000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "default", + "retry_codes_name": "no_retry_2_codes", + "retry_params_name": "no_retry_2_params", }, }, } diff --git a/google/cloud/spanner_admin_instance_v1/gapic/transports/instance_admin_grpc_transport.py b/google/cloud/spanner_admin_instance_v1/gapic/transports/instance_admin_grpc_transport.py index c0fd87efbe..c823c59bbb 100644 --- a/google/cloud/spanner_admin_instance_v1/gapic/transports/instance_admin_grpc_transport.py +++ b/google/cloud/spanner_admin_instance_v1/gapic/transports/instance_admin_grpc_transport.py @@ -120,58 +120,6 @@ def channel(self): """ return self._channel - @property - def list_instance_configs(self): - """Return the gRPC stub for :meth:`InstanceAdminClient.list_instance_configs`. - - Lists the supported instance configurations for a given project. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["instance_admin_stub"].ListInstanceConfigs - - @property - def get_instance_config(self): - """Return the gRPC stub for :meth:`InstanceAdminClient.get_instance_config`. - - Gets information about a particular instance configuration. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["instance_admin_stub"].GetInstanceConfig - - @property - def list_instances(self): - """Return the gRPC stub for :meth:`InstanceAdminClient.list_instances`. - - Lists all instances in the given project. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["instance_admin_stub"].ListInstances - - @property - def get_instance(self): - """Return the gRPC stub for :meth:`InstanceAdminClient.get_instance`. - - Gets information about a particular instance. - - Returns: - Callable: A callable which accepts the appropriate - deserialized request object and returns a - deserialized response object. - """ - return self._stubs["instance_admin_stub"].GetInstance - @property def create_instance(self): """Return the gRPC stub for :meth:`InstanceAdminClient.create_instance`. @@ -263,6 +211,58 @@ def update_instance(self): """ return self._stubs["instance_admin_stub"].UpdateInstance + @property + def list_instance_configs(self): + """Return the gRPC stub for :meth:`InstanceAdminClient.list_instance_configs`. + + Lists the supported instance configurations for a given project. + + Returns: + Callable: A callable which accepts the appropriate + deserialized request object and returns a + deserialized response object. + """ + return self._stubs["instance_admin_stub"].ListInstanceConfigs + + @property + def get_instance_config(self): + """Return the gRPC stub for :meth:`InstanceAdminClient.get_instance_config`. + + Gets information about a particular instance configuration. + + Returns: + Callable: A callable which accepts the appropriate + deserialized request object and returns a + deserialized response object. + """ + return self._stubs["instance_admin_stub"].GetInstanceConfig + + @property + def list_instances(self): + """Return the gRPC stub for :meth:`InstanceAdminClient.list_instances`. + + Lists all instances in the given project. + + Returns: + Callable: A callable which accepts the appropriate + deserialized request object and returns a + deserialized response object. + """ + return self._stubs["instance_admin_stub"].ListInstances + + @property + def get_instance(self): + """Return the gRPC stub for :meth:`InstanceAdminClient.get_instance`. + + Gets information about a particular instance. + + Returns: + Callable: A callable which accepts the appropriate + deserialized request object and returns a + deserialized response object. + """ + return self._stubs["instance_admin_stub"].GetInstance + @property def delete_instance(self): """Return the gRPC stub for :meth:`InstanceAdminClient.delete_instance`. diff --git a/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2.py b/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2.py index 77fd945e6c..8d086520e5 100644 --- a/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2.py +++ b/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2.py @@ -1555,7 +1555,7 @@ Required. The name of the requested instance. Values are of the form ``projects//instances/``. field_mask: - If field\_mask is present, specifies the subset of + If field_mask is present, specifies the subset of [Instance][google.spanner.admin.instance.v1.Instance] fields that should be returned. If absent, all [Instance][google.spanner.admin.instance.v1.Instance] fields diff --git a/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2_grpc.py b/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2_grpc.py index 3ee5c19c02..29964606bd 100644 --- a/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2_grpc.py +++ b/google/cloud/spanner_admin_instance_v1/proto/spanner_instance_admin_pb2_grpc.py @@ -1,4 +1,5 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc from google.cloud.spanner_admin_instance_v1.proto import ( @@ -15,33 +16,33 @@ class InstanceAdminStub(object): """Cloud Spanner Instance Admin API - The Cloud Spanner Instance Admin API can be used to create, delete, - modify and list instances. Instances are dedicated Cloud Spanner serving - and storage resources to be used by Cloud Spanner databases. - - Each instance has a "configuration", which dictates where the - serving resources for the Cloud Spanner instance are located (e.g., - US-central, Europe). Configurations are created by Google based on - resource availability. - - Cloud Spanner billing is based on the instances that exist and their - sizes. After an instance exists, there are no additional - per-database or per-operation charges for use of the instance - (though there may be additional network bandwidth charges). - Instances offer isolation: problems with databases in one instance - will not affect other instances. However, within an instance - databases can affect each other. For example, if one database in an - instance receives a lot of requests and consumes most of the - instance resources, fewer resources are available for other - databases in that instance, and their performance may suffer. - """ + The Cloud Spanner Instance Admin API can be used to create, delete, + modify and list instances. Instances are dedicated Cloud Spanner serving + and storage resources to be used by Cloud Spanner databases. + + Each instance has a "configuration", which dictates where the + serving resources for the Cloud Spanner instance are located (e.g., + US-central, Europe). Configurations are created by Google based on + resource availability. + + Cloud Spanner billing is based on the instances that exist and their + sizes. After an instance exists, there are no additional + per-database or per-operation charges for use of the instance + (though there may be additional network bandwidth charges). + Instances offer isolation: problems with databases in one instance + will not affect other instances. However, within an instance + databases can affect each other. For example, if one database in an + instance receives a lot of requests and consumes most of the + instance resources, fewer resources are available for other + databases in that instance, and their performance may suffer. + """ def __init__(self, channel): """Constructor. - Args: - channel: A grpc.Channel. - """ + Args: + channel: A grpc.Channel. + """ self.ListInstanceConfigs = channel.unary_unary( "/google.spanner.admin.instance.v1.InstanceAdmin/ListInstanceConfigs", request_serializer=google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.ListInstanceConfigsRequest.SerializeToString, @@ -97,137 +98,137 @@ def __init__(self, channel): class InstanceAdminServicer(object): """Cloud Spanner Instance Admin API - The Cloud Spanner Instance Admin API can be used to create, delete, - modify and list instances. Instances are dedicated Cloud Spanner serving - and storage resources to be used by Cloud Spanner databases. - - Each instance has a "configuration", which dictates where the - serving resources for the Cloud Spanner instance are located (e.g., - US-central, Europe). Configurations are created by Google based on - resource availability. - - Cloud Spanner billing is based on the instances that exist and their - sizes. After an instance exists, there are no additional - per-database or per-operation charges for use of the instance - (though there may be additional network bandwidth charges). - Instances offer isolation: problems with databases in one instance - will not affect other instances. However, within an instance - databases can affect each other. For example, if one database in an - instance receives a lot of requests and consumes most of the - instance resources, fewer resources are available for other - databases in that instance, and their performance may suffer. - """ + The Cloud Spanner Instance Admin API can be used to create, delete, + modify and list instances. Instances are dedicated Cloud Spanner serving + and storage resources to be used by Cloud Spanner databases. + + Each instance has a "configuration", which dictates where the + serving resources for the Cloud Spanner instance are located (e.g., + US-central, Europe). Configurations are created by Google based on + resource availability. + + Cloud Spanner billing is based on the instances that exist and their + sizes. After an instance exists, there are no additional + per-database or per-operation charges for use of the instance + (though there may be additional network bandwidth charges). + Instances offer isolation: problems with databases in one instance + will not affect other instances. However, within an instance + databases can affect each other. For example, if one database in an + instance receives a lot of requests and consumes most of the + instance resources, fewer resources are available for other + databases in that instance, and their performance may suffer. + """ def ListInstanceConfigs(self, request, context): """Lists the supported instance configurations for a given project. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetInstanceConfig(self, request, context): """Gets information about a particular instance configuration. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ListInstances(self, request, context): """Lists all instances in the given project. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetInstance(self, request, context): """Gets information about a particular instance. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def CreateInstance(self, request, context): """Creates an instance and begins preparing it to begin serving. The - returned [long-running operation][google.longrunning.Operation] - can be used to track the progress of preparing the new - instance. The instance name is assigned by the caller. If the - named instance already exists, `CreateInstance` returns - `ALREADY_EXISTS`. - - Immediately upon completion of this request: - - * The instance is readable via the API, with all requested attributes - but no allocated resources. Its state is `CREATING`. - - Until completion of the returned operation: - - * Cancelling the operation renders the instance immediately unreadable - via the API. - * The instance can be deleted. - * All other attempts to modify the instance are rejected. - - Upon completion of the returned operation: - - * Billing for all successfully-allocated resources begins (some types - may have lower than the requested levels). - * Databases can be created in the instance. - * The instance's allocated resource levels are readable via the API. - * The instance's state becomes `READY`. - - The returned [long-running operation][google.longrunning.Operation] will - have a name of the format `/operations/` and - can be used to track creation of the instance. The - [metadata][google.longrunning.Operation.metadata] field type is - [CreateInstanceMetadata][google.spanner.admin.instance.v1.CreateInstanceMetadata]. - The [response][google.longrunning.Operation.response] field type is - [Instance][google.spanner.admin.instance.v1.Instance], if successful. - """ + returned [long-running operation][google.longrunning.Operation] + can be used to track the progress of preparing the new + instance. The instance name is assigned by the caller. If the + named instance already exists, `CreateInstance` returns + `ALREADY_EXISTS`. + + Immediately upon completion of this request: + + * The instance is readable via the API, with all requested attributes + but no allocated resources. Its state is `CREATING`. + + Until completion of the returned operation: + + * Cancelling the operation renders the instance immediately unreadable + via the API. + * The instance can be deleted. + * All other attempts to modify the instance are rejected. + + Upon completion of the returned operation: + + * Billing for all successfully-allocated resources begins (some types + may have lower than the requested levels). + * Databases can be created in the instance. + * The instance's allocated resource levels are readable via the API. + * The instance's state becomes `READY`. + + The returned [long-running operation][google.longrunning.Operation] will + have a name of the format `/operations/` and + can be used to track creation of the instance. The + [metadata][google.longrunning.Operation.metadata] field type is + [CreateInstanceMetadata][google.spanner.admin.instance.v1.CreateInstanceMetadata]. + The [response][google.longrunning.Operation.response] field type is + [Instance][google.spanner.admin.instance.v1.Instance], if successful. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def UpdateInstance(self, request, context): """Updates an instance, and begins allocating or releasing resources - as requested. The returned [long-running - operation][google.longrunning.Operation] can be used to track the - progress of updating the instance. If the named instance does not - exist, returns `NOT_FOUND`. - - Immediately upon completion of this request: - - * For resource types for which a decrease in the instance's allocation - has been requested, billing is based on the newly-requested level. - - Until completion of the returned operation: - - * Cancelling the operation sets its metadata's - [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceMetadata.cancel_time], and begins - restoring resources to their pre-request values. The operation - is guaranteed to succeed at undoing all resource changes, - after which point it terminates with a `CANCELLED` status. - * All other attempts to modify the instance are rejected. - * Reading the instance via the API continues to give the pre-request - resource levels. - - Upon completion of the returned operation: - - * Billing begins for all successfully-allocated resources (some types - may have lower than the requested levels). - * All newly-reserved resources are available for serving the instance's - tables. - * The instance's new resource levels are readable via the API. - - The returned [long-running operation][google.longrunning.Operation] will - have a name of the format `/operations/` and - can be used to track the instance modification. The - [metadata][google.longrunning.Operation.metadata] field type is - [UpdateInstanceMetadata][google.spanner.admin.instance.v1.UpdateInstanceMetadata]. - The [response][google.longrunning.Operation.response] field type is - [Instance][google.spanner.admin.instance.v1.Instance], if successful. - - Authorization requires `spanner.instances.update` permission on - resource [name][google.spanner.admin.instance.v1.Instance.name]. - """ + as requested. The returned [long-running + operation][google.longrunning.Operation] can be used to track the + progress of updating the instance. If the named instance does not + exist, returns `NOT_FOUND`. + + Immediately upon completion of this request: + + * For resource types for which a decrease in the instance's allocation + has been requested, billing is based on the newly-requested level. + + Until completion of the returned operation: + + * Cancelling the operation sets its metadata's + [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceMetadata.cancel_time], and begins + restoring resources to their pre-request values. The operation + is guaranteed to succeed at undoing all resource changes, + after which point it terminates with a `CANCELLED` status. + * All other attempts to modify the instance are rejected. + * Reading the instance via the API continues to give the pre-request + resource levels. + + Upon completion of the returned operation: + + * Billing begins for all successfully-allocated resources (some types + may have lower than the requested levels). + * All newly-reserved resources are available for serving the instance's + tables. + * The instance's new resource levels are readable via the API. + + The returned [long-running operation][google.longrunning.Operation] will + have a name of the format `/operations/` and + can be used to track the instance modification. The + [metadata][google.longrunning.Operation.metadata] field type is + [UpdateInstanceMetadata][google.spanner.admin.instance.v1.UpdateInstanceMetadata]. + The [response][google.longrunning.Operation.response] field type is + [Instance][google.spanner.admin.instance.v1.Instance], if successful. + + Authorization requires `spanner.instances.update` permission on + resource [name][google.spanner.admin.instance.v1.Instance.name]. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") @@ -235,38 +236,38 @@ def UpdateInstance(self, request, context): def DeleteInstance(self, request, context): """Deletes an instance. - Immediately upon completion of the request: + Immediately upon completion of the request: - * Billing ceases for all of the instance's reserved resources. + * Billing ceases for all of the instance's reserved resources. - Soon afterward: + Soon afterward: - * The instance and *all of its databases* immediately and - irrevocably disappear from the API. All data in the databases - is permanently deleted. - """ + * The instance and *all of its databases* immediately and + irrevocably disappear from the API. All data in the databases + is permanently deleted. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def SetIamPolicy(self, request, context): """Sets the access control policy on an instance resource. Replaces any - existing policy. + existing policy. - Authorization requires `spanner.instances.setIamPolicy` on - [resource][google.iam.v1.SetIamPolicyRequest.resource]. - """ + Authorization requires `spanner.instances.setIamPolicy` on + [resource][google.iam.v1.SetIamPolicyRequest.resource]. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetIamPolicy(self, request, context): """Gets the access control policy for an instance resource. Returns an empty - policy if an instance exists but does not have a policy set. + policy if an instance exists but does not have a policy set. - Authorization requires `spanner.instances.getIamPolicy` on - [resource][google.iam.v1.GetIamPolicyRequest.resource]. - """ + Authorization requires `spanner.instances.getIamPolicy` on + [resource][google.iam.v1.GetIamPolicyRequest.resource]. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") @@ -274,11 +275,11 @@ def GetIamPolicy(self, request, context): def TestIamPermissions(self, request, context): """Returns permissions that the caller has on the specified instance resource. - Attempting this RPC on a non-existent Cloud Spanner instance resource will - result in a NOT_FOUND error if the user has `spanner.instances.list` - permission on the containing Google Cloud Project. Otherwise returns an - empty set of permissions. - """ + Attempting this RPC on a non-existent Cloud Spanner instance resource will + result in a NOT_FOUND error if the user has `spanner.instances.list` + permission on the containing Google Cloud Project. Otherwise returns an + empty set of permissions. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") @@ -341,3 +342,299 @@ def add_InstanceAdminServicer_to_server(servicer, server): "google.spanner.admin.instance.v1.InstanceAdmin", rpc_method_handlers ) server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class InstanceAdmin(object): + """Cloud Spanner Instance Admin API + + The Cloud Spanner Instance Admin API can be used to create, delete, + modify and list instances. Instances are dedicated Cloud Spanner serving + and storage resources to be used by Cloud Spanner databases. + + Each instance has a "configuration", which dictates where the + serving resources for the Cloud Spanner instance are located (e.g., + US-central, Europe). Configurations are created by Google based on + resource availability. + + Cloud Spanner billing is based on the instances that exist and their + sizes. After an instance exists, there are no additional + per-database or per-operation charges for use of the instance + (though there may be additional network bandwidth charges). + Instances offer isolation: problems with databases in one instance + will not affect other instances. However, within an instance + databases can affect each other. For example, if one database in an + instance receives a lot of requests and consumes most of the + instance resources, fewer resources are available for other + databases in that instance, and their performance may suffer. + """ + + @staticmethod + def ListInstanceConfigs( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/ListInstanceConfigs", + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.ListInstanceConfigsRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.ListInstanceConfigsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetInstanceConfig( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/GetInstanceConfig", + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.GetInstanceConfigRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.InstanceConfig.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListInstances( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/ListInstances", + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.ListInstancesRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.ListInstancesResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetInstance( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/GetInstance", + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.GetInstanceRequest.SerializeToString, + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.Instance.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def CreateInstance( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/CreateInstance", + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.CreateInstanceRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.Operation.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def UpdateInstance( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/UpdateInstance", + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.UpdateInstanceRequest.SerializeToString, + google_dot_longrunning_dot_operations__pb2.Operation.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DeleteInstance( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/DeleteInstance", + google_dot_cloud_dot_spanner__admin__instance__v1_dot_proto_dot_spanner__instance__admin__pb2.DeleteInstanceRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def SetIamPolicy( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/SetIamPolicy", + google_dot_iam_dot_v1_dot_iam__policy__pb2.SetIamPolicyRequest.SerializeToString, + google_dot_iam_dot_v1_dot_policy__pb2.Policy.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetIamPolicy( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/GetIamPolicy", + google_dot_iam_dot_v1_dot_iam__policy__pb2.GetIamPolicyRequest.SerializeToString, + google_dot_iam_dot_v1_dot_policy__pb2.Policy.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def TestIamPermissions( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.admin.instance.v1.InstanceAdmin/TestIamPermissions", + google_dot_iam_dot_v1_dot_iam__policy__pb2.TestIamPermissionsRequest.SerializeToString, + google_dot_iam_dot_v1_dot_iam__policy__pb2.TestIamPermissionsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/google/cloud/spanner_v1/gapic/enums.py b/google/cloud/spanner_v1/gapic/enums.py index 1372d3c05a..3d4a941849 100644 --- a/google/cloud/spanner_v1/gapic/enums.py +++ b/google/cloud/spanner_v1/gapic/enums.py @@ -65,6 +65,14 @@ class TypeCode(enum.IntEnum): STRUCT (int): Encoded as ``list``, where list element ``i`` is represented according to [struct_type.fields[i]][google.spanner.v1.StructType.fields]. + NUMERIC (int): Encoded as ``string``, in decimal format or scientific notation + format. Decimal format: \ ``[+-]Digits[.[Digits]]`` or + \``+-\ ``.Digits`` + + Scientific notation: + \ ``[+-]Digits[.[Digits]][ExponentIndicator[+-]Digits]`` or + \``+-\ ``.Digits[ExponentIndicator[+-]Digits]`` (ExponentIndicator is + \`"e"\` or \`"E"`) """ TYPE_CODE_UNSPECIFIED = 0 @@ -77,6 +85,7 @@ class TypeCode(enum.IntEnum): BYTES = 7 ARRAY = 8 STRUCT = 9 + NUMERIC = 10 class ExecuteSqlRequest(object): diff --git a/google/cloud/spanner_v1/gapic/spanner_client_config.py b/google/cloud/spanner_v1/gapic/spanner_client_config.py index 44b81c5fb9..458ea6d731 100644 --- a/google/cloud/spanner_v1/gapic/spanner_client_config.py +++ b/google/cloud/spanner_v1/gapic/spanner_client_config.py @@ -2,12 +2,14 @@ "interfaces": { "google.spanner.v1.Spanner": { "retry_codes": { - "idempotent": ["UNAVAILABLE"], - "non_idempotent": [], - "long_running": ["UNAVAILABLE"], + "retry_policy_1_codes": ["UNAVAILABLE"], + "no_retry_codes": [], + "retry_policy_3_codes": ["UNAVAILABLE"], + "retry_policy_2_codes": ["UNAVAILABLE"], + "no_retry_1_codes": [], }, "retry_params": { - "default": { + "retry_policy_1_params": { "initial_retry_delay_millis": 250, "retry_delay_multiplier": 1.3, "max_retry_delay_millis": 32000, @@ -16,19 +18,37 @@ "max_rpc_timeout_millis": 3600000, "total_timeout_millis": 3600000, }, - "streaming": { + "retry_policy_3_params": { "initial_retry_delay_millis": 250, "retry_delay_multiplier": 1.3, "max_retry_delay_millis": 32000, - "initial_rpc_timeout_millis": 3600000, + "initial_rpc_timeout_millis": 30000, "rpc_timeout_multiplier": 1.0, - "max_rpc_timeout_millis": 3600000, - "total_timeout_millis": 3600000, + "max_rpc_timeout_millis": 30000, + "total_timeout_millis": 30000, }, - "long_running": { + "retry_policy_2_params": { "initial_retry_delay_millis": 250, "retry_delay_multiplier": 1.3, "max_retry_delay_millis": 32000, + "initial_rpc_timeout_millis": 60000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 60000, + "total_timeout_millis": 60000, + }, + "no_retry_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, + "initial_rpc_timeout_millis": 0, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 0, + "total_timeout_millis": 0, + }, + "no_retry_1_params": { + "initial_retry_delay_millis": 0, + "retry_delay_multiplier": 0.0, + "max_retry_delay_millis": 0, "initial_rpc_timeout_millis": 3600000, "rpc_timeout_multiplier": 1.0, "max_rpc_timeout_millis": 3600000, @@ -38,78 +58,78 @@ "methods": { "CreateSession": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "BatchCreateSessions": { "timeout_millis": 60000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_2_codes", + "retry_params_name": "retry_policy_2_params", }, "GetSession": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "ListSessions": { "timeout_millis": 3600000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "DeleteSession": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "ExecuteSql": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "ExecuteStreamingSql": { "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "streaming", + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", }, "ExecuteBatchDml": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "Read": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "StreamingRead": { "timeout_millis": 3600000, - "retry_codes_name": "non_idempotent", - "retry_params_name": "streaming", + "retry_codes_name": "no_retry_1_codes", + "retry_params_name": "no_retry_1_params", }, "BeginTransaction": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "Commit": { "timeout_millis": 3600000, - "retry_codes_name": "long_running", - "retry_params_name": "long_running", + "retry_codes_name": "retry_policy_1_codes", + "retry_params_name": "retry_policy_1_params", }, "Rollback": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "PartitionQuery": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, "PartitionRead": { "timeout_millis": 30000, - "retry_codes_name": "idempotent", - "retry_params_name": "default", + "retry_codes_name": "retry_policy_3_codes", + "retry_params_name": "retry_policy_3_params", }, }, } diff --git a/google/cloud/spanner_v1/proto/keys_pb2.py b/google/cloud/spanner_v1/proto/keys_pb2.py index 0f0dba9787..8481775d4b 100644 --- a/google/cloud/spanner_v1/proto/keys_pb2.py +++ b/google/cloud/spanner_v1/proto/keys_pb2.py @@ -347,7 +347,7 @@ { "DESCRIPTOR": _KEYSET, "__module__": "google.cloud.spanner_v1.proto.keys_pb2", - "__doc__": """\ ``KeySet`` defines a collection of Cloud Spanner keys and/or key + "__doc__": """``KeySet`` defines a collection of Cloud Spanner keys and/or key ranges. All the keys are expected to be in the same table or index. The keys need not be sorted in any particular way. If the same key is specified multiple times in the set (for example if two ranges, two diff --git a/google/cloud/spanner_v1/proto/keys_pb2_grpc.py b/google/cloud/spanner_v1/proto/keys_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_v1/proto/keys_pb2_grpc.py +++ b/google/cloud/spanner_v1/proto/keys_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/google/cloud/spanner_v1/proto/mutation_pb2_grpc.py b/google/cloud/spanner_v1/proto/mutation_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_v1/proto/mutation_pb2_grpc.py +++ b/google/cloud/spanner_v1/proto/mutation_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/google/cloud/spanner_v1/proto/query_plan_pb2_grpc.py b/google/cloud/spanner_v1/proto/query_plan_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_v1/proto/query_plan_pb2_grpc.py +++ b/google/cloud/spanner_v1/proto/query_plan_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/google/cloud/spanner_v1/proto/result_set_pb2_grpc.py b/google/cloud/spanner_v1/proto/result_set_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_v1/proto/result_set_pb2_grpc.py +++ b/google/cloud/spanner_v1/proto/result_set_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/google/cloud/spanner_v1/proto/spanner_pb2.py b/google/cloud/spanner_v1/proto/spanner_pb2.py index 3ca2e3ba7f..a48a12ca59 100644 --- a/google/cloud/spanner_v1/proto/spanner_pb2.py +++ b/google/cloud/spanner_v1/proto/spanner_pb2.py @@ -2994,10 +2994,10 @@ [table][google.spanner.v1.PartitionReadRequest.table]. This index is used instead of the table primary key when interpreting - [key\_set][google.spanner.v1.PartitionReadRequest.key\_set] - and sorting result rows. See - [key\_set][google.spanner.v1.PartitionReadRequest.key\_set] - for further information. + [key_set][google.spanner.v1.PartitionReadRequest.key_set] and + sorting result rows. See + [key_set][google.spanner.v1.PartitionReadRequest.key_set] for + further information. columns: The columns of [table][google.spanner.v1.PartitionReadRequest.table] to be @@ -3011,7 +3011,7 @@ present. If [index][google.spanner.v1.PartitionReadRequest.index] is present, then - [key\_set][google.spanner.v1.PartitionReadRequest.key\_set] + [key_set][google.spanner.v1.PartitionReadRequest.key_set] instead names index keys in [index][google.spanner.v1.PartitionReadRequest.index]. It is not an error for the ``key_set`` to name rows that do not @@ -3133,7 +3133,7 @@ partition previously created using PartitionRead(). There must be an exact match for the values of fields common to this message and the PartitionReadRequest message used to create - this partition\_token. + this partition_token. """, # @@protoc_insertion_point(class_scope:google.spanner.v1.ReadRequest) }, diff --git a/google/cloud/spanner_v1/proto/spanner_pb2_grpc.py b/google/cloud/spanner_v1/proto/spanner_pb2_grpc.py index 1ac098d328..f7591434a9 100644 --- a/google/cloud/spanner_v1/proto/spanner_pb2_grpc.py +++ b/google/cloud/spanner_v1/proto/spanner_pb2_grpc.py @@ -1,4 +1,5 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc from google.cloud.spanner_v1.proto import ( @@ -16,16 +17,16 @@ class SpannerStub(object): """Cloud Spanner API - The Cloud Spanner API can be used to manage sessions and execute - transactions on data stored in Cloud Spanner databases. - """ + The Cloud Spanner API can be used to manage sessions and execute + transactions on data stored in Cloud Spanner databases. + """ def __init__(self, channel): """Constructor. - Args: - channel: A grpc.Channel. - """ + Args: + channel: A grpc.Channel. + """ self.CreateSession = channel.unary_unary( "/google.spanner.v1.Spanner/CreateSession", request_serializer=google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.CreateSessionRequest.SerializeToString, @@ -106,31 +107,31 @@ def __init__(self, channel): class SpannerServicer(object): """Cloud Spanner API - The Cloud Spanner API can be used to manage sessions and execute - transactions on data stored in Cloud Spanner databases. - """ + The Cloud Spanner API can be used to manage sessions and execute + transactions on data stored in Cloud Spanner databases. + """ def CreateSession(self, request, context): """Creates a new session. A session can be used to perform - transactions that read and/or modify data in a Cloud Spanner database. - Sessions are meant to be reused for many consecutive - transactions. - - Sessions can only execute one transaction at a time. To execute - multiple concurrent read-write/write-only transactions, create - multiple sessions. Note that standalone reads and queries use a - transaction internally, and count toward the one transaction - limit. - - Active sessions use additional server resources, so it is a good idea to - delete idle and unneeded sessions. - Aside from explicit deletes, Cloud Spanner may delete sessions for which no - operations are sent for more than an hour. If a session is deleted, - requests to it return `NOT_FOUND`. - - Idle sessions can be kept alive by sending a trivial SQL query - periodically, e.g., `"SELECT 1"`. - """ + transactions that read and/or modify data in a Cloud Spanner database. + Sessions are meant to be reused for many consecutive + transactions. + + Sessions can only execute one transaction at a time. To execute + multiple concurrent read-write/write-only transactions, create + multiple sessions. Note that standalone reads and queries use a + transaction internally, and count toward the one transaction + limit. + + Active sessions use additional server resources, so it is a good idea to + delete idle and unneeded sessions. + Aside from explicit deletes, Cloud Spanner may delete sessions for which no + operations are sent for more than an hour. If a session is deleted, + requests to it return `NOT_FOUND`. + + Idle sessions can be kept alive by sending a trivial SQL query + periodically, e.g., `"SELECT 1"`. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") @@ -138,183 +139,183 @@ def CreateSession(self, request, context): def BatchCreateSessions(self, request, context): """Creates multiple new sessions. - This API can be used to initialize a session cache on the clients. - See https://goo.gl/TgSFN2 for best practices on session cache management. - """ + This API can be used to initialize a session cache on the clients. + See https://goo.gl/TgSFN2 for best practices on session cache management. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def GetSession(self, request, context): """Gets a session. Returns `NOT_FOUND` if the session does not exist. - This is mainly useful for determining whether a session is still - alive. - """ + This is mainly useful for determining whether a session is still + alive. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ListSessions(self, request, context): """Lists all sessions in a given database. - """ + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def DeleteSession(self, request, context): """Ends a session, releasing server resources associated with it. This will - asynchronously trigger cancellation of any operations that are running with - this session. - """ + asynchronously trigger cancellation of any operations that are running with + this session. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ExecuteSql(self, request, context): """Executes an SQL statement, returning all results in a single reply. This - method cannot be used to return a result set larger than 10 MiB; - if the query yields more data than that, the query fails with - a `FAILED_PRECONDITION` error. + method cannot be used to return a result set larger than 10 MiB; + if the query yields more data than that, the query fails with + a `FAILED_PRECONDITION` error. - Operations inside read-write transactions might return `ABORTED`. If - this occurs, the application should restart the transaction from - the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. + Operations inside read-write transactions might return `ABORTED`. If + this occurs, the application should restart the transaction from + the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. - Larger result sets can be fetched in streaming fashion by calling - [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] instead. - """ + Larger result sets can be fetched in streaming fashion by calling + [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] instead. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ExecuteStreamingSql(self, request, context): """Like [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], except returns the result - set as a stream. Unlike [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], there - is no limit on the size of the returned result set. However, no - individual row in the result set can exceed 100 MiB, and no - column value can exceed 10 MiB. - """ + set as a stream. Unlike [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], there + is no limit on the size of the returned result set. However, no + individual row in the result set can exceed 100 MiB, and no + column value can exceed 10 MiB. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def ExecuteBatchDml(self, request, context): """Executes a batch of SQL DML statements. This method allows many statements - to be run with lower latency than submitting them sequentially with - [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. + to be run with lower latency than submitting them sequentially with + [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. - Statements are executed in sequential order. A request can succeed even if - a statement fails. The [ExecuteBatchDmlResponse.status][google.spanner.v1.ExecuteBatchDmlResponse.status] field in the - response provides information about the statement that failed. Clients must - inspect this field to determine whether an error occurred. + Statements are executed in sequential order. A request can succeed even if + a statement fails. The [ExecuteBatchDmlResponse.status][google.spanner.v1.ExecuteBatchDmlResponse.status] field in the + response provides information about the statement that failed. Clients must + inspect this field to determine whether an error occurred. - Execution stops after the first failed statement; the remaining statements - are not executed. - """ + Execution stops after the first failed statement; the remaining statements + are not executed. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def Read(self, request, context): """Reads rows from the database using key lookups and scans, as a - simple key/value style alternative to - [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. This method cannot be used to - return a result set larger than 10 MiB; if the read matches more - data than that, the read fails with a `FAILED_PRECONDITION` - error. - - Reads inside read-write transactions might return `ABORTED`. If - this occurs, the application should restart the transaction from - the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. - - Larger result sets can be yielded in streaming fashion by calling - [StreamingRead][google.spanner.v1.Spanner.StreamingRead] instead. - """ + simple key/value style alternative to + [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. This method cannot be used to + return a result set larger than 10 MiB; if the read matches more + data than that, the read fails with a `FAILED_PRECONDITION` + error. + + Reads inside read-write transactions might return `ABORTED`. If + this occurs, the application should restart the transaction from + the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. + + Larger result sets can be yielded in streaming fashion by calling + [StreamingRead][google.spanner.v1.Spanner.StreamingRead] instead. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def StreamingRead(self, request, context): """Like [Read][google.spanner.v1.Spanner.Read], except returns the result set as a - stream. Unlike [Read][google.spanner.v1.Spanner.Read], there is no limit on the - size of the returned result set. However, no individual row in - the result set can exceed 100 MiB, and no column value can exceed - 10 MiB. - """ + stream. Unlike [Read][google.spanner.v1.Spanner.Read], there is no limit on the + size of the returned result set. However, no individual row in + the result set can exceed 100 MiB, and no column value can exceed + 10 MiB. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def BeginTransaction(self, request, context): """Begins a new transaction. This step can often be skipped: - [Read][google.spanner.v1.Spanner.Read], [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and - [Commit][google.spanner.v1.Spanner.Commit] can begin a new transaction as a - side-effect. - """ + [Read][google.spanner.v1.Spanner.Read], [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and + [Commit][google.spanner.v1.Spanner.Commit] can begin a new transaction as a + side-effect. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def Commit(self, request, context): """Commits a transaction. The request includes the mutations to be - applied to rows in the database. - - `Commit` might return an `ABORTED` error. This can occur at any time; - commonly, the cause is conflicts with concurrent - transactions. However, it can also happen for a variety of other - reasons. If `Commit` returns `ABORTED`, the caller should re-attempt - the transaction from the beginning, re-using the same session. - """ + applied to rows in the database. + + `Commit` might return an `ABORTED` error. This can occur at any time; + commonly, the cause is conflicts with concurrent + transactions. However, it can also happen for a variety of other + reasons. If `Commit` returns `ABORTED`, the caller should re-attempt + the transaction from the beginning, re-using the same session. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def Rollback(self, request, context): """Rolls back a transaction, releasing any locks it holds. It is a good - idea to call this for any transaction that includes one or more - [Read][google.spanner.v1.Spanner.Read] or [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] requests and - ultimately decides not to commit. - - `Rollback` returns `OK` if it successfully aborts the transaction, the - transaction was already aborted, or the transaction is not - found. `Rollback` never returns `ABORTED`. - """ + idea to call this for any transaction that includes one or more + [Read][google.spanner.v1.Spanner.Read] or [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] requests and + ultimately decides not to commit. + + `Rollback` returns `OK` if it successfully aborts the transaction, the + transaction was already aborted, or the transaction is not + found. `Rollback` never returns `ABORTED`. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def PartitionQuery(self, request, context): """Creates a set of partition tokens that can be used to execute a query - operation in parallel. Each of the returned partition tokens can be used - by [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] to specify a subset - of the query result to read. The same session and read-only transaction - must be used by the PartitionQueryRequest used to create the - partition tokens and the ExecuteSqlRequests that use the partition tokens. - - Partition tokens become invalid when the session used to create them - is deleted, is idle for too long, begins a new transaction, or becomes too - old. When any of these happen, it is not possible to resume the query, and - the whole operation must be restarted from the beginning. - """ + operation in parallel. Each of the returned partition tokens can be used + by [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] to specify a subset + of the query result to read. The same session and read-only transaction + must be used by the PartitionQueryRequest used to create the + partition tokens and the ExecuteSqlRequests that use the partition tokens. + + Partition tokens become invalid when the session used to create them + is deleted, is idle for too long, begins a new transaction, or becomes too + old. When any of these happen, it is not possible to resume the query, and + the whole operation must be restarted from the beginning. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") def PartitionRead(self, request, context): """Creates a set of partition tokens that can be used to execute a read - operation in parallel. Each of the returned partition tokens can be used - by [StreamingRead][google.spanner.v1.Spanner.StreamingRead] to specify a subset of the read - result to read. The same session and read-only transaction must be used by - the PartitionReadRequest used to create the partition tokens and the - ReadRequests that use the partition tokens. There are no ordering - guarantees on rows returned among the returned partition tokens, or even - within each individual StreamingRead call issued with a partition_token. - - Partition tokens become invalid when the session used to create them - is deleted, is idle for too long, begins a new transaction, or becomes too - old. When any of these happen, it is not possible to resume the read, and - the whole operation must be restarted from the beginning. - """ + operation in parallel. Each of the returned partition tokens can be used + by [StreamingRead][google.spanner.v1.Spanner.StreamingRead] to specify a subset of the read + result to read. The same session and read-only transaction must be used by + the PartitionReadRequest used to create the partition tokens and the + ReadRequests that use the partition tokens. There are no ordering + guarantees on rows returned among the returned partition tokens, or even + within each individual StreamingRead call issued with a partition_token. + + Partition tokens become invalid when the session used to create them + is deleted, is idle for too long, begins a new transaction, or becomes too + old. When any of these happen, it is not possible to resume the read, and + the whole operation must be restarted from the beginning. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details("Method not implemented!") raise NotImplementedError("Method not implemented!") @@ -402,3 +403,417 @@ def add_SpannerServicer_to_server(servicer, server): "google.spanner.v1.Spanner", rpc_method_handlers ) server.add_generic_rpc_handlers((generic_handler,)) + + +# This class is part of an EXPERIMENTAL API. +class Spanner(object): + """Cloud Spanner API + + The Cloud Spanner API can be used to manage sessions and execute + transactions on data stored in Cloud Spanner databases. + """ + + @staticmethod + def CreateSession( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/CreateSession", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.CreateSessionRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.Session.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def BatchCreateSessions( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/BatchCreateSessions", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.BatchCreateSessionsRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.BatchCreateSessionsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def GetSession( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/GetSession", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.GetSessionRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.Session.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ListSessions( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/ListSessions", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ListSessionsRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ListSessionsResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def DeleteSession( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/DeleteSession", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.DeleteSessionRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ExecuteSql( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/ExecuteSql", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ExecuteSqlRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_result__set__pb2.ResultSet.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ExecuteStreamingSql( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_stream( + request, + target, + "/google.spanner.v1.Spanner/ExecuteStreamingSql", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ExecuteSqlRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_result__set__pb2.PartialResultSet.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def ExecuteBatchDml( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/ExecuteBatchDml", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ExecuteBatchDmlRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ExecuteBatchDmlResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Read( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/Read", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ReadRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_result__set__pb2.ResultSet.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def StreamingRead( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_stream( + request, + target, + "/google.spanner.v1.Spanner/StreamingRead", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.ReadRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_result__set__pb2.PartialResultSet.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def BeginTransaction( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/BeginTransaction", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.BeginTransactionRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_transaction__pb2.Transaction.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Commit( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/Commit", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.CommitRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.CommitResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def Rollback( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/Rollback", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.RollbackRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def PartitionQuery( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/PartitionQuery", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.PartitionQueryRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.PartitionResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) + + @staticmethod + def PartitionRead( + request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None, + ): + return grpc.experimental.unary_unary( + request, + target, + "/google.spanner.v1.Spanner/PartitionRead", + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.PartitionReadRequest.SerializeToString, + google_dot_cloud_dot_spanner__v1_dot_proto_dot_spanner__pb2.PartitionResponse.FromString, + options, + channel_credentials, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + ) diff --git a/google/cloud/spanner_v1/proto/transaction_pb2_grpc.py b/google/cloud/spanner_v1/proto/transaction_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_v1/proto/transaction_pb2_grpc.py +++ b/google/cloud/spanner_v1/proto/transaction_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/google/cloud/spanner_v1/proto/type.proto b/google/cloud/spanner_v1/proto/type.proto index eebed5a49b..1e5e5ff313 100644 --- a/google/cloud/spanner_v1/proto/type.proto +++ b/google/cloud/spanner_v1/proto/type.proto @@ -16,6 +16,7 @@ syntax = "proto3"; package google.spanner.v1; +import "google/api/field_behavior.proto"; import "google/api/annotations.proto"; option csharp_namespace = "Google.Cloud.Spanner.V1"; @@ -26,6 +27,47 @@ option java_package = "com.google.spanner.v1"; option php_namespace = "Google\\Cloud\\Spanner\\V1"; option ruby_package = "Google::Cloud::Spanner::V1"; +// `Type` indicates the type of a Cloud Spanner value, as might be stored in a +// table cell or returned from an SQL query. +message Type { + // Required. The [TypeCode][google.spanner.v1.TypeCode] for this type. + TypeCode code = 1 [(google.api.field_behavior) = REQUIRED]; + + // If [code][google.spanner.v1.Type.code] == [ARRAY][google.spanner.v1.TypeCode.ARRAY], then `array_element_type` + // is the type of the array elements. + Type array_element_type = 2; + + // If [code][google.spanner.v1.Type.code] == [STRUCT][google.spanner.v1.TypeCode.STRUCT], then `struct_type` + // provides type information for the struct's fields. + StructType struct_type = 3; +} + +// `StructType` defines the fields of a [STRUCT][google.spanner.v1.TypeCode.STRUCT] type. +message StructType { + // Message representing a single field of a struct. + message Field { + // The name of the field. For reads, this is the column name. For + // SQL queries, it is the column alias (e.g., `"Word"` in the + // query `"SELECT 'hello' AS Word"`), or the column name (e.g., + // `"ColName"` in the query `"SELECT ColName FROM Table"`). Some + // columns might have an empty name (e.g., !"SELECT + // UPPER(ColName)"`). Note that a query result can contain + // multiple fields with the same name. + string name = 1; + + // The type of the field. + Type type = 2; + } + + // The list of fields that make up this struct. Order is + // significant, because values of this struct type are represented as + // lists, where the order of field values matches the order of + // fields in the [StructType][google.spanner.v1.StructType]. In turn, the order of fields + // matches the order of columns in a read request, or the order of + // fields in the `SELECT` clause of a query. + repeated Field fields = 1; +} + // `TypeCode` is used as part of [Type][google.spanner.v1.Type] to // indicate the type of a Cloud Spanner value. // @@ -75,45 +117,15 @@ enum TypeCode { // Encoded as `list`, where list element `i` is represented according // to [struct_type.fields[i]][google.spanner.v1.StructType.fields]. STRUCT = 9; -} - -// `Type` indicates the type of a Cloud Spanner value, as might be stored in a -// table cell or returned from an SQL query. -message Type { - // Required. The [TypeCode][google.spanner.v1.TypeCode] for this type. - TypeCode code = 1; - - // If [code][google.spanner.v1.Type.code] == [ARRAY][google.spanner.v1.TypeCode.ARRAY], then `array_element_type` - // is the type of the array elements. - Type array_element_type = 2; - - // If [code][google.spanner.v1.Type.code] == [STRUCT][google.spanner.v1.TypeCode.STRUCT], then `struct_type` - // provides type information for the struct's fields. - StructType struct_type = 3; -} - -// `StructType` defines the fields of a [STRUCT][google.spanner.v1.TypeCode.STRUCT] type. -message StructType { - // Message representing a single field of a struct. - message Field { - // The name of the field. For reads, this is the column name. For - // SQL queries, it is the column alias (e.g., `"Word"` in the - // query `"SELECT 'hello' AS Word"`), or the column name (e.g., - // `"ColName"` in the query `"SELECT ColName FROM Table"`). Some - // columns might have an empty name (e.g., !"SELECT - // UPPER(ColName)"`). Note that a query result can contain - // multiple fields with the same name. - string name = 1; - - // The type of the field. - Type type = 2; - } - // The list of fields that make up this struct. Order is - // significant, because values of this struct type are represented as - // lists, where the order of field values matches the order of - // fields in the [StructType][google.spanner.v1.StructType]. In turn, the order of fields - // matches the order of columns in a read request, or the order of - // fields in the `SELECT` clause of a query. - repeated Field fields = 1; + // Encoded as `string`, in decimal format or scientific notation format. + //
Decimal format: + //
`[+-]Digits[.[Digits]]` or + //
`[+-][Digits].Digits` + // + // Scientific notation: + //
`[+-]Digits[.[Digits]][ExponentIndicator[+-]Digits]` or + //
`[+-][Digits].Digits[ExponentIndicator[+-]Digits]` + //
(ExponentIndicator is `"e"` or `"E"`) + NUMERIC = 10; } diff --git a/google/cloud/spanner_v1/proto/type_pb2.py b/google/cloud/spanner_v1/proto/type_pb2.py index 7664963a70..8e763fd247 100644 --- a/google/cloud/spanner_v1/proto/type_pb2.py +++ b/google/cloud/spanner_v1/proto/type_pb2.py @@ -13,6 +13,7 @@ _sym_db = _symbol_database.Default() +from google.api import field_behavior_pb2 as google_dot_api_dot_field__behavior__pb2 from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 @@ -22,8 +23,11 @@ syntax="proto3", serialized_options=b"\n\025com.google.spanner.v1B\tTypeProtoP\001Z8google.golang.org/genproto/googleapis/spanner/v1;spanner\252\002\027Google.Cloud.Spanner.V1\312\002\027Google\\Cloud\\Spanner\\V1\352\002\032Google::Cloud::Spanner::V1", create_key=_descriptor._internal_create_key, - serialized_pb=b'\n(google/cloud/spanner_v1/proto/type.proto\x12\x11google.spanner.v1\x1a\x1cgoogle/api/annotations.proto"\x9a\x01\n\x04Type\x12)\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x1b.google.spanner.v1.TypeCode\x12\x33\n\x12\x61rray_element_type\x18\x02 \x01(\x0b\x32\x17.google.spanner.v1.Type\x12\x32\n\x0bstruct_type\x18\x03 \x01(\x0b\x32\x1d.google.spanner.v1.StructType"\x7f\n\nStructType\x12\x33\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.spanner.v1.StructType.Field\x1a<\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x04type\x18\x02 \x01(\x0b\x32\x17.google.spanner.v1.Type*\x8e\x01\n\x08TypeCode\x12\x19\n\x15TYPE_CODE_UNSPECIFIED\x10\x00\x12\x08\n\x04\x42OOL\x10\x01\x12\t\n\x05INT64\x10\x02\x12\x0b\n\x07\x46LOAT64\x10\x03\x12\r\n\tTIMESTAMP\x10\x04\x12\x08\n\x04\x44\x41TE\x10\x05\x12\n\n\x06STRING\x10\x06\x12\t\n\x05\x42YTES\x10\x07\x12\t\n\x05\x41RRAY\x10\x08\x12\n\n\x06STRUCT\x10\tB\xaf\x01\n\x15\x63om.google.spanner.v1B\tTypeProtoP\x01Z8google.golang.org/genproto/googleapis/spanner/v1;spanner\xaa\x02\x17Google.Cloud.Spanner.V1\xca\x02\x17Google\\Cloud\\Spanner\\V1\xea\x02\x1aGoogle::Cloud::Spanner::V1b\x06proto3', - dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR], + serialized_pb=b'\n(google/cloud/spanner_v1/proto/type.proto\x12\x11google.spanner.v1\x1a\x1fgoogle/api/field_behavior.proto\x1a\x1cgoogle/api/annotations.proto"\x9f\x01\n\x04Type\x12.\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x1b.google.spanner.v1.TypeCodeB\x03\xe0\x41\x02\x12\x33\n\x12\x61rray_element_type\x18\x02 \x01(\x0b\x32\x17.google.spanner.v1.Type\x12\x32\n\x0bstruct_type\x18\x03 \x01(\x0b\x32\x1d.google.spanner.v1.StructType"\x7f\n\nStructType\x12\x33\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.spanner.v1.StructType.Field\x1a<\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\x04type\x18\x02 \x01(\x0b\x32\x17.google.spanner.v1.Type*\x9b\x01\n\x08TypeCode\x12\x19\n\x15TYPE_CODE_UNSPECIFIED\x10\x00\x12\x08\n\x04\x42OOL\x10\x01\x12\t\n\x05INT64\x10\x02\x12\x0b\n\x07\x46LOAT64\x10\x03\x12\r\n\tTIMESTAMP\x10\x04\x12\x08\n\x04\x44\x41TE\x10\x05\x12\n\n\x06STRING\x10\x06\x12\t\n\x05\x42YTES\x10\x07\x12\t\n\x05\x41RRAY\x10\x08\x12\n\n\x06STRUCT\x10\t\x12\x0b\n\x07NUMERIC\x10\nB\xaf\x01\n\x15\x63om.google.spanner.v1B\tTypeProtoP\x01Z8google.golang.org/genproto/googleapis/spanner/v1;spanner\xaa\x02\x17Google.Cloud.Spanner.V1\xca\x02\x17Google\\Cloud\\Spanner\\V1\xea\x02\x1aGoogle::Cloud::Spanner::V1b\x06proto3', + dependencies=[ + google_dot_api_dot_field__behavior__pb2.DESCRIPTOR, + google_dot_api_dot_annotations__pb2.DESCRIPTOR, + ], ) _TYPECODE = _descriptor.EnumDescriptor( @@ -113,11 +117,19 @@ type=None, create_key=_descriptor._internal_create_key, ), + _descriptor.EnumValueDescriptor( + name="NUMERIC", + index=10, + number=10, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key, + ), ], containing_type=None, serialized_options=None, - serialized_start=380, - serialized_end=522, + serialized_start=418, + serialized_end=573, ) _sym_db.RegisterEnumDescriptor(_TYPECODE) @@ -132,6 +144,7 @@ BYTES = 7 ARRAY = 8 STRUCT = 9 +NUMERIC = 10 _TYPE = _descriptor.Descriptor( @@ -157,7 +170,7 @@ containing_type=None, is_extension=False, extension_scope=None, - serialized_options=None, + serialized_options=b"\340A\002", file=DESCRIPTOR, create_key=_descriptor._internal_create_key, ), @@ -208,8 +221,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=94, - serialized_end=248, + serialized_start=127, + serialized_end=286, ) @@ -268,8 +281,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=317, - serialized_end=377, + serialized_start=355, + serialized_end=415, ) _STRUCTTYPE = _descriptor.Descriptor( @@ -308,8 +321,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=250, - serialized_end=377, + serialized_start=288, + serialized_end=415, ) _TYPE.fields_by_name["code"].enum_type = _TYPECODE @@ -401,4 +414,5 @@ DESCRIPTOR._options = None +_TYPE.fields_by_name["code"]._options = None # @@protoc_insertion_point(module_scope) diff --git a/google/cloud/spanner_v1/proto/type_pb2_grpc.py b/google/cloud/spanner_v1/proto/type_pb2_grpc.py index 07cb78fe03..8a9393943b 100644 --- a/google/cloud/spanner_v1/proto/type_pb2_grpc.py +++ b/google/cloud/spanner_v1/proto/type_pb2_grpc.py @@ -1,2 +1,3 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" import grpc diff --git a/scripts/decrypt-secrets.sh b/scripts/decrypt-secrets.sh new file mode 100755 index 0000000000..ff599eb2af --- /dev/null +++ b/scripts/decrypt-secrets.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Copyright 2015 Google Inc. All rights reserved. +# +# 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. + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT=$( dirname "$DIR" ) + +# Work from the project root. +cd $ROOT + +# Use SECRET_MANAGER_PROJECT if set, fallback to cloud-devrel-kokoro-resources. +PROJECT_ID="${SECRET_MANAGER_PROJECT:-cloud-devrel-kokoro-resources}" + +gcloud secrets versions access latest --secret="python-docs-samples-test-env" \ + > testing/test-env.sh +gcloud secrets versions access latest \ + --secret="python-docs-samples-service-account" \ + > testing/service-account.json +gcloud secrets versions access latest \ + --secret="python-docs-samples-client-secrets" \ + > testing/client-secrets.json \ No newline at end of file diff --git a/scripts/readme-gen/readme_gen.py b/scripts/readme-gen/readme_gen.py new file mode 100644 index 0000000000..d309d6e975 --- /dev/null +++ b/scripts/readme-gen/readme_gen.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +# Copyright 2016 Google Inc +# +# 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. + +"""Generates READMEs using configuration defined in yaml.""" + +import argparse +import io +import os +import subprocess + +import jinja2 +import yaml + + +jinja_env = jinja2.Environment( + trim_blocks=True, + loader=jinja2.FileSystemLoader( + os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates')))) + +README_TMPL = jinja_env.get_template('README.tmpl.rst') + + +def get_help(file): + return subprocess.check_output(['python', file, '--help']).decode() + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('source') + parser.add_argument('--destination', default='README.rst') + + args = parser.parse_args() + + source = os.path.abspath(args.source) + root = os.path.dirname(source) + destination = os.path.join(root, args.destination) + + jinja_env.globals['get_help'] = get_help + + with io.open(source, 'r') as f: + config = yaml.load(f) + + # This allows get_help to execute in the right directory. + os.chdir(root) + + output = README_TMPL.render(config) + + with io.open(destination, 'w') as f: + f.write(output) + + +if __name__ == '__main__': + main() diff --git a/scripts/readme-gen/templates/README.tmpl.rst b/scripts/readme-gen/templates/README.tmpl.rst new file mode 100644 index 0000000000..4fd239765b --- /dev/null +++ b/scripts/readme-gen/templates/README.tmpl.rst @@ -0,0 +1,87 @@ +{# The following line is a lie. BUT! Once jinja2 is done with it, it will + become truth! #} +.. This file is automatically generated. Do not edit this file directly. + +{{product.name}} Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/README.rst + + +This directory contains samples for {{product.name}}. {{product.description}} + +{{description}} + +.. _{{product.name}}: {{product.url}} + +{% if required_api_url %} +To run the sample, you need to enable the API at: {{required_api_url}} +{% endif %} + +{% if required_role %} +To run the sample, you need to have `{{required_role}}` role. +{% endif %} + +{{other_required_steps}} + +{% if setup %} +Setup +------------------------------------------------------------------------------- + +{% for section in setup %} + +{% include section + '.tmpl.rst' %} + +{% endfor %} +{% endif %} + +{% if samples %} +Samples +------------------------------------------------------------------------------- + +{% for sample in samples %} +{{sample.name}} ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +{% if not sample.hide_cloudshell_button %} +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/{{sample.file}},{{folder}}/README.rst +{% endif %} + + +{{sample.description}} + +To run this sample: + +.. code-block:: bash + + $ python {{sample.file}} +{% if sample.show_help %} + + {{get_help(sample.file)|indent}} +{% endif %} + + +{% endfor %} +{% endif %} + +{% if cloud_client_library %} + +The client library +------------------------------------------------------------------------------- + +This sample uses the `Google Cloud Client Library for Python`_. +You can read the documentation for more details on API usage and use GitHub +to `browse the source`_ and `report issues`_. + +.. _Google Cloud Client Library for Python: + https://googlecloudplatform.github.io/google-cloud-python/ +.. _browse the source: + https://github.com/GoogleCloudPlatform/google-cloud-python +.. _report issues: + https://github.com/GoogleCloudPlatform/google-cloud-python/issues + +{% endif %} + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file diff --git a/scripts/readme-gen/templates/auth.tmpl.rst b/scripts/readme-gen/templates/auth.tmpl.rst new file mode 100644 index 0000000000..1446b94a5e --- /dev/null +++ b/scripts/readme-gen/templates/auth.tmpl.rst @@ -0,0 +1,9 @@ +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started diff --git a/scripts/readme-gen/templates/auth_api_key.tmpl.rst b/scripts/readme-gen/templates/auth_api_key.tmpl.rst new file mode 100644 index 0000000000..11957ce271 --- /dev/null +++ b/scripts/readme-gen/templates/auth_api_key.tmpl.rst @@ -0,0 +1,14 @@ +Authentication +++++++++++++++ + +Authentication for this service is done via an `API Key`_. To obtain an API +Key: + +1. Open the `Cloud Platform Console`_ +2. Make sure that billing is enabled for your project. +3. From the **Credentials** page, create a new **API Key** or use an existing + one for your project. + +.. _API Key: + https://developers.google.com/api-client-library/python/guide/aaa_apikeys +.. _Cloud Console: https://console.cloud.google.com/project?_ diff --git a/scripts/readme-gen/templates/install_deps.tmpl.rst b/scripts/readme-gen/templates/install_deps.tmpl.rst new file mode 100644 index 0000000000..a0406dba8c --- /dev/null +++ b/scripts/readme-gen/templates/install_deps.tmpl.rst @@ -0,0 +1,29 @@ +Install Dependencies +++++++++++++++++++++ + +#. Clone python-docs-samples and change directory to the sample directory you want to use. + + .. code-block:: bash + + $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ diff --git a/scripts/readme-gen/templates/install_portaudio.tmpl.rst b/scripts/readme-gen/templates/install_portaudio.tmpl.rst new file mode 100644 index 0000000000..5ea33d18c0 --- /dev/null +++ b/scripts/readme-gen/templates/install_portaudio.tmpl.rst @@ -0,0 +1,35 @@ +Install PortAudio ++++++++++++++++++ + +Install `PortAudio`_. This is required by the `PyAudio`_ library to stream +audio from your computer's microphone. PyAudio depends on PortAudio for cross-platform compatibility, and is installed differently depending on the +platform. + +* For Mac OS X, you can use `Homebrew`_:: + + brew install portaudio + + **Note**: if you encounter an error when running `pip install` that indicates + it can't find `portaudio.h`, try running `pip install` with the following + flags:: + + pip install --global-option='build_ext' \ + --global-option='-I/usr/local/include' \ + --global-option='-L/usr/local/lib' \ + pyaudio + +* For Debian / Ubuntu Linux:: + + apt-get install portaudio19-dev python-all-dev + +* Windows may work without having to install PortAudio explicitly (it will get + installed with PyAudio). + +For more details, see the `PyAudio installation`_ page. + + +.. _PyAudio: https://people.csail.mit.edu/hubert/pyaudio/ +.. _PortAudio: http://www.portaudio.com/ +.. _PyAudio installation: + https://people.csail.mit.edu/hubert/pyaudio/#downloads +.. _Homebrew: http://brew.sh diff --git a/synth.metadata b/synth.metadata index 198e9c4cb0..3618f8cff9 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,8 +3,16 @@ { "git": { "name": ".", - "remote": "git@github.com:larkee/python-spanner.git", - "sha": "33055e577288cbcc848aa9abf43ccd382c9907a9" + "remote": "https://github.com/googleapis/python-spanner.git", + "sha": "edfefc8aa2e74e0366b0f9208896c5637f1a0b11" + } + }, + { + "git": { + "name": "googleapis", + "remote": "https://github.com/googleapis/googleapis.git", + "sha": "3474dc892349674efda09d74b3a574765d996188", + "internalRef": "321098618" } }, { diff --git a/testing/.gitignore b/testing/.gitignore new file mode 100644 index 0000000000..b05fbd6308 --- /dev/null +++ b/testing/.gitignore @@ -0,0 +1,3 @@ +test-env.sh +service-account.json +client-secrets.json \ No newline at end of file diff --git a/tests/unit/gapic/v1/test_database_admin_client_v1.py b/tests/unit/gapic/v1/test_database_admin_client_v1.py index 96eac6d395..baab7eb7ad 100644 --- a/tests/unit/gapic/v1/test_database_admin_client_v1.py +++ b/tests/unit/gapic/v1/test_database_admin_client_v1.py @@ -68,18 +68,18 @@ class CustomException(Exception): class TestDatabaseAdminClient(object): - def test_list_databases(self): + def test_create_database(self): # Setup Expected Response - next_page_token = "" - databases_element = {} - databases = [databases_element] - expected_response = {"next_page_token": next_page_token, "databases": databases} - expected_response = spanner_database_admin_pb2.ListDatabasesResponse( - **expected_response + name = "name3373707" + expected_response = {"name": name} + expected_response = spanner_database_admin_pb2.Database(**expected_response) + operation = operations_pb2.Operation( + name="operations/test_create_database", done=True ) + operation.response.Pack(expected_response) # Mock the API response - channel = ChannelStub(responses=[expected_response]) + channel = ChannelStub(responses=[operation]) patch = mock.patch("google.api_core.grpc_helpers.create_channel") with patch as create_channel: create_channel.return_value = channel @@ -87,41 +87,48 @@ def test_list_databases(self): # Setup Request parent = client.instance_path("[PROJECT]", "[INSTANCE]") + create_statement = "createStatement552974828" - paged_list_response = client.list_databases(parent) - resources = list(paged_list_response) - assert len(resources) == 1 - - assert expected_response.databases[0] == resources[0] + response = client.create_database(parent, create_statement) + result = response.result() + assert expected_response == result assert len(channel.requests) == 1 - expected_request = spanner_database_admin_pb2.ListDatabasesRequest( - parent=parent + expected_request = spanner_database_admin_pb2.CreateDatabaseRequest( + parent=parent, create_statement=create_statement ) actual_request = channel.requests[0][1] assert expected_request == actual_request - def test_list_databases_exception(self): - channel = ChannelStub(responses=[CustomException()]) + def test_create_database_exception(self): + # Setup Response + error = status_pb2.Status() + operation = operations_pb2.Operation( + name="operations/test_create_database_exception", done=True + ) + operation.error.CopyFrom(error) + + # Mock the API response + channel = ChannelStub(responses=[operation]) patch = mock.patch("google.api_core.grpc_helpers.create_channel") with patch as create_channel: create_channel.return_value = channel client = spanner_admin_database_v1.DatabaseAdminClient() - # Setup request + # Setup Request parent = client.instance_path("[PROJECT]", "[INSTANCE]") + create_statement = "createStatement552974828" - paged_list_response = client.list_databases(parent) - with pytest.raises(CustomException): - list(paged_list_response) + response = client.create_database(parent, create_statement) + exception = response.exception() + assert exception.errors[0] == error - def test_create_database(self): + def test_update_database_ddl(self): # Setup Expected Response - name = "name3373707" - expected_response = {"name": name} - expected_response = spanner_database_admin_pb2.Database(**expected_response) + expected_response = {} + expected_response = empty_pb2.Empty(**expected_response) operation = operations_pb2.Operation( - name="operations/test_create_database", done=True + name="operations/test_update_database_ddl", done=True ) operation.response.Pack(expected_response) @@ -133,25 +140,25 @@ def test_create_database(self): client = spanner_admin_database_v1.DatabaseAdminClient() # Setup Request - parent = client.instance_path("[PROJECT]", "[INSTANCE]") - create_statement = "createStatement552974828" + database = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") + statements = [] - response = client.create_database(parent, create_statement) + response = client.update_database_ddl(database, statements) result = response.result() assert expected_response == result assert len(channel.requests) == 1 - expected_request = spanner_database_admin_pb2.CreateDatabaseRequest( - parent=parent, create_statement=create_statement + expected_request = spanner_database_admin_pb2.UpdateDatabaseDdlRequest( + database=database, statements=statements ) actual_request = channel.requests[0][1] assert expected_request == actual_request - def test_create_database_exception(self): + def test_update_database_ddl_exception(self): # Setup Response error = status_pb2.Status() operation = operations_pb2.Operation( - name="operations/test_create_database_exception", done=True + name="operations/test_update_database_ddl_exception", done=True ) operation.error.CopyFrom(error) @@ -163,57 +170,83 @@ def test_create_database_exception(self): client = spanner_admin_database_v1.DatabaseAdminClient() # Setup Request - parent = client.instance_path("[PROJECT]", "[INSTANCE]") - create_statement = "createStatement552974828" + database = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") + statements = [] - response = client.create_database(parent, create_statement) + response = client.update_database_ddl(database, statements) exception = response.exception() assert exception.errors[0] == error - def test_get_database(self): + def test_create_backup(self): # Setup Expected Response - name_2 = "name2-1052831874" - expected_response = {"name": name_2} - expected_response = spanner_database_admin_pb2.Database(**expected_response) + database = "database1789464955" + name = "name3373707" + size_bytes = 1796325715 + expected_response = { + "database": database, + "name": name, + "size_bytes": size_bytes, + } + expected_response = backup_pb2.Backup(**expected_response) + operation = operations_pb2.Operation( + name="operations/test_create_backup", done=True + ) + operation.response.Pack(expected_response) # Mock the API response - channel = ChannelStub(responses=[expected_response]) + channel = ChannelStub(responses=[operation]) patch = mock.patch("google.api_core.grpc_helpers.create_channel") with patch as create_channel: create_channel.return_value = channel client = spanner_admin_database_v1.DatabaseAdminClient() # Setup Request - name = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") + parent = client.instance_path("[PROJECT]", "[INSTANCE]") + backup_id = "backupId1355353272" + backup = {} - response = client.get_database(name) - assert expected_response == response + response = client.create_backup(parent, backup_id, backup) + result = response.result() + assert expected_response == result assert len(channel.requests) == 1 - expected_request = spanner_database_admin_pb2.GetDatabaseRequest(name=name) + expected_request = backup_pb2.CreateBackupRequest( + parent=parent, backup_id=backup_id, backup=backup + ) actual_request = channel.requests[0][1] assert expected_request == actual_request - def test_get_database_exception(self): + def test_create_backup_exception(self): + # Setup Response + error = status_pb2.Status() + operation = operations_pb2.Operation( + name="operations/test_create_backup_exception", done=True + ) + operation.error.CopyFrom(error) + # Mock the API response - channel = ChannelStub(responses=[CustomException()]) + channel = ChannelStub(responses=[operation]) patch = mock.patch("google.api_core.grpc_helpers.create_channel") with patch as create_channel: create_channel.return_value = channel client = spanner_admin_database_v1.DatabaseAdminClient() - # Setup request - name = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") + # Setup Request + parent = client.instance_path("[PROJECT]", "[INSTANCE]") + backup_id = "backupId1355353272" + backup = {} - with pytest.raises(CustomException): - client.get_database(name) + response = client.create_backup(parent, backup_id, backup) + exception = response.exception() + assert exception.errors[0] == error - def test_update_database_ddl(self): + def test_restore_database(self): # Setup Expected Response - expected_response = {} - expected_response = empty_pb2.Empty(**expected_response) + name = "name3373707" + expected_response = {"name": name} + expected_response = spanner_database_admin_pb2.Database(**expected_response) operation = operations_pb2.Operation( - name="operations/test_update_database_ddl", done=True + name="operations/test_restore_database", done=True ) operation.response.Pack(expected_response) @@ -225,25 +258,25 @@ def test_update_database_ddl(self): client = spanner_admin_database_v1.DatabaseAdminClient() # Setup Request - database = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") - statements = [] + parent = client.instance_path("[PROJECT]", "[INSTANCE]") + database_id = "databaseId816491103" - response = client.update_database_ddl(database, statements) + response = client.restore_database(parent, database_id) result = response.result() assert expected_response == result assert len(channel.requests) == 1 - expected_request = spanner_database_admin_pb2.UpdateDatabaseDdlRequest( - database=database, statements=statements + expected_request = spanner_database_admin_pb2.RestoreDatabaseRequest( + parent=parent, database_id=database_id ) actual_request = channel.requests[0][1] assert expected_request == actual_request - def test_update_database_ddl_exception(self): + def test_restore_database_exception(self): # Setup Response error = status_pb2.Status() operation = operations_pb2.Operation( - name="operations/test_update_database_ddl_exception", done=True + name="operations/test_restore_database_exception", done=True ) operation.error.CopyFrom(error) @@ -255,13 +288,98 @@ def test_update_database_ddl_exception(self): client = spanner_admin_database_v1.DatabaseAdminClient() # Setup Request - database = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") - statements = [] + parent = client.instance_path("[PROJECT]", "[INSTANCE]") + database_id = "databaseId816491103" - response = client.update_database_ddl(database, statements) + response = client.restore_database(parent, database_id) exception = response.exception() assert exception.errors[0] == error + def test_list_databases(self): + # Setup Expected Response + next_page_token = "" + databases_element = {} + databases = [databases_element] + expected_response = {"next_page_token": next_page_token, "databases": databases} + expected_response = spanner_database_admin_pb2.ListDatabasesResponse( + **expected_response + ) + + # Mock the API response + channel = ChannelStub(responses=[expected_response]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_database_v1.DatabaseAdminClient() + + # Setup Request + parent = client.instance_path("[PROJECT]", "[INSTANCE]") + + paged_list_response = client.list_databases(parent) + resources = list(paged_list_response) + assert len(resources) == 1 + + assert expected_response.databases[0] == resources[0] + + assert len(channel.requests) == 1 + expected_request = spanner_database_admin_pb2.ListDatabasesRequest( + parent=parent + ) + actual_request = channel.requests[0][1] + assert expected_request == actual_request + + def test_list_databases_exception(self): + channel = ChannelStub(responses=[CustomException()]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_database_v1.DatabaseAdminClient() + + # Setup request + parent = client.instance_path("[PROJECT]", "[INSTANCE]") + + paged_list_response = client.list_databases(parent) + with pytest.raises(CustomException): + list(paged_list_response) + + def test_get_database(self): + # Setup Expected Response + name_2 = "name2-1052831874" + expected_response = {"name": name_2} + expected_response = spanner_database_admin_pb2.Database(**expected_response) + + # Mock the API response + channel = ChannelStub(responses=[expected_response]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_database_v1.DatabaseAdminClient() + + # Setup Request + name = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") + + response = client.get_database(name) + assert expected_response == response + + assert len(channel.requests) == 1 + expected_request = spanner_database_admin_pb2.GetDatabaseRequest(name=name) + actual_request = channel.requests[0][1] + assert expected_request == actual_request + + def test_get_database_exception(self): + # Mock the API response + channel = ChannelStub(responses=[CustomException()]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_database_v1.DatabaseAdminClient() + + # Setup request + name = client.database_path("[PROJECT]", "[INSTANCE]", "[DATABASE]") + + with pytest.raises(CustomException): + client.get_database(name) + def test_drop_database(self): channel = ChannelStub() patch = mock.patch("google.api_core.grpc_helpers.create_channel") @@ -461,69 +579,6 @@ def test_test_iam_permissions_exception(self): with pytest.raises(CustomException): client.test_iam_permissions(resource, permissions) - def test_create_backup(self): - # Setup Expected Response - database = "database1789464955" - name = "name3373707" - size_bytes = 1796325715 - expected_response = { - "database": database, - "name": name, - "size_bytes": size_bytes, - } - expected_response = backup_pb2.Backup(**expected_response) - operation = operations_pb2.Operation( - name="operations/test_create_backup", done=True - ) - operation.response.Pack(expected_response) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_database_v1.DatabaseAdminClient() - - # Setup Request - parent = client.instance_path("[PROJECT]", "[INSTANCE]") - backup_id = "backupId1355353272" - backup = {} - - response = client.create_backup(parent, backup_id, backup) - result = response.result() - assert expected_response == result - - assert len(channel.requests) == 1 - expected_request = backup_pb2.CreateBackupRequest( - parent=parent, backup_id=backup_id, backup=backup - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_create_backup_exception(self): - # Setup Response - error = status_pb2.Status() - operation = operations_pb2.Operation( - name="operations/test_create_backup_exception", done=True - ) - operation.error.CopyFrom(error) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_database_v1.DatabaseAdminClient() - - # Setup Request - parent = client.instance_path("[PROJECT]", "[INSTANCE]") - backup_id = "backupId1355353272" - backup = {} - - response = client.create_backup(parent, backup_id, backup) - exception = response.exception() - assert exception.errors[0] == error - def test_get_backup(self): # Setup Expected Response database = "database1789464955" @@ -690,61 +745,6 @@ def test_list_backups_exception(self): with pytest.raises(CustomException): list(paged_list_response) - def test_restore_database(self): - # Setup Expected Response - name = "name3373707" - expected_response = {"name": name} - expected_response = spanner_database_admin_pb2.Database(**expected_response) - operation = operations_pb2.Operation( - name="operations/test_restore_database", done=True - ) - operation.response.Pack(expected_response) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_database_v1.DatabaseAdminClient() - - # Setup Request - parent = client.instance_path("[PROJECT]", "[INSTANCE]") - database_id = "databaseId816491103" - - response = client.restore_database(parent, database_id) - result = response.result() - assert expected_response == result - - assert len(channel.requests) == 1 - expected_request = spanner_database_admin_pb2.RestoreDatabaseRequest( - parent=parent, database_id=database_id - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_restore_database_exception(self): - # Setup Response - error = status_pb2.Status() - operation = operations_pb2.Operation( - name="operations/test_restore_database_exception", done=True - ) - operation.error.CopyFrom(error) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_database_v1.DatabaseAdminClient() - - # Setup Request - parent = client.instance_path("[PROJECT]", "[INSTANCE]") - database_id = "databaseId816491103" - - response = client.restore_database(parent, database_id) - exception = response.exception() - assert exception.errors[0] == error - def test_list_database_operations(self): # Setup Expected Response next_page_token = "" diff --git a/tests/unit/gapic/v1/test_instance_admin_client_v1.py b/tests/unit/gapic/v1/test_instance_admin_client_v1.py index da8dfcd8d4..5104645a6f 100644 --- a/tests/unit/gapic/v1/test_instance_admin_client_v1.py +++ b/tests/unit/gapic/v1/test_instance_admin_client_v1.py @@ -67,6 +67,134 @@ class CustomException(Exception): class TestInstanceAdminClient(object): + def test_create_instance(self): + # Setup Expected Response + name = "name3373707" + config = "config-1354792126" + display_name = "displayName1615086568" + node_count = 1539922066 + expected_response = { + "name": name, + "config": config, + "display_name": display_name, + "node_count": node_count, + } + expected_response = spanner_instance_admin_pb2.Instance(**expected_response) + operation = operations_pb2.Operation( + name="operations/test_create_instance", done=True + ) + operation.response.Pack(expected_response) + + # Mock the API response + channel = ChannelStub(responses=[operation]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_instance_v1.InstanceAdminClient() + + # Setup Request + parent = client.project_path("[PROJECT]") + instance_id = "instanceId-2101995259" + instance = {} + + response = client.create_instance(parent, instance_id, instance) + result = response.result() + assert expected_response == result + + assert len(channel.requests) == 1 + expected_request = spanner_instance_admin_pb2.CreateInstanceRequest( + parent=parent, instance_id=instance_id, instance=instance + ) + actual_request = channel.requests[0][1] + assert expected_request == actual_request + + def test_create_instance_exception(self): + # Setup Response + error = status_pb2.Status() + operation = operations_pb2.Operation( + name="operations/test_create_instance_exception", done=True + ) + operation.error.CopyFrom(error) + + # Mock the API response + channel = ChannelStub(responses=[operation]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_instance_v1.InstanceAdminClient() + + # Setup Request + parent = client.project_path("[PROJECT]") + instance_id = "instanceId-2101995259" + instance = {} + + response = client.create_instance(parent, instance_id, instance) + exception = response.exception() + assert exception.errors[0] == error + + def test_update_instance(self): + # Setup Expected Response + name = "name3373707" + config = "config-1354792126" + display_name = "displayName1615086568" + node_count = 1539922066 + expected_response = { + "name": name, + "config": config, + "display_name": display_name, + "node_count": node_count, + } + expected_response = spanner_instance_admin_pb2.Instance(**expected_response) + operation = operations_pb2.Operation( + name="operations/test_update_instance", done=True + ) + operation.response.Pack(expected_response) + + # Mock the API response + channel = ChannelStub(responses=[operation]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_instance_v1.InstanceAdminClient() + + # Setup Request + instance = {} + field_mask = {} + + response = client.update_instance(instance, field_mask) + result = response.result() + assert expected_response == result + + assert len(channel.requests) == 1 + expected_request = spanner_instance_admin_pb2.UpdateInstanceRequest( + instance=instance, field_mask=field_mask + ) + actual_request = channel.requests[0][1] + assert expected_request == actual_request + + def test_update_instance_exception(self): + # Setup Response + error = status_pb2.Status() + operation = operations_pb2.Operation( + name="operations/test_update_instance_exception", done=True + ) + operation.error.CopyFrom(error) + + # Mock the API response + channel = ChannelStub(responses=[operation]) + patch = mock.patch("google.api_core.grpc_helpers.create_channel") + with patch as create_channel: + create_channel.return_value = channel + client = spanner_admin_instance_v1.InstanceAdminClient() + + # Setup Request + instance = {} + field_mask = {} + + response = client.update_instance(instance, field_mask) + exception = response.exception() + assert exception.errors[0] == error + def test_list_instance_configs(self): # Setup Expected Response next_page_token = "" @@ -253,134 +381,6 @@ def test_get_instance_exception(self): with pytest.raises(CustomException): client.get_instance(name) - def test_create_instance(self): - # Setup Expected Response - name = "name3373707" - config = "config-1354792126" - display_name = "displayName1615086568" - node_count = 1539922066 - expected_response = { - "name": name, - "config": config, - "display_name": display_name, - "node_count": node_count, - } - expected_response = spanner_instance_admin_pb2.Instance(**expected_response) - operation = operations_pb2.Operation( - name="operations/test_create_instance", done=True - ) - operation.response.Pack(expected_response) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_instance_v1.InstanceAdminClient() - - # Setup Request - parent = client.project_path("[PROJECT]") - instance_id = "instanceId-2101995259" - instance = {} - - response = client.create_instance(parent, instance_id, instance) - result = response.result() - assert expected_response == result - - assert len(channel.requests) == 1 - expected_request = spanner_instance_admin_pb2.CreateInstanceRequest( - parent=parent, instance_id=instance_id, instance=instance - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_create_instance_exception(self): - # Setup Response - error = status_pb2.Status() - operation = operations_pb2.Operation( - name="operations/test_create_instance_exception", done=True - ) - operation.error.CopyFrom(error) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_instance_v1.InstanceAdminClient() - - # Setup Request - parent = client.project_path("[PROJECT]") - instance_id = "instanceId-2101995259" - instance = {} - - response = client.create_instance(parent, instance_id, instance) - exception = response.exception() - assert exception.errors[0] == error - - def test_update_instance(self): - # Setup Expected Response - name = "name3373707" - config = "config-1354792126" - display_name = "displayName1615086568" - node_count = 1539922066 - expected_response = { - "name": name, - "config": config, - "display_name": display_name, - "node_count": node_count, - } - expected_response = spanner_instance_admin_pb2.Instance(**expected_response) - operation = operations_pb2.Operation( - name="operations/test_update_instance", done=True - ) - operation.response.Pack(expected_response) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_instance_v1.InstanceAdminClient() - - # Setup Request - instance = {} - field_mask = {} - - response = client.update_instance(instance, field_mask) - result = response.result() - assert expected_response == result - - assert len(channel.requests) == 1 - expected_request = spanner_instance_admin_pb2.UpdateInstanceRequest( - instance=instance, field_mask=field_mask - ) - actual_request = channel.requests[0][1] - assert expected_request == actual_request - - def test_update_instance_exception(self): - # Setup Response - error = status_pb2.Status() - operation = operations_pb2.Operation( - name="operations/test_update_instance_exception", done=True - ) - operation.error.CopyFrom(error) - - # Mock the API response - channel = ChannelStub(responses=[operation]) - patch = mock.patch("google.api_core.grpc_helpers.create_channel") - with patch as create_channel: - create_channel.return_value = channel - client = spanner_admin_instance_v1.InstanceAdminClient() - - # Setup Request - instance = {} - field_mask = {} - - response = client.update_instance(instance, field_mask) - exception = response.exception() - assert exception.errors[0] == error - def test_delete_instance(self): channel = ChannelStub() patch = mock.patch("google.api_core.grpc_helpers.create_channel")