# restful-aws-lambda
[![CI/CD Status](https://github.com/joffreybvn/restful-aws-lambda/workflows/CI%2FCD/badge.svg?branch=master)](https://github.com/joffreybvn/restful-aws-lambda/actions?query=branch:master)
[![Coverage Status](https://coveralls.io/repos/github/Joffreybvn/restful-aws-lambda/badge.svg?branch=master)](https://coveralls.io/github/Joffreybvn/restful-aws-lambda?branch=master)
[![Latest Version](https://img.shields.io/pypi/v/restful-aws-lambda.svg?color=blue)](https://pypi.python.org/pypi/restful-aws-lambda)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/restful-aws-lambda?label=pypi%20downloads)](https://pypi.org/project/restful-aws-lambda/)
![License](https://img.shields.io/github/license/joffreybvn/restful-aws-lambda)
restful-aws-lambda is a lightweight opinionated framework for building REST API using [AWS Lambda](https://aws.amazon.com/lambda/) and [API Gateway](https://aws.amazon.com/api-gateway/).
## Motivation
Why another framework ?
When using API Gateway and python Lambda functions, the most common pattern is to have a unique Lambda function triggered by a proxy API Gateway resource. The Lambda then uses a framework like [Flask](https://flask.palletsprojects.com/en/1.1.x/) to do all the routing. In an API Gateway + Lambda context, I feel like **the routing should be handled by API Gateway itself**, then forwarding the request to specific Lambda functions for each resource or endpoint.
## Features
- No routing. Yes, this is a feature. Routing should be handled by API Gateway.
- API Gateway event parsing (including request body and path parameters).
- Cleaner syntax.
- Customizable JSON dumps behavior
- No schema validation
## Installation
Install the package from PyPI using pip:
```
$ pip install restful-aws-lambda
```
restful-aws-lambda should also be included in the deployment package of your Lambda functions.
## Getting started
restful-aws-lambda provides a `@route` decorator to parse the API Gateway event into a `Request` object available in the handler function as an argument. It also formats the handler's output to the expected Lambda + API Gateway format seamlessly.
Turning this:
```python
import json
def handler(event, context):
body = json.loads(event["body"])
query_params = event["queryStringParameters"]
path_params = event["pathParameters"]
return {
"statusCode": 200,
"body": json.dumps({
"message": f"Hello from AWS Lambda {body['name']}!!"
})
}
```
Into this:
```python
from restful_aws_lambda import route
@route
def handler(request):
body = request.json
query_params = request.query_params
path_params = request.path_params
return 200, {"message": f"Hello from AWS Lambda {body['name']}!!"}
```
You can still access the original `event` and `context` arguments from the handler:
```python
from restful_aws_lambda import route
@route
def handler(request, event, context):
print(event)
body = request.json
return 200, {"message": f"Hello from AWS Lambda {body['name']}!!"}
```
<br/>
Path parameters defined in API Gateway can also be accessed directly as function argument:
<br/>
![api-gateway-path-params](https://raw.githubusercontent.com/joffreybvn/restful-aws-lambda/master/images/api-gateway-path-params.png)
```python
from restful_aws_lambda import route
@route
def get_user(user_id):
print(user_id)
# get user from db
user = {"id": user_id, "name": "John Doe"}
return 200, user
```
## JSON dumps options
restful-aws-lambda uses the default `json` library to dump the lambda handler response. You can customize the behavior of it by passing `json.dumps()` keyword arguments to the `json=` parameter:
```python
import json
import datetime
from restful_aws_lambda import route
class JSONDatetimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()
return super(JSONDatetimeEncoder, self).default(obj)
@route(json={"cls": JSONDatetimeEncoder})
def lambda_handler(request):
today = datetime.date.today()
return 200, {"today": today}
```
## Example
You can look at the [sample](https://github.com/joffreybvn/restful-aws-lambda/tree/master/sample) for a minimal pylambdarest API.
In this sample, we use the [serverless](https://www.serverless.com/) framework to declare the API Gateway -> Lambda routing
The packaging of the Lambda functions is done using the [serverless-python-requirements](https://github.com/UnitedIncome/serverless-python-requirements) plugin.
Raw data
{
"_id": null,
"home_page": "https://github.com/Joffreybvn/restful-aws-lambda",
"name": "restful-aws-lambda",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7.0,<4.0.0",
"maintainer_email": "",
"keywords": "aws-lambda,serverless,api-gateway,rest-api",
"author": "Joffrey Bienvenu",
"author_email": "joffreybvn@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/26/99/7b1cd48efcb1862017ef91b3b8693b8c44946f540af604e63e3aa487a3ad/restful_aws_lambda-0.1.2.tar.gz",
"platform": null,
"description": "# restful-aws-lambda\n\n[![CI/CD Status](https://github.com/joffreybvn/restful-aws-lambda/workflows/CI%2FCD/badge.svg?branch=master)](https://github.com/joffreybvn/restful-aws-lambda/actions?query=branch:master)\n[![Coverage Status](https://coveralls.io/repos/github/Joffreybvn/restful-aws-lambda/badge.svg?branch=master)](https://coveralls.io/github/Joffreybvn/restful-aws-lambda?branch=master)\n[![Latest Version](https://img.shields.io/pypi/v/restful-aws-lambda.svg?color=blue)](https://pypi.python.org/pypi/restful-aws-lambda)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/restful-aws-lambda?label=pypi%20downloads)](https://pypi.org/project/restful-aws-lambda/)\n![License](https://img.shields.io/github/license/joffreybvn/restful-aws-lambda)\n\nrestful-aws-lambda is a lightweight opinionated framework for building REST API using [AWS Lambda](https://aws.amazon.com/lambda/) and [API Gateway](https://aws.amazon.com/api-gateway/).\n\n## Motivation\n\nWhy another framework ?\n\nWhen using API Gateway and python Lambda functions, the most common pattern is to have a unique Lambda function triggered by a proxy API Gateway resource. The Lambda then uses a framework like [Flask](https://flask.palletsprojects.com/en/1.1.x/) to do all the routing. In an API Gateway + Lambda context, I feel like **the routing should be handled by API Gateway itself**, then forwarding the request to specific Lambda functions for each resource or endpoint.\n\n## Features\n\n- No routing. Yes, this is a feature. Routing should be handled by API Gateway.\n- API Gateway event parsing (including request body and path parameters).\n- Cleaner syntax.\n- Customizable JSON dumps behavior\n- No schema validation\n\n## Installation\n\nInstall the package from PyPI using pip:\n\n```\n$ pip install restful-aws-lambda\n```\n\nrestful-aws-lambda should also be included in the deployment package of your Lambda functions.\n\n## Getting started\n\nrestful-aws-lambda provides a `@route` decorator to parse the API Gateway event into a `Request` object available in the handler function as an argument. It also formats the handler's output to the expected Lambda + API Gateway format seamlessly.\n\nTurning this:\n\n```python\nimport json\n\ndef handler(event, context):\n body = json.loads(event[\"body\"])\n query_params = event[\"queryStringParameters\"]\n path_params = event[\"pathParameters\"]\n\n return {\n \"statusCode\": 200,\n \"body\": json.dumps({\n \"message\": f\"Hello from AWS Lambda {body['name']}!!\"\n })\n }\n\n```\n\nInto this:\n\n```python\nfrom restful_aws_lambda import route\n\n\n@route\ndef handler(request):\n body = request.json\n query_params = request.query_params\n path_params = request.path_params\n\n return 200, {\"message\": f\"Hello from AWS Lambda {body['name']}!!\"}\n```\n\nYou can still access the original `event` and `context` arguments from the handler:\n\n```python\nfrom restful_aws_lambda import route\n\n\n@route\ndef handler(request, event, context):\n print(event)\n body = request.json\n\n return 200, {\"message\": f\"Hello from AWS Lambda {body['name']}!!\"}\n```\n\n<br/>\n\nPath parameters defined in API Gateway can also be accessed directly as function argument:\n\n<br/>\n\n![api-gateway-path-params](https://raw.githubusercontent.com/joffreybvn/restful-aws-lambda/master/images/api-gateway-path-params.png)\n\n```python\nfrom restful_aws_lambda import route\n\n\n@route\ndef get_user(user_id):\n print(user_id)\n\n # get user from db\n user = {\"id\": user_id, \"name\": \"John Doe\"}\n\n return 200, user\n```\n\n## JSON dumps options\n\nrestful-aws-lambda uses the default `json` library to dump the lambda handler response. You can customize the behavior of it by passing `json.dumps()` keyword arguments to the `json=` parameter:\n\n```python\nimport json\nimport datetime\nfrom restful_aws_lambda import route\n\nclass JSONDatetimeEncoder(json.JSONEncoder):\n def default(self, obj):\n if isinstance(obj, (datetime.date, datetime.datetime)):\n return obj.isoformat()\n\n return super(JSONDatetimeEncoder, self).default(obj)\n\n\n@route(json={\"cls\": JSONDatetimeEncoder})\ndef lambda_handler(request):\n today = datetime.date.today()\n return 200, {\"today\": today}\n```\n\n## Example\n\nYou can look at the [sample](https://github.com/joffreybvn/restful-aws-lambda/tree/master/sample) for a minimal pylambdarest API.\n\nIn this sample, we use the [serverless](https://www.serverless.com/) framework to declare the API Gateway -> Lambda routing\n\nThe packaging of the Lambda functions is done using the [serverless-python-requirements](https://github.com/UnitedIncome/serverless-python-requirements) plugin.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Lightweight framework for building REST API using AWS Lambda + API Gateway",
"version": "0.1.2",
"split_keywords": [
"aws-lambda",
"serverless",
"api-gateway",
"rest-api"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "8e3a3fd7ff925f37077928e7ab14e3eb743d850acba51bae80b6ddf48a14e8bc",
"md5": "9d8ff41596919f00d0b128761d224c0e",
"sha256": "3e8439528e745874278c093e2277bfba6755ee16c06acee65f51773f93d8b80c"
},
"downloads": -1,
"filename": "restful_aws_lambda-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9d8ff41596919f00d0b128761d224c0e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7.0,<4.0.0",
"size": 6848,
"upload_time": "2023-01-08T11:47:15",
"upload_time_iso_8601": "2023-01-08T11:47:15.630890Z",
"url": "https://files.pythonhosted.org/packages/8e/3a/3fd7ff925f37077928e7ab14e3eb743d850acba51bae80b6ddf48a14e8bc/restful_aws_lambda-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "26997b1cd48efcb1862017ef91b3b8693b8c44946f540af604e63e3aa487a3ad",
"md5": "f6ee4a0da6122f1f24ef04892b77a414",
"sha256": "23c3c0561187146eb621096f5305cd046703eb09fb4371270763b48cf36d8ff6"
},
"downloads": -1,
"filename": "restful_aws_lambda-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "f6ee4a0da6122f1f24ef04892b77a414",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7.0,<4.0.0",
"size": 6149,
"upload_time": "2023-01-08T11:47:17",
"upload_time_iso_8601": "2023-01-08T11:47:17.595748Z",
"url": "https://files.pythonhosted.org/packages/26/99/7b1cd48efcb1862017ef91b3b8693b8c44946f540af604e63e3aa487a3ad/restful_aws_lambda-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-01-08 11:47:17",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "Joffreybvn",
"github_project": "restful-aws-lambda",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "restful-aws-lambda"
}