7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Serverless(2)Advent Calendar 2016

Day 17

Serverless Framework(v1.x) でPythonの追加パッケージを使う

Last updated at Posted at 2016-12-16

Serverless(2)アドベントカレンダー17日目の記事です。
正直大したネタではないですが…(^_^;)
Serverless Framework(v1.x)でPythonの情報が少なくて自分でも悩んだため、こんなネタにしてみました。
(12月17日AM6:17追記)
別の件もあってインプットデータをCSVからJSONに変更しました。

#背景
もともとうちの「IoTかんたんパック」では選択できるメッセージブローカーがMQTTのものしかなくてHTTPSに対応しないといけなくなったのがきっかけです。
(AWS IoTのRESTでもpublishできるんだけど認証が特殊すぎて今回は対象のデバイスがマイコンチップのためできるだけシンプルなAPIにしないといけなかったというか…^^;)

前回はServerless Framework(v1.1)でサンプルをそのままAPI Gatewayで動かしてみました。
[Serverless Frameworkを使ってみた](http://qiita.com/daikunjp/items/2b8aa35ecd104001f4e5 Serverless Frameworkを使ってみた)

今回はWebAPIにPUTされたCSVデータをMySQLにInsertするAPIを作ってみたいと思います。

#Serverless Framework をつかったWebAPI構築手順
##Serverless Framework のバージョンアップ
いつのまにやらv1.3にアップデートされていたので[前回](http://qiita.com/daikunjp/items/2b8aa35ecd104001f4e5 Serverless Frameworkを使ってみた)作成した環境をバージョンアップします。

% npm install -g serverless

バージョンの確認

% sls --version
1.3.0

##プロジェクト作成
プロジェクトのディレクトリを作成して初期化

% mkdir iot-api
% cd iot-api
% sls create --template aws-python --name iot-api

##PythonのMySQLライブラリ追加
lambdaのPythonにMySQLドライバを入れないといけないんだけど…
マニュアル見たらPythonの場合はpip使えと書いてあるので、普通にpipでmysql-pythonをインストールしたがうまくいかない。
どうやらプロジェクトのディレクトリに置いておけばそのままlambdaにアップロードするzipに入れてくれるみたいなので以下の手順でプロジェクトディレクトリにインストール。

% pip install mysql-python -t .

Shared Objectをカレントディレクトリにコピー

% cp /usr/lib64/mysql/libmysqlclient.so.18 .

##serverless.yml の編集
serverless.ymlを以下のように編集。
今回はlambdaからRDSのMySQLにアクセスするためVPCの設定も追加
【参考】
https://serverless.com/framework/docs/providers/aws/guide/functions/
http://dev.classmethod.jp/etc/serverless-framework-lambda-function-run-in-vpc/

serverless.yml
service: iot-api
provider:
  name: aws
  runtime: python2.7
  vpc:
   securityGroupIds:
     - sg-xxxxxxxx ←セキュリティグループID
   subnetIds:
     - subnet-xxxxxxxx ←サブネットID
     - subnet-xxxxxxxx ←サブネットID
  stage: dev
  region: ap-northeast-1
  iamRoleStatements:
  - Effect: "Allow"
    Action:
      - "ec2:CreateNetworkInterface"
      - "ec2:DescribeNetworkInterfaces"
      - "ec2:DeleteNetworkInterface"
    Resource:
      - "*"
functions:
  iotput:
    handler: handler.iotput
    events:
      - http:
          path: iotput
          method: put

##Pythonコード
実際に動かすコードはこちら
デモ用なので引数のチェックとかまったくやってません(^_^;)

handler.py
# -*- coding: utf-8 -*-
import MySQLdb,json

HOST = "接続するRDSのホスト名"
DBNAME = "DB名"
DBUSER = "DBユーザ名"
PASSWD = "パスワード"
CHARSET = "utf8"

def iotput(event, context):

  # MySQL Connect
    connect = MySQLdb.connect(host=HOST, db=DBNAME, user=DBUSER, passwd=PASSWD, charset=CHARSET)
    connect.cursorclass = MySQLdb.cursors.DictCursor
    cursor = connect.cursor()

  # BODY Data split for CSV
  #  data1 = event['body'].split(",")
  # BODY Data split for JSON
    data1 = json.loads(event['body'])
    data1[0] = data1['data1']
    data1[1] = data1['data2']
    data1[2] = data1['data3']

  # MySQL Data insert
    cursor.execute("insert into sensor01(data1,data2,data3) values(%s,%s,%s)",
        (data1[0],data1[1],data1[2]))
    connect.commit()
    cursor.close()
    connect.close()

    body = {
        "message": "input data is %s %s %s" % (data1[0],data1[1],data1[2]),
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

##デプロイ

% sls deploy
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (916.94 KB)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............
Serverless: Stack update finished...

Service Information
service: iot-api
stage: dev
region: ap-northeast-1
api keys:
  None
endpoints:
  PUT - https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/iotput
functions:
  iot-api-dev-iotput: arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxxxx:function:iot-api-dev-iotput

##テスト
別のマシンからcurlでテストしてみる。

% curl -X PUT  -d '{"data1":"10","data2":"20","data3":"40"}' https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/iotput
{"message": "input data is 10 20 40"}
% curl -X PUT  -d '{"data1":"1.1","data2":"5.4","data3":"2.7"}' https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/iotput
{"message": "input data is 1.1 5.4 2.7"}

結果確認

mysql> select * from sensor01;
+-------+-------+-------+
| data1 | data2 | data3 |
+-------+-------+-------+
|    10 |    20 |    40 |
|   1.1 |   5.4 |   2.7 |
+-------+-------+-------+
2 rows in set (0.01 sec)
7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?