API Blobstore per Python 3

In questa pagina viene descritto come utilizzare l'API Blobstore, uno dei servizi in bundle legacy, con il runtime Python 3 per dell'ambiente standard. L'app può accedere ai servizi in bundle tramite l'SDK per i servizi App Engine per Python 3.

Panoramica

Poiché webapp non è supportato in Python 3, devi apportare alcune modifiche minime durante la migrazione del codice dell'handler Blobstore da Python 2 a Python 3. Per utilizzare l'API Blobstore per Python 3, tieni presente quanto segue:

  • Le classi di gestore di Blobstore sono classi di utilità. Ciò significa che il gestore non sono più basati su app web e non puoi usare blobstore_handlers modulo fornito dal pacchetto dell'app web (google.appengine.ext.webapp) o i parametri webapp2.RequestHandler in le sottoclassi di questi gestori.

  • Tutti i metodi nelle classi dei gestori di Blobstore richiedono Dizionario WSGI environ come parametro di input.

Le seguenti sezioni mostrano come utilizzare BlobstoreUploadHandler e Classi BlobstoreDownloadHandler per Python 3 in un'app Flask e un'app WSGI che non utilizza un framework Python. Puoi gli esempi di Python 3 vengono confrontati Codice di esempio Python 2 per scoprire di più sulle differenze delle modifiche al codice.

Esempio: app Flask

In Python 3, le classi dei gestori di Blobstore fanno parte del modulo google.appengine.ext.blobstore Per un'app Flask, tutte le chiamate effettuate ai metodi in BlobstoreUploadHandler e BlobstoreDownloadHandler corso richiede il dizionario request.environ (importazione di request dal modulo flask in corso...

Confronta le modifiche al codice apportate da Python 2 (webapp2) a Python 3 (Flask). Nota come L'app Flask usa il parametro request.environ nei metodi get_uploads() e 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()

Per visualizzare l'esempio di codice completo per Python 3 (Flask), consulta GitHub.

Esempio: app WSGI senza un framework web

Il seguente codice Python 3 (app WSGI) mostra come aggiungere il parametro environ quando si utilizzano classi di gestore Blobstore per un'app WSGI senza un framework web. Nota come viene utilizzato il parametro environ nei metodi get_uploads() e send_blob() e confrontalo con la versione di Python 2:

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),
]

Per visualizzare il codice di esempio completo per Python 3, consulta GitHub.