Skip to main content
Donate to the Python Software Foundation or Purchase a PyCharm License to Benefit the PSF! Donate Now

pico framework for aws lambda with optional json schema validation

Project description

Build Status Latest Version Python Support

Python routing mini-framework for AWS Lambda with optional JSON-schema validation.

Features

  • lambda_handler function constructor with built-in dispatcher
  • Decorator to register functions to handle HTTP methods
  • Optional JSON-schema input validation using same decorator

Installation

Install the package from PyPI using pip:

pip install lambdarest

Getting Started

This module helps you to handle different HTTP methods in your AWS Lambda.

from lambdarest import lambda_handler

@lambda_handler.handle("get")
def my_own_get(event):
    return {"this": "will be json dumped"}


##### TEST #####


input_event = {
    "body": '{}',
    "httpMethod": "GET",
    "resource": "/"
}
result = lambda_handler(event=input_event)
assert result == {"body": '{"this": "will be json dumped"}', "statusCode": 200, "headers":{}}

Advanced Usage

Optionally you can validate an incoming JSON body against a JSON schema:

from lambdarest import lambda_handler

my_schema = {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "body":{
            "type": "object",
            "properties": {
                "foo": {
                    "type": "string"
                }
            }
        }
    }
}

@lambda_handler.handle("get", path="/with-schema/", schema=my_schema)
def my_own_get(event):
    return {"this": "will be json dumped"}


##### TEST #####


valid_input_event = {
    "body": '{"foo":"bar"}',
    "httpMethod": "GET",
    "resource": "/with-schema/"
}
result = lambda_handler(event=valid_input_event)
assert result == {"body": '{"this": "will be json dumped"}', "statusCode": 200, "headers":{}}


invalid_input_event = {
    "body": '{"foo":666}',
    "httpMethod": "GET",
    "resource": "/with-schema/"
}
result = lambda_handler(event=invalid_input_event)
assert result == {"body": '"Validation Error"', "statusCode": 400, "headers":{}}

Query Params

Query params are also analyzed and validatable with JSON schemas. Query arrays are expected to be comma separated, all numbers are converted to floats.

from lambdarest import lambda_handler

my_schema = {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "query":{
            "type": "object",
            "properties": {
                "foo": {
                    "type": "array",
                    "items": {
                        "type": "number"
                    }
                }
            }
        }
    }
}

@lambda_handler.handle("get", path="/with-params/", schema=my_schema)
def my_own_get(event):
    return event["json"]["query"]


##### TEST #####


valid_input_event = {
    "queryStringParameters": {
        "foo": "1, 2.2, 3"
    },
    "httpMethod": "GET",
    "resource": "/with-params/"
}
result = lambda_handler(event=valid_input_event)
assert result == {"body": '{"foo": [1.0, 2.2, 3.0]}', "statusCode": 200, "headers":{}}

Routing

You can also specify which path to react on for individual handlers using the path param:

from lambdarest import lambda_handler

@lambda_handler.handle("get", path="/foo/bar/baz")
def my_own_get(event):
    return {"this": "will be json dumped"}


##### TEST #####


input_event = {
    "body": '{}',
    "httpMethod": "GET",
    "resource": "/foo/bar/baz"
}
result = lambda_handler(event=input_event)
assert result == {"body": '{"this": "will be json dumped"}', "statusCode": 200, "headers":{}}

And you can specify path parameters as well, which will be passed as keyword arguments:

from lambdarest import lambda_handler

@lambda_handler.handle("get", path="/foo/<int:id>/")
def my_own_get(event, id):
    return {"my-id": id}


##### TEST #####


input_event = {
    "body": '{}',
    "httpMethod": "GET",
    "resource": "/foo/1234/"
}
result = lambda_handler(event=input_event)
assert result == {"body": '{"my-id": 1234}', "statusCode": 200, "headers":{}}

Or use the Proxy APIGateway magic endpoint:

from lambdarest import lambda_handler

@lambda_handler.handle("get", path="/bar/<path:path>")
def my_own_get(event, path):
    return {"path": path}


##### TEST #####

input_event = {
    "body": '{}',
    "httpMethod": "GET",
    "path": "/v1/bar/baz",
    "resource": "/bar/{proxy+}",
    "pathParameters": {
      "proxy": "bar/baz"
    }
}
result = lambda_handler(event=input_event)
assert result == {"body": '{"path": "bar/baz"}', "statusCode": 200, "headers":{}}

Use it with AWS Application Load Balancer

In order to use it with Application Load Balancer you need to create your own lambda_handler and not use the singleton:

from lambdarest import create_lambda_handler

lambda_handler = create_lambda_handler(application_load_balancer=True)

@lambda_handler.handle("get", path="/foo/<int:id>/")
def my_own_get(event, id):
    return {"my-id": id}


##### TEST #####


input_event = {
    "body": '{}',
    "httpMethod": "GET",
    "resource": "/foo/1234/"
}
result = lambda_handler(event=input_event)
assert result == {"body": '{"my-id": 1234}', "statusCode": 200, "headers":{}, "statusDescription": "HTTP OK", "isBase64Encoded": False}

Anormal unittest behaviour with lambda_handler singleton

Because of python unittests leaky test-cases it seems like you shall beware of this issue when using the singleton lambda_handler in a multiple test-case scenario.

Tests

You can use pytest to run tests against your current Python version. To run tests for current python version run pytest

See `setup.py <setup.py>`__ for test dependencies and install them with .[test].

Contributors

sloev, svdgraaf, simongarnier, elviejokike, paddie, AlbertoTrinidade, martinbuberl

Release History

1.0.1 (2017-02-24)

This is not a backwards compatible change.

First OSS release

features - dispatching handler for individual HTTP methods - (optional) jsonschema validation for endpoints - automatic wrapping of responses

2.0.0 (2017-03-04)

This is not a backwards compatible change.

features - now json is divided into [“json”][“body”] for post body and [“json”][“query”] for json loaded query params - jsonschema validation gets whole [“json”] object so remember to change your schemas/code!!!

2.1.0 (2017-03-06)

bugfixes - empty body and queryStringParameters are tolerated

features - query parameters arrays are now supported - array items are tried casted to numbers, defaulted to strings (see last README example) - more tests

2.2.1 (2017-10-03)

features - builds and deploys automatically using travis to pypi and github releases

2.2.6 (2017-12-13)

features - An error handler can now be passed when creating a handler. Any unhandled error will be re-raise when None is passed

4.0.0 (2018-04-06)

features - added Werkzeug path parameters

4.1.0 (2018-04-12)

features - added support for custom domains

5.0.0 (2018-06-07)

This is not a backwards compatible change.

features - removed support for python 3.3

5.0.1 (2018-06-13)

features - Fixed issue with custom domains and path variables

5.1.0 (2018-11-01)

features - Return None only if the value of the variable is None. This will allow to return empty strings.

5.2.0 (2019-03-06)

features - you can override the json encoder with your own

5.3.0 (2019-03-06)

features - Add support for Application Load Balancer

5.4.0 (2019-03-06)

features - Add application_load_balancer arg to create_lambda_handler to create lambda_handlers specifically for Application Load Balancer

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
lambdarest-5.4.0.tar.gz (11.7 kB) Copy SHA256 hash SHA256 Source None

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page