Google App Engine(以下 GAE) で画像とかファイルをアップロードするのどう実装しようか迷っていたら、「Blobstore 使えばいいよ〜」というアドバイスをもらいました。そういえば、Blobstore が提供されたことは知っていたけど、試したこと無かったな。
さっそく試してみました。初めて Blobstore を使うので、webapp フレームワークでシンプルに実装。
# -*- coding: utf-8 -*- import os import urllib from google.appengine.ext import blobstore from google.appengine.ext import webapp from google.appengine.ext.webapp import blobstore_handlers from google.appengine.ext.webapp import template from google.appengine.ext.webapp.util import run_wsgi_app class MainHandler(webapp.RequestHandler): def get(self): # アップロード用の URL を作成 # アップロードに成功したら /upload に移動させる upload_url = blobstore.create_upload_url('/upload') # Blobstore に保存されているファイルを取得 files = blobstore.BlobInfo.all() # テンプレートを使って出力 data = dict( upload_url=upload_url, files=files) path = os.path.join(os.path.dirname(__file__), 'main.html') self.response.out.write(template.render(path, data)) class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): def post(self): # Blobstore にアップロードされたファイルの情報を取得 files = self.get_uploads('file') blob_info = files[0] # ファイル表示用の URL へリダイレクト self.redirect('/serve/%s' % blob_info.key()) class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler): def get(self, blob_key): blob_key = str(urllib.unquote(blob_key)) # BlobKeyを指定してファイルを取得 blob_info = blobstore.BlobInfo.get(blob_key) # 結果をクライアントに返す self.send_blob(blob_info) def main(): application = webapp.WSGIApplication([ ('/', MainHandler), ('/upload', UploadHandler), ('/serve/([^/]+)?', ServeHandler), ], debug=True) run_wsgi_app(application) if __name__ == '__main__': main()
<html> <head> <title>Blobstore Sample</title> </head> <body> <form action="{{ upload_url }}" method="POST" enctype="multipart/form-data"> Upload File: <input type="file" name="file"><br> <input type="submit" name="submit" value="Submit"> </form> <!--Blobstore内のファイルを列挙する--> <h2>Uploaded Files</h2> <ul> <!--file.key()だとテンプレートのパースに失敗するので注意--> {% for file in files %} <li><a href="/serve/{{ file.key }}">{{ file.filename }}</a></lI> {% endfor %} </ul> </body> </html>
すごく簡単にファイルのアップロードやダウンロードが実装できました。ファイル分割して BlobProperty に保存しようなんて考えていた自分が馬鹿みたいです。
GAE でファイルを保存するなら Blobstore で決定として、残る問題は料金ですねぇ。。。