google-cloud-spanner 3.55.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. google/cloud/spanner.py +47 -0
  2. google/cloud/spanner_admin_database_v1/__init__.py +146 -0
  3. google/cloud/spanner_admin_database_v1/gapic_metadata.json +418 -0
  4. google/cloud/spanner_admin_database_v1/gapic_version.py +16 -0
  5. google/cloud/spanner_admin_database_v1/py.typed +2 -0
  6. google/cloud/spanner_admin_database_v1/services/__init__.py +15 -0
  7. google/cloud/spanner_admin_database_v1/services/database_admin/__init__.py +22 -0
  8. google/cloud/spanner_admin_database_v1/services/database_admin/async_client.py +4097 -0
  9. google/cloud/spanner_admin_database_v1/services/database_admin/client.py +4602 -0
  10. google/cloud/spanner_admin_database_v1/services/database_admin/pagers.py +989 -0
  11. google/cloud/spanner_admin_database_v1/services/database_admin/transports/__init__.py +38 -0
  12. google/cloud/spanner_admin_database_v1/services/database_admin/transports/base.py +820 -0
  13. google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc.py +1303 -0
  14. google/cloud/spanner_admin_database_v1/services/database_admin/transports/grpc_asyncio.py +1688 -0
  15. google/cloud/spanner_admin_database_v1/services/database_admin/transports/rest.py +6512 -0
  16. google/cloud/spanner_admin_database_v1/services/database_admin/transports/rest_base.py +1650 -0
  17. google/cloud/spanner_admin_database_v1/types/__init__.py +144 -0
  18. google/cloud/spanner_admin_database_v1/types/backup.py +1106 -0
  19. google/cloud/spanner_admin_database_v1/types/backup_schedule.py +369 -0
  20. google/cloud/spanner_admin_database_v1/types/common.py +180 -0
  21. google/cloud/spanner_admin_database_v1/types/spanner_database_admin.py +1303 -0
  22. google/cloud/spanner_admin_instance_v1/__init__.py +110 -0
  23. google/cloud/spanner_admin_instance_v1/gapic_metadata.json +343 -0
  24. google/cloud/spanner_admin_instance_v1/gapic_version.py +16 -0
  25. google/cloud/spanner_admin_instance_v1/py.typed +2 -0
  26. google/cloud/spanner_admin_instance_v1/services/__init__.py +15 -0
  27. google/cloud/spanner_admin_instance_v1/services/instance_admin/__init__.py +22 -0
  28. google/cloud/spanner_admin_instance_v1/services/instance_admin/async_client.py +3466 -0
  29. google/cloud/spanner_admin_instance_v1/services/instance_admin/client.py +3881 -0
  30. google/cloud/spanner_admin_instance_v1/services/instance_admin/pagers.py +856 -0
  31. google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/__init__.py +38 -0
  32. google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/base.py +545 -0
  33. google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc.py +1347 -0
  34. google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/grpc_asyncio.py +1539 -0
  35. google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest.py +4834 -0
  36. google/cloud/spanner_admin_instance_v1/services/instance_admin/transports/rest_base.py +1198 -0
  37. google/cloud/spanner_admin_instance_v1/types/__init__.py +104 -0
  38. google/cloud/spanner_admin_instance_v1/types/common.py +99 -0
  39. google/cloud/spanner_admin_instance_v1/types/spanner_instance_admin.py +2375 -0
  40. google/cloud/spanner_dbapi/__init__.py +93 -0
  41. google/cloud/spanner_dbapi/_helpers.py +113 -0
  42. google/cloud/spanner_dbapi/batch_dml_executor.py +135 -0
  43. google/cloud/spanner_dbapi/checksum.py +80 -0
  44. google/cloud/spanner_dbapi/client_side_statement_executor.py +140 -0
  45. google/cloud/spanner_dbapi/client_side_statement_parser.py +106 -0
  46. google/cloud/spanner_dbapi/connection.py +818 -0
  47. google/cloud/spanner_dbapi/cursor.py +609 -0
  48. google/cloud/spanner_dbapi/exceptions.py +172 -0
  49. google/cloud/spanner_dbapi/parse_utils.py +392 -0
  50. google/cloud/spanner_dbapi/parsed_statement.py +63 -0
  51. google/cloud/spanner_dbapi/parser.py +258 -0
  52. google/cloud/spanner_dbapi/partition_helper.py +41 -0
  53. google/cloud/spanner_dbapi/transaction_helper.py +294 -0
  54. google/cloud/spanner_dbapi/types.py +106 -0
  55. google/cloud/spanner_dbapi/utils.py +147 -0
  56. google/cloud/spanner_dbapi/version.py +20 -0
  57. google/cloud/spanner_v1/__init__.py +154 -0
  58. google/cloud/spanner_v1/_helpers.py +751 -0
  59. google/cloud/spanner_v1/_opentelemetry_tracing.py +165 -0
  60. google/cloud/spanner_v1/backup.py +397 -0
  61. google/cloud/spanner_v1/batch.py +433 -0
  62. google/cloud/spanner_v1/client.py +538 -0
  63. google/cloud/spanner_v1/data_types.py +350 -0
  64. google/cloud/spanner_v1/database.py +1968 -0
  65. google/cloud/spanner_v1/database_sessions_manager.py +249 -0
  66. google/cloud/spanner_v1/gapic_metadata.json +268 -0
  67. google/cloud/spanner_v1/gapic_version.py +16 -0
  68. google/cloud/spanner_v1/instance.py +735 -0
  69. google/cloud/spanner_v1/keyset.py +193 -0
  70. google/cloud/spanner_v1/merged_result_set.py +146 -0
  71. google/cloud/spanner_v1/metrics/constants.py +71 -0
  72. google/cloud/spanner_v1/metrics/metrics_capture.py +75 -0
  73. google/cloud/spanner_v1/metrics/metrics_exporter.py +384 -0
  74. google/cloud/spanner_v1/metrics/metrics_interceptor.py +156 -0
  75. google/cloud/spanner_v1/metrics/metrics_tracer.py +588 -0
  76. google/cloud/spanner_v1/metrics/metrics_tracer_factory.py +328 -0
  77. google/cloud/spanner_v1/metrics/spanner_metrics_tracer_factory.py +172 -0
  78. google/cloud/spanner_v1/param_types.py +110 -0
  79. google/cloud/spanner_v1/pool.py +813 -0
  80. google/cloud/spanner_v1/py.typed +2 -0
  81. google/cloud/spanner_v1/request_id_header.py +64 -0
  82. google/cloud/spanner_v1/services/__init__.py +15 -0
  83. google/cloud/spanner_v1/services/spanner/__init__.py +22 -0
  84. google/cloud/spanner_v1/services/spanner/async_client.py +2205 -0
  85. google/cloud/spanner_v1/services/spanner/client.py +2624 -0
  86. google/cloud/spanner_v1/services/spanner/pagers.py +196 -0
  87. google/cloud/spanner_v1/services/spanner/transports/__init__.py +38 -0
  88. google/cloud/spanner_v1/services/spanner/transports/base.py +520 -0
  89. google/cloud/spanner_v1/services/spanner/transports/grpc.py +911 -0
  90. google/cloud/spanner_v1/services/spanner/transports/grpc_asyncio.py +1144 -0
  91. google/cloud/spanner_v1/services/spanner/transports/rest.py +3468 -0
  92. google/cloud/spanner_v1/services/spanner/transports/rest_base.py +981 -0
  93. google/cloud/spanner_v1/session.py +631 -0
  94. google/cloud/spanner_v1/session_options.py +133 -0
  95. google/cloud/spanner_v1/snapshot.py +1057 -0
  96. google/cloud/spanner_v1/streamed.py +402 -0
  97. google/cloud/spanner_v1/table.py +181 -0
  98. google/cloud/spanner_v1/testing/__init__.py +0 -0
  99. google/cloud/spanner_v1/testing/database_test.py +121 -0
  100. google/cloud/spanner_v1/testing/interceptors.py +118 -0
  101. google/cloud/spanner_v1/testing/mock_database_admin.py +38 -0
  102. google/cloud/spanner_v1/testing/mock_spanner.py +261 -0
  103. google/cloud/spanner_v1/testing/spanner_database_admin_pb2_grpc.py +1267 -0
  104. google/cloud/spanner_v1/testing/spanner_pb2_grpc.py +882 -0
  105. google/cloud/spanner_v1/transaction.py +747 -0
  106. google/cloud/spanner_v1/types/__init__.py +118 -0
  107. google/cloud/spanner_v1/types/commit_response.py +94 -0
  108. google/cloud/spanner_v1/types/keys.py +248 -0
  109. google/cloud/spanner_v1/types/mutation.py +201 -0
  110. google/cloud/spanner_v1/types/query_plan.py +220 -0
  111. google/cloud/spanner_v1/types/result_set.py +379 -0
  112. google/cloud/spanner_v1/types/spanner.py +1815 -0
  113. google/cloud/spanner_v1/types/transaction.py +818 -0
  114. google/cloud/spanner_v1/types/type.py +288 -0
  115. google_cloud_spanner-3.55.0.dist-info/LICENSE +202 -0
  116. google_cloud_spanner-3.55.0.dist-info/METADATA +318 -0
  117. google_cloud_spanner-3.55.0.dist-info/RECORD +119 -0
  118. google_cloud_spanner-3.55.0.dist-info/WHEEL +5 -0
  119. google_cloud_spanner-3.55.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,165 @@
