Skip to content

Commit e780cc4

Browse files
committed
Pull snippets from docstrings.
1 parent 1157488 commit e780cc4

File tree

6 files changed

+324
-100
lines changed

6 files changed

+324
-100
lines changed

docs/storage_snippets.py

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
# Copyright 2016 Google Inc.
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+
"""Testable usage examples for Google Cloud Storage API wrapper
16+
17+
Each example function takes a ``client`` argument (which must be an instance
18+
of :class:`google.cloud.storage.client.Client`) and uses it to perform a task
19+
with the API.
20+
21+
To facilitate running the examples as system tests, each example is also passed
22+
a ``to_delete`` list; the function adds to the list any objects created which
23+
need to be deleted during teardown.
24+
"""
25+
26+
from google.cloud import storage
27+
28+
29+
def snippet(func):
30+
"""Mark ``func`` as a snippet example function."""
31+
func._snippet = True
32+
return func
33+
34+
35+
@snippet
36+
def storage_get_started(client, to_delete):
37+
# [START storage_get_started]
38+
client = storage.Client()
39+
bucket = client.get_bucket('bucket-id-here')
40+
# Then do other things...
41+
blob = bucket.get_blob('/remote/path/to/file.txt')
42+
assert blob.download_as_string() == 'My old contents!'
43+
blob.upload_from_string('New contents!')
44+
blob2 = bucket.blob('/remote/path/storage.txt')
45+
blob2.upload_from_filename(filename='/local/path.txt')
46+
# [END storage_get_started]
47+
48+
to_delete.append(bucket)
49+
50+
51+
@snippet
52+
def client_bucket_acl(client, to_delete):
53+
bucket_name = 'system-test-bucket'
54+
bucket = client.bucket(bucket_name)
55+
bucket.create()
56+
57+
# [START client_bucket_acl]
58+
client = storage.Client()
59+
bucket = client.get_bucket(bucket_name)
60+
acl = bucket.acl
61+
# [END client_bucket_acl]
62+
to_delete.append(bucket)
63+
64+
# [START acl_user_settings]
65+
acl.user('[email protected]').grant_read()
66+
acl.all_authenticated().grant_write()
67+
# [END acl_user_settings]
68+
69+
# [START acl_save]
70+
acl.save()
71+
# [END acl_save]
72+
73+
# [START acl_revoke_write]
74+
acl.all().grant_read().revoke_write()
75+
# [END acl_revoke_write]
76+
77+
# [START acl_save_bucket]
78+
bucket.acl.save(acl=acl)
79+
# [END acl_save_bucket]
80+
81+
# [START acl_print]
82+
print(list(acl))
83+
# [{'role': 'OWNER', 'entity': 'allUsers'}, ...]
84+
# [END acl_print]
85+
86+
87+
@snippet
88+
def download_to_file(client, to_delete):
89+
# [START download_to_file]
90+
from google.cloud.storage import Blob
91+
92+
client = storage.Client(project='my-project')
93+
bucket = client.get_bucket('my-bucket')
94+
encryption_key = 'c7f32af42e45e85b9848a6a14dd2a8f6'
95+
blob = Blob('secure-data', bucket, encryption_key=encryption_key)
96+
with open('/tmp/my-secure-file', 'wb') as file_obj:
97+
blob.download_to_file(file_obj)
98+
# [END download_to_file]
99+
100+
to_delete.append(blob)
101+
102+
103+
@snippet
104+
def upload_from_file(client, to_delete):
105+
# [START upload_from_file]
106+
from google.cloud.storage import Blob
107+
108+
client = storage.Client(project='my-project')
109+
bucket = client.get_bucket('my-bucket')
110+
encryption_key = 'aa426195405adee2c8081bb9e7e74b19'
111+
blob = Blob('secure-data', bucket, encryption_key=encryption_key)
112+
with open('my-file', 'rb') as my_file:
113+
blob.upload_from_file(my_file)
114+
# [END upload_from_file]
115+
116+
to_delete.append(blob)
117+
118+
119+
@snippet
120+
def get_blob(client, to_delete):
121+
from google.cloud.storage.blob import Blob
122+
# [START get_blob]
123+
client = storage.Client()
124+
bucket = client.get_bucket('my-bucket')
125+
assert isinstance(bucket.get_blob('/path/to/blob.txt'), Blob)
126+
# <Blob: my-bucket, /path/to/blob.txt>
127+
assert not bucket.get_blob('/does-not-exist.txt')
128+
# None
129+
# [END get_blob]
130+
131+
to_delete.append(bucket)
132+
133+
134+
@snippet
135+
def delete_blob(client, to_delete):
136+
# [START delete_blob]
137+
from google.cloud.exceptions import NotFound
138+
client = storage.Client()
139+
bucket = client.get_bucket('my-bucket')
140+
assert isinstance(bucket.list_blobs(), list)
141+
# [<Blob: my-bucket, my-file.txt>]
142+
bucket.delete_blob('my-file.txt')
143+
try:
144+
bucket.delete_blob('doesnt-exist')
145+
except NotFound:
146+
pass
147+
# [END delete_blob]
148+
149+
blob = None
150+
# [START delete_blobs]
151+
bucket.delete_blobs([blob], on_error=lambda blob: None)
152+
# [END delete_blobs]
153+
154+
to_delete.append(bucket)
155+
156+
157+
@snippet
158+
def configure_website(client, to_delete):
159+
bucket_name = 'test-bucket'
160+
# [START configure_website]
161+
client = storage.Client()
162+
bucket = client.get_bucket(bucket_name)
163+
bucket.configure_website('index.html', '404.html')
164+
# [END configure_website]
165+
166+
# [START make_public]
167+
bucket.make_public(recursive=True, future=True)
168+
# [END make_public]
169+
170+
to_delete.append(bucket)
171+
172+
173+
@snippet
174+
def get_bucket(client, to_delete):
175+
import google
176+
# [START get_bucket]
177+
try:
178+
bucket = client.get_bucket('my-bucket')
179+
except google.cloud.exceptions.NotFound:
180+
print('Sorry, that bucket does not exist!')
181+
# [END get_bucket]
182+
to_delete.append(bucket)
183+
184+
185+
@snippet
186+
def lookup_bucket(client, to_delete):
187+
from google.cloud.storage.bucket import Bucket
188+
# [START lookup_bucket]
189+
bucket = client.lookup_bucket('doesnt-exist')
190+
assert not bucket
191+
# None
192+
bucket = client.lookup_bucket('my-bucket')
193+
assert isinstance(bucket, Bucket)
194+
# <Bucket: my-bucket>
195+
# [END lookup_bucket]
196+
197+
to_delete.append(bucket)
198+
199+
200+
@snippet
201+
def create_bucket(client, to_delete):
202+
from google.cloud.storage import Bucket
203+
# [START create_bucket]
204+
bucket = client.create_bucket('my-bucket')
205+
assert isinstance(bucket, Bucket)
206+
# <Bucket: my-bucket>
207+
# [END create_bucket]
208+
209+
to_delete.append(bucket)
210+
211+
212+
@snippet
213+
def list_buckets(client, to_delete):
214+
# [START list_buckets]
215+
for bucket in client.list_buckets():
216+
print(bucket)
217+
# [END list_buckets]
218+
219+
for bucket in client.list_buckets():
220+
to_delete.append(bucket)
221+
222+
223+
def _line_no(func):
224+
code = getattr(func, '__code__', None) or getattr(func, 'func_code')
225+
return code.co_firstlineno
226+
227+
228+
def _find_examples():
229+
funcs = [obj for obj in globals().values()
230+
if getattr(obj, '_snippet', False)]
231+
for func in sorted(funcs, key=_line_no):
232+
yield func
233+
234+
235+
def _name_and_doc(func):
236+
return func.__name__, func.__doc__
237+
238+
239+
def main():
240+
client = storage.Client()
241+
for example in _find_examples():
242+
to_delete = []
243+
print('%-25s: %s' % _name_and_doc(example))
244+
try:
245+
example(client, to_delete)
246+
except AssertionError as failure:
247+
print(' FAIL: %s' % (failure,))
248+
except Exception as error: # pylint: disable=broad-except
249+
print(' ERROR: %r' % (error,))
250+
for item in to_delete:
251+
item.delete()
252+
253+
254+
if __name__ == '__main__':
255+
main()

