51

RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

  • Upload
    -

  • View
    83

  • Download
    7

Embed Size (px)

Citation preview

Page 1: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 2: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 3: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 4: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 5: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 6: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

••

Page 7: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

••••••

see@http://www.restapitutorial.com/lessons/whatisrest.html

Page 8: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 9: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

������

����

Page 10: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 11: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

RESTAPI

Client

Mobile client

Page 12: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

RESTAPI

GET /users HTTP/1.1

{"users": […]}

Page 13: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 14: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

RESTAPI

AmazonDynamoDB

AmazonS3

AmazonCloudWatch

Page 15: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

Auto Scaling group

Security group

Elastic Load Balancing

Instance

REST API

AmazonDynamoDB

AmazonCloudWatch

AmazonS3

Page 16: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

AmazonDynamoDB

AmazonCloudWatch

Amazon API Gateway

AWS Lambda

AmazonS3

Page 17: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 18: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

Lambda.GetFunction(params: {'body': '', 'url': u'https://lambda.us-west-2.amazonaws.com/2015-03-31/functionIAM.GetRole(params: {'body': {'Action': u'GetRole', 'RoleName': u'helloworld7', 'Version': u'2010-05IAM.CreateRole(params: {'body': {'Action': u'CreateRole', 'RoleName': u'helloworld7', 'Version': u'2010IAM.PutRolePolicy(params: {'body': {'Action': u'PutRolePolicy', 'RoleName': u'helloworld7', 'PolicyDocumentLambda.CreateFunction(params: (... omitted from logs due to size ...)APIGateway.GetRestApis(params: {'body': '', 'url': u'https://apigateway.us-west-2.amazonaws.com/restapisAPIGateway.CreateRestApi(params: {'body': '{"name": "helloworld7"}', 'url': u'https://apigateway.usAPIGateway.GetResources(params: {'body': '', 'url': u'https://apigateway.us-west-2.amazonaws.com/restapisAPIGateway.PutMethod(params: {'body': '{"authorizationType": "NONE"}', 'url': u'https://apigateway.usAPIGateway.PutIntegration(params: {'body': '{"httpMethod": "POST", "requestTemplates": {"application/APIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"responseTemplates": {"application/json": ""}}', 'APIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"selectionPattern": "ChaliceViewError.*", "responseTemAPIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"selectionPattern": "BadRequestError.*", "responseTempAPIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"selectionPattern": "NotFoundError.*", "responseTemplaAPIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"selectionPattern": "UnauthorizedError.*", "responseTeAPIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"selectionPattern": "ForbiddenError.*", "responseTemplAPIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"selectionPattern": "ConflictError.*", "responseTemplaAPIGateway.PutMethodResponse(params: {'body': '{"responseModels": {"application/json": "Empty"}}', 'APIGateway.PutIntegrationResponse(params: {'body': '{"selectionPattern": "TooManyRequestsError.*", "Lambda.GetPolicy(params: {'body': '', 'url': u'https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/Lambda.AddPermission(params: {'body': '{"Action": "lambda:InvokeFunction", "StatementId": "1e964686APIGatewayCreateDeployment(params: {'body': '{"stageName": "dev"}', 'url': u'https://apigateway.us-

�� #��� API ����!"�� ���������# AWS SAM ����������

Page 19: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 20: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

https://github.com/aws/chalice

Page 21: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

••

••

••

Page 22: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

$ pip install chalice$ chalice new-project helloworld && cd helloworld$ cat app.py

from chalice import Chalice

app = Chalice(app_name="helloworld")

@app.route("/")def index():

return {"hello": "world"}

Page 23: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

$ chalice deploy...https://endpoint/api

$ curl https://endpoint/api{"hello": "world"}

Page 24: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

$ git difffrom chalice import Chalice+import boto3

app = Chalice(app_name='chalice-sample')+S3 = boto3.client('s3', region_name='us-east-1')

@app.route('/')def index():

+ S3.get_object(Bucket = BUCKET, Key = key)return {'hello': 'world'}

Page 25: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

$ chalice deployCreating role: chalice-sample-devThe following execution policy will be used:{"Version": "2012-10-17","Statement": [{ "Effect": "Allow","Action": ["s3:GetObject"

],"Resource": ["*"],"Sid": "40e10c45a..."

},...

}Would you like to continue? [Y/n]:

Page 26: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

$ chalice localServing on localhost:8000

$ npm install -g nodemon$ nodemon --exec "chalice local" --watch *.py[nodemon] 1.12.5[nodemon] to restart at any time, enter `rs`[nodemon] watching: app.py[nodemon] starting `chalice local`Serving on localhost:8000

see@https://qiita.com/TakenoriHirao/items/69f2af5aaf64db77124b

Page 27: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

Page 28: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 29: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

# Basic [email protected]('/')def index():

return {"GET": "/"}

Page 30: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

# Specify [email protected]('/', methods=['PUT'])def index_put():

return {"PUT": "/"}

Page 31: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

@app.route('/res', methods=['GET', 'POST'])def my_resource():

request = app.current_requestif request.method == 'GET':

return {"GET": "/res"}elif request.method == 'POST':

return {"POST": "/res"}

Page 32: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

# Path [email protected]('/myresources/{object_name}')def my_resource_key(object_name):

try:response = S3.get_object(

Bucket = BUCKET, Key = object_name)return response['Body'].read()

except ClientError as e:raise e

Page 33: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

@app.route('/s3/{bucket_name}/objects')def objects_of(bucket_name):

try:response =

S3.list_objects_v2(Bucket=bucket_name, Prefix = S3_PREFIX)

objects = list(map(lambda x: x["Key"], response["Contents"]))

return {"objects": objects}except ClientError as e:

raise ...

Page 34: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

@app.route('/')def index():

return Response(body = 'hello world!',status_code = 200,headers = {'Content-Type': 'text/plain'}

)

Page 35: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 36: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

@app.route('/',cors=True,api_key_required=True,authorizer=IAMAuthorizer())

def index():return "yey"

@app.schedule(Rate(1,unit=Rate.HOURS))def every_hour(event):

print(event.to_dict())

Page 37: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 38: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

•••••

Page 39: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

class Chalice(object):def route(self, path, **kwargs): # ��������

def _register_view(view_func):self._add_route(path, view_func, **kwargs)return view_func

return _register_view

def _add_route(self, path, view_func, **kwargs):methods = kwargs.pop('methods', ['GET'])...for method in methods:

...entry = RouteEntry(view_func, name,

path, method, api_key_required, content_types, cors, authorizer)

self.routes[path][method] = entry

Page 40: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

class Chalice(object):def __call__(self, event, context): # ��������

resource_path = event.get('requestContext', {}).get('resourcePath')

http_method = event['requestContext']['httpMethod']route_entry = self.routes[resource_path][http_method]view_function = route_entry.view_functionfunction_args = {name: event['pathParameters'][name]

for name in route_entry.view_args}...response = self._get_view_function_response(view_function,

function_args)response_headers = CaseInsensitiveMapping(response.headers)...response = response.to_dict(self.api.binary_types)return response

Page 41: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

class Chalice(object):def _get_view_function_response(self, view_function, function_args):

try:response = view_function(**function_args)if not isinstance(response, Response):

response = Response(body=response)self._validate_response(response)

except ChaliceViewError as e:response = Response(...)

except Exception as e:headers = {}if self.debug:

...else:

response = Response(..., status_code=500)return response

Page 42: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 43: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

https://speakerdeck.com/akitsukada/sabaresudewang-dao-webhuremuwakuwoshi-ufang-fa

Page 44: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

https://www.slideshare.net/shimy_net/aws-79149218

Page 45: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

https://www.slideshare.net/shimy_net/cloud-roadshow-2017-osaka

Page 46: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

•••

https://github.com/kislyuk/domovoi

Page 47: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

@app.sns_topic_subscriber("bartender")def tend(event, context):

message = json.loads(event["Records"][0]["Sns"]["Message"])context.log(dict(beer="Quadrupel", quantity=message["beer"]))

@app.cloudwatch_event_handler(source=["aws.ecs"])def monitor_ecs_events(event, context):

message = json.loads(event["Records"][0]["Sns"]["Message"])context.log("Got an event from ECS: {}".format(message))

@app.s3_event_handler(bucket="myS3bucket",events=["s3:ObjectCreated:*"], prefix="foo", suffix=".bar")

def monitor_s3(event, context):message = json.loads(event["Records"][0]["Sns"]["Message"])context.log("Got an event from S3: {}".format(message))

Page 48: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 49: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜

••

••

••

Page 50: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜
Page 51: RESTful API を Chalice で紐解く 〜 Python Serverless Microframework for AWS 〜