HTTP

The BaseHttpController is mainly for building RESTful HTTP APIs, and may leverage the Aioli toolkit to perform transformation, validation, request-object plucking and more.

API

class aioli.controller.BaseHttpController(unit, config_override=None)[source]

HTTP API Controller

Parameters:

unit – Attach to this unit

Variables:
  • unit – Parent Unit
  • config – Unit configuration
  • log – Controller logger
on_request(*args)[source]

Called on request arrival for this Controller

on_shutdown()

Called when the Application is shutting down gracefully

on_startup()

Called after the Unit has been successfully attached to the Application and the Loop is available

Example – Controller without route handlers

from aioli.controller import BaseHttpController

from .service import VisitService


class HttpController(BaseHttpController):
    def __init__(self):
        super(HttpController, self).__init__(unit)

        self.log.debug("Guestbook opening")
        self.visit = VisitService(unit)

    async def on_startup(self):
        self.log.debug(f"Guestbook opened")

    async def on_request(self, request):
        self.log.debug(f"Request received: {request}")

Route

Route handlers are standard Python methods decorated with @route.

API

aioli.controller.decorators.route(path, method, description=None)[source]

Prepares route registration, and performs handler injection.

Parameters:
  • path – Handler path, relative to application and unit paths
  • method – HTTP Method
  • description – Endpoint description
Returns:

Route handler

Example – Route handler without transformation helpers

from aioli.controller import BaseHttpController, Method, route

from .service import VisitService


class Controller(BaseController):
    def __init__(self):
        self.visit = VisitService()

    @route("/", Method.GET, "List of entries")
    async def visits_get(self, request):
        # Pass along the query params as-is.
        # Then..
        # Return whatever get_many() returned.
        return await self.visit.get_many(**query)

Transform

Transformation is implemented on route handlers using @takes and @returns. These decorators offer a simple yet powerful way of shaping and validating request data, while also ensuring API endpoints returns according to their schemas.

Takes

The @takes decorator is used to instruct Aioli how to deserialize and validate parts of a request, and injects the validated data as arguments into the decorated function.

API

aioli.controller.decorators.takes(props=None, **schemas)[source]

Takes a list of schemas used to validate and transform parts of a request object. The selected parts are injected into the route handler as arguments.

Parameters:
  • props – List of Pluck targets
  • schemas – list of schemas (kwargs)
Returns:

Route handler

Example – Route handler making use of @takes

from aioli.controller import (
    BaseHttpController, ParamsSchema, RequestProp,
    Method, route, takes
)

from .service import VisitService


class Controller(BaseController):
    def __init__(self):
        self.visit = VisitService()

    @route("/", Method.GET, "List of entries")
    @takes(query=ParamsSchema)
    async def visits_get(self, query):
        # Transform and validate query params using
        # ParamsSchema and pass along to get_many().
        # Then..
        # Return whatever get_many() returned.
        return await self.visit.get_many(**query)

Returns

The @returns decorator takes care of serializing data returned by its route handler, into JSON.

API

aioli.controller.decorators.returns(schema_cls=None, status=200, many=False)[source]

Returns a transformed and serialized Response

Parameters:
  • schema_cls – Marshmallow.Schema class
  • status – Return status (on success)
  • many – Whether to return a list or single object
Returns:

Response

Example – Route handler making use of @takes and @returns

from aioli.controller import (
    BaseHttpController, ParamsSchema, RequestProp,
    Method, route, takes, returns
)

from .service import VisitService


class Controller(BaseController):
    def __init__(self):
        self.visit = VisitService()

    @route("/", Method.GET, "List of entries")
    @takes(query=ParamsSchema)
    @returns(Visit, many=True)
    async def visits_get(self, query):
        # Transform and validate query params using
        # ParamsSchema and pass along to VisitService.get_many()
        # Then..
        # Transform and dump the object returned by get_many()
        # using the Visit schema, as a JSON encoded response.
        return await self.visit.get_many(**query)