Skip to content

Blobstore API with Google Cloud Storage samples #709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions appengine/standard/blobstore/blobreader/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: .*
script: main.app
login: required
18 changes: 18 additions & 0 deletions appengine/standard/blobstore/blobreader/appengine_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.appengine.ext import vendor

# Add any libraries installed in the "lib" folder.
vendor.add('lib')
69 changes: 69 additions & 0 deletions appengine/standard/blobstore/blobreader/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""A sample app that operates on GCS files with blobstore API's BlobReader."""

import cloudstorage
from google.appengine.api import app_identity
from google.appengine.ext import blobstore
import webapp2


class BlobreaderHandler(webapp2.RequestHandler):
def get(self):
# Get the default Cloud Storage Bucket name and create a file name for
# the object in Cloud Storage.
bucket = app_identity.get_default_gcs_bucket_name()

# Cloud Storage file names are in the format /bucket/object.
filename = '/{}/blobreader_demo'.format(bucket)

# Create a file in Google Cloud Storage and write something to it.
with cloudstorage.open(filename, 'w') as filehandle:
filehandle.write('abcde\n')

# In order to read the contents of the file using the Blobstore API,
# you must create a blob_key from the Cloud Storage file name.
# Blobstore expects the filename to be in the format of:
# /gs/bucket/object
blobstore_filename = '/gs{}'.format(filename)
blob_key = blobstore.create_gs_key(blobstore_filename)

# [START blob_reader]
# Instantiate a BlobReader for a given Blobstore blob_key.
blob_reader = blobstore.BlobReader(blob_key)

# Instantiate a BlobReader for a given Blobstore blob_key, setting the
# buffer size to 1 MB.
blob_reader = blobstore.BlobReader(blob_key, buffer_size=1048576)

# Instantiate a BlobReader for a given Blobstore blob_key, setting the
# initial read position.
blob_reader = blobstore.BlobReader(blob_key, position=0)

# Read the entire value into memory. This may take a while depending
# on the size of the value and the size of the read buffer, and is not
# recommended for large values.
blob_reader_data = blob_reader.read()

# Write the contents to the response.
self.response.headers['Content-Type'] = 'text/plain'
self.response.write(blob_reader_data)

# Set the read position back to 0, then read and write 3 bytes.
blob_reader.seek(0)
blob_reader_data = blob_reader.read(3)
self.response.write(blob_reader_data)
self.response.write('\n')

# Set the read position back to 0, then read and write one line (up to
# and including a '\n' character) at a time.
blob_reader.seek(0)
for line in blob_reader:
self.response.write(line)
# [END blob_reader]

# Delete the file from Google Cloud Storage using the blob_key.
blobstore.delete(blob_key)


app = webapp2.WSGIApplication([
('/', BlobreaderHandler),
('/blobreader', BlobreaderHandler)], debug=True)
25 changes: 25 additions & 0 deletions appengine/standard/blobstore/blobreader/main_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import webtest

import main


def test_blobreader(testbed, login):
app = webtest.TestApp(main.app)

response = app.get('/blobreader')

assert 'abcde\nabc\nabcde\n' in response
1 change: 1 addition & 0 deletions appengine/standard/blobstore/blobreader/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GoogleAppEngineCloudStorageClient==1.9.22.1
8 changes: 8 additions & 0 deletions appengine/standard/blobstore/gcs/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: .*
script: main.app
login: required
18 changes: 18 additions & 0 deletions appengine/standard/blobstore/gcs/appengine_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.appengine.ext import vendor

# Add any libraries installed in the "lib" folder.
vendor.add('lib')
76 changes: 76 additions & 0 deletions appengine/standard/blobstore/gcs/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""A sample app that operates on GCS files with blobstore API."""

import cloudstorage
from google.appengine.api import app_identity
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
import webapp2


# This handler creates a file in Cloud Storage using the cloudstorage
# client library and then reads the data back using the Blobstore API.
class CreateAndReadFileHandler(webapp2.RequestHandler):
def get(self):
# Get the default Cloud Storage Bucket name and create a file name for
# the object in Cloud Storage.
bucket = app_identity.get_default_gcs_bucket_name()

# Cloud Storage file names are in the format /bucket/object.
filename = '/{}/blobstore_demo'.format(bucket)

# Create a file in Google Cloud Storage and write something to it.
with cloudstorage.open(filename, 'w') as filehandle:
filehandle.write('abcde\n')

# In order to read the contents of the file using the Blobstore API,
# you must create a blob_key from the Cloud Storage file name.
# Blobstore expects the filename to be in the format of:
# /gs/bucket/object
blobstore_filename = '/gs{}'.format(filename)
blob_key = blobstore.create_gs_key(blobstore_filename)

# Read the file's contents using the Blobstore API.
# The last two parameters specify the start and end index of bytes we
# want to read.
data = blobstore.fetch_data(blob_key, 0, 6)

# Write the contents to the response.
self.response.headers['Content-Type'] = 'text/plain'
self.response.write(data)

# Delete the file from Google Cloud Storage using the blob_key.
blobstore.delete(blob_key)


# This handler creates a file in Cloud Storage using the cloudstorage
# client library and then serves the file back using the Blobstore API.
class CreateAndServeFileHandler(blobstore_handlers.BlobstoreDownloadHandler):

def get(self):
# Get the default Cloud Storage Bucket name and create a file name for
# the object in Cloud Storage.
bucket = app_identity.get_default_gcs_bucket_name()

# Cloud Storage file names are in the format /bucket/object.
filename = '/{}/blobstore_serving_demo'.format(bucket)

# Create a file in Google Cloud Storage and write something to it.
with cloudstorage.open(filename, 'w') as filehandle:
filehandle.write('abcde\n')

# In order to read the contents of the file using the Blobstore API,
# you must create a blob_key from the Cloud Storage file name.
# Blobstore expects the filename to be in the format of:
# /gs/bucket/object
blobstore_filename = '/gs{}'.format(filename)
blob_key = blobstore.create_gs_key(blobstore_filename)

# BlobstoreDownloadHandler serves the file from Google Cloud Storage to
# your computer using blob_key.
self.send_blob(blob_key)


app = webapp2.WSGIApplication([
('/', CreateAndReadFileHandler),
('/blobstore/read', CreateAndReadFileHandler),
('/blobstore/serve', CreateAndServeFileHandler)], debug=True)
34 changes: 34 additions & 0 deletions appengine/standard/blobstore/gcs/main_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import webtest

import main


def test_create_and_read(testbed, login):
app = webtest.TestApp(main.app)

response = app.get('/blobstore/read')

assert 'abcde' in response


def test_create_and_serve(testbed, login):
app = webtest.TestApp(main.app)

response = app.get('/blobstore/serve')
served_file_header = response.headers['X-AppEngine-BlobKey']

assert 'encoded_gs_file' in served_file_header
1 change: 1 addition & 0 deletions appengine/standard/blobstore/gcs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GoogleAppEngineCloudStorageClient==1.9.22.1