0
votes

The following code is almost verbatim copy of the sample code from Google to serve a file from Google Cloud Storage via Python 2.7 App Engine Standard Environment. When serving locally with command:

dev_appserver.py --default_gcs_bucket_name darianhickman-201423.appspot.com

import cloudstorage as gcs
import webapp2

class LogoPage(webapp2.RequestHandler):
  def get(self):
    bucket_name = "darianhickman-201423.appspot.com"
    self.response.headers['Content-Type'] = 'image/jpeg'
    self.response.headers['Message'] = "LogoPage"
    gcs_file = gcs.open("/"+ bucket_name +'/logo.jpg')
    contents = gcs_file.read()
    gcs_file.close()
    self.response.body.(contents)

app = webapp2.WSGIApplication([ ('/logo.jpg', LogoPage),
                               ('/logo2.jpg', LogoPage)],
                              debug=True)

The empty body message I see on the console is:

NotFoundError: Expect status [200] from Google Storage. But got status 404.
Path: '/darianhickman-201423.appspot.com/logo.jpg'.
Request headers: None.
Response headers: {'date': 'Sun, 30 Dec 2018 18:54:54 GMT', 'connection': 'close', 'server': 'Development/2.0'}.
Body: ''.
Extra info: None.

Again this is almost identical to read logic documented at https://cloud.google.com/appengine/docs/standard/python/googlecloudstorageclient/read-write-to-cloud-storage

1

1 Answers

0
votes

If you serve it locally using dev_appserver.py, it runs a local emulation of Cloud Storage and does not connect to the actual Google Cloud Storage.

Try writing a file and then reading it. You’ll see that it will succeed.

Here is a sample:

import os
import cloudstorage as gcs
from google.appengine.api import app_identity
import webapp2

class MainPage(webapp2.RequestHandler):
  def get(self):
    bucket_name = os.environ.get('BUCKET_NAME',app_identity.get_default_gcs_bucket_name())
    self.response.headers['Content-Type'] = 'text/plain'
    filename = "/" + bucket_name + "/testfile"

#Create file    
    gcs_file = gcs.open(filename,
                        'w',
                        content_type='text/plain')
    gcs_file.write('Hello world\n')
    gcs_file.close()

#Read file and display content    
    gcs_file = gcs.open(filename)
    contents = gcs_file.read()
    gcs_file.close()
    self.response.write(contents)

app = webapp2.WSGIApplication(
    [('/', MainPage)], debug=True)

Run it with dev_appserver.py --default_gcs_bucket_name a-local-bucket .

If you deploy your application on Google App Engine then it will work (assuming you have a file called logo.jpg uploaded) because it connects to Google Cloud Storage. I tested it with minor changes:

import os
import cloudstorage as gcs
from google.appengine.api import app_identity
import webapp2

class LogoPage(webapp2.RequestHandler):
  def get(self):
    bucket_name = os.environ.get('BUCKET_NAME',app_identity.get_default_gcs_bucket_name())
    #or you can use bucket_name = "<your-bucket-name>"
    self.response.headers['Content-Type'] = 'image/jpeg'
    self.response.headers['Message'] = "LogoPage"
    gcs_file = gcs.open("/"+ bucket_name +'/logo.jpg')
    contents = gcs_file.read()
    gcs_file.close()
    self.response.write(contents)

app = webapp2.WSGIApplication(
    [('/', LogoPage)], debug=True)

Also, It's worth mentioning that the documentation for Using the client library with the development app server seems to be outdated, it states that:

There is no local emulation of Cloud Storage, all requests to read and write files must be sent over the Internet to an actual Cloud Storage bucket.

The team responsible for the documentation has already been informed about this issue.