Python Advent Calendar 2016の5日目及び
Fusic Advent Calendar 2016の5日目の記事です。
はじめまして、seike460と申します。
普段は主にPHPとサーバー触っています。
ふと流行りのサーバーレスしたい!と思いましたが、
僕が懇意に使用しているAWSでは、PHPでサーバーレス出来ないのが現状です。
(正確には頑張れば出来ますが、その話は置いておきます。)
出来ないものはしょうがないので、他の言語でサーバーレスしようと思いたち、
最近魅力を感じているPythonを使ってサーバーレスする事にしました。
何も使用せずにLambdaとAPIGatewayの設定をしようとすると、
面倒臭すぎて気が狂いそうになるので 効率が悪く、実運用に耐えられない印象を受けました。
そこで安心のAmazon公式 Python ライブラリ「chalice」を選択して実装しました。
AWSアカウント持っているなら、Quickstartセクションを実行するだけで10分かからずサーバーレスHello World出来ます。
あと何と言っても厨二心を刺激する名前が最高に良い、聖杯ですよ!聖杯!
既にREADMEで導入方法が書かれていますので導入方法は省きます。
今回のゴール設定
今回は、APIGatewayにJsonを送信して、S3にJsonを保存することをゴールとしました。
データを受信するAPIを設置して、そのデータをS3経由で利用する事を想定しています。
開発環境
OS:macOS v10.12(Sierra)
Python:2.7.10
AWS側の準備
まず、chalice用のIAMロールを用意します。
今回は特に権限に拘らず設定していきます。ひとまずエイヤって権限振ります。
※実際は考えて設定すべきです!自己責任!!
- AWSLambdaFullAccess
- IAMFullAccess
- AmazonS3FullAccess
- AmazonAPIGatewayAdministrator
↓こんな感じです。
その後、開発環境にcredentialsを設定します。
[default]
aws_access_key_id=【見せられないよ!!!】
aws_secret_access_key=【見せられないよ!!!】
region=ap-northeast-1 ←Tokyoリージョン
Hello world出来る準備が整いました。
あとAWS触るので、boto3も入れておきます。
この時virtualenvsを使う場合はchaliceを使用する環境にインストールしましょう。
(chalice) $ pip install boto3
- 参考
Let's hello world
save2S3プロジェクトを作成します。
(chalice) $ chalice new-project save2S3
すると以下の様なディレクトリ構成が作成されます。
save2S3
├── .chalice
│ └── config.json
├── .gitignore
├── app.py
└── requirements.txt
このapp.pyを編集してサーバーレスするわけです。
app.pyを開いて見ましょう
from chalice import Chalice
app = Chalice(app_name='save2S3')
@app.route('/')
def index():
return {'hello': 'world'}
# The view function above will return {"hello": "world"}
# whenver you make an HTTP GET request to '/'.
#
# Here are a few more examples:
#
# @app.route('/hello/{name}')
# def hello_name(name):
# # '/hello/james' -> {"hello": "james"}
# return {'hello': name}
#
# @app.route('/users', methods=['POST'])
# def create_user():
# # This is the JSON body the user sent in their POST request.
# user_as_json = app.json_body
# # Suppose we had some 'db' object that we used to
# # read/write from our database.
# # user_id = db.create_user(user_as_json)
# return {'user_id': user_id}
#
# See the README documentation for more examples.
#
既にhello world出来そうな雰囲気が凄いですね。
chaliceがhello worldしたそうなので、早速AWS上にデプロイしましょう。
(chalice) $ chalice deploy
Initial creation of lambda function.
Creating role
Creating deployment package.
Lambda deploy done.
Initiating first time deployment...
Deploying to: dev
https://【あなた固有のPath】.execute-api.ap-northeast-1.amazonaws.com/dev/
なんとも簡単にデプロイされました。初期設定だと/devというPathに作成されます。
apiというPathに作成したい場合、以下のコマンドでOKです。
(chalice) $ chalice deploy api
早速URLにアクセスしてみます。
(chalice) $ curl https://【あなた固有のPath】.execute-api.ap-northeast-1.amazonaws.com/dev/
{"hello": "world"}
これであなたのchaliceデビューは完了です。
隣の人に「俺、聖杯使えるぜ」と自慢しましょう。
結果キモがられても僕のせいじゃないです。自己責任
ゴールに辿り着くコード
こまけえことはいいんだよ!って感じで、ちゃっちゃかコード書いちゃいます。
from chalice import Chalice
import boto3
import json
# for S3
clientS3 = boto3.client('s3')
yourBucketPath = '【ここにあなたのバケットを書くんだ!】'
app = Chalice(app_name='save2S3')
@app.route('/save', methods=['POST'], content_types=['application/json'])
def save():
saveJson = app.current_request.json_body
if (validateKey(saveJson) == False):
return {'error':'please input key'}
SavePath = saveJson['key'] + '.json'
clientS3.put_object(Bucket=yourBucketPath, Key=SavePath, Body=json.dumps(saveJson, ensure_ascii=False))
return {'save':saveJson['key']}
def validateKey(saveJson):
if (saveJson.has_key("key") == False):
return False
return True
最低限のKeyValidateだけして保存しちゃいます。
こいつ確認するためのコードも、ちゃっちゃか書きます。
※ここはpython3で書きました。 (lambdaのpython3対応はよ )
import urllib.request
import json
url = "https://【あなた固有のPath】.execute-api.ap-northeast-1.amazonaws.com/dev/save"
method = "POST"
headers = {"Content-Type" : "application/json"}
obj = {"key" : "seike460", "val" : "オレ、聖杯使えるぜ"}
json_data = json.dumps(obj).encode("utf-8")
request = urllib.request.Request(
url,
data=json_data,
method=method,
headers=headers
)
with urllib.request.urlopen(request) as response:
response_body = response.read().decode("utf-8")
print(response_body)
こいつを実行すると ※python3コマンドです!!
$ python3 postJson.py
{"save": "seike460"}
S3にもバッチリ保存されているはずです。
ここまでくれば、もうあなたはサーバーレスラーです。
思う存分サーバーレスしましょう。
弊社でこの段階でサーバーレス出来ますぶると、
弊社サーバーレス軍曹にこってり理論的に説き伏せられそうですので、僕はやめておきます。
まとめと所感
今回はサーバーレスをする目的で、PHPerがPythonを使ってみました。
その中で、
- Python書きやすい!
- 機械学習とか流行ってるし楽しそう!
- とりあえず基本どのOSも最初からPython入ってるからいざという時に便利そう(ほぼ2.7だけど)
と感じており、今回はAWSに寄った話になってしまいましたが、
これからもPythonネタで何か書いてみようかと思います。
Djangoを触ってみたいな