Blobstore API for Python 3

This page describes how to use the Blobstore API, one of the legacy bundled services, with the Python 3 runtime for the standard environment. Your app can access the bundled services through the App Engine services SDK for Python 3 .

Overview

Since webapp is not supported in Python 3, you need to make some minimal changes when migrating Blobstore handler code from Python 2 to Python 3. To use the Blobstore API for Python 3, keep in mind the following:

  • Blobstore handler classes are utility classes. This means that the handler classes are no longer webapp-based, and you cannot use the blobstore_handlers module provided by the webapp package ( google.appengine.ext.webapp ) or the webapp2.RequestHandler parameters in subclasses of these handlers.

  • All of the methods in Blobstore handler classes require the WSGI environ dictionary as an input parameter.

The following sections show how to use BlobstoreUploadHandler and BlobstoreDownloadHandler classes for Python 3 in a Flask app and a WSGI app that does not use a Python framework. You can compare the Python 3 examples with the Python 2 example code to learn more about code change differences.

Example: Flask app

In Python 3, the Blobstore handler classes are part of module google.appengine.ext.blobstore . For a Flask app, all calls made to methods in BlobstoreUploadHandler and BlobstoreDownloadHandler classes require the request.environ dictionary ( request being imported from the flask module).

Compare the code changes made from Python 2 (webapp2) to Python 3 (Flask). Notice how the Flask app uses the request.environ parameter in the methods get_uploads() and send_blob() :

Python 2 (webapp2)

  class 
  
 PhotoUploadHandler 
 ( 
 blobstore_handlers 
 . 
 BlobstoreUploadHandler 
 ): 
 def 
  
 post 
 ( 
 self 
 ): 
 upload 
 = 
 self 
 . 
 get_uploads 
 ()[ 
 0 
 ] 
 user_photo 
 = 
 UserPhoto 
 ( 
 user 
 = 
 users 
 . 
 get_current_user 
 () 
 . 
 user_id 
 (), 
 blob_key 
 = 
 upload 
 . 
 key 
 ()) 
 user_photo 
 . 
 put 
 () 
 self 
 . 
 redirect 
 ( 
 '/view_photo/ 
 %s 
 ' 
 % 
 upload 
 . 
 key 
 ()) 
 class 
  
 ViewPhotoHandler 
 ( 
 blobstore_handlers 
 . 
 BlobstoreDownloadHandler 
 ): 
 def 
  
 get 
 ( 
 self 
 , 
 photo_key 
 ): 
 if 
 not 
 blobstore 
 . 
 get 
 ( 
 photo_key 
 ): 
 self 
 . 
 error 
 ( 
 404 
 ) 
 else 
 : 
 self 
 . 
 send_blob 
 ( 
 photo_key 
 ) 
 app 
 = 
 webapp2 
 . 
 WSGIApplication 
 ([ 
 ( 
 '/' 
 , 
 PhotoUploadFormHandler 
 ), 
 ( 
 '/upload_photo' 
 , 
 PhotoUploadHandler 
 ), 
 ( 
 '/view_photo/([^/]+)?' 
 , 
 ViewPhotoHandler 
 ), 
 ], 
 debug 
 = 
 True 
 ) 
 

Python 3 (Flask)

  class 
  
 PhotoUploadHandler 
 ( 
 blobstore 
 . 
 BlobstoreUploadHandler 
 ): 
 def 
  
 post 
 ( 
 self 
 ): 
 upload 
 = 
 self 
 . 
 get_uploads 
 ( 
 request 
 . 
 environ 
 )[ 
 0 
 ] 
 photo 
 = 
 PhotoUpload 
 ( 
 blob_key 
 = 
 upload 
 . 
 key 
 ()) 
 photo 
 . 
 put 
 () 
 return 
 redirect 
 ( 
 "/view_photo/ 
 %s 
 " 
 % 
 upload 
 . 
 key 
 ()) 
 class 
  
 ViewPhotoHandler 
 ( 
 blobstore 
 . 
 BlobstoreDownloadHandler 
 ): 
 def 
  
 get 
 ( 
 self 
 , 
 photo_key 
 ): 
 if 
 not 
 blobstore 
 . 
 get 
 ( 
 photo_key 
 ): 
 return 
 "Photo key not found" 
 , 
 404 
 else 
 : 
 headers 
 = 
 self 
 . 
 send_blob 
 ( 
 request 
 . 
 environ 
 , 
 photo_key 
 ) 
 # Prevent Flask from setting a default content-type. 
 # GAE sets it to a guessed type if the header is not set. 
 headers 
 [ 
 "Content-Type" 
 ] 
 = 
 None 
 return 
 "" 
 , 
 headers 
 @app 
 . 
 route 
 ( 
 "/view_photo/<photo_key>" 
 ) 
 def 
  
 view_photo 
 ( 
 photo_key 
 ): 
  
 """View photo given a key.""" 
 return 
 ViewPhotoHandler 
 () 
 . 
 get 
 ( 
 photo_key 
 ) 
 @app 
 . 
 route 
 ( 
 "/upload_photo" 
 , 
 methods 
 = 
 [ 
 "POST" 
 ]) 
 def 
  
 upload_photo 
 (): 
  
 """Upload handler called by blobstore when a blob is uploaded in the test.""" 
 return 
 PhotoUploadHandler 
 () 
 . 
 post 
 () 
 

