Welcome to lamapi’s documentation!¶
A simple framework for building serverless api web applications based on AWS lambda and API Gateway.
User’s Guide¶
Installation¶
Python Version¶
We recommend using the latest version of Python 3. Lamapi supports Python 3.5 and newer.
Dependencies¶
Lamapi is a serverless framework and depends on AWS Lambda and API Gateway, so we try to restrict dependent packages. This is the only package you need to try Lamapi except built-in packages.
Lamapi depends on AWS Lambda and API Gateway, you should deploy the code to AWS after development. We recommend you to use something like Serverless Framework, check here to see how to use serverless framework on AWS.
Installation¶
You should install lamapi in the current directory since you can upload it to Lambda.
pip install -t lib lamapi
Lamapi is now installed. Check out the Quick Start or go to the Documentation Overview.
Check out our source from Github.
Start Serverless Project using Serverless Framework and Lamapi¶
We assume you have Serverless Framework installed. Installation Guide
Create A Project¶
serverless create --template aws-python3 --path hello
Update Configuration File¶
Update serverless.yml to something like this:
service: hello
provider:
name: aws
runtime: python3.7
functions:
hello:
handler: handler.handler
events:
- http:
path: hello
method: get
We use the python3.7 interpreter and add a function named hello listening at /hello path.
Note, you should use lambda-proxy integration (it is the default value) for your function because it formats a standard request and response structure. See Serverless Lambda Proxy Integration and AWS API Gateway Integration.
Then we edit handler.py file as below:
from lib.lamapi import Application
def handler(event, context):
app = Application()
@app.route(path='/hello', method='GET')
def hello(request):
return ['hello world']
return app.run(event)
Deploy & Test Your Project¶
Deploy project
serverless deploy
Invoke function
serverless invoke -f hello -l
Next start to use Lamapi to build a web API Quick Start.
Quick Start¶
A Minimal Application¶
We assume you install Lamapi under lib directory and start a serverless project using Serverless Framework. Installation.
A minimal Lamapi application looks something like this:
from lib.lamapi.app import Application
def lambda_handler(event, context):
app = Application()
@app.route(path='/', method='GET')
def hello(request):
return 'Hello'
return app.run(event)
So what did that code do?
- First we import Application class, an instance of this class will help us to handle http event and return response.
- Next in the lambda_handler() function (which is the entry point for the Lambda) we create an instance of this class.
- Then we use the route() decorator to tell Lamapi what URL should trigger our function.
- The function receives a request object and returns the message we want to display in the user’s browser.
Just save it as hello.py or something similar. Then deploy it to the AWS Lambda and API Gateway or deploy using Serverless Framework as below.
serverless deploy
Then test it as:
serverless invoke -f hello
Then you will get output as below:
blalbal
Is it as simple as Flask?
Routing¶
Routing is as simple as Flask. Use app.route descriptor to functions with path and/or methods.
Listening on path /
with all methods,
def lambda_handler(event, context):
app = Application()
@app.route(path='/')
def hello(request):
return 'Hello'
return app.run(event)
Listening on path /
with GET
method,
def lambda_handler(event, context):
app = Application()
@app.route(path='/', method='GET')
def hello(request):
return 'Hello'
return app.run(event)
Use list to listen on more methods,
def lambda_handler(event, context):
app = Application()
@app.route(path='/', method=['GET', 'POST'])
def hello(request):
return 'Hello'
return app.run(event)
Request¶
Each function will receive a request instance as parameter. You can use this object to get anything you want.
A request body from API Gateway will look like this:
{
"body": "",
"resource": "/hello",
"path": "/hello",
"httpMethod": "GET",
"isBase64Encoded": false,
"queryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "en-US,en;q=0.8",
"Cache-Control": "max-age=0",
"User-Agent": "Custom User Agent String"
}
"requestContext": {
//......
}
}
Lamapi framework will store this object in request object. And you can get all you want by accessing request object’s attributes.
Request Path¶
def hello(request):
path = request.path
Request Method¶
def hello(request):
method = request.method
Query Parameters¶
def hello(request):
id = request.query.get('id')
# if request url is /hello?id=1
# then id = 1
name = request.query.get('name') or 'default'
# give some default value
Form Data¶
To access form data (data transmitted in a POST or PUT request) you can use the data attributes.
def hello(request):
name = request.data.get('name') or 'default'
Path Parameters¶
If you define some path parameters in API Gateway, you can get them by path_param. If you define your path as /hello/{name}, then requested as /hello/world, you will get path parameters as name=world.
def hello(request):
name = request.path_param.get('name') or 'default'
Request Header¶
Headers will be stored in header attribute as a dict.
def hello(request):
accept = request.header.get('Accept')
Response¶
Anything you return to handler function will be translated to a JSON object which will be returned to client. You can return a string, dict, list or any object can be encoded to json.
def hello(request):
return 'hello world'
If you want to return a custom http code such as 400 or custom headers, you can build response object by yourself.
from lib.lamapi.wrappers import Response
def hello(request):
return Response([], status=400, headers={'X-CUSTOM': 'xxx'})
Where to go next? Learn deep about Configuration.
Configuration¶
Use your own configuration object¶
Lamapi use a simple config object to store variables. You can get config object by config attribute of request object.
def hello(request):
// get config object
config = request.config
// get config variables
log_level = request.config.LOG_LEVEL
You can define your own variables by extending the base config class.
Add a config.py file,
from lib.lamapi.config import BaseConfig
class Config(BaseConfig):
VAR1 = 'value1'
Then you can start application by this config class,
from lib.lamapi import Application
from config import Config
def handler(event, context):
config = Config()
app = Application(config)
@app.route(path='/', method='GET')
def hello(request):
// get config variable
var1 = request.config.VAR1
Load configuration from environments¶
Mostly you want to config your application by environments.
Change your config.py file,
import os
from lib.lamapi.config import BaseConfig
class Config(BaseConfig):
VAR1 = os.environ.get('VALUE1') or 'default'
Built-in configuration
There are also some built-in configuration defined in the BaseConfig class. You can change them by using environments.
LOG_LEVEL
Define the logging level, values [FATAL
, ERROR
, WARNING
, INFO
, DEBUG
], default ERROR
LOG_FORMATTER
Define the logging formatter, default %(asctime)s [%(levelname)s] %(filename)s (%(lineno)d): %(message)s
ENABLE_CORS
Enable CORS or not, values [on
, off
], default off