8000 App Engine Cloud Storage Client Sample (#793) · dcaballerod/python-docs-samples@d5d402d · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit d5d402d

Browse files
ryanmatsJon Wayne Parrott
authored andcommitted
App Engine Cloud Storage Client Sample (GoogleCloudPlatform#793)
* Added AppEngine Storage Client sample, renamed subfolders * Fixed code review issues * Updated storage api-client code to upload/delete objects - now testing works * Changed BUCKET_NAME back to <your-bucket-name> * Fixed code review issues
1 parent 5861d19 commit d5d402d

File tree

12 files changed

+233
-1
lines changed

12 files changed

+233
-1
lines changed

appengine/standard/storage/main.py renamed to appengine/standard/storage/api-client/main.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
"""
2424

2525
import json
26+
import StringIO
2627

2728
from googleapiclient import discovery
29+
from googleapiclient import http
2830
from oauth2client.client import GoogleCredentials
2931
import webapp2
3032

@@ -37,14 +39,33 @@
3739

3840

3941
class MainPage(webapp2.RequestHandler):
42+
def upload_object(self, bucket, file_object):
43+
body = {
44+
'name': 'storage-api-client-sample-file.txt',
45+
}
46+
req = storage.objects().insert(
47+
bucket=bucket, body=body, media_body=http.MediaIoBaseUpload(
48+
file_object, 'application/octet-stream'))
49+
resp = req.execute()
50+
return resp
51+
52+
def delete_object(self, bucket, filename):
53+
req = storage.objects().delete(bucket=bucket, object=filename)
54+
resp = req.execute()
55+
return resp
56+
4057
def get(self):
41-
response = storage.objects().list(bucket=BUCKET_NAME).execute()
58+
string_io_file = StringIO.StringIO('Hello World!')
59+
self.upload_object(BUCKET_NAME, string_io_file)
4260

61+
response = storage.objects().list(bucket=BUCKET_NAME).execute()
4362
self.response.write(
4463
'<h3>Objects.list raw response:</h3>'
4564
'<pre>{}</pre>'.format(
4665
json.dumps(response, sort_keys=True, indent=2)))
4766

67+
self.delete_object(BUCKET_NAME, 'storage-api-client-sample-file.txt')
68+
4869

4970
app = webapp2.WSGIApplication([
5071
('/', MainPage)

appengine/standard/storage/appengine-client/__init__.py

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
runtime: python27
2+
api_version: 1
3+
threadsafe: yes
4+
5+
env_variables:
6+
7+
handlers:
8+
- url: /blobstore.*
9+
script: blobstore.app
10+
11+
- url: /.*
12+
script: main.app
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from google.appengine.ext import vendor
2+
3+
# Add any libraries installed in the "lib" folder.
4+
vendor.add('lib')
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2017 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+
# [START sample]
18+
"""A sample app that uses GCS client to operate on bucket and file."""
19+
20+
# [START imports]
21+
import os
22+
23+
import cloudstorage
24+
from google.appengine.api import app_identity
25+
26+
import webapp2
27+
28+
# [END imports]
29+
30+
# [START retries]
31+
cloudstorage.set_default_retry_params(
32+
cloudstorage.RetryParams(
33+
initial_delay=0.2, max_delay=5.0, backoff_factor=2, max_retry_period=15
34+
))
35+
# [END retries]
36+
37+
38+
class MainPage(webapp2.RequestHandler):
39+
"""Main page for GCS demo application."""
40+
41+
# [START get_default_bucket]
42+
def get(self):
43+
bucket_name = os.environ.get(
44+
'BUCKET_NAME', app_identity.get_default_gcs_bucket_name())
45+
46+
self.response.headers['Content-Type'] = 'text/plain'
47+
self.response.write(
48+
'Demo GCS Application running from Version: {}\n'.format(
49+
os.environ['CURRENT_VERSION_ID']))
50+
self.response.write('Using bucket name: \n\n'.format(bucket_name))
51+
# [END get_default_bucket]
52+
53+
bucket = '/' + bucket_name
54+
filename = bucket + '/demo-testfile'
55+
self.tmp_filenames_to_clean_up = []
56+
57+
self.create_file(filename)
58+
self.response.write('\n\n')
59+
60+
self.read_file(filename)
61+
self.response.write('\n\n')
62+
63+
self.stat_file(filename)
64+
self.response.write('\n\n')
65+
66+
self.create_files_for_list_bucket(bucket)
67+
self.response.write('\n\n')
68+
69+
self.list_bucket(bucket)
70+
self.response.write('\n\n')
71+
72+
self.list_bucket_directory_mode(bucket)
73+
self.response.write('\n\n')
74+
75+
self.delete_files()
76+
self.response.write('\n\nThe demo ran successfully!\n')
77+
78+
# [START write]
79+
def create_file(self, filename):
80+
"""Create a file."""
81+
82+
self.response.write('Creating file {}\n'.format(filename))
83+
84+
# The retry_params specified in the open call will override the default
85+
# retry params for this particular file handle.
86+
write_retry_params = cloudstorage.RetryParams(backoff_factor=1.1)
87+
with cloudstorage.open(
88+
filename, 'w', content_type='text/plain', options={
89+
'x-goog-meta-foo': 'foo', 'x-goog-meta-bar': 'bar'},
90+
retry_params=write_retry_params) as cloudstorage_file:
91+
cloudstorage_file.write('abcde\n')
92+
cloudstorage_file.write('f'*1024*4 + '\n')
93+
self.tmp_filenames_to_clean_up.append(filename)
94+
# [END write]
95+
96+
# [START read]
97+
def read_file(self, filename):
98+
self.response.write(
99+
'Abbreviated file content (first line and last 1K):\n')
100+
101+
with cloudstorage.open(filename) as cloudstorage_file:
102+
self.response.write(cloudstorage_file.readline())
103+
cloudstorage_file.seek(-1024, os.SEEK_END)
104+
self.response.write(cloudstorage_file.read())
105+
# [END read]
106+
107+
def stat_file(self, filename):
108+
self.response.write('File stat:\n')
109+
110+
stat = cloudstorage.stat(filename)
111+
self.response.write(repr(stat))
112+
113+
def create_files_for_list_bucket(self, bucket):
114+
self.response.write('Creating more files for listbucket...\n')
115+
filenames = [bucket + n for n in [
116+
'/foo1', '/foo2', '/bar', '/bar/1', '/bar/2', '/boo/']]
117+
for f in filenames:
118+
self.create_file(f)
119+
120+
# [START list_bucket]
121+
def list_bucket(self, bucket):
122+
"""Create several files and paginate through them."""
123+
124+
self.response.write('Listbucket result:\n')
125+
126+
# Production apps should set page_size to a practical value.
127+
page_size = 1
128+
stats = cloudstorage.listbucket(bucket + '/foo', max_keys=page_size)
129+
while True:
130+
count = 0
131+
for stat in stats:
132+
count += 1
133+
self.response.write(repr(stat))
134+
self.response.write('\n')
135+
136+
if count != page_size or count == 0:
137+
break
138+
stats = cloudstorage.listbucket(
139+
bucket + '/foo', max_keys=page_size, marker=stat.filename)
140+
# [END list_bucket]
141+
142+
def list_bucket_directory_mode(self, bucket):
143+
self.response.write('Listbucket directory mode result:\n')
144+
for stat in cloudstorage.listbucket(bucket + '/b', delimiter='/'):
145+
self.response.write(stat)
146+
self.response.write('\n')
147+
if stat.is_dir:
148+
for subdir_file in cloudstorage.listbucket(
149+
stat.filename, delimiter='/'):
150+
self.response.write(' {}'.format(subdir_file))
151+
self.response.write('\n')
152+
153+
# [START delete_files]
154+
def delete_files(self):
155+
self.response.write('Deleting files...\n')
156+
for filename in self.tmp_filenames_to_clean_up:
157+
self.response.write('Deleting file {}\n'.format(filename))
158+
try:
159+
cloudstorage.delete(filename)
160+
except cloudstorage.NotFoundError:
161+
pass
162+
# [END delete_files]
163+
164+
165+
app = webapp2.WSGIApplication(
166+
[('/', MainPage)], debug=True)
167+
# [END sample]

0 commit comments

Comments
 (0)
0