Skip to content

Latest commit

 

History

History
122 lines (72 loc) · 4.45 KB

README.md

File metadata and controls

122 lines (72 loc) · 4.45 KB

Peyton

A lightweight framework for AWS Lambda for building Rest APIs.

Peyton is designed to be as small as possible, with no requirements outside of the standard python library. It allows developers to create and deploy serverless applications easily.

Codefresh build status

Currently Peyton supports v1.0 of the API Gateway Payload format and has been tested with both HTTP and REST APIs.

Peyton is being used in pre-production and is stable. However, the project is in it's pre-1.0 state and may change quickly. The author(s) will note breaking changes for releases, when necessary.


Dependencies

Peyton has no dependencies outside of the Python standard library.

Note: Pipenv is used for local development and CI only.


How To

At this time Peyton only supports class based views, using HTTP verbs as method names. In practice class based views prove to be generally easy to reason about and encourage organization within a codebase.

At a minimum you must do three things to use Peyton:

  • Instantiate the Router class
  • Define a new class that subclasses Peyton's ViewClass
  • Add the register decorator to the class, specifying the path to be used

Below is a simple example of an API definition with two views (routes).

from peyton.view import ViewBase
from peyton.response import Response
from peyton.request import Request
from peyton.router import Router

router = Router()


@router.register(path="/")
class Index(ViewBase):
    def get(self) -> dict:
        resp = Response(status_code=200, headers={}, body={"message": "received GET to index"},)

        return resp.to_json()

    def put(self) -> dict:
        # Retrieve the body from the request
        body = router.current_request.body

        # Do something with the body

        resp = Response(status_code=201, headers={}, body={"message": "received PUT to index"})

        return resp.to_json()

    def post(self) -> dict:
        # Retrieve the body from the request
        body = router.current_request.body

        # Do something with the body

        resp = Response(status_code=201, headers={}, body={"message": "received POST to index"})

        return resp.to_json()

@router.register(path="/foo/{foo_id}/bar/{bar_id}")
class AllBars(ViewBase):
    def get(self, foo_id, bar_id) -> dict:
        resp = Response(status_code=200, headers={}, body={"foo_id": foo_id, "bar_id": bar_id, "message": "all bars by foo"},)

        return resp.to_json()

    def put(self, foo_id, bar_id) -> dict:
        # Retrieve the body from the request
        body = router.current_request.body

        # Do something with the body

        resp = Response(status_code=201, headers={}, body={"message": "received PUT to index"})

        return resp.to_json()

    def post(self, foo_id, bar_id) -> dict:
        # Retrieve the body from the request
        body = router.current_request.body

        # Do something with the body

        resp = Response(status_code=201, headers={}, body={"message": "received POST to index"})

        return resp.to_json()


def lambda_handler(event, context):
    request = Request(event)
    return router.dispatch(request=request)

Performance

Performance is a top priority of this project. The total code package is designed to be as small as possible with no dependencies outside of the standard library. There will be continuous work being done to increase the speed of the code.

It is important to recognize when performing benchmarks when running APIs on lambda and observing the benchmarks below that using (or increasing) Provisioned Concurrency will reduce concurrent request times dramatically.

You can see benchmarks here


Inspiration

Peyton was inspired by Flask and Chalice. Please check out those great projects in addition to Peyton.