PythonDay 5

chaliceを使って簡単にPythonでサーバーレスしよう

More than 1 year has passed since last update.

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経由で利用する事を想定しています。

qiita-2016-12-05_1.png


開発環境

OS:macOS v10.12(Sierra)

Python:2.7.10


AWS側の準備

まず、chalice用のIAMロールを用意します。

今回は特に権限に拘らず設定していきます。ひとまずエイヤって権限振ります。

※実際は考えて設定すべきです!自己責任!!


  • AWSLambdaFullAccess

  • IAMFullAccess

  • AmazonS3FullAccess

  • AmazonAPIGatewayAdministrator

↓こんな感じです。

qiita-2016-12-05_2.png

その後、開発環境にcredentialsを設定します。


~/.aws/config

[default]

aws_access_key_id=【見せられないよ!!!】
aws_secret_access_key=【見せられないよ!!!】
region=ap-northeast-1 ←Tokyoリージョン

Hello world出来る準備が整いました。

あとAWS触るので、boto3も入れておきます。

この時virtualenvsを使う場合はchaliceを使用する環境にインストールしましょう。


boto3

(chalice) $ pip install boto3



Let's hello world

save2S3プロジェクトを作成します。


new-project

(chalice) $ chalice new-project save2S3


すると以下の様なディレクトリ構成が作成されます。


save2S3

save2S3

├── .chalice
│   └── config.json
├── .gitignore
├── app.py
└── requirements.txt

このapp.pyを編集してサーバーレスするわけです。

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上にデプロイしましょう。


deploy

(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です。


deploy_to_api

(chalice) $ chalice deploy api


早速URLにアクセスしてみます。


deploy

(chalice) $ curl https://【あなた固有のPath】.execute-api.ap-northeast-1.amazonaws.com/dev/

{"hello": "world"}

これであなたのchaliceデビューは完了です。

隣の人に「俺、聖杯使えるぜ」と自慢しましょう。

結果キモがられても僕のせいじゃないです。自己責任


ゴールに辿り着くコード

こまけえことはいいんだよ!って感じで、ちゃっちゃかコード書いちゃいます。


app.py

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対応はよ )


postJson.py

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コマンドです!!


deploy

$ python3 postJson.py

{"save": "seike460"}

S3にもバッチリ保存されているはずです。

ここまでくれば、もうあなたはサーバーレスラーです。

思う存分サーバーレスしましょう。

弊社でこの段階でサーバーレス出来ますぶると、

弊社サーバーレス軍曹にこってり理論的に説き伏せられそうですので、僕はやめておきます。


まとめと所感

今回はサーバーレスをする目的で、PHPerがPythonを使ってみました。

その中で、


  • Python書きやすい!

  • 機械学習とか流行ってるし楽しそう!

  • とりあえず基本どのOSも最初からPython入ってるからいざという時に便利そう(ほぼ2.7だけど)

と感じており、今回はAWSに寄った話になってしまいましたが、

これからもPythonネタで何か書いてみようかと思います。

Djangoを触ってみたいな