[Django]-What is the purpose of the psa decorator and how do we use it?

3đź‘Ť

Here’s the code for psa (from here):

def psa(redirect_uri=None, load_strategy=load_strategy):
def decorator(func):
    @wraps(func)
    def wrapper(request, backend, *args, **kwargs):
        uri = redirect_uri
        if uri and not uri.startswith('/'):
            uri = reverse(redirect_uri, args=(backend,))
        request.social_strategy = load_strategy(request)
        # backward compatibility in attribute name, only if not already
        # defined
        if not hasattr(request, 'strategy'):
            request.strategy = request.social_strategy

        try:
            request.backend = load_backend(request.social_strategy,
                                           backend, uri)
        except MissingBackend:
            raise Http404('Backend not found')
        return func(request, backend, *args, **kwargs)
    return wrapper
return decorator

As a decorator, it augments the function that it decorates.

It’s doing three things:

  1. Setting request.social_strategy (this object is framework-specific, eg, Django).
  2. Setting request.backend (this object is specific to the authorization backend, eg, Facebook) based on the incoming backend string argument (eg, “facebook”).
  3. Providing a redirect URI or URI name (which is then “reversed” to get the URI) and passing the URI off to the backend so it knows where to redirect to when the time comes.

The decorated function can conveniently access request.social_strategy and request.backend and know that they will be set. See the Python Social Auth documentation for more information about what the Strategy and Backend are for.

👤Steve Capell

Leave a comment