Skip to content

Extending Views

PokieView functionality can be extended in several ways, either by using pre-dispatch hooks, subclassing or by using Mixins.

Using Hooks

Hooks are methods that are called before performing the dispatch of a given request, and they are maintained in two list attributes - PokieView.dispatch_hooks and PokieView.internal_hooks. Because when a request is received these methods are called in order sequence by name, by using two lists we guarantee that expensive system hooks - such as automatic body serialization - are postponed to execute after all application hooks, such as authentication.

All hooks must use the interface (method:str, *args: t.Any, **kwargs: t.Any) -> Optional[ResponseReturnValue] and if they return a value different than None, the dispatch is immediately aborted and that value is used as a Response.

There is no specific naming nomenclature for hooks, but due to their status as protected functions, their name should start with underscore ("_").

Hooks in subclasses

Adding custom hooks to subclasses is quite simple - just override the init() method, add your hooks, and fill the appropriate lists with their names:

from pokie.constants import DI_CONFIG
from pokie.http import PokieView
from flask import request
from typing import Any, Optional
from flask.typing import ResponseReturnValue

class TokenAuthView(PokieView):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # get hardcoded auth key from a config value
        self.auth_token = self.di.get(DI_CONFIG).GET("auth_token", None)
        # add auth hook 
        self.dispatch_hooks.append("_hook_token_auth")

    def _hook_token_auth(self, method: str, *args: Any, **kwargs: Any) -> Optional[ResponseReturnValue]:
        if not self.auth_token:
            # no token defined, allow access
            return None

        if "x-access-key" in request.headers:
             if self.auth_token == request.headers['x-access-token']:
                 # valid auth token 
                 return None

        # Invalid auth token            
        return self.forbidden()

Hooks in Mixins

Pokie also supports Mixin initializers, that can be used to implement specific hook functionality. These initializers are called by name at the end of the init() function. These initializer methods can have any valid name and follow (**kwargs) as an interface:

from pokie.http import PokieView
from flask import request
from typing import Any, Optional
from flask.typing import ResponseReturnValue

class TokenAuthMixin:

    def init_auth(self, **kwargs):
        self.dispatch_hooks.append("_hook_token_auth")        

    def _hook_token_auth(self, method: str, *args: Any, **kwargs: Any) -> Optional[ResponseReturnValue]:
        if not self.auth_token:
            # no token defined, allow access
            return None

        if "x-access-key" in request.headers:
             if self.auth_token == request.headers['x-access-token']:
                 # valid auth token 
                 return None

        # Invalid auth token            
        return self.forbidden()


# declare a class using the mixin
class MyView(PokieView, TokenAuthMixin):
    # Add the Mixin initializer name to be called on __init__()
    init_methods = ["init_auth",]