Blobstore API for Python 3 Stay organized with collections Save and categorize content based on your preferences.
This page describes how to use the Blobstore API, one of the legacy bundled services,with thePython 3 runtime forthe standard environment. Your app can access the bundled servicesthrough theApp Engine services SDK for Python 3.
Overview
Since webapp is not supported in Python 3, you need to make some minimalchanges when migrating Blobstore handler code from Python 2 to Python 3. To usethe Blobstore API for Python 3, keep in mind the following:
Blobstore handler classes are utility classes. This means that the handlerclasses are no longer webapp-based, and you cannot use the
blobstore_handlersmodule provided by the webapp package(google.appengine.ext.webapp) or thewebapp2.RequestHandlerparameters insubclasses of these handlers.All of the methods in Blobstore handler classes require theWSGI
environdictionaryas an input parameter.
The following sections show how to useBlobstoreUploadHandler andBlobstoreDownloadHandler classes for Python3 in a Flask app and a WSGI app that does not use a Python framework. You cancompare the Python 3 examples with thePython 2 example codeto learn more about code change differences.
Example: Flask app
In Python 3, the Blobstore handler classes are part of modulegoogle.appengine.ext.blobstore.For a Flask app, all calls made to methods inBlobstoreUploadHandler andBlobstoreDownloadHandler classes require therequest.environ dictionary(request being imported from theflask module).
Compare the code changes made from Python 2 (webapp2) to Python 3 (Flask). Notice how theFlask app uses therequest.environ parameter in the methodsget_uploads() andsend_blob():
Python 2 (webapp2)
classPhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):defpost(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())classViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):defget(self,photo_key):ifnotblobstore.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)
classPhotoUploadHandler(blobstore.BlobstoreUploadHandler):defpost(self):upload=self.get_uploads(request.environ)[0]photo=PhotoUpload(blob_key=upload.key())photo.put()returnredirect("/view_photo/%s"%upload.key())classViewPhotoHandler(blobstore.BlobstoreDownloadHandler):defget(self,photo_key):ifnotblobstore.get(photo_key):return"Photo key not found",404else: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"]=Nonereturn"",headers@app.route("/view_photo/<photo_key>")defview_photo(photo_key):"""View photo given a key."""returnViewPhotoHandler().get(photo_key)@app.route("/upload_photo",methods=["POST"])defupload_photo():"""Upload handler called by blobstore when a blob is uploaded in the test."""returnPhotoUploadHandler().post()To view the complete code sample for Python 3 (Flask), seeGitHub.
Example: WSGI app without a web framework
The following Python 3 (WSGI app) code shows how to add theenviron parameterwhen using Blobstore handler classes for a WSGI app without a web framework.Notice how theenviron parameter is used in theget_uploads() andsend_blob() methods,and compare it with the Python 2 version:
Python 2
classPhotoUploadHandler(blobstore_handlers.BlobstoreUploadHandler):defpost(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())classViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):defget(self,photo_key):ifnotblobstore.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
classUploadPhotoHandler(blobstore.BlobstoreUploadHandler):"""Upload handler called by blobstore when a blob is uploaded in the test."""defpost(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>' URLreturn("",http.HTTPStatus.FOUND,[("Location","/view_photo/%s"%upload.key())],)classViewPhotoHandler(blobstore.BlobstoreDownloadHandler):defget_photo(self,environ,photo_key):ifnotblobstore.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()),)defget(self,environ):photo_key=(environ["app.url_args"])[0]returnself.get_photo(environ,photo_key)# map urls to functionsurls=[(r"^$",UploadFormHandler),(r"upload_photo/?$",UploadPhotoHandler),(r"view_photo/(.+)$",ViewPhotoHandler),]To view the complete code sample for Python 3, seeGitHub.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.