Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions google/cloud/spanner_admin_database_v1/gapic_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,106 @@
]
}
}
},
"rest": {
"libraryClient": "DatabaseAdminClient",
"rpcs": {
"CopyBackup": {
"methods": [
"copy_backup"
]
},
"CreateBackup": {
"methods": [
"create_backup"
]
},
"CreateDatabase": {
"methods": [
"create_database"
]
},
"DeleteBackup": {
"methods": [
"delete_backup"
]
},
"DropDatabase": {
"methods": [
"drop_database"
]
},
"GetBackup": {
"methods": [
"get_backup"
]
},
"GetDatabase": {
"methods": [
"get_database"
]
},
"GetDatabaseDdl": {
"methods": [
"get_database_ddl"
]
},
"GetIamPolicy": {
"methods": [
"get_iam_policy"
]
},
"ListBackupOperations": {
"methods": [
"list_backup_operations"
]
},
"ListBackups": {
"methods": [
"list_backups"
]
},
"ListDatabaseOperations": {
"methods": [
"list_database_operations"
]
},
"ListDatabaseRoles": {
"methods": [
"list_database_roles"
]
},
"ListDatabases": {
"methods": [
"list_databases"
]
},
"RestoreDatabase": {
"methods": [
"restore_database"
]
},
"SetIamPolicy": {
"methods": [
"set_iam_policy"
]
},
"TestIamPermissions": {
"methods": [
"test_iam_permissions"
]
},
"UpdateBackup": {
"methods": [
"update_backup"
]
},
"UpdateDatabaseDdl": {
"methods": [
"update_database_ddl"
]
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

from google.protobuf import json_format
from google.api_core import operations_v1
from google.longrunning import operations_pb2
from requests import __version__ as requests_version
import dataclasses
import re
Expand All @@ -46,8 +45,8 @@
from google.cloud.spanner_admin_database_v1.types import spanner_database_admin
from google.iam.v1 import iam_policy_pb2 # type: ignore
from google.iam.v1 import policy_pb2 # type: ignore
from google.longrunning import operations_pb2 # type: ignore
from google.protobuf import empty_pb2 # type: ignore
from google.longrunning import operations_pb2 # type: ignore

from .base import (
DatabaseAdminTransport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
from google.cloud.spanner_admin_instance_v1.types import spanner_instance_admin
from google.iam.v1 import iam_policy_pb2 # type: ignore
from google.iam.v1 import policy_pb2 # type: ignore
from google.longrunning import operations_pb2 # type: ignore
from google.protobuf import empty_pb2 # type: ignore
from google.longrunning import operations_pb2 # type: ignore

from .base import (
InstanceAdminTransport,
Expand Down Expand Up @@ -505,10 +505,12 @@ class InstanceAdminRestTransport(InstanceAdminTransport):
"""REST backend transport for InstanceAdmin.

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
Expand Down
4 changes: 4 additions & 0 deletions google/cloud/spanner_v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
from .types.spanner import CommitRequest
from .types.spanner import CreateSessionRequest
from .types.spanner import DeleteSessionRequest
from .types.spanner import DirectedReadOptions
from .types.spanner import ExecuteBatchDmlRequest
from .types.spanner import ExecuteBatchDmlResponse
from .types.spanner import ExecuteSqlRequest
Expand Down Expand Up @@ -77,6 +78,7 @@
This value can only be used for timestamp columns that have set the option
``(allow_commit_timestamp=true)`` in the schema.
"""
TransactionTypes = DirectedReadOptions.ReplicaSelection.Type


__all__ = (
Expand All @@ -96,6 +98,7 @@
"TransactionPingingPool",
# local
"COMMIT_TIMESTAMP",
"TransactionTypes",
# google.cloud.spanner_v1.types
"BatchCreateSessionsRequest",
"BatchCreateSessionsResponse",
Expand All @@ -104,6 +107,7 @@
"CommitResponse",
"CreateSessionRequest",
"DeleteSessionRequest",
"DirectedReadOptions",
"ExecuteBatchDmlRequest",
"ExecuteBatchDmlResponse",
"ExecuteSqlRequest",
Expand Down
50 changes: 50 additions & 0 deletions google/cloud/spanner_v1/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
from google.cloud.spanner_v1 import TypeCode
from google.cloud.spanner_v1 import ExecuteSqlRequest
from google.cloud.spanner_v1 import JsonObject
from google.cloud.spanner_v1 import DirectedReadOptions
from google.api_core.exceptions import InvalidArgument

# Validation error messages
NUMERIC_MAX_SCALE_ERR_MSG = (
Expand Down Expand Up @@ -358,3 +360,51 @@ def _metadata_with_leader_aware_routing(value, **kw):
List[Tuple[str, str]]: RPC metadata with leader aware routing header
"""
return ("x-goog-spanner-route-to-leader", str(value).lower())


def verify_directed_read_options(directed_read_options):
"""Verifies if value of directed_read_options is correct.
:type directed_read_options: :class:`~googlecloud.spanner_v1.types.DirectedReadOptions`
or :class:`dict`
:param directed_read_options: directed_read_options for ReadRequests and ExecuteSqlRequests.

:raises InvalidArguement: if directed_read_options is incorrect.
"""
if type(directed_read_options) == dict:
if (
"include_replicas" in directed_read_options.keys()
and "exclude_replicas" in directed_read_options.keys()
):
raise InvalidArgument(
"Only one of include_replicas or exclude_replicas can be set"
)
if (
"include_replicas" in directed_read_options.keys()
and "replica_selections" in directed_read_options["include_replicas"].keys()
and len(directed_read_options["include_replicas"]["replica_selections"])
> 10
) or (
"exclude_replicas" in directed_read_options.keys()
and "replica_selections" in directed_read_options["exclude_replicas"].keys()
and len(directed_read_options["exclude_replicas"]["replica_selections"])
> 10
):
raise InvalidArgument("Maximum length of replica selection allowed is 10")
elif isinstance(directed_read_options, DirectedReadOptions):
if (
directed_read_options.include_replicas is not None
and directed_read_options.exclude_replicas is not None
):
raise InvalidArgument(
"Only one of include_replicas or exclude_replicas can be set"
)
if (
directed_read_options.include_replicas is not None
and directed_read_options.include_replicas.replica_selections is not None
and len(directed_read_options.include_replicas.replica_selections) > 10
) or (
directed_read_options.include_replicas is not None
and directed_read_options.exclude_replicas.replica_selections is not None
and len(directed_read_options.exclude_replicas.replica_selections) > 10
):
raise InvalidArgument("Maximum length of replica selection allowed is 10")
32 changes: 32 additions & 0 deletions google/cloud/spanner_v1/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from google.cloud.spanner_v1 import ExecuteSqlRequest
from google.cloud.spanner_v1._helpers import _merge_query_options
from google.cloud.spanner_v1._helpers import _metadata_with_prefix
from google.cloud.spanner_v1._helpers import verify_directed_read_options
from google.cloud.spanner_v1.instance import Instance

_CLIENT_INFO = client_info.ClientInfo(client_library_version=__version__)
Expand Down Expand Up @@ -120,6 +121,12 @@ class Client(ClientWithProject):
disable leader aware routing. Disabling leader aware routing would
route all requests in RW/PDML transactions to the closest region.

:type directed_read_options: :class:`~googlecloud.spanner_v1.types.DirectedReadOptions`
or :class:`dict`
:param directed_read_options: (Optional) Client options used to set the directed_read_options
for all ReadRequests and ExecuteSqlRequests for the Client which indicate which replicas
or regions should be used for non-transactional reads or queries.

:raises: :class:`ValueError <exceptions.ValueError>` if both ``read_only``
and ``admin`` are :data:`True`
"""
Expand All @@ -139,6 +146,7 @@ def __init__(
client_options=None,
query_options=None,
route_to_leader_enabled=True,
directed_read_options=None,
):
self._emulator_host = _get_spanner_emulator_host()

Expand Down Expand Up @@ -180,6 +188,9 @@ def __init__(

self._route_to_leader_enabled = route_to_leader_enabled

verify_directed_read_options(directed_read_options)
self._directed_read_options = directed_read_options

@property
def credentials(self):
"""Getter for client's credentials.
Expand Down Expand Up @@ -260,6 +271,17 @@ def route_to_leader_enabled(self):
"""
return self._route_to_leader_enabled

@property
def directed_read_options(self):
"""Getter for directed_read_options.

:rtype:
:class:`~googlecloud.spanner_v1.types.DirectedReadOptions`
or :class:`dict`
:returns: The directed_read_options for the client.
"""
return self._directed_read_options

def copy(self):
"""Make a copy of this client.

Expand Down Expand Up @@ -383,3 +405,13 @@ def list_instances(self, filter_="", page_size=None):
request=request, metadata=metadata
)
return page_iter

def set_directed_read_options(self, directed_read_options):
"""Sets directed_read_options for the client
:type directed_read_options: :class:`~google.cloud.spanner_v1.types.DirectedReadOptions`
or :class:`dict`
:param directed_read_options: Client options used to set the directed_read_options
for all ReadRequests and ExecuteSqlRequests for the Client which indicate which replicas
or regions should be used for non-transactional reads or queries.
"""
self._directed_read_options = directed_read_options
1 change: 1 addition & 0 deletions google/cloud/spanner_v1/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def __init__(
self._route_to_leader_enabled = self._instance._client.route_to_leader_enabled
self._enable_drop_protection = enable_drop_protection
self._reconciling = False
self._directed_read_options = self._instance._client.directed_read_options

if pool is None:
pool = BurstyPool(database_role=database_role)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ class SpannerRestTransport(SpannerTransport):
"""REST backend transport for Spanner.

Cloud Spanner API

The Cloud Spanner API can be used to manage sessions and execute
transactions on data stored in Cloud Spanner databases.

Expand Down
Loading