Source code for seshat.actions

#!/usr/bin/env python
"""
Actions allow you to write code that looks like::

    class RandomController(Controller):
      def GET(self):
        return Redirect("/")

This module provides a few common Action classes to use, along with a base
Action class which can be inherited to create your own Actions by overriding
the `__init__` function.
"""
"""
For more information and licensing, see: https://github.com/JoshAshby/seshat

http://xkcd.com/353/

Josh Ashby
2014
http://joshashby.com
joshuaashby@joshashby.com
"""
from response import Response
from collections import namedtuple


[docs]class Action(object): """ Provides a base for creating a new object which represents an HTTP Status code. All returned data is checked if it is of type :py:class:`.Action` and if so, the data/actions head is returned rather than the controllers head. This allows for a syntax like:: return NotFound() which will cause the controller to return a 404 status code. To create a new action, inherit this class then make a new `__init__(self, *kargs)` which sets `self.response` to a :py:class:`.Reponse` object (or just call super), and adds any headers or status changes to that :py:class:`.Response` object. """ def __init__(self): self.response = Response() def __call__(self): return self.response ############################################################################## ###### ### ### # ## ## ## ## # ## ## ## ## # ## ## ## ## ###### ## ## ## ## # ## ## ## ## # ## ## ## ## # ## ## ## ## ###### ### ### ##############################################################################
[docs]class Redirect(Action): """ Returns a 303 See Other status code along with a `location` header back to the client. :param loc: The location to which the client should be redirect to :type loc: str """ def __init__(self, loc): self.response = Response() self.response.status = 303 self.response.headers.append("Location", loc) ############################################################################## ### ### ### # # ## ## ## ## # # ## ## ## ## # # ## ## ## ## ####### ## ## ## ## # ## ## ## ## # ## ## ## ## # ## ## ## ## # ### ### ##############################################################################
[docs]class BadRequest(Action): """Returns a 400 BAD REQUEST""" def __init__(self): self.response = Response() self.response.status = 400
[docs]class Unauthorized(Action): """ Returns a 401 UNAUTHORIZED back to the client This should probably also include a WWW-Authenticate header, but I'll leave that for later right now. """ def __init__(self): self.response = Response() self.response.status = 401
[docs]class Forbidden(Action): """Returns a 403 FORBIDDEN""" def __init__(self): self.response = Response() self.response.status = 403
[docs]class NotFound(Action): """Returns a 404 Not Found""" def __init__(self): self.response = Response() self.response.status = 404
[docs]class MethodNotAllowed(Action): """ Returns a 405 METHOD NOT ALLOWED :param allow: A `list` of allowable methods :type allow: list """ def __init__(self, allow): self.response = Response() self.response.status = 405 assert type(allow) is list a = ", ".join(allow).upper() self.response.headers.append("Allow", a) ############################################################################## ##### ### ### # ## ## ## ## # ## ## ## ## # ## ## ## ## #### ## ## ## ## # ## ## ## ## # ## ## ## ## # ## ## ## ## #### ### ### ##############################################################################
[docs]class InternalServerError(Action): """ Returns a 500 INTERNAL SERVER ERROR :param e: The Exception :type e: Exception :param tb: The traceback of the exception :type tb: str """ def __init__(self, e=None, tb=None): self.response = Response() self.response.status = 500 self.response.errors = namedtuple("Error", ["exception", "traceback"])(e, tb)