pylambdarest


Namepylambdarest JSON
Version 0.2.1 PyPI version JSON
download
home_pagehttps://github.com/MarwanDebbiche/pylambdarest
SummaryLightweight framework for building REST API using AWS Lambda + API Gateway
upload_time2022-10-31 17:07:15
maintainer
docs_urlNone
authorMarwan Debbiche (Macbook Pro)
requires_python>=3.7.2,<4.0.0
licenseMIT
keywords aws-lambda serverless api-gateway rest-api
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pylambdarest

[![CI/CD Status](https://github.com/MarwanDebbiche/pylambdarest/workflows/CI%2FCD/badge.svg?branch=master)](https://github.com/MarwanDebbiche/pylambdarest/actions?query=branch:master)
[![Coverage Status](https://coveralls.io/repos/github/MarwanDebbiche/pylambdarest/badge.svg?branch=master)](https://coveralls.io/github/MarwanDebbiche/pylambdarest?branch=master)
[![Latest Version](https://img.shields.io/pypi/v/pylambdarest.svg?color=blue)](https://pypi.python.org/pypi/pylambdarest)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/pylambdarest?label=pypi%20downloads)](https://pypi.org/project/pylambdarest/)
![License](https://img.shields.io/github/license/MarwanDebbiche/pylambdarest)

pylambdarest 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.
- Optional body schema and query parameters validation.

## Installation

Install the package from PyPI using pip:

```
$ pip install pylambdarest
```

pylambdarest should also be included in the deployment package of your Lambda functions.

## Getting started

pylambdarest 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 pylambdarest 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 pylambdarest 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/MarwanDebbiche/pylambdarest/master/images/api-gateway-path-params.png)

```python
from pylambdarest 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
```

## Schema Validation

pylambdarest optionally provides schema validation using [jsonschema](https://github.com/Julian/jsonschema):

```python
from pylambdarest import route

user_schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"}
    },
    "required": ["name"],
    "additionalProperties": False
}

@route(body_schema=user_schema)
def create_user(request):
    # If the request's body does not
    # satisfy the user_schema,
    # a 400 will be returned

    # Create user here

    return 201


query_params_schema = {
    "type": "object",
    "properties": {
        # Only string types are allowed for query parameters.
        # Types casting should be done in the handler.
        "page": {"type": "string"}
    },
    "additionalProperties": False
}

@route(query_params_schema=query_params_schema)
def get_users(request):
    page = int(request.query_params.get("page", 1))

    # request users in db
    users = [
        {"userId": i}
        for i in range((page - 1) * 50, page * 50)
    ]

    return 200, users
```

## Example

You can look at the [sample](https://github.com/MarwanDebbiche/pylambdarest/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/MarwanDebbiche/pylambdarest",
    "name": "pylambdarest",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7.2,<4.0.0",
    "maintainer_email": "",
    "keywords": "aws-lambda,serverless,api-gateway,rest-api",
    "author": "Marwan Debbiche (Macbook Pro)",
    "author_email": "marwan.debbiche@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/c1/5b/2ebd216e671a48e72b9c6255996cfb661fa288e5cdd7b70bd85c91ee6cad/pylambdarest-0.2.1.tar.gz",
    "platform": null,
    "description": "# pylambdarest\n\n[![CI/CD Status](https://github.com/MarwanDebbiche/pylambdarest/workflows/CI%2FCD/badge.svg?branch=master)](https://github.com/MarwanDebbiche/pylambdarest/actions?query=branch:master)\n[![Coverage Status](https://coveralls.io/repos/github/MarwanDebbiche/pylambdarest/badge.svg?branch=master)](https://coveralls.io/github/MarwanDebbiche/pylambdarest?branch=master)\n[![Latest Version](https://img.shields.io/pypi/v/pylambdarest.svg?color=blue)](https://pypi.python.org/pypi/pylambdarest)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/pylambdarest?label=pypi%20downloads)](https://pypi.org/project/pylambdarest/)\n![License](https://img.shields.io/github/license/MarwanDebbiche/pylambdarest)\n\npylambdarest 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- Optional body schema and query parameters validation.\n\n## Installation\n\nInstall the package from PyPI using pip:\n\n```\n$ pip install pylambdarest\n```\n\npylambdarest should also be included in the deployment package of your Lambda functions.\n\n## Getting started\n\npylambdarest 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 pylambdarest import route\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 pylambdarest import route\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/MarwanDebbiche/pylambdarest/master/images/api-gateway-path-params.png)\n\n```python\nfrom pylambdarest import route\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## Schema Validation\n\npylambdarest optionally provides schema validation using [jsonschema](https://github.com/Julian/jsonschema):\n\n```python\nfrom pylambdarest import route\n\nuser_schema = {\n    \"type\": \"object\",\n    \"properties\": {\n        \"name\": {\"type\": \"string\"}\n    },\n    \"required\": [\"name\"],\n    \"additionalProperties\": False\n}\n\n@route(body_schema=user_schema)\ndef create_user(request):\n    # If the request's body does not\n    # satisfy the user_schema,\n    # a 400 will be returned\n\n    # Create user here\n\n    return 201\n\n\nquery_params_schema = {\n    \"type\": \"object\",\n    \"properties\": {\n        # Only string types are allowed for query parameters.\n        # Types casting should be done in the handler.\n        \"page\": {\"type\": \"string\"}\n    },\n    \"additionalProperties\": False\n}\n\n@route(query_params_schema=query_params_schema)\ndef get_users(request):\n    page = int(request.query_params.get(\"page\", 1))\n\n    # request users in db\n    users = [\n        {\"userId\": i}\n        for i in range((page - 1) * 50, page * 50)\n    ]\n\n    return 200, users\n```\n\n## Example\n\nYou can look at the [sample](https://github.com/MarwanDebbiche/pylambdarest/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.2.1",
    "project_urls": {
        "Documentation": "https://pylambdarest.readthedocs.io",
        "Homepage": "https://github.com/MarwanDebbiche/pylambdarest",
        "Repository": "https://github.com/MarwanDebbiche/pylambdarest"
    },
    "split_keywords": [
        "aws-lambda",
        "serverless",
        "api-gateway",
        "rest-api"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "69cf35d37623512490945681ad87af5dd994bb1da339582ab3d7b86295b7c1fc",
                "md5": "f68b4a4bb29fde6e2081c632f5958dad",
                "sha256": "44acfad5d240ec5b7dbf84e8ca03a1b81e4bc7d52c4f8529e5296fbdab5ace9e"
            },
            "downloads": -1,
            "filename": "pylambdarest-0.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f68b4a4bb29fde6e2081c632f5958dad",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7.2,<4.0.0",
            "size": 6799,
            "upload_time": "2022-10-31T17:07:13",
            "upload_time_iso_8601": "2022-10-31T17:07:13.998165Z",
            "url": "https://files.pythonhosted.org/packages/69/cf/35d37623512490945681ad87af5dd994bb1da339582ab3d7b86295b7c1fc/pylambdarest-0.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c15b2ebd216e671a48e72b9c6255996cfb661fa288e5cdd7b70bd85c91ee6cad",
                "md5": "f8bfe2826d5d077eb522e13657102bb4",
                "sha256": "1057a77eb7d669a625b0092cbd03f6a317757965e9739164b18bed0606ec144f"
            },
            "downloads": -1,
            "filename": "pylambdarest-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "f8bfe2826d5d077eb522e13657102bb4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7.2,<4.0.0",
            "size": 6545,
            "upload_time": "2022-10-31T17:07:15",
            "upload_time_iso_8601": "2022-10-31T17:07:15.989490Z",
            "url": "https://files.pythonhosted.org/packages/c1/5b/2ebd216e671a48e72b9c6255996cfb661fa288e5cdd7b70bd85c91ee6cad/pylambdarest-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-10-31 17:07:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "MarwanDebbiche",
    "github_project": "pylambdarest",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "pylambdarest"
}
        
Elapsed time: 0.07636s