Skip to content

Commit 8910771

Browse files
larkeeJon Wayne Parrottjasonmortonryanmatsdpebot
authored
docs: add samples from spanner/cloud-client (#117)
* Add spanner samples [(#804)](GoogleCloudPlatform/python-docs-samples#804) * Update snippets.py [(#815)](GoogleCloudPlatform/python-docs-samples#815) * Changed read_write minimum amount to 300,000 as per bug [(#818)](GoogleCloudPlatform/python-docs-samples#818) * Remove cloud config fixture [(#887)](GoogleCloudPlatform/python-docs-samples#887) * Remove cloud config fixture * Fix client secrets * Fix bigtable instance * Fix reference to our testing tools * Auto-update dependencies. [(#914)](GoogleCloudPlatform/python-docs-samples#914) * Auto-update dependencies. * xfail the error reporting test * Fix lint * Re-generate all readmes * Auto-update dependencies. [(#922)](GoogleCloudPlatform/python-docs-samples#922) * Auto-update dependencies. * Fix pubsub iam samples * Update spanner sample to use bind parameters [(#928)](GoogleCloudPlatform/python-docs-samples#928) * Fix default arguments * Fix README rst links [(#962)](GoogleCloudPlatform/python-docs-samples#962) * Fix README rst links * Update all READMEs * Auto-update dependencies. [(#992)](GoogleCloudPlatform/python-docs-samples#992) * Auto-update dependencies. [(#1004)](GoogleCloudPlatform/python-docs-samples#1004) * Auto-update dependencies. * Fix natural language samples * Fix pubsub iam samples * Fix language samples * Fix bigquery samples * Swap the album titles to be consistent with other samples [(#1035)](GoogleCloudPlatform/python-docs-samples#1035) * Auto-update dependencies. [(#1055)](GoogleCloudPlatform/python-docs-samples#1055) * Auto-update dependencies. * Explicitly use latest bigtable client Change-Id: Id71e9e768f020730e4ca9514a0d7ebaa794e7d9e * Revert language update for now Change-Id: I8867f154e9a5aae00d0047c9caf880e5e8f50c53 * Remove pdb. smh Change-Id: I5ff905fadc026eebbcd45512d4e76e003e3b2b43 * Pass multi_use=True to spanner read-only transaction [(#1063)](GoogleCloudPlatform/python-docs-samples#1063) Change-Id: Ied9d9f519edd572d79dc95d2812c1b98f5a92794 * fix typo Change-Id: I887507fa33ea30f5859707063326934e5c11208f * Auto-update dependencies. [(#1093)](GoogleCloudPlatform/python-docs-samples#1093) * Auto-update dependencies. * Fix storage notification poll sample Change-Id: I6afbc79d15e050531555e4c8e51066996717a0f3 * Fix spanner samples Change-Id: I40069222c60d57e8f3d3878167591af9130895cb * Drop coverage because it's not useful Change-Id: Iae399a7083d7866c3c7b9162d0de244fbff8b522 * Try again to fix flaky logging test Change-Id: I6225c074701970c17c426677ef1935bb6d7e36b4 * Add spanner stale data sample [(#1107)](GoogleCloudPlatform/python-docs-samples#1107) * Update all generated readme auth instructions [(#1121)](GoogleCloudPlatform/python-docs-samples#1121) Change-Id: I03b5eaef8b17ac3dc3c0339fd2c7447bd3e11bd2 * Added Link to Python Setup Guide [(#1158)](GoogleCloudPlatform/python-docs-samples#1158) * Update Readme.rst to add Python setup guide As requested in b/64770713. This sample is linked in documentation https://cloud.google.com/bigtable/docs/scaling, and it would make more sense to update the guide here than in the documentation. * Update README.rst * Update README.rst * Update README.rst * Update README.rst * Update README.rst * Update install_deps.tmpl.rst * Updated readmegen scripts and re-generated related README files * Fixed the lint error * Auto-update dependencies. [(#1138)](GoogleCloudPlatform/python-docs-samples#1138) * Auto-update dependencies. [(#1186)](GoogleCloudPlatform/python-docs-samples#1186) * Fixed failed tests on Kokoro (Spanner + Translate) [(#1192)](GoogleCloudPlatform/python-docs-samples#1192) * Fixed failed tests on Kokoro (Spanner + Translate) * Update quickstart_test.py * Bump spanner stale read from 10 to 15 seconds. [(#1207)](GoogleCloudPlatform/python-docs-samples#1207) At the request of the spanner team. * Added "Open in Cloud Shell" buttons to README files [(#1254)](GoogleCloudPlatform/python-docs-samples#1254) * Auto-update dependencies. [(#1316)](GoogleCloudPlatform/python-docs-samples#1316) * Auto-update dependencies. [(#1354)](GoogleCloudPlatform/python-docs-samples#1354) * Add Spanner region tags. [(#1376)](GoogleCloudPlatform/python-docs-samples#1376) * Auto-update dependencies. [(#1377)](GoogleCloudPlatform/python-docs-samples#1377) * Auto-update dependencies. * Update requirements.txt * Spanner Batch Query Sample [(#1402)](GoogleCloudPlatform/python-docs-samples#1402) * Auto-update dependencies. [(#1406)](GoogleCloudPlatform/python-docs-samples#1406) * Spanner Commit Timestamp Sample [(#1425)](GoogleCloudPlatform/python-docs-samples#1425) * Regenerate the README files and fix the Open in Cloud Shell link for some samples [(#1441)](GoogleCloudPlatform/python-docs-samples#1441) * Update READMEs to fix numbering and add git clone [(#1464)](GoogleCloudPlatform/python-docs-samples#1464) * Adding Spanner STRUCT param samples [(#1519)](GoogleCloudPlatform/python-docs-samples#1519) * Adding Spanner STRUCT param samples * Fix python Cloud Spanner tests. [(#1548)](GoogleCloudPlatform/python-docs-samples#1548) * Fix python Cloud Spanner tests. * Lint. * Cleanup spanner tests. [(#1633)](GoogleCloudPlatform/python-docs-samples#1633) * Cleanup spanner tests. * Update requirements. * Added Spanner DML/PDML samples. [(#1742)](GoogleCloudPlatform/python-docs-samples#1742) * Added Spanner DML/PDML samples. * Fixed lint issues and bumped version. * Update method name to match action. [(#1836)](GoogleCloudPlatform/python-docs-samples#1836) * Auto-update dependencies. [(#1846)](GoogleCloudPlatform/python-docs-samples#1846) ACK, merging. * Add sample to delete data. [(#1872)](GoogleCloudPlatform/python-docs-samples#1872) * Update snippets.py * Update snippets_test.py * Auto-update dependencies. [(#1980)](GoogleCloudPlatform/python-docs-samples#1980) * Auto-update dependencies. * Update requirements.txt * Update requirements.txt * Add Cloud Spanner Batch DML sample [(#2068)](GoogleCloudPlatform/python-docs-samples#2068) * Add Cloud Spanner Batch DML sample * Fix test. * Lint. * More Lint. * Add queryWithParameter to Cloud Spanner sample. [(#2153)](GoogleCloudPlatform/python-docs-samples#2153) * Add queryWithParameter to Cloud Spanner sample. * Lint. * Update to fix test. * Deflake bigtable and spanner tests. [(#2224)](GoogleCloudPlatform/python-docs-samples#2224) * Spanner doesn't actually promise the order of the results, so make the assertion work regardless of ordering. * Bigtable might need some more time to scale, so retry the assertion up to 10 times. * Improve and fix Cloud Spanner samples that transfer marketing budget [(#2198)](GoogleCloudPlatform/python-docs-samples#2198) The samples that transfer part of an album's marketing budget had some issues: + `read_write_transaction`: Compared `second_album_budget` with an arbitrary integer, rather than explicitly checking against `transfer_amount`. + `write_with_dml_transaction`: Moved money from album 1 to album 2, even though `read_write_transaction` was the other way around. Also retrieved album 1's budget where it should have retrieved album 2's budget. This change fixes those issues and updates the tests accordingly. * Add Datatypes examples to Spanner sample. [(#2251)](GoogleCloudPlatform/python-docs-samples#2251) * Add Datatypes examples to Spanner sample. * Lint. * Lint. * Fix test. * Add bulk loading Python Sample [(#2295)](GoogleCloudPlatform/python-docs-samples#2295) Adds the following functionality: * Create bulk_load_csv * Delete bulk_load_csv * Create schema.ddl * Fix Spanner `BOOL` example after upstream typo fix [(#2356)](GoogleCloudPlatform/python-docs-samples#2356) Summary: This code used to be correct, when the Spanner Python API had a typo in the parameter name, but that typo was fixed in an upstream pull request: <googleapis/google-cloud-python#7295> Test Plan: Running `git grep BOOE` now returns no results. wchargin-branch: bool-not-booe * Updates to spanner version with BOOL correctly spelled. [(#2392)](GoogleCloudPlatform/python-docs-samples#2392) * Adds updates for samples profiler ... vision [(#2439)](GoogleCloudPlatform/python-docs-samples#2439) * update filenames to match the CSV files [(#2535)](GoogleCloudPlatform/python-docs-samples#2535) fixes GoogleCloudPlatform/python-docs-samples#2532 * Auto-update dependencies. [(#2005)](GoogleCloudPlatform/python-docs-samples#2005) * Auto-update dependencies. * Revert update of appengine/flexible/datastore. * revert update of appengine/flexible/scipy * revert update of bigquery/bqml * revert update of bigquery/cloud-client * revert update of bigquery/datalab-migration * revert update of bigtable/quickstart * revert update of compute/api * revert update of container_registry/container_analysis * revert update of dataflow/run_template * revert update of datastore/cloud-ndb * revert update of dialogflow/cloud-client * revert update of dlp * revert update of functions/imagemagick * revert update of functions/ocr/app * revert update of healthcare/api-client/fhir * revert update of iam/api-client * revert update of iot/api-client/gcs_file_to_device * revert update of iot/api-client/mqtt_example * revert update of language/automl * revert update of run/image-processing * revert update of vision/automl * revert update testing/requirements.txt * revert update of vision/cloud-client/detect * revert update of vision/cloud-client/product_search * revert update of jobs/v2/api_client * revert update of jobs/v3/api_client * revert update of opencensus * revert update of translate/cloud-client * revert update to speech/cloud-client Co-authored-by: Kurtis Van Gent <[email protected]> Co-authored-by: Doug Mahugh <[email protected]> * Delete spanner/cloud-client/bulk_load_csv. [(#2721)](GoogleCloudPlatform/python-docs-samples#2721) This has been moved to https://github.com/cloudspannerecosystem/sampledb. Co-authored-by: Kurtis Van Gent <[email protected]> * spanner: add query options versioning samples [(#3093)](GoogleCloudPlatform/python-docs-samples#3093) * spanner: add query versioning samples * update test assertions * Fixed the region tags. * Removed extra whitespace. * update required spanner version Co-authored-by: larkee <[email protected]> Co-authored-by: skuruppu <[email protected]> * spanner: Add Cloud Spanner Backup samples [(#3101)](GoogleCloudPlatform/python-docs-samples#3101) * add backup samples * update required spanner version * fix lint errors * run backup samples tests against a new instance * fix lint * wait for instance creation to complete * Apply suggestions from code review Co-Authored-By: skuruppu <[email protected]> * add list_backups test * fix lint * add missing newline character in assert * update samples to be consistent with other languages * lint fix * add pagination sample * reorder tests Co-authored-by: larkee <[email protected]> Co-authored-by: skuruppu <[email protected]> * Simplify noxfile setup. [(#2806)](GoogleCloudPlatform/python-docs-samples#2806) * chore(deps): update dependency requests to v2.23.0 * Simplify noxfile and add version control. * Configure appengine/standard to only test Python 2.7. * Update Kokokro configs to match noxfile. * Add requirements-test to each folder. * Remove Py2 versions from everything execept appengine/standard. * Remove conftest.py. * Remove appengine/standard/conftest.py * Remove 'no-sucess-flaky-report' from pytest.ini. * Add GAE SDK back to appengine/standard tests. * Fix typo. * Roll pytest to python 2 version. * Add a bunch of testing requirements. * Remove typo. * Add appengine lib directory back in. * Add some additional requirements. * Fix issue with flake8 args. * Even more requirements. * Readd appengine conftest.py. * Add a few more requirements. * Even more Appengine requirements. * Add webtest for appengine/standard/mailgun. * Add some additional requirements. * Add workaround for issue with mailjet-rest. * Add responses for appengine/standard/mailjet. Co-authored-by: Renovate Bot <[email protected]> * Update dependency google-cloud-spanner to v1.15.1 [(#3377)](GoogleCloudPlatform/python-docs-samples#3377) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-cloud-spanner](https://togithub.com/googleapis/python-spanner) | patch | `==1.15.0` -> `==1.15.1` | --- ### Release Notes <details> <summary>googleapis/python-spanner</summary> ### [`v1.15.1`](https://togithub.com/googleapis/python-spanner/blob/master/CHANGELOG.md#&#8203;1151-httpswwwgithubcomgoogleapispython-spannercomparev1150v1151-2020-04-08) [Compare Source](https://togithub.com/googleapis/python-spanner/compare/v1.15.0...v1.15.1) </details> --- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * [spanner] fix: bump the timeout for instance creation [(#3468)](GoogleCloudPlatform/python-docs-samples#3468) fixes #3466 * [spanner] fix: set timeout for polling on operations [(#3488)](GoogleCloudPlatform/python-docs-samples#3488) * [spanner] fix: set timeout for polling on operations fixes #3471 * bump the deadline to 1200 for backup and restore * bumped the deadline to 120 * fix: use DELETE FROM for consistency [(#3498)](GoogleCloudPlatform/python-docs-samples#3498) Being consistent with [docs](https://cloud.google.com/spanner/docs/dml-syntax#delete_examples). Co-authored-by: gcf-merge-on-green[bot] <60162190+gcf-merge-on-green[bot]@users.noreply.github.com> Co-authored-by: Takashi Matsuo <[email protected]> * chore: pin new release [(#3688)](GoogleCloudPlatform/python-docs-samples#3688) Co-authored-by: larkee <[email protected]> * chore: some lint fixes [(#3749)](GoogleCloudPlatform/python-docs-samples#3749) * chore(deps): update dependency google-cloud-spanner to v1.17.0 [(#3885)](GoogleCloudPlatform/python-docs-samples#3885) * Improve Spanner delete_data sample coverage [(#3922)](GoogleCloudPlatform/python-docs-samples#3922) * improve Spanner delete_data sample coverage * specify end to stay consistent with other languages Co-authored-by: larkee <[email protected]> * chore(deps): update dependency google-cloud-spanner to v1.17.1 [(#4160)](GoogleCloudPlatform/python-docs-samples#4160) Co-authored-by: Takashi Matsuo <[email protected]> * fix(spanner): use uuid for unique id [(#4198)](GoogleCloudPlatform/python-docs-samples#4198) fixes #4197 (possibly) * feat(spanner): add sample for create instance [(#4230)](GoogleCloudPlatform/python-docs-samples#4230) Co-authored-by: larkee <[email protected]> Co-authored-by: Leah E. Cole <[email protected]> * chore(deps): update dependency pytest to v5.4.3 [(#4279)](GoogleCloudPlatform/python-docs-samples#4279) * chore(deps): update dependency pytest to v5.4.3 * specify pytest for python 2 in appengine Co-authored-by: Leah Cole <[email protected]> * chore(deps): update dependency mock to v4 [(#4287)](GoogleCloudPlatform/python-docs-samples#4287) * chore(deps): update dependency mock to v4 * specify mock version for appengine python 2 Co-authored-by: Leah Cole <[email protected]> * test(spanner): add sleep to fix flaky test [(#4289)](GoogleCloudPlatform/python-docs-samples#4289) Co-authored-by: larkee <[email protected]> * chore: update templates * fix lint Co-authored-by: Jon Wayne Parrott <[email protected]> Co-authored-by: Jason Morton <[email protected]> Co-authored-by: Ryan Matsumoto <[email protected]> Co-authored-by: DPE bot <[email protected]> Co-authored-by: Bill Prin <[email protected]> Co-authored-by: michaelawyu <[email protected]> Co-authored-by: Jeffrey Rennie <[email protected]> Co-authored-by: Jason Dobry <[email protected]> Co-authored-by: Kurtis Van Gent <[email protected]> Co-authored-by: Frank Natividad <[email protected]> Co-authored-by: Jisha Abubaker <[email protected]> Co-authored-by: Jonathan Simon <[email protected]> Co-authored-by: Robin Reynolds-Haertle <[email protected]> Co-authored-by: Thea Flowers <[email protected]> Co-authored-by: Jeff Williams <[email protected]> Co-authored-by: Oluwatoni Oshikanlu <[email protected]> Co-authored-by: William Chargin <[email protected]> Co-authored-by: Gus Class <[email protected]> Co-authored-by: Mark <[email protected]> Co-authored-by: Doug Mahugh <[email protected]> Co-authored-by: Leonhard Gruenschloss <[email protected]> Co-authored-by: larkee <[email protected]> Co-authored-by: skuruppu <[email protected]> Co-authored-by: Renovate Bot <[email protected]> Co-authored-by: Takashi Matsuo <[email protected]> Co-authored-by: gcf-merge-on-green[bot] <60162190+gcf-merge-on-green[bot]@users.noreply.github.com> Co-authored-by: Leah E. Cole <[email protected]> Co-authored-by: Leah Cole <[email protected]> Co-authored-by: root <[email protected]>
1 parent 4069c37 commit 8910771

18 files changed

+3356
-39
lines changed

.github/CODEOWNERS

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Code owners file.
2+
# This file controls who is tagged for review for any given pull request.
3+
#
4+
# For syntax help see:
5+
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
6+
7+
8+
# The api-spanner-python team is the default owner for anything not
9+
# explicitly taken by someone else.
10+
* @googleapis/api-spanner-python
11+
/samples/ @googleapis/api-spanner-python @googleapis/python-samples-owners

docs/_templates/layout.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121

2222
<div class="body" role="main">
2323
<div class="admonition" id="python2-eol">
24-
On January 1, 2020 this library will no longer support Python 2 on the latest released version.
25-
Previously released library versions will continue to be available. For more information please
24+
As of January 1, 2020 this library no longer supports Python 2 on the latest released version.
25+
Library versions released prior to that date will continue to be available. For more information please
2626
visit <a href="https://cloud.google.com/python/docs/python2-sunset/">Python 2 support on Google Cloud</a>.
2727
</div>
2828
{% block body %} {% endblock %}

samples/AUTHORING_GUIDE.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md

samples/CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/CONTRIBUTING.md

samples/samples/README.rst

+290
Large diffs are not rendered by default.

samples/samples/README.rst.in

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# This file is used to generate README.rst
2+
3+
product:
4+
name: Google Cloud Spanner
5+
short_name: Cloud Spanner
6+
url: https://cloud.google.com/spanner/docs
7+
description: >
8+
`Google Cloud Spanner`_ is a highly scalable, transactional, managed,
9+
NewSQL database service. Cloud Spanner solves the need for a
10+
horizontally-scaling database with consistent global transactions and
11+
SQL semantics.
12+
13+
setup:
14+
- auth
15+
- install_deps
16+
17+
samples:
18+
- name: Snippets
19+
file: snippets.py
20+
show_help: true
21+
22+
cloud_client_library: true
23+
24+
folder: spanner/cloud-client

samples/samples/backup_sample.py

+314
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
# Copyright 2020 Google Inc. 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+
"""This application demonstrates how to create and restore from backups
16+
using Cloud Spanner.
17+
18+
For more information, see the README.rst under /spanner.
19+
"""
20+
21+
import argparse
22+
from datetime import datetime, timedelta
23+
import time
24+
25+
from google.cloud import spanner
26+
27+
28+
# [START spanner_create_backup]
29+
def create_backup(instance_id, database_id, backup_id):
30+
"""Creates a backup for a database."""
31+
spanner_client = spanner.Client()
32+
instance = spanner_client.instance(instance_id)
33+
database = instance.database(database_id)
34+
35+
# Create a backup
36+
expire_time = datetime.utcnow() + timedelta(days=14)
37+
backup = instance.backup(backup_id, database=database, expire_time=expire_time)
38+
operation = backup.create()
39+
40+
# Wait for backup operation to complete.
41+
operation.result(1200)
42+
43+
# Verify that the backup is ready.
44+
backup.reload()
45+
assert backup.is_ready() is True
46+
47+
# Get the name, create time and backup size.
48+
backup.reload()
49+
print(
50+
"Backup {} of size {} bytes was created at {}".format(
51+
backup.name, backup.size_bytes, backup.create_time
52+
)
53+
)
54+
55+
56+
# [END spanner_create_backup]
57+
58+
59+
# [START spanner_restore_database]
60+
def restore_database(instance_id, new_database_id, backup_id):
61+
"""Restores a database from a backup."""
62+
spanner_client = spanner.Client()
63+
instance = spanner_client.instance(instance_id)
64+
# Create a backup on database_id.
65+
66+
# Start restoring backup to a new database.
67+
backup = instance.backup(backup_id)
68+
new_database = instance.database(new_database_id)
69+
operation = new_database.restore(backup)
70+
71+
# Wait for restore operation to complete.
72+
operation.result(1200)
73+
74+
# Newly created database has restore information.
75+
new_database.reload()
76+
restore_info = new_database.restore_info
77+
print(
78+
"Database {} restored to {} from backup {}.".format(
79+
restore_info.backup_info.source_database,
80+
new_database_id,
81+
restore_info.backup_info.backup,
82+
)
83+
)
84+
85+
86+
# [END spanner_restore_database]
87+
88+
89+
# [START spanner_cancel_backup]
90+
def cancel_backup(instance_id, database_id, backup_id):
91+
spanner_client = spanner.Client()
92+
instance = spanner_client.instance(instance_id)
93+
database = instance.database(database_id)
94+
95+
expire_time = datetime.utcnow() + timedelta(days=30)
96+
97+
# Create a backup.
98+
backup = instance.backup(backup_id, database=database, expire_time=expire_time)
99+
operation = backup.create()
100+
101+
# Cancel backup creation.
102+
operation.cancel()
103+
104+
# Cancel operations are best effort so either it will complete or
105+
# be cancelled.
106+
while not operation.done():
107+
time.sleep(300) # 5 mins
108+
109+
# Deal with resource if the operation succeeded.
110+
if backup.exists():
111+
print("Backup was created before the cancel completed.")
112+
backup.delete()
113+
print("Backup deleted.")
114+
else:
115+
print("Backup creation was successfully cancelled.")
116+
117+
118+
# [END spanner_cancel_backup]
119+
120+
121+
# [START spanner_list_backup_operations]
122+
def list_backup_operations(instance_id, database_id):
123+
spanner_client = spanner.Client()
124+
instance = spanner_client.instance(instance_id)
125+
126+
# List the CreateBackup operations.
127+
filter_ = (
128+
"(metadata.database:{}) AND "
129+
"(metadata.@type:type.googleapis.com/"
130+
"google.spanner.admin.database.v1.CreateBackupMetadata)"
131+
).format(database_id)
132+
operations = instance.list_backup_operations(filter_=filter_)
133+
for op in operations:
134+
metadata = op.metadata
135+
print(
136+
"Backup {} on database {}: {}% complete.".format(
137+
metadata.name, metadata.database, metadata.progress.progress_percent
138+
)
139+
)
140+
141+
142+
# [END spanner_list_backup_operations]
143+
144+
145+
# [START spanner_list_database_operations]
146+
def list_database_operations(instance_id):
147+
spanner_client = spanner.Client()
148+
instance = spanner_client.instance(instance_id)
149+
150+
# List the progress of restore.
151+
filter_ = (
152+
"(metadata.@type:type.googleapis.com/"
153+
"google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata)"
154+
)
155+
operations = instance.list_database_operations(filter_=filter_)
156+
for op in operations:
157+
print(
158+
"Database {} restored from backup is {}% optimized.".format(
159+
op.metadata.name, op.metadata.progress.progress_percent
160+
)
161+
)
162+
163+
164+
# [END spanner_list_database_operations]
165+
166+
167+
# [START spanner_list_backups]
168+
def list_backups(instance_id, database_id, backup_id):
169+
spanner_client = spanner.Client()
170+
instance = spanner_client.instance(instance_id)
171+
172+
# List all backups.
173+
print("All backups:")
174+
for backup in instance.list_backups():
175+
print(backup.name)
176+
177+
# List all backups that contain a name.
178+
print('All backups with backup name containing "{}":'.format(backup_id))
179+
for backup in instance.list_backups(filter_="name:{}".format(backup_id)):
180+
print(backup.name)
181+
182+
# List all backups for a database that contains a name.
183+
print('All backups with database name containing "{}":'.format(database_id))
184+
for backup in instance.list_backups(filter_="database:{}".format(database_id)):
185+
print(backup.name)
186+
187+
# List all backups that expire before a timestamp.
188+
expire_time = datetime.utcnow().replace(microsecond=0) + timedelta(days=30)
189+
print(
190+
'All backups with expire_time before "{}-{}-{}T{}:{}:{}Z":'.format(
191+
*expire_time.timetuple()
192+
)
193+
)
194+
for backup in instance.list_backups(
195+
filter_='expire_time < "{}-{}-{}T{}:{}:{}Z"'.format(*expire_time.timetuple())
196+
):
197+
print(backup.name)
198+
199+
# List all backups with a size greater than some bytes.
200+
print("All backups with backup size more than 100 bytes:")
201+
for backup in instance.list_backups(filter_="size_bytes > 100"):
202+
print(backup.name)
203+
204+
# List backups that were created after a timestamp that are also ready.
205+
create_time = datetime.utcnow().replace(microsecond=0) - timedelta(days=1)
206+
print(
207+
'All backups created after "{}-{}-{}T{}:{}:{}Z" and are READY:'.format(
208+
*create_time.timetuple()
209+
)
210+
)
211+
for backup in instance.list_backups(
212+
filter_='create_time >= "{}-{}-{}T{}:{}:{}Z" AND state:READY'.format(
213+
*create_time.timetuple()
214+
)
215+
):
216+
print(backup.name)
217+
218+
print("All backups with pagination")
219+
for page in instance.list_backups(page_size=2).pages:
220+
for backup in page:
221+
print(backup.name)
222+
223+
224+
# [END spanner_list_backups]
225+
226+
227+
# [START spanner_delete_backup]
228+
def delete_backup(instance_id, backup_id):
229+
spanner_client = spanner.Client()
230+
instance = spanner_client.instance(instance_id)
231+
backup = instance.backup(backup_id)
232+
backup.reload()
233+
234+
# Wait for databases that reference this backup to finish optimizing.
235+
while backup.referencing_databases:
236+
time.sleep(30)
237+
backup.reload()
238+
239+
# Delete the backup.
240+
backup.delete()
241+
242+
# Verify that the backup is deleted.
243+
assert backup.exists() is False
244+
print("Backup {} has been deleted.".format(backup.name))
245+
246+
247+
# [END spanner_delete_backup]
248+
249+
250+
# [START spanner_update_backup]
251+
def update_backup(instance_id, backup_id):
252+
spanner_client = spanner.Client()
253+
instance = spanner_client.instance(instance_id)
254+
backup = instance.backup(backup_id)
255+
backup.reload()
256+
257+
# Expire time must be within 366 days of the create time of the backup.
258+
old_expire_time = backup.expire_time
259+
new_expire_time = old_expire_time + timedelta(days=30)
260+
backup.update_expire_time(new_expire_time)
261+
print(
262+
"Backup {} expire time was updated from {} to {}.".format(
263+
backup.name, old_expire_time, new_expire_time
264+
)
265+
)
266+
267+
268+
# [END spanner_update_backup]
269+
270+
271+
if __name__ == "__main__": # noqa: C901
272+
parser = argparse.ArgumentParser(
273+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
274+
)
275+
parser.add_argument("instance_id", help="Your Cloud Spanner instance ID.")
276+
parser.add_argument(
277+
"--database-id", help="Your Cloud Spanner database ID.", default="example_db"
278+
)
279+
parser.add_argument(
280+
"--backup-id", help="Your Cloud Spanner backup ID.", default="example_backup"
281+
)
282+
283+
subparsers = parser.add_subparsers(dest="command")
284+
subparsers.add_parser("create_backup", help=create_backup.__doc__)
285+
subparsers.add_parser("cancel_backup", help=cancel_backup.__doc__)
286+
subparsers.add_parser("update_backup", help=update_backup.__doc__)
287+
subparsers.add_parser("restore_database", help=restore_database.__doc__)
288+
subparsers.add_parser("list_backups", help=list_backups.__doc__)
289+
subparsers.add_parser("list_backup_operations", help=list_backup_operations.__doc__)
290+
subparsers.add_parser(
291+
"list_database_operations", help=list_database_operations.__doc__
292+
)
293+
subparsers.add_parser("delete_backup", help=delete_backup.__doc__)
294+
295+
args = parser.parse_args()
296+
297+
if args.command == "create_backup":
298+
create_backup(args.instance_id, args.database_id, args.backup_id)
299+
elif args.command == "cancel_backup":
300+
cancel_backup(args.instance_id, args.database_id, args.backup_id)
301+
elif args.command == "update_backup":
302+
update_backup(args.instance_id, args.backup_id)
303+
elif args.command == "restore_database":
304+
restore_database(args.instance_id, args.database_id, args.backup_id)
305+
elif args.command == "list_backups":
306+
list_backups(args.instance_id, args.database_id, args.backup_id)
307+
elif args.command == "list_backup_operations":
308+
list_backup_operations(args.instance_id, args.database_id)
309+
elif args.command == "list_database_operations":
310+
list_database_operations(args.instance_id)
311+
elif args.command == "delete_backup":
312+
delete_backup(args.instance_id, args.backup_id)
313+
else:
314+
print("Command {} did not match expected commands.".format(args.command))

0 commit comments

Comments
 (0)