Skip to content

Commit fe89e2f

Browse files
committed
Added AppEngine Storage Client sample, renamed subfolders
1 parent 4002e93 commit fe89e2f

12 files changed

Lines changed: 230 additions & 0 deletions

File tree

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

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: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
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 logging
22+
import os
23+
24+
import cloudstorage as gcs
25+
from google.appengine.api import app_identity
26+
27+
import webapp2
28+
29+
# [END imports]
30+
31+
# [START retries]
32+
my_default_retry_params = gcs.RetryParams(
33+
initial_delay=0.2, max_delay=5.0, backoff_factor=2, max_retry_period=15)
34+
gcs.set_default_retry_params(my_default_retry_params)
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: ' +
49+
os.environ['CURRENT_VERSION_ID'] + '\n')
50+
self.response.write('Using bucket name: ' + bucket_name + '\n\n')
51+
# [END get_default_bucket]
52+
53+
bucket = '/' + bucket_name
54+
filename = bucket + '/demo-testfile'
55+
self.tmp_filenames_to_clean_up = []
56+
57+
try:
58+
self.create_file(filename)
59+
self.response.write('\n\n')
60+
61+
self.read_file(filename)
62+
self.response.write('\n\n')
63+
64+
self.stat_file(filename)
65+
self.response.write('\n\n')
66+
67+
self.create_files_for_list_bucket(bucket)
68+
self.response.write('\n\n')
69+
70+
self.list_bucket(bucket)
71+
self.response.write('\n\n')
72+
73+
self.list_bucket_directory_mode(bucket)
74+
self.response.write('\n\n')
75+
76+
except Exception, e:
77+
logging.exception(e)
78+
self.delete_files()
79+
self.response.write(
80+
'\n\nThere was an error running the demo!Please check the logs'
81+
' for more details.\n')
82+
83+
else:
84+
self.delete_files()
85+
self.response.write('\n\nThe demo ran successfully!\n')
86+
87+
# [START write]
88+
def create_file(self, filename):
89+
"""Create a file.
90+
91+
The retry_params specified in the open call will override the default
92+
retry params for this particular file handle.
93+
94+
Args:
95+
filename: filename.
96+
"""
97+
self.response.write('Creating file %s\n' % filename)
98+
99+
write_retry_params = gcs.RetryParams(backoff_factor=1.1)
100+
gcs_file = gcs.open(
101+
filename, 'w', content_type='text/plain', options={
102+
'x-goog-meta-foo': 'foo', 'x-goog-meta-bar': 'bar'},
103+
retry_params=write_retry_params)
104+
gcs_file.write('abcde\n')
105+
gcs_file.write('f'*1024*4 + '\n')
106+
gcs_file.close()
107+
self.tmp_filenames_to_clean_up.append(filename)
108+
# [END write]
109+
110+
# [START read]
111+
def read_file(self, filename):
112+
self.response.write(
113+
'Abbreviated file content (first line and last 1K):\n')
114+
115+
gcs_file = gcs.open(filename)
116+
self.response.write(gcs_file.readline())
117+
gcs_file.seek(-1024, os.SEEK_END)
118+
self.response.write(gcs_file.read())
119+
gcs_file.close()
120+
# [END read]
121+
122+
def stat_file(self, filename):
123+
self.response.write('File stat:\n')
124+
125+
stat = gcs.stat(filename)
126+
self.response.write(repr(stat))
127+
128+
def create_files_for_list_bucket(self, bucket):
129+
self.response.write('Creating more files for listbucket...\n')
130+
filenames = [bucket + n for n in [
131+
'/foo1', '/foo2', '/bar', '/bar/1', '/bar/2', '/boo/']]
132+
for f in filenames:
133+
self.create_file(f)
134+
135+
# [START list_bucket]
136+
def list_bucket(self, bucket):
137+
"""Create several files and paginate through them.
138+
139+
Production apps should set page_size to a practical value.
140+
141+
Args:
142+
bucket: bucket.
143+
"""
144+
self.response.write('Listbucket result:\n')
145+
146+
page_size = 1
147+
stats = gcs.listbucket(bucket + '/foo', max_keys=page_size)
148+
while True:
149+
count = 0
150+
for stat in stats:
151+
count += 1
152+
self.response.write(repr(stat))
153+
self.response.write('\n')
154+
155+
if count != page_size or count == 0:
156+
break
157+
stats = gcs.listbucket(
158+
bucket + '/foo', max_keys=page_size, marker=stat.filename)
159+
# [END list_bucket]
160+
161+
def list_bucket_directory_mode(self, bucket):
162+
self.response.write('Listbucket directory mode result:\n')
163+
for stat in gcs.listbucket(bucket + '/b', delimiter='/'):
164+
self.response.write('%r' % stat)
165+
self.response.write('\n')
166+
if stat.is_dir:
167+
for subdir_file in gcs.listbucket(
168+
stat.filename, delimiter='/'):
169+
self.response.write(' %r' % subdir_file)
170+
self.response.write('\n')
171+
172+
# [START delete_files]
173+
def delete_files(self):
174+
self.response.write('Deleting files...\n')
175+
for filename in self.tmp_filenames_to_clean_up:
176+
self.response.write('Deleting file %s\n' % filename)
177+
try:
178+
gcs.delete(filename)
179+
except gcs.NotFoundError:
180+
pass
181+
# [END delete_files]
182+
183+
184+
app = webapp2.WSGIApplication(
185+
[('/', MainPage)], debug=True)
186+
# [END sample]

0 commit comments

Comments
 (0)