Flask like web framework for AWS Lambda

Overview

lambdarest logo

lambdarest

Build Status Latest Version PyPI - Downloads Python Support Examples tested with pytest-readme

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

⚠️ A user study is currently happening here, and your opinion makes the day! Thanks for participating! 😊

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

Support the development ❤️

You can support the development by:

  1. Contributing code

  2. Buying the maintainer a coffee

  3. Buying some Lambdarest swag

    like this mug for example:

    lambdarest mug

External articles / tutorials

Other articles? add them here

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":{}}

Documentation

See docs for documentation and examples covering amongst:

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

This package uses Poetry to install requirements and run tests.

Use the following commands to install requirements and run test-suite:

$ poetry install
$ poetry run task test

For more info see Contributing...

Changelog

See HISTORY.md

Contributors

Thanks for contributing!

@sphaugh, @amacks, @jacksgt, @mkreg, @aphexer, @nabrosimoff, @elviejokike, @eduardomourar, @devgrok, @AlbertoTrindade, @paddie, @svdgraaf, @simongarnier, @martinbuberl, @adamelmore, @sloev

Wanna contribute?

And by the way, we have a Code Of Friendlyhood!

Comments
  • Support of resource path {placeholders} in the middle

    Support of resource path {placeholders} in the middle

    I made a resource path preparing before routing.

    The issue was found when I tried to implement lambda for working with URL /bay/{bay_id}/status. The router was not able to find a correct handler.

    I made preparing of the path before routing. Now, the resource path is being filled by path parameters before the routing, but if the parameters list is incorrect, the code still returns code 404.

    opened by nabrosimoff 12
  • Make Api Gateway custom domain work (with basepath)

    Make Api Gateway custom domain work (with basepath)

    When APIGW is setup with a custom domain. The path to the call will include the basepath (if setup). To fix this, we need to check for the resource path which will contain the actual path without the basepath.

    This fixes #31

    opened by svdgraaf 12
  • Fixed issue where using path parameters but no custom domain breaks

    Fixed issue where using path parameters but no custom domain breaks

    I just redeployed an api to api gateway without a custom domain, but with path parameters in the url. This broke the parsing. I think this was an edge cased that I missed last time.

    This change fixes this issue. It checks if both path and resource are set. If so, it checks if they are the same. If so, it uses resource, if not. It uses path, which will contain all the values for the path parameters.

    opened by svdgraaf 11
  • [Question/BUG] Query Parameters converted to float

    [Question/BUG] Query Parameters converted to float

    issue / feature request

    I Would like to understand the rationale of converting any query parameter that is a series of digits to floats. I am building an API that relies on Account ID's being based which are digits, these are needed in string form and python-lambdarest uses the float() function to convert all strings that are numeric, without the ability to override this behaviour from what i can tell.

    Is there a reason for this - HTTP is a string based protocol afaik, hence converting to float seems somewhat arbitrary and if needed something that could be done in business logic vs the underlying library which is parsing the API Gateway JSON payload.

    Thanks!

    opened by andyfase 9
  • Use workzeug for route parsing

    Use workzeug for route parsing

    TL/DR: This PR makes paths like /foo/bar/<int:id>/ work.

    I needed path parameter support for my api, I noticed that Workzeug (from Flask) solved that issue already, and here we are.

    • I added a dependency on workzeug
    • I added the mapper for mapping the function calls
    • I added a short description in the readme
    opened by svdgraaf 7
  • minimally process standard lambda (dict) responses

    minimally process standard lambda (dict) responses

    Personally, I'd prefer to be able to return a normal lambda response from my handlers and not have to introduce a library-specific output format:

    @lambda_handler.handle("get", path="/")
    def index(event: dict) -> dict:
    	return {
    		"statusCode": 302,
    		"headers": {
    			"Location": "https://example.com"
    		}
    	}
    

    This allows the library to be used solely for its routing capabilities which is desirable to those that aren't interested in any output massaging.

    opened by adamelmore 6
  • Using functools wraps on inner function

    Using functools wraps on inner function

    This fixes the same issues from PR #51 , but it also works for python 2.7.

    I run into problems when trying to document the code that contained @lambda_handler and it was not possible because the wrapper function was not marked as decorator.

    opened by eduardomourar 6
  • Options for configuring CORS and preflight requests

    Options for configuring CORS and preflight requests

    Is CORS handling within the scope of this project?

    I'd like to configure CORS when I call create_lambda_handler. Maybe it would be sufficient to add a headers kwarg for my use case?

    @sloev

    opened by furrycatherder 5
  • [BUG] multiValueHeaders not being sent back (ALB)

    [BUG] multiValueHeaders not being sent back (ALB)

    It looks like ALB needs support for multiValueHeaders as part of the return JSON for things like Content-Type, headers does not seem to be properly passed through the ALB. I added a multiValueHeader element by copying and modifying headers in the to_json and inner_lambda_handler and it seems to work as expected and the ALB properly interprets. I can submit a PR, but I cannot vouch for the quality of the code, however it does seem to work

    diff --git a/lambdarest/__init__.py b/lambdarest/__init__.py
    index d8cd80f..8079e97 100755
    --- a/lambdarest/__init__.py
    +++ b/lambdarest/__init__.py
    @@ -22,10 +22,11 @@ class Response(object):
         if no headers are specified, empty dict is returned
         """
     
    -    def __init__(self, body=None, status_code=None, headers=None):
    +    def __init__(self, body=None, status_code=None, headers=None, multiValueHeaders=None):
             self.body = body
             self.status_code = status_code
             self.headers = headers
    +        self.multiValueHeaders = multiValueHeaders
             self.status_code_description = None
             self.isBase64_encoded = False
     
    @@ -42,8 +43,12 @@ class Response(object):
                 if do_json_dumps
                 else self.body,
                 "statusCode": status_code,
    -            "headers": self.headers or {},
             }
    +        ## handle multiValueHeaders if defined, default to headers
    +        if (self.multiValueHeaders == None) :
    +            response["headers"] = self.headers or {}
    +        else:
    +            response["multiValueHeaders"] = self.multiValueHeaders
             # if body is None, remove the key
             if response.get("body") == None:
                 response.pop("body")
    @@ -235,21 +240,22 @@ def create_lambda_handler(
                                 raise ValueError("Response tuple has more than 3 items")
     
                             # Unpack the tuple, missing items will be defaulted
    -                        body, status_code, headers = response + (None,) * (
    -                            3 - response_len
    +                        body, status_code, headers, multiValueHeaders = response + (None,) * (
    +                            4 - response_len
                             )
     
                         elif isinstance(response, dict) and all(
    -                        key in ["body", "statusCode", "headers"]
    +                        key in ["body", "statusCode", "headers", "multiValueHeaders"]
                             for key in response.keys()
                         ):
                             body = response.get("body")
                             status_code = response.get("statusCode") or status_code
                             headers = response.get("headers") or headers
    +                        multiValueHeaders = response.get("multiValueHeaders") or multiValueHeaders
     
                         else:  # if response is string, int, etc.
                             body = response
    -                    response = Response(body, status_code, headers)
    +                    response = Response(body, status_code, headers, multiValueHeaders)
                     return response.to_json(
                         encoder=json_encoder,
                         application_load_balancer=application_load_balancer,
    
    
    opened by amacks 5
  • Trouble installing with pip

    Trouble installing with pip

    When running the install command "pip install lambdarest" I get an error

    ERROR: Command errored out with exit status 1: command: /backend/api_lambda/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/65/jpxwzrxj68xb7lp74c2_yf8hrp6vql/T/pip-install-wor4aeh7/lambdarest/setup.py'"'"'; file='"'"'/private/var/folders/65/jpxwzrxj68xb7lp74c2_yf8hrp6vql/T/pip-install-wor4aeh7/lambdarest/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/65/jpxwzrxj68xb7lp74c2_yf8hrp6vql/T/pip-install-wor4aeh7/lambdarest/pip-egg-info cwd: /private/var/folders/65/jpxwzrxj68xb7lp74c2_yf8hrp6vql/T/pip-install-wor4aeh7/lambdarest/ Complete output (5 lines): Traceback (most recent call last): File "", line 1, in File "/private/var/folders/65/jpxwzrxj68xb7lp74c2_yf8hrp6vql/T/pip-install-wor4aeh7/lambdarest/setup.py", line 9, in history = open("HISTORY.md").read() FileNotFoundError: [Errno 2] No such file or directory: 'HISTORY.md' ---------------------------------------- ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

    Is there an issue with the setup.py script? Is this a known issue?

    opened by zchesty 5
  • Briefly mention in README how to setup api-gateway for Lambdarest lambda

    Briefly mention in README how to setup api-gateway for Lambdarest lambda

    Hi @svdgraaf, Can you maybe briefly write an update to the readme mentioning how to setup the api-gateway for using Lambdarest. I haven't been using lambdarest in production in over a year so i am a bit rusty. Thanks for your contributions!

    help wanted 
    opened by sloev 5
  • [ENHANCEMENT] Support Lambda Function URLs

    [ENHANCEMENT] Support Lambda Function URLs

    I've been using lambdarest for years and tried the latest version with Lambda Function URLs, which will not work without a bit of work (notably, the field names in the event are slightly different than what the code expects). I recognize this project is currently unmaintained, but wanted to introduce this enhancement as a notice to other users should they consider trying this themselves.

    Sample event from Lambda Function URL request

    {
      "version": "2.0",
      "routeKey": "$default",
      "rawPath": "/my/path",
      "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
      "cookies": [
        "cookie1",
        "cookie2"
      ],
      "headers": {
        "header1": "value1",
        "header2": "value1,value2"
      },
      "queryStringParameters": {
        "parameter1": "value1,value2",
        "parameter2": "value"
      },
      "requestContext": {
        "accountId": "123456789012",
        "apiId": "<urlid>",
        "authentication": null,
        "authorizer": {
            "iam": {
                    "accessKey": "AKIA...",
                    "accountId": "111122223333",
                    "callerId": "AIDA...",
                    "cognitoIdentity": null,
                    "principalOrgId": null,
                    "userArn": "arn:aws:iam::111122223333:user/example-user",
                    "userId": "AIDA..."
            }
        },
        "domainName": "<url-id>.lambda-url.us-west-2.on.aws",
        "domainPrefix": "<url-id>",
        "http": {
          "method": "POST",
          "path": "/my/path",
          "protocol": "HTTP/1.1",
          "sourceIp": "123.123.123.123",
          "userAgent": "agent"
        },
        "requestId": "id",
        "routeKey": "$default",
        "stage": "$default",
        "time": "12/Mar/2020:19:03:58 +0000",
        "timeEpoch": 1583348638390
      },
      "body": "Hello from client!",
      "pathParameters": null,
      "isBase64Encoded": false,
      "stageVariables": null
    }
    
    help wanted Pay maintainer to give a damn 😅 
    opened by gswalden 1
Releases(untagged-080ed2ae2bbff1b043aa)
Owner
sloev / Johannes Valbjørn
I like to write software and then give it away for free. Walking the thin line between silly and useful.
sloev / Johannes Valbjørn
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Jan 08, 2023
REST API framework designed for human beings

Eve Eve is an open source Python REST API framework designed for human beings. It allows to effortlessly build and deploy highly customizable, fully f

eve 6.6k Jan 07, 2023
Distribution Analyser is a Web App that allows you to interactively explore continuous distributions from SciPy and fit distribution(s) to your data.

Distribution Analyser Distribution Analyser is a Web App that allows you to interactively explore continuous distributions from SciPy and fit distribu

Robert Dzudzar 46 Nov 08, 2022
A framework that let's you compose websites in Python with ease!

Perry Perry = A framework that let's you compose websites in Python with ease! Perry works similar to Qt and Flutter, allowing you to create componen

Linkus 13 Oct 09, 2022
Restful API framework wrapped around MongoEngine

Flask-MongoRest A Restful API framework wrapped around MongoEngine. Setup from flask import Flask from flask_mongoengine import MongoEngine from flask

Close 525 Jan 01, 2023
Cses2humio - CrowdStrike Falcon Event Stream to Humio

CrowdStrike Falcon Event Stream to Humio This project intend to provide a simple

Trifork.Security 6 Aug 02, 2022
NO LONGER MAINTAINED - A Flask extension for creating simple ReSTful JSON APIs from SQLAlchemy models.

NO LONGER MAINTAINED This repository is no longer maintained due to lack of time. You might check out the fork https://github.com/mrevutskyi/flask-res

1k Jan 04, 2023
You can use the mvc pattern in your flask application using this extension.

You can use the mvc pattern in your flask application using this extension. Installation Run the follow command to install mvc_flask: $ pip install mv

Marcus Pereira 37 Dec 17, 2022
Pulumi-checkly - Checkly Pulumi Provider With Python

🚨 This project is still in very early stages and is not stable, use at your own

Checkly 16 Dec 15, 2022
The no-nonsense, minimalist REST and app backend framework for Python developers, with a focus on reliability, correctness, and performance at scale.

The Falcon Web Framework Falcon is a reliable, high-performance Python web framework for building large-scale app backends and microservices. It encou

Falconry 9k Jan 01, 2023
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Dec 28, 2022
WebSocket and WAMP in Python for Twisted and asyncio

Autobahn|Python WebSocket & WAMP for Python on Twisted and asyncio. Quick Links: Source Code - Documentation - WebSocket Examples - WAMP Examples Comm

Crossbar.io 2.4k Jan 06, 2023
Fast⚡, simple and light💡weight ASGI micro🔬 web🌏-framework for Python🐍.

NanoASGI Asynchronous Python Web Framework NanoASGI is a fast ⚡ , simple and light 💡 weight ASGI micro 🔬 web 🌏 -framework for Python 🐍 . It is dis

Kavindu Santhusa 8 Jun 16, 2022
A shopping list and kitchen inventory management app.

Flask React Project This is the backend for the Flask React project. Getting started Clone this repository (only this branch) git clone https://github

11 Jun 03, 2022
Python Wrapper for interacting with the Flutterwave API

Python Flutterwave Description Python Wrapper for interacting with the Flutterwa

William Otieno 32 Dec 14, 2022
The source code to the Midnight project

MidnightSniper Started: 24/08/2021 Ended: 24/10/2021 What? This is the source code to a project developed to snipe minecraft names Why release? The ad

Kami 2 Dec 03, 2021
Official mirror of https://gitlab.com/pgjones/quart

Quart Quart is an async Python web microframework. Using Quart you can, render and serve HTML templates, write (RESTful) JSON APIs, serve WebSockets,

Phil Jones 2 Oct 05, 2022
Flask-Potion is a RESTful API framework for Flask and SQLAlchemy, Peewee or MongoEngine

Flask-Potion Description Flask-Potion is a powerful Flask extension for building RESTful JSON APIs. Potion features include validation, model resource

DTU Biosustain 491 Dec 08, 2022
Screaming-fast Python 3.5+ HTTP toolkit integrated with pipelining HTTP server based on uvloop and picohttpparser.

Japronto! There is no new project development happening at the moment, but it's not abandoned either. Pull requests and new maintainers are welcome. I

Paweł Piotr Przeradowski 8.6k Dec 29, 2022
The Web framework for perfectionists with deadlines.

Django Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Thanks for checking it out. All docu

Django 67.9k Dec 29, 2022