serverless framework AWS
Lambda
PyCon Kyushu 2018 Fukuoka
2018/06/30@LINE Fukuoka
• Masato Nakamura
• twitter: masahito
• work at Nulab inc. Typetalk team
• Python Lover
Goal
• AWS Lambda Python !
• !
• AWS
• node
Python ? !
Python ?
• ?
• ?
• Web ?
• ?
•
• Twitter
• 1
•
• Cron
•
• Serverless
• AWS Lambda
• Google Cloud Functions
• Microsoft Azule Functions
AWS Lambda
Target
• Python
• AWSLambda /
Goal
• ! AWS Lambda Python !
• !
AWS
•
•
• : ->
• : ->
• ! 3rd Party
• requests
• add requirements.txt
requests
• run
$ pip install -r requirements.txt -t vendor/
$ edit python-file
$ zip /path/to/service-dir
$ aws lambda ~~
AWS
! 3rd party
! C-API
! (git )
AWS
• zip
!
• zip
$ aws lambda create-function 
--function-name AccessMemCache 
--region us-east-1 
--zip-file fileb://path-to/app.zip 
--role execution-role-arn 
--handler app.handler 
--runtime python3.6 
--timeout 30 
--vpc-config SubnetIds=comma-separated-vpc-subnet-ids,SecurityGroupIds=default-security-group-id 
--memory-size 1024
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/vpc-ec-
upload-deployment-pkg.html
! zip -> deploy
!
•
$ edit python-file
$ (pip install ~~)
$ zip /path/to/service-dir
$ aws lambda ~~
Serverless framework
Serverlessframework?
• http://www.serverless.com
Serverless Framework – Build web, mobile and IoT applications
with serverless architectures using AWS Lambda, Azure Functions,
Google CloudFunctions & more!
• AWS Lambda, Azure Functions, Google CloudFunctions
web, Mobile IoT
serveless framework
• pros !
! git/svn/hg
! zip -> deploy
! CloudWatch/ AWS IAM
serverless framework
.
$ npm install serverless -g
$ sls -v
1.27.3
serverless framework
$ sls create -t aws-python3 -p py3-hello
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/masahito-nulab/src/jobs/typetalk-serverless-internal/py3-hello"
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| ___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v1.27.3
-------'
Serverless: Successfully generated boilerplate for template: "aws-python3"
$ tree py3-hello/
py3-hello/
├── handler.py
└── serverless.yml
• handler.py
import json
def hello(event, context):
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
• serverless.yml
service: py3-hello
provider:
name: aws
runtime: python3.6
functions:
hello:
handler: handler.hello
$ cd py3-hello
$ sls invoke local -f hello
{
"statusCode": 200,
"body": "{"message": "Go Serverless v1.0! Your function executed successfully!", "input": {}}"
}
AWS Lambda
! IAM/Role deploy
$ sls deploy
! 3rd-party
# !
$ pip install -r requirement.txt -t vendor/
$ sls deploy
serverless-framework plugin
• UnitedIncome/serverless-python-requirements
• serverless >= v1.12
$ sls plugin install -n serverless-python-requirements
service: py3-hello
provider:
name: aws
runtime: python3.6
cfLogs: true
plugins:
- serverless-python-requirements
functions:
hello:
handler: handler.hello
($ sls requirements install)
$ sls deploy
!
Pure Python
• Windows/OSX
• Python CAPI
• numpy
• : pillow etc
• Lambda !
• Amazon Lambda Linux
dockerize pip
docker cross-compile
* docker image lambci/docker-lambda
service: py3-hello
provider:
name: aws
runtime: python3.6
cfLogs: true
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: true
functions:
hello:
handler: handler.hello
Goal
• AWS Lambda Python !
• ! !
print logging.* CloudWatch Logs
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def my_logging_handler(event, context):
logger.info('got event{}'.format(event))
logger.error('something went wrong')
return 'Hello from Lambda!'
AWS Lambda
• AWS Lambda TAG
•
• AWS Lambda description( )
AWS Lambda
•
•
• Why
def _service_json_to_dict(service_dict) -> Dict[TypetalkPlan, int]:
# service_json format is too strange, I'd like to change simple Dict
# e.g. [{"key": [“ham”], "value": 7}, {"key": [“spam”], "value": 1}]
result: Dict[TypetalkPlan, int] = dict()
for m in mixpanel_dict:
key = m['key'][0]
value = m['value']
result[key] = value
return result
unittest
•
• python doctest !
def hello(name: str) -> str:
"""
>>> from hello import hello
>>> hello('test')
'hello, test'
"""
return f'hello {name}'
run unites
• nose, pytest runner
•
def ham(ipadresses):
return ','.join(buffer)
TypeHints (Python3 later)
from typing import List
def ham(ipadresses: List[str]) -> str:
return ','.join(buffer)
TypeHints (Python2)
** Python2 **
from typing import List
def ham(ipadresses): # type: List[str] -> str
return ','.join(buffer)
mypy
• serverless !
•
•
• UnitTest/Comment/Type Hints
• !
Thanks
Q&A

Presentation kyushu-2018