Skip to content

Commit 87ff834

Browse files
author
Jerjou Cheng
committed
Add sample for CRUD on GCS.
(or at least, CRD)
1 parent 6f3c788 commit 87ff834

File tree

2 files changed

+171
-0
lines changed

2 files changed

+171
-0
lines changed

storage/api/crud_object.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright (C) 2016 Google Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Application for uploading an object using the Cloud Storage API.
18+
19+
This sample is used on this page:
20+
21+
https://cloud.google.com/storage/docs/json_api/v1/json-api-python-samples
22+
23+
For more information, see the README.md under /storage.
24+
"""
25+
26+
import argparse
27+
import filecmp
28+
import json
29+
import tempfile
30+
31+
from googleapiclient import discovery
32+
from googleapiclient import http
33+
34+
from oauth2client.client import GoogleCredentials
35+
36+
37+
def main(bucket, filename, readers=[], owners=[]):
38+
print('Uploading object..')
39+
resp = upload_object(bucket, filename, readers, owners)
40+
print(json.dumps(resp, indent=2))
41+
42+
print('Fetching object..')
43+
with tempfile.NamedTemporaryFile(mode='w+b') as tmpfile:
44+
get_object(bucket, filename, out_file=tmpfile)
45+
tmpfile.seek(0)
46+
47+
if not filecmp.cmp(filename, tmpfile.name):
48+
raise Exception('Downloaded file != uploaded object')
49+
50+
print('Deleting object..')
51+
resp = delete_object(bucket, filename)
52+
if resp:
53+
print(json.dumps(resp, indent=2))
54+
print 'Done'
55+
56+
57+
def create_service():
58+
# Get the application default credentials. When running locally, these are
59+
# available after running `gcloud init`. When running on compute
60+
# engine, these are available from the environment.
61+
credentials = GoogleCredentials.get_application_default()
62+
63+
# Construct the service object for interacting with the Cloud Storage API -
64+
# the 'storage' service, at version 'v1'.
65+
# You can browse other available api services and versions here:
66+
# http://g.co/dev/api-client-library/python/apis/
67+
return discovery.build('storage', 'v1', credentials=credentials)
68+
69+
70+
def upload_object(bucket, filename, readers, owners):
71+
service = create_service()
72+
73+
# This is the request body as specified:
74+
# http://g.co/cloud/storage/docs/json_api/v1/objects/insert#request
75+
body = {
76+
'name': filename,
77+
}
78+
79+
# If specified, create the access control objects and add them to the
80+
# request body
81+
if readers or owners:
82+
body['acl'] = []
83+
for r in readers:
84+
body['acl'].append({
85+
'entity': 'user-%s' % r,
86+
'role': 'READER',
87+
'email': r
88+
})
89+
for o in owners:
90+
body['acl'].append({
91+
'entity': 'user-%s' % o,
92+
'role': 'OWNER',
93+
'email': o
94+
})
95+
96+
# Now insert them into the specified bucket as a media insertion.
97+
# http://g.co/dev/resources/api-libraries/documentation/storage/v1/python/latest/storage_v1.objects.html#insert
98+
with open(filename, 'rb') as f:
99+
req = service.objects().insert(
100+
bucket=bucket, body=body,
101+
# You can also just set media_body=filename, but # for the sake of
102+
# demonstration, pass in the more generic file handle, which could
103+
# very well be a StringIO or similar.
104+
media_body=http.MediaIoBaseUpload(f, 'application/octet-stream'))
105+
resp = req.execute()
106+
107+
return resp
108+
109+
110+
def get_object(bucket, filename, out_file):
111+
service = create_service()
112+
113+
# Use get_media instead of get to get the actual contents of the object.
114+
# http://g.co/dev/resources/api-libraries/documentation/storage/v1/python/latest/storage_v1.objects.html#get_media
115+
req = service.objects().get_media(bucket=bucket, object=filename)
116+
117+
downloader = http.MediaIoBaseDownload(out_file, req)
118+
119+
done = False
120+
while done is False:
121+
status, done = downloader.next_chunk()
122+
print("Download {}%.".format(int(status.progress() * 100)))
123+
124+
return out_file
125+
126+
127+
def delete_object(bucket, filename):
128+
service = create_service()
129+
130+
req = service.objects().delete(bucket=bucket, object=filename)
131+
resp = req.execute()
132+
133+
return resp
134+
135+
136+
if __name__ == '__main__':
137+
parser = argparse.ArgumentParser(
138+
description=__doc__,
139+
formatter_class=argparse.RawDescriptionHelpFormatter)
140+
parser.add_argument('filename', help='The name of the file to upload')
141+
parser.add_argument('bucket', help='Your Cloud Storage bucket.')
142+
parser.add_argument('--reader', action='append', default=[],
143+
help='Your Cloud Storage bucket.')
144+
parser.add_argument('--owner', action='append', default=[],
145+
help='Your Cloud Storage bucket.')
146+
147+
args = parser.parse_args()
148+
149+
main(args.bucket, args.filename, args.reader, args.owner)

storage/api/crud_object_test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2016, Google, Inc.
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
from crud_object import main
15+
16+
17+
def test_main(cloud_config, capsys):
18+
main(cloud_config.storage_bucket, __file__)
19+
out, err = capsys.readouterr()
20+
21+
assert not re.search(r'Downloaded file [!]=', out)
22+
assert re.search(r'Uploading.*Fetching.*Deleting.*Done', out)

0 commit comments

Comments
 (0)