storage/google/cloud/storage/__init__.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,9 @@
1616
1717
You'll typically use these to get started with the API:
1818
19-
>>> from google.cloud import storage
20-
>>> client = storage.Client()
21-
>>> bucket = client.get_bucket('bucket-id-here')
22-
>>> # Then do other things...
23-
>>> blob = bucket.get_blob('/remote/path/to/file.txt')
24-
>>> print(blob.download_as_string())
25-
>>> blob.upload_from_string('New contents!')
26-
>>> blob2 = bucket.blob('/remote/path/storage.txt')
27-
>>> blob2.upload_from_filename(filename='/local/path.txt')
19+
.. literalinclude:: storage_snippets.py
20+
:start-after: [START storage_get_started]
21+
:end-before: [END storage_get_started]
2822
2923
The main concepts with this API are:
3024

storage/google/cloud/storage/acl.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
1717
:class:`google.cloud.storage.bucket.Bucket` has a getting method that creates
1818
an ACL object under the hood, and you can interact with that using
19-
:func:`google.cloud.storage.bucket.Bucket.acl`::
19+
:func:`google.cloud.storage.bucket.Bucket.acl`:
20+
21+
.. literalinclude:: storage_snippets.py
22+
:start-after: [START client_bucket_acl]
23+
:end-before: [END client_bucket_acl]
2024
21-
>>> from google.cloud import storage
22-
>>> client = storage.Client()
23-
>>> bucket = client.get_bucket(bucket_name)
24-
>>> acl = bucket.acl
2525
2626
Adding and removing permissions can be done with the following methods
2727
(in increasing order of granularity):
@@ -47,32 +47,40 @@
4747
:func:`_ACLEntity.grant_owner` and :func:`_ACLEntity.revoke_owner`
4848
4949
You can use any of these like any other factory method (these happen to
50-
be :class:`_ACLEntity` factories)::
50+
be :class:`_ACLEntity` factories):
5151
52-
>>> acl.user('[email protected]').grant_read()
53-
>>> acl.all_authenticated().grant_write()
52+
.. literalinclude:: storage_snippets.py
53+
:start-after: [START acl_user_settings]
54+
:end-before: [END acl_user_settings]
5455
5556
You can also chain these ``grant_*`` and ``revoke_*`` methods together
56-
for brevity::
57+
for brevity:
5758
58-
>>> acl.all().grant_read().revoke_write()
59+
.. literalinclude:: storage_snippets.py
60+
:start-after: [START acl_revoke_write]
61+
:end-before: [END acl_revoke_write]
5962
6063
After that, you can save any changes you make with the
61-
:func:`google.cloud.storage.acl.ACL.save` method::
64+
:func:`google.cloud.storage.acl.ACL.save` method:
6265
63-
>>> acl.save()
66+
.. literalinclude:: storage_snippets.py
67+
:start-after: [START acl_save]
68+
:end-before: [END acl_save]
6469
6570
You can alternatively save any existing :class:`google.cloud.storage.acl.ACL`
6671
object (whether it was created by a factory method or not) from a
67-
:class:`google.cloud.storage.bucket.Bucket`::
72+
:class:`google.cloud.storage.bucket.Bucket`:
6873
69-
>>> bucket.acl.save(acl=acl)
74+
.. literalinclude:: storage_snippets.py
75+
:start-after: [START acl_save_bucket]
76+
:end-before: [END acl_save_bucket]
7077
7178
To get the list of ``entity`` and ``role`` for each unique pair, the
72-
:class:`ACL` class is iterable::
79+
:class:`ACL` class is iterable:
7380
74-
>>> print(list(ACL))
75-
[{'role': 'OWNER', 'entity': 'allUsers'}, ...]
81+
.. literalinclude:: storage_snippets.py
82+
:start-after: [START acl_print]
83+
:end-before: [END acl_print]
7684
7785
This list of tuples can be used as the ``entity`` and ``role`` fields
7886
when sending metadata for ACLs to the API.

