TRILHA PYTHON
Peter Sbarski
“Serverless Architectures on AWS: With examples using AWS Lambda”
AWS EC2/ECS, Azure VMs, Google Compute Engine, OpenStack, VMware
Heroku, OpenShift, GC App Engine, AWS Beanstalk, Azure App Service
AWS Lambda, Azure Functions, Webtask
Google Cloud Functions, IBM OpenWhisk
Datacenter
"Serverless" by Badri Janakiraman on martinfowler.com
( JS only )
( experimental )
1 million requests per month are free
$0.20 per 1 million requests thereafter ($0.0000002 per request)
400,000 GB-seconds of compute time per month free
import json
def hello(event, context):
body = {
"message": "Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
handler.py
import time
def get_my_log_stream(event, context):
print("Log stream name:", context.log_stream_name)
print("Log group name:", context.log_group_name)
print("Request ID:",context.aws_request_id)
print("Mem. limits(MB):", context.memory_limit_in_mb)
time.sleep(1)
print("Time remaining (MS):", context.get_remaining_time_in_millis())
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 World!'
CloudWatch
def always_failed_handler(event, context):
raise Exception('I failed!')
{
"errorMessage": "I failed!",
"stackTrace": [
[
"/var/task/lambda_function.py",
3,
"my_always_fails_handler",
"raise Exception('I failed!')"
]
],
"errorType": "Exception"
}
Chalice
Organization unit, project file (multiple services for a single application).
Independent unit of deployment, code deployed in the cloud.
Anything that triggers a Function (HTTP request, timers, uploads, streams, etc.)
Infrastructure components (DB Table, Storage, etc.)
Deployment environments (dev, staging, production, etc.)
> pip install --upgrade --user awscli
> aws configure
> npm install -g serverless
> serverless create --template aws-python3
> serverless deploy
service: service-name
provider:
name: aws
region: us-east-1
runtime: python3.6
timeout: 300
memorySize: 128
environment:
SERVICE_NAME: ${self:service}
STAGE: ${opt:stage}
MY_ENV_VAR: ${self:custom.env.myEnvVar}
custom:
env: ${file(env.yml)}
package:
individually: true
functions:
hello:
handler: handler.hello
events:
- http:
path: /
method: get
package:
include:
- handler.py
- include_me_dir/**
exclude:
- include_me_dir/not_this_one.py
serverless.yml ➭ CloudFormation template
from flask import Flask
app = Flask(__name__)
@app.route("/cats")
def cats():
return "Cats"
@app.route("/dogs/<id>")
def dog(id):
return "Dog"
service: flask-example
provider:
name: aws
runtime: python3.6
plugins:
- serverless-wsgi
functions:
api:
handler: wsgi.handler
events:
- http: ANY {proxy+}
custom:
wsgi:
app: api.app
Flask==0.11.1
api.py
serverless.yml
requirements.txt
project
├── package1
| ├── .requirements
| ├── handler1.py
| └── requirements.txt
├── package2
| ├── .requirements
| ├── handler2.py
| └── requirements.txt
├── utils
| ├── .requirements
| ├── helper.py
| └── requirements.txt
└── serverless.yml
import json
import os
import sys
import pkg1dependency
from utils import helper
# Add requirements to PATH
file_path = os.path.realpath(__file__)
file_dir = os.path.dirname(file_path)
requirements_path = os.path.join(file_dir, '.requirements')
sys.path.append(requirements_path)
def handler1(event, context):
data = helper.function(event)
response = pkg1dependency(data)
return response
handler1.py
project
├── package1
| ├── .requirements
| ├── __init__.py
| ├── handler1.py
| └── requirements.txt
├── package2
| ├── .requirements
| ├── __init__.py
| ├── handler2.py
| └── requirements.txt
├── utils
| ├── .requirements
| ├── __init__.py
| ├── helper.py
| └── requirements.txt
└── serverless.yml
import json
import package1 # noqa
import pkg1dependency
from utils import helper
def handler1(event, context):
data = helper.function(event)
response = pkg1dependency(data)
return response
import os
import sys
# Add requirements to PATH
file_path = os.path.realpath(__file__)
file_dir = os.path.dirname(file_path)
requirements_path = os.path.join(file_dir, '.requirements')
__init__.py
handler1.py
install:
find . -name "*requirements.txt" -not -path "*node_modules*"
-exec bash -c 'pip3 install -r {} -t $$(dirname {})/.requirements' \;
uninstall:
find . -name "*requirements.txt" -not -path "*node_modules*"
-exec bash -c 'rm -rf $$(dirname {})/.requirements' \;
devinstall: install
pip3 install -r requirements-dev.txt
Makefile
is
the
new
lucascosta
@lucasrcosta
@lucasrcosta
lucas@sugarads.io
slides.com/lucasrcosta/tdc2017