1
+ # Copyright 2020 Google LLC All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Manages OpenTelemetry trace creation and handling"""
16
+
17
+ from contextlib import contextmanager
18
+ from datetime import datetime
19
+ import os
20
+
21
+ from google.cloud.spanner_v1 import SpannerClient
22
+ from google.cloud.spanner_v1 import gapic_version
23
+ from google.cloud.spanner_v1._helpers import (
24
+ _metadata_with_span_context,
25
+ )
26
+
27
+ try:
28
+ from opentelemetry import trace
29
+ from opentelemetry.trace.status import Status, StatusCode
30
+ from opentelemetry.semconv.attributes.otel_attributes import (
31
+ OTEL_SCOPE_NAME,
32
+ OTEL_SCOPE_VERSION,
33
+ )
34
+
35
+ HAS_OPENTELEMETRY_INSTALLED = True
36
+ except ImportError:
37
+ HAS_OPENTELEMETRY_INSTALLED = False
38
+
39
+ from google.cloud.spanner_v1.metrics.metrics_capture import MetricsCapture
40
+
41
+ TRACER_NAME = "cloud.google.com/python/spanner"
42
+ TRACER_VERSION = gapic_version.__version__
43
+ extended_tracing_globally_disabled = (
44
+ os.getenv("SPANNER_ENABLE_EXTENDED_TRACING", "").lower() == "false"
45
+ )
46
+ end_to_end_tracing_globally_enabled = (
47
+ os.getenv("SPANNER_ENABLE_END_TO_END_TRACING", "").lower() == "true"
48
+ )
49
+
50
+
51
+ def get_tracer(tracer_provider=None):
52
+ """
53
+ get_tracer is a utility to unify and simplify retrieval of the tracer, without
54
+ leaking implementation details given that retrieving a tracer requires providing
55
+ the full qualified library name and version.
56
+ When the tracer_provider is set, it'll retrieve the tracer from it, otherwise
57
+ it'll fall back to the global tracer provider and use this library's specific semantics.
58
+ """
59
+ if not tracer_provider:
60
+ # Acquire the global tracer provider.
61
+ tracer_provider = trace.get_tracer_provider()
62
+
63
+ return tracer_provider.get_tracer(TRACER_NAME, TRACER_VERSION)
64
+
65
+
66
+ @contextmanager
67
+ def trace_call(
68
+ name, session=None, extra_attributes=None, observability_options=None, metadata=None
69
+ ):
70
+ if session:
71
+ session._last_use_time = datetime.now()
72
+
73
+ if not (HAS_OPENTELEMETRY_INSTALLED and name):
74
+ # Empty context manager. Users will have to check if the generated value is None or a span
75
+ yield None
76
+ return
77
+
78
+ tracer_provider = None
79
+
80
+ # By default enable_extended_tracing=True because in a bid to minimize
81
+ # breaking changes and preserve legacy behavior, we are keeping it turned
82
+ # on by default.
83
+ enable_extended_tracing = True
84
+
85
+ enable_end_to_end_tracing = False
86
+
87
+ db_name = ""
88
+ if session and getattr(session, "_database", None):
89
+ db_name = session._database.name
90
+
91
+ if isinstance(observability_options, dict): # Avoid false positives with mock.Mock
92
+ tracer_provider = observability_options.get("tracer_provider", None)
93
+ enable_extended_tracing = observability_options.get(
94
+ "enable_extended_tracing", enable_extended_tracing
95
+ )
96
+ enable_end_to_end_tracing = observability_options.get(
97
+ "enable_end_to_end_tracing", enable_end_to_end_tracing
98
+ )
99
+ db_name = observability_options.get("db_name", db_name)
100
+
101
+ tracer = get_tracer(tracer_provider)
102
+
103
+ # Set base attributes that we know for every trace created
104
+ attributes = {
105
+ "db.type": "spanner",
106
+ "db.url": SpannerClient.DEFAULT_ENDPOINT,
107
+ "db.instance": db_name,
108
+ "net.host.name": SpannerClient.DEFAULT_ENDPOINT,
109
+ OTEL_SCOPE_NAME: TRACER_NAME,
110
+ OTEL_SCOPE_VERSION: TRACER_VERSION,
111
+ # Standard GCP attributes for OTel, attributes are used for internal purpose and are subjected to change
112
+ "gcp.client.service": "spanner",
113
+ "gcp.client.version": TRACER_VERSION,
114
+ "gcp.client.repo": "googleapis/python-spanner",
115
+ }
116
+
117
+ if extra_attributes:
118
+ attributes.update(extra_attributes)
119
+
120
+ if extended_tracing_globally_disabled:
121
+ enable_extended_tracing = False
122
+
123
+ if not enable_extended_tracing:
124
+ attributes.pop("db.statement", False)
125
+
126
+ if end_to_end_tracing_globally_enabled:
127
+ enable_end_to_end_tracing = True
128
+
129
+ with tracer.start_as_current_span(
130
+ name, kind=trace.SpanKind.CLIENT, attributes=attributes
131
+ ) as span:
132
+ with MetricsCapture():
133
+ try:
134
+ if enable_end_to_end_tracing:
135
+ _metadata_with_span_context(metadata)
136
+ yield span
137
+ except Exception as error:
138
+ span.set_status(Status(StatusCode.ERROR, str(error)))
139
+ # OpenTelemetry-Python imposes invoking span.record_exception on __exit__
140
+ # on any exception. We should file a bug later on with them to only
141
+ # invoke .record_exception if not already invoked, hence we should not
142
+ # invoke .record_exception on our own else we shall have 2 exceptions.
143
+ raise
144
+ else:
145
+ # All spans still have set_status available even if for example
146
+ # NonRecordingSpan doesn't have "_status".
147
+ absent_span_status = getattr(span, "_status", None) is None
148
+ if absent_span_status or span._status.status_code == StatusCode.UNSET:
149
+ # OpenTelemetry-Python only allows a status change
150
+ # if the current code is UNSET or ERROR. At the end
151
+ # of the generator's consumption, only set it to OK
152
+ # it wasn't previously set otherwise.
153
+ # https://github.com/googleapis/python-spanner/issues/1246
154
+ span.set_status(Status(StatusCode.OK))
155
+
156
+
157
+ def get_current_span():
158
+ if not HAS_OPENTELEMETRY_INSTALLED:
159
+ return None
160
+ return trace.get_current_span()
161
+
162
+
163
+ def add_span_event(span, event_name, event_attributes=None):
164
+ if span:
165
+ span.add_event(event_name, event_attributes)
@@ -0,0 +1,397 @@
1
+ # Copyright 2020 Google LLC All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """User friendly container for Cloud Spanner Backup."""
16
+
17
+ import re
18
+
19
+ from google.cloud.exceptions import NotFound
20
+
21
+ from google.cloud.spanner_admin_database_v1 import Backup as BackupPB
22
+ from google.cloud.spanner_admin_database_v1 import CreateBackupEncryptionConfig
23
+ from google.cloud.spanner_admin_database_v1 import CreateBackupRequest
24
+ from google.cloud.spanner_admin_database_v1 import CopyBackupEncryptionConfig
25
+ from google.cloud.spanner_admin_database_v1 import CopyBackupRequest
26
+ from google.cloud.spanner_v1._helpers import _metadata_with_prefix
27
+
28
+ _BACKUP_NAME_RE = re.compile(
29
+ r"^projects/(?P<project>[^/]+)/"
30
+ r"instances/(?P<instance_id>[a-z][-a-z0-9]*)/"
31
+ r"backups/(?P<backup_id>[a-z][a-z0-9_\-]*[a-z0-9])$"
32
+ )
33
+
34
+
35
+ class Backup(object):
36
+ """Representation of a Cloud Spanner Backup.
37
+
38
+ We can use a :class`Backup` to:
39
+
40
+ * :meth:`create` the backup
41
+ * :meth:`update` the backup
42
+ * :meth:`delete` the backup
43
+
44
+ :type backup_id: str
45
+ :param backup_id: The ID of the backup.
46
+
47
+ :type instance: :class:`~google.cloud.spanner_v1.instance.Instance`
48
+ :param instance: The instance that owns the backup.
49
+
50
+ :type database: str
51
+ :param database: (Optional) The URI of the database that the backup is
52
+ for. Required if the create method needs to be called.
53
+
54
+ :type expire_time: :class:`datetime.datetime`
55
+ :param expire_time: (Optional) The expire time that will be used to
56
+ create the backup. Required if the create method
57
+ needs to be called.
58
+
59
+ :type version_time: :class:`datetime.datetime`
60
+ :param version_time: (Optional) The version time that was specified for
61
+ the externally consistent copy of the database. If
62
+ not present, it is the same as the `create_time` of
63
+ the backup.
64
+
65
+ :type encryption_config:
66
+ :class:`~google.cloud.spanner_admin_database_v1.types.CreateBackupEncryptionConfig`
67
+ or :class:`dict`
68
+ :param encryption_config:
69
+ (Optional) Encryption configuration for the backup.
70
+ If a dict is provided, it must be of the same form as the protobuf
71
+ message :class:`~google.cloud.spanner_admin_database_v1.types.CreateBackupEncryptionConfig`
72
+ """
73
+
74
+ def __init__(
75
+ self,
76
+ backup_id,
77
+ instance,
78
+ database="",
79
+ expire_time=None,
80
+ version_time=None,
81
+ encryption_config=None,
82
+ source_backup=None,
83
+ ):
84
+ self.backup_id = backup_id
85
+ self._instance = instance
86
+ self._database = database
87
+ self._source_backup = source_backup
88
+ self._expire_time = expire_time
89
+ self._create_time = None
90
+ self._version_time = version_time
91
+ self._size_bytes = None
92
+ self._state = None
93
+ self._referencing_databases = None
94
+ self._encryption_info = None
95
+ self._max_expire_time = None
96
+ self._referencing_backups = None
97
+ self._database_dialect = None
98
+ if type(encryption_config) is dict:
99
+ if source_backup:
100
+ self._encryption_config = CopyBackupEncryptionConfig(
101
+ **encryption_config
102
+ )
103
+ else:
104
+ self._encryption_config = CreateBackupEncryptionConfig(
105
+ **encryption_config
106
+ )
107
+ else:
108
+ self._encryption_config = encryption_config
109
+
110
+ @property
111
+ def name(self):
112
+ """Backup name used in requests.
113
+
114
+ The backup name is of the form
115
+
116
+ ``"projects/../instances/../backups/{backup_id}"``
117
+
118
+ :rtype: str
119
+ :returns: The backup name.
120
+ """
121
+ return self._instance.name + "/backups/" + self.backup_id
122
+
123
+ @property
124
+ def database(self):
125
+ """Database name used in requests.
126
+
127
+ The database name is of the form
128
+
129
+ ``"projects/../instances/../backups/{backup_id}"``
130
+
131
+ :rtype: str
132
+ :returns: The database name.
133
+ """
134
+ return self._database
135
+
136
+ @property
137
+ def expire_time(self):
138
+ """Expire time used in creation requests.
139
+
140
+ :rtype: :class:`datetime.datetime`
141
+ :returns: a datetime object representing the expire time of
142
+ this backup
143
+ """
144
+ return self._expire_time
145
+
146
+ @property
147
+ def create_time(self):
148
+ """Create time of this backup.
149
+
150
+ :rtype: :class:`datetime.datetime`
151
+ :returns: a datetime object representing the create time of
152
+ this backup
153
+ """
154
+ return self._create_time
155
+
156
+ @property
157
+ def version_time(self):
158
+ """Version time of this backup.
159
+
160
+ :rtype: :class:`datetime.datetime`
161
+ :returns: a datetime object representing the version time of
162
+ this backup
163
+ """
164
+ return self._version_time
165
+
166
+ @property
167
+ def size_bytes(self):
168
+ """Size of this backup in bytes.
169
+
170
+ :rtype: int
171
+ :returns: the number size of this backup measured in bytes
172
+ """
173
+ return self._size_bytes
174
+
175
+ @property
176
+ def state(self):
177
+ """State of this backup.
178
+
179
+ :rtype: :class:`~google.cloud.spanner_admin_database_v1.types.Backup.State`
180
+ :returns: an enum describing the state of the backup
181
+ """
182
+ return self._state
183
+
184
+ @property
185
+ def referencing_databases(self):
186
+ """List of databases referencing this backup.
187
+
188
+ :rtype: list of strings
189
+ :returns: a list of database path strings which specify the databases still
190
+ referencing this backup
191
+ """
192
+ return self._referencing_databases
193
+
194
+ @property
195
+ def encryption_info(self):
196
+ """Encryption info for this backup.
197
+ :rtype: :class:`~google.cloud.spanner_admin_database_v1.types.EncryptionInfo`
198
+ :returns: a class representing the encryption info
199
+ """
200
+ return self._encryption_info
201
+
202
+ @property
203
+ def max_expire_time(self):
204
+ """The max allowed expiration time of the backup.
205
+ :rtype: :class:`datetime.datetime`
206
+ :returns: a datetime object representing the max expire time of
207
+ this backup
208
+ """
209
+ return self._max_expire_time
210
+
211
+ @property
212
+ def referencing_backups(self):
213
+ """The names of the destination backups being created by copying this source backup.
214
+ :rtype: list of strings
215
+ :returns: a list of backup path strings which specify the backups that are
216
+ referencing this copy backup
217
+ """
218
+ return self._referencing_backups
219
+
220
+ def database_dialect(self):
221
+ """Database Dialect for this backup.
222
+ :rtype: :class:`~google.cloud.spanner_admin_database_v1.types.DatabaseDialect`
223
+ :returns: a class representing the dialect of this backup's database
224
+ """
225
+ return self._database_dialect
226
+
227
+ @classmethod
228
+ def from_pb(cls, backup_pb, instance):
229
+ """Create an instance of this class from a protobuf message.
230
+
231
+ :type backup_pb: :class:`~google.cloud.spanner_admin_database_v1.types.Backup`
232
+ :param backup_pb: A backup protobuf object.
233
+
234
+ :type instance: :class:`~google.cloud.spanner_v1.instance.Instance`
235
+ :param instance: The instance that owns the backup.
236
+
237
+ :rtype: :class:`Backup`
238
+ :returns: The backup parsed from the protobuf response.
239
+ :raises ValueError:
240
+ if the backup name does not match the expected format or if
241
+ the parsed project ID does not match the project ID on the
242
+ instance's client, or if the parsed instance ID does not match
243
+ the instance's ID.
244
+ """
245
+ match = _BACKUP_NAME_RE.match(backup_pb.name)
246
+ if match is None:
247
+ raise ValueError(
248
+ "Backup protobuf name was not in the expected format.", backup_pb.name
249
+ )
250
+ if match.group("project") != instance._client.project:
251
+ raise ValueError(
252
+ "Project ID on backup does not match the project ID"
253
+ "on the instance's client"
254
+ )
255
+ instance_id = match.group("instance_id")
256
+ if instance_id != instance.instance_id:
257
+ raise ValueError(
258
+ "Instance ID on database does not match the instance ID"
259
+ "on the instance"
260
+ )
261
+ backup_id = match.group("backup_id")
262
+ return cls(backup_id, instance)
263
+
264
+ def create(self):
265
+ """Create this backup or backup copy within its instance.
266
+
267
+ :rtype: :class:`~google.api_core.operation.Operation`
268
+ :returns: a future used to poll the status of the create request
269
+ :raises Conflict: if the backup already exists
270
+ :raises NotFound: if the instance owning the backup does not exist
271
+ :raises BadRequest: if the database or expire_time values are invalid
272
+ or expire_time is not set
273
+ """
274
+ if not self._expire_time:
275
+ raise ValueError("expire_time not set")
276
+
277
+ if not self._database and not self._source_backup:
278
+ raise ValueError("database and source backup both not set")
279
+
280
+ if (
281
+ (
282
+ self._encryption_config
283
+ and self._encryption_config.kms_key_name
284
+ and self._encryption_config.encryption_type
285
+ != CreateBackupEncryptionConfig.EncryptionType.CUSTOMER_MANAGED_ENCRYPTION
286
+ )
287
+ and self._encryption_config
288
+ and self._encryption_config.kms_key_name
289
+ and self._encryption_config.encryption_type
290
+ != CopyBackupEncryptionConfig.EncryptionType.CUSTOMER_MANAGED_ENCRYPTION
291
+ ):
292
+ raise ValueError("kms_key_name only used with CUSTOMER_MANAGED_ENCRYPTION")
293
+
294
+ api = self._instance._client.database_admin_api
295
+ metadata = _metadata_with_prefix(self.name)
296
+
297
+ if self._source_backup:
298
+ request = CopyBackupRequest(
299
+ parent=self._instance.name,
300
+ backup_id=self.backup_id,
301
+ source_backup=self._source_backup,
302
+ expire_time=self._expire_time,
303
+ encryption_config=self._encryption_config,
304
+ )
305
+
306
+ future = api.copy_backup(
307
+ request=request,
308
+ metadata=metadata,
309
+ )
310
+ return future
311
+
312
+ backup = BackupPB(
313
+ database=self._database,
314
+ expire_time=self.expire_time,
315
+ version_time=self.version_time,
316
+ )
317
+
318
+ request = CreateBackupRequest(
319
+ parent=self._instance.name,
320
+ backup_id=self.backup_id,
321
+ backup=backup,
322
+ encryption_config=self._encryption_config,
323
+ )
324
+
325
+ future = api.create_backup(
326
+ request=request,
327
+ metadata=metadata,
328
+ )
329
+ return future
330
+
331
+ def exists(self):
332
+ """Test whether this backup exists.
333
+
334
+ :rtype: bool
335
+ :returns: True if the backup exists, else False.
336
+ """
337
+ api = self._instance._client.database_admin_api
338
+ metadata = _metadata_with_prefix(self.name)
339
+
340
+ try:
341
+ api.get_backup(name=self.name, metadata=metadata)
342
+ except NotFound:
343
+ return False
344
+ return True
345
+
346
+ def reload(self):
347
+ """Reload this backup.
348
+
349
+ Refresh the stored backup properties.
350
+
351
+ :raises NotFound: if the backup does not exist
352
+ """
353
+ api = self._instance._client.database_admin_api
354
+ metadata = _metadata_with_prefix(self.name)
355
+ pb = api.get_backup(name=self.name, metadata=metadata)
356
+ self._database = pb.database
357
+ self._expire_time = pb.expire_time
358
+ self._create_time = pb.create_time
359
+ self._version_time = pb.version_time
360
+ self._size_bytes = pb.size_bytes
361
+ self._state = BackupPB.State(pb.state)
362
+ self._referencing_databases = pb.referencing_databases
363
+ self._encryption_info = pb.encryption_info
364
+ self._max_expire_time = pb.max_expire_time
365
+ self._referencing_backups = pb.referencing_backups
366
+
367
+ def update_expire_time(self, new_expire_time):
368
+ """Update the expire time of this backup.
369
+
370
+ :type new_expire_time: :class:`datetime.datetime`
371
+ :param new_expire_time: the new expire time timestamp
372
+ """
373
+ api = self._instance._client.database_admin_api
374
+ metadata = _metadata_with_prefix(self.name)
375
+ backup_update = BackupPB(
376
+ name=self.name,
377
+ expire_time=new_expire_time,
378
+ )
379
+ update_mask = {"paths": ["expire_time"]}
380
+ api.update_backup(
381
+ backup=backup_update, update_mask=update_mask, metadata=metadata
382
+ )
383
+ self._expire_time = new_expire_time
384
+
385
+ def is_ready(self):
386
+ """Test whether this backup is ready for use.
387
+
388
+ :rtype: bool
389
+ :returns: True if the backup state is READY, else False.
390
+ """
391
+ return self.state == BackupPB.State.READY
392
+
393
+ def delete(self):
394
+ """Delete this backup."""
395
+ api = self._instance._client.database_admin_api
396
+ metadata = _metadata_with_prefix(self.name)
397
+ api.delete_backup(name=self.name, metadata=metadata)