storage/google/cloud/storage/blob.py

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -299,18 +299,11 @@ def download_to_file(self, file_obj, client=None):
299299
initialized, makes an additional API request to load it.
300300
301301
Downloading a file that has been encrypted with a `customer-supplied`_
302-
encryption key::
302+
encryption key:
303303
304-
>>> from google.cloud import storage
305-
>>> from google.cloud.storage import Blob
306-
307-
>>> client = storage.Client(project='my-project')
308-
>>> bucket = client.get_bucket('my-bucket')
309-
>>> encryption_key = 'aa426195405adee2c8081bb9e7e74b19'
310-
>>> blob = Blob('secure-data', bucket,
311-
... encryption_key=encryption_key)
312-
>>> with open('/tmp/my-secure-file', 'wb') as file_obj:
313-
>>> blob.download_to_file(file_obj)
304+
.. literalinclude:: storage_snippets.py
305+
:start-after: [START download_to_file]
306+
:end-before: [END download_to_file]
314307
315308
The ``encryption_key`` should be a str or bytes with a length of at
316309
least 32.
@@ -418,18 +411,11 @@ def upload_from_file(self, file_obj, rewind=False, size=None,
418411
`lifecycle <https://cloud.google.com/storage/docs/lifecycle>`_
419412
API documents for details.
420413
421-
Uploading a file with a `customer-supplied`_ encryption key::
422-
423-
>>> from google.cloud import storage
424-
>>> from google.cloud.storage import Blob
414+
Uploading a file with a `customer-supplied`_ encryption key:
425415
426-
>>> client = storage.Client(project='my-project')
427-
>>> bucket = client.get_bucket('my-bucket')
428-
>>> encryption_key = 'aa426195405adee2c8081bb9e7e74b19'
429-
>>> blob = Blob('secure-data', bucket,
430-
... encryption_key=encryption_key)
431-
>>> with open('my-file', 'rb') as my_file:
432-
>>> blob.upload_from_file(my_file)
416+
.. literalinclude:: storage_snippets.py
417+
:start-after: [START upload_from_file]
418+
:end-before: [END upload_from_file]
433419
434420
The ``encryption_key`` should be a str or bytes with a length of at
435421
least 32.

0 commit comments

Comments
 (0)