Help us understand the problem. What is going on with this article?

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

More than 3 years have 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を触ってみたいな

fusic
受託開発・自社サービスの2本柱で「日本を代表する福岡の企業」を目指している企業です。
https://fusic.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした