※2016年7月4日に書いたブログ記事からの転記です。
Cloud Storage を利用可能にしておく
まず最初に、Google Cloud Console から Cloud Storage を使用できるように初期設定しておく必要があります。
初期設定は「利用開始」を選択して「バケットを作成」しておくだけです。
デフォルトのバケットを作成してそれを使用してもよいですし、新たにバケットを作成してもOKです。
Cloud Storafe クライアント・ライブラリをダウンロードする
App Engine Python アプリから Cloud Storage を利用するには、まず最初に Google Cloud Storage クライアント・ライブラリをダウンロードする必要があります。その方法は3つあります。
(1)Github から ZIP をダウンロードする:Google Cloud Storage client library on GitHub
(2)GitHub から clone する:
git clone https://github.com/GoogleCloudPlatform/appengine-gcs-client.git
(3)PIP からインストールする:
pip install GoogleAppEngineCloudStorageClient -t <your_app_directory/lib>
自分の場合は(1)の方法でダウンロードしました。
ダウンロードしたファイルを解凍して、python → src → cloudstorage というフォルダを app_id/lib に配置します。
app_id/
lib/
cloudstorage/
さて、これで準備は整いました。
リクエストハンドラーを記述する
プログラムの大まかな流れは次のとおりです。
(1)ブラウザからファイルを受け取る。
(2)受け取ったファイルを Cloud Storage へ保存する。
(3)Cloud Storage での保存先を Datastore に保存する。
(4)Cloud Storage に保存したファイルを表示する。
まずはフォームの HTML です。
<html>
<body>
<form method="post" action="" enctype="multipart/form-data">
<label for="inputTitle">タイトル</label>
<input type="text" name="title" id="inputTitle">
<label for="inputFile">ファイル</label>
<input type="file" name="file" id="inputFile">
</form>
</body>
</html>
次に、このフォームから送信されるデータを受け取る POST のリクエストハンドラーです。
from google.appengine.ext import ndb
from google.appengine.ext import blobstore
from lib import cloudstorage as gcs
# Cloud Storage に保存したファイルのパスを保持するための Datastore モデル
class File(ndb.Model):
path = ndb.StringProperty()
type = ddb.StringProperty()
class AdminCreateFileHandler(BaseHandler):
def get(self):
context = {}
self.render_template('file.html', **context) # 上記のフォームのHTMLを表示
def post(self):
title = self.request.get('title')
file_data = self.request.get('file')
file_name = self.request.POST['file'].filename
file_type = self.request.POST['file'].type
# フォームから受け取ったファイルをCloud Storageに保存
if file_data:
bucket_name = os.environ.get(
"GCS_BUCKET_NAME", # app.yaml に環境変数としてバケット名があればそれを使用
app_identity.get_default_gcs_bucket_name()) # なければデフォルトのバケット名を使用
file_path = '/' + bucket_name + '/files/' + file_name
with gcs.open(file_path, 'w') as gcs_file:
gcs_file.write(file_data)
# Cloud Storage での保存先をDatastoreに保存
file_key = File(
path=file_path,
type=file_type,
title=title,
).put()
self.redirect('/files/%s' % file_key.urlsafe()) # 適当なURLへリダイレクト
最後に、Cloud Storage に保存したファイルを表示するハンドラーです。
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
class RequestHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, gcs_path):
gs_key = blobstore.create_gs_key('/gs' + gcs_path)
self.send_blob(gs_key)
このハンドラーを routes 内で
Route(
r'/gcs<gcs_path:/.+>',
handler='handlers.gcs.RequestHandler',
)
といった感じのURLにマッピングしてあげます。
ファイルを表示
ファイルを表示したい場合は、テンプレートに以下のように記述します。
<img src="/gcs{{ file.path }}">
<!--file は File モデルのエンティティ-->
以上です。