Home

Awesome

Build Status PyPI pyversions PyPI license PyPI status

Pyverless

Developing complex APIs within AWS lambdas can be somewhat of a messy task. Lambdas are independent functions that have to work together in order to create a full-blown app, like atoms to a complex organism.

In order to define the infrastructure you may use a framework like Serverless, but you may find yourself copying and pasting blobs of code within your handler functions, namely for authentication, data validation, error handling and response creation to name a few.

Enter Pyverless

Pyverless is a mini-framework with a bunch of utilities that aims to help you create APIs using AWS Lambdas fast and in a consistent way. Pyverless provides the following.

Bring more consistency and development speed to your lambda-based APIs!

Class-Based Handlers

Class based handlers (CBH) use the approach of Django's Class-Based Views to provide code reuse, consistency and generally abstract simple and common tasks. The aim of class-based handlers is to suit a wide range of applications by providing generic Handler classes and mixins.

Within AWS Lambda, a handler is a function that takes an event and a context and returns a response.

Generic CBH are based off the following base handler

BaseHandler

This class provides the as_handler() method that returns a handler function (taking event and context as arguments).

Usage:

class MyHandler(BaseHandler):
    pass

_myHandler = MyHandler.as_handler()

There is a set of generic CBHs to handle basic CRUD operations within an API:

CreateHandler

Handler that reads the request body and creates the object with each (key, value) pair as a parameter for the constructor.

The model attribute must be set on the handler and the create_object method can be overwritten.

Usage:

class UserCreateHandler(CreateHandler):

    model = MyUserClass # MyUserClass(k1=v1, k2=v2, ...) for each k,v on body
    required_body_keys = ['email', 'password']

RetrieveHandler

Handler that returns a serialized Object.

The model attribute must be set and id must be present on the pathParameters.

The user must overwrite either the serializer attribute or the serialize method.

Usage:

class UserRetrieveHandler(RetrieveHandler):

    model = MyUserClass
    serializer = serialize_user

UpdateHandler

Handler that sets self.object and for each (key, value) pair of the body sets self.object.key = value.

The model attribute must be set and id must be present on the pathParameters.

Returns the serialized node and sets the HTTP status code to 200

Usage:

class UserUpdateHandler(UpdateHandler):
    model = MyUserClass
    required_body_keys = ['title', 'body']
    serializer = serialize_user

DeleteHandler

Handler that sets self.object, calls its delete() method and sets the HTTP status code to 204.

The model attribute must be set and id must be present on the pathParameters.

The user can also overwrite the get_queryset method to limit the search.

Usage:

class UserDeleteHandler(DeleteHandler):
    model = MyUserClass

ListHandler

Handler that returns a list of serialized nodes and sets the HTTP status code to 200.

The model attribute must be set and the user must overwrite either the serializer attribute or the serialize method.

class UserListHandler(ListHandler):
    model = MyUserClass
    serializer = user_serializer
    
    def get_queryset(self):
        return only_some_users

Mixins

There are also a set of mixins available:

RequestBodyMixin

This mixin provides the get_body() method which is in charge of gathering the request body dictionary. Define required_body_keys and optinal_body_keys as follows. Within the handler, you can access the body via self.body or by calling get_body()

class MyHandler(RequestBodyMixin, BaseHandler):
    required_body_keys = ['name', 'email']
    optinal_body_keys = ['phone']

_myHandler = MyHandler.as_handler()

AuthorizationMixin

This mixin provides the get_user() method in charge of getting the user out of an authenticated API call. Within the handler, you can access the body via self.user or by calling get_user(). The user will be a object of the class specified on pyverless settings as USER_MODEL.

RequestBodyMixin

This mixin provides the get_object() method in charge of gathering a particular object, you can access the object via self.object. The id of the object will be taken from the pathParameters and the user must set the model attribute on the handler.

ListMixin

This mixin provides the get_queryset() method in charge of getting a list of objects, you can access the list via self.queryset. The user must set the model attribute and either the serializer attribute or serialize() method on the handler.

S3FileMixin

This mixin provides the get_file() and get_message_part() methods in charge of reading an event from aws S3, you can access the file via self.file.

The file will be a dict() with the following keys: bucket, owner, file_name, size.

Warning: Only tested with objectCreated!!!!

SQSMessagesMixin

This mixin provides the get_messages() method in charge of reading an SQS event from aws. You can access the list of messages via self.messages.

Each message will be a dict() with the following keys: attributes, text_message, queue_source, region.

Serializers

TODO