To view the complete code sample for Python 3 (Flask), see GitHub .

Example: WSGI app without a web framework

The following Python 3 (WSGI app) code shows how to add the environ parameter when using Blobstore handler classes for a WSGI app without a web framework. Notice how the environ parameter is used in the get_uploads() and send_blob() methods, and compare it with the Python 2 version:

Python 2

  class 
  
 PhotoUploadHandler 
 ( 
 blobstore_handlers 
 . 
 BlobstoreUploadHandler 
 ): 
 def 
  
 post 
 ( 
 self 
 ): 
 upload 
 = 
 self 
 . 
 get_uploads 
 ()[ 
 0 
 ] 
 user_photo 
 = 
 UserPhoto 
 ( 
 user 
 = 
 users 
 . 
 get_current_user 
 () 
 . 
 user_id 
 (), 
 blob_key 
 = 
 upload 
 . 
 key 
 ()) 
 user_photo 
 . 
 put 
 () 
 self 
 . 
 redirect 
 ( 
 '/view_photo/ 
 %s 
 ' 
 % 
 upload 
 . 
 key 
 ()) 
 class 
  
 ViewPhotoHandler 
 ( 
 blobstore_handlers 
 . 
 BlobstoreDownloadHandler 
 ): 
 def 
  
 get 
 ( 
 self 
 , 
 photo_key 
 ): 
 if 
 not 
 blobstore 
 . 
 get 
 ( 
 photo_key 
 ): 
 self 
 . 
 error 
 ( 
 404 
 ) 
 else 
 : 
 self 
 . 
 send_blob 
 ( 
 photo_key 
 ) 
 app 
 = 
 webapp2 
 . 
 WSGIApplication 
 ([ 
 ( 
 '/' 
 , 
 PhotoUploadFormHandler 
 ), 
 ( 
 '/upload_photo' 
 , 
 PhotoUploadHandler 
 ), 
 ( 
 '/view_photo/([^/]+)?' 
 , 
 ViewPhotoHandler 
 ), 
 ], 
 debug 
 = 
 True 
 ) 
 

Python 3

  class 
  
 UploadPhotoHandler 
 ( 
 blobstore 
 . 
 BlobstoreUploadHandler 
 ): 
  
 """Upload handler called by blobstore when a blob is uploaded in the test.""" 
 def 
  
 post 
 ( 
 self 
 , 
 environ 
 ): 
 upload 
 = 
 self 
 . 
 get_uploads 
 ( 
 environ 
 )[ 
 0 
 ] 
 user_photo 
 = 
 UserPhoto 
 ( 
 blob_key 
 = 
 upload 
 . 
 key 
 ()) 
 user_photo 
 . 
 put 
 () 
 # Redirect to the '/view_photo/<Photo Key>' URL 
 return 
 ( 
 "" 
 , 
 http 
 . 
 HTTPStatus 
 . 
 FOUND 
 , 
 [( 
 "Location" 
 , 
 "/view_photo/ 
 %s 
 " 
 % 
 upload 
 . 
 key 
 ())], 
 ) 
 class 
  
 ViewPhotoHandler 
 ( 
 blobstore 
 . 
 BlobstoreDownloadHandler 
 ): 
 def 
  
 get_photo 
 ( 
 self 
 , 
 environ 
 , 
 photo_key 
 ): 
 if 
 not 
 blobstore 
 . 
 get 
 ( 
 photo_key 
 ): 
 return 
 "Photo key not found" 
 , 
 http 
 . 
 HTTPStatus 
 . 
 NOT_FOUND 
 , 
 [] 
 else 
 : 
 return 
 ( 
 "" 
 , 
 http 
 . 
 HTTPStatus 
 . 
 OK 
 , 
 list 
 ( 
 self 
 . 
 send_blob 
 ( 
 environ 
 , 
 photo_key 
 ) 
 . 
 items 
 ()), 
 ) 
 def 
  
 get 
 ( 
 self 
 , 
 environ 
 ): 
 photo_key 
 = 
 ( 
 environ 
 [ 
 "app.url_args" 
 ])[ 
 0 
 ] 
 return 
 self 
 . 
 get_photo 
 ( 
 environ 
 , 
 photo_key 
 ) 
 # map urls to functions 
 urls 
 = 
 [ 
 ( 
 r 
 "^$" 
 , 
 UploadFormHandler 
 ), 
 ( 
 r 
 "upload_photo/?$" 
 , 
 UploadPhotoHandler 
 ), 
 ( 
 r 
 "view_photo/(.+)$" 
 , 
 ViewPhotoHandler 
 ), 
 ] 
 

To view the complete code sample for Python 3, see GitHub .

Design a Mobile Site
View Site in Mobile | Classic
Share by: