Automatic error pages in Flask

Posted on Tue 08 September 2015 in Code • Tagged with Flask, Python, HTTP, errorsLeave a comment

In Flask, a popular web framework for Python, it’s pretty easy to implement custom handlers for specific HTTP errors. All you have to do is to write a function and annotate it with the @errorhandler decorator:

@app.errorhandler(404)
def not_found(error):
    return render_template('errors/404.html')

Albeit simple, the above example is actually very realistic. There’s rarely anything else to do in response to serious request error than to send back some HTML with an appropriate message. If you have more handlers like that, though, you’ll notice they get pretty repetitive: for each erroneous HTTP status code (404, 403, 400, etc.), pick a corresponding template and simply render it.

Which is, of course, why we’d want to deal with all in a little smarter way and with less boilerplate.

Just add a template

Ideally, we would like to avoid writing any Python code at all for each individual error handler. Since all we’re doing revolves around predefined templates, let’s just define the handlers automatically based on the HTML files themselves.

Assuming we store them in the same template directory — say, errors/ — and name their files after numeric status codes (e.g. 404.html), getting all those codes is quite simple1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from pathlib import Path, PurePath

from mywebapp import app


#: Path to the directory where HTML templates for error pages are stored.
ERRORS_DIR = PurePath('errors')


def get_supported_error_codes():
    """Returns an iterable of HTTP status codes for which we have
    a custom error page templates defined.
    """
    error_templates_dir = Path(app.root_path, app.template_folder, ERRORS_DIR)

    potential_error_templates = (
        entry for entry in error_templates_dir.glob('*.html')
        if entry.is_file())
    for template in potential_error_templates:
        try:
            code = int(template.stem)  # e.g. 404.html
        except ValueError:
            pass  # could be some base.html template, or similar
        else:
            if code < 400:
                app.logger.warning(
                    "Found error template for non-error HTTP status %s", code)
                continue
            yield code

Once we have them, we can try wiring up the handlers programmatically and making them do the right thing.

One function to handle them all

Although I’ve used a plural here, in reality we only need a single handler, as it’ll be perfectly capable of dealing with any HTTP error we bind it to. To help distinguishing between the different status codes, Flask by default invokes our error handlers with an HTTPException argument that has the code as an attribute:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from flask import render_template
from jinja2 import TemplateNotFound


def error_handler(error):
    """Universal handler for all HTTP errors.

    :param error: :class:`~werkzeug.exceptions.HTTPException`
                  representing the HTTP error.

    :return: HTTP response to be returned
    """
    code = getattr(error, 'code', None)
    if not code:
        app.logger.warning(
            "Got spurious argument to HTTP error handler: %r", error)
        return FATAL_ERROR_RESPONSE

    app.logger.debug("HTTP error %s, rendering error page", code)
    template = ERRORS_DIR / ('%s.html' % code)
    try:
        return render_template(str(template)), code
    except TemplateNotFound:
        # shouldn't happen if the handler has been wired up properly
        app.logger.fatal("Missing template for HTTP error page: %s", template)
        return FATAL_ERROR_RESPONSE

#: Response emitted when an error occurs in the error handler itself.
FATAL_ERROR_RESPONSE = ("Internal Server Error", 500)

Catching TemplateNotFound exception is admittedly a little paranoid here, as it can occur pretty much exclusively due to a programming error elsewhere. Feel free to treat it as a failed assertion about application’s internal state and e.g. convert to AssertionError if desirable.

The setup

The final step is to actually set up the handler(s):

for code in get_supported_error_codes():
    app.errorhandler(code)(error_handler)

It may look a bit wonky, but it’s just a simple desugaring of the standard Python decorator syntax from the first example. There exists a more direct approach of putting the handler inside app.error_handler_spec dictionary, but it is discouraged by Flask documentation.

Where to put the above code, though? I posit it’s perfectly fine to place in the module’s global scope, because the error handlers (and other request handlers) are traditionally defined at import time anyway.

Also notice that the default error handling we’ve defined here doesn’t preclude more specialized variants for select HTTP codes. All you have to do is ensure that your custom @app.errorhandler definition occurs after the above loop.


  1. Note that I’m using the pathlib module here — and you should, too, since it’s all around awesome. However, it is only a part of the standard library since Python 3.4, so you will most likely need to get the backport first. 

Continue reading

Decorated functions in Go

Posted on Fri 04 September 2015 in Code • Tagged with Go, functions, decoratorsLeave a comment

One of the downsides of working with a simple and minimalistic programming language such as Go is that abstracting for code reuse is often rather challenging. What’s brought up most often in this context is Go’s lack of support for generics (higher order types).

But here I wanted to talk about a different mechanism that — unlike generics — can be transplanted to Go quite successfully: function decorators.

Canonical example

Decorators are most commonly found in Python (where they can be applied not just to functions, but also classes), but have syntactical analogues in Java (annotations), C# (attributes), and a few other languages.

A decorator looks like a modifier adorning a function definition, distinguished by its initial @ sign:

@app.route('/home')
@login_required
def home():
    return render_template('user/home.html')

Even if you’re not familiar with the particular web framework this request handler is meant for — or indeed, the Python language itself — it shouldn’t be too difficult to figure out what purpose the two decorators serve.

What’s really important is that their goals are neatly separated from essential logic of the request handler:

  • it doesn’t have to explicitly check if the user is logged in — it has the @login_required decorator
  • it doesn’t have to be separately registered in some centalized URL routing choke point — it has the @app.route decorator instead

Such separation of concerns is a desirable quality in software, because it makes it easier to reason about different aspects of the system.

Under the hood

Behind this synctactic sugar and lofty phrasing, the code above is still perfectly equivalent to its undecorated version:

def home():
    if not current_user.is_authenticated:
        abort(403, "Login Required")
    return render_template('user/home.html')

app.add_url_route('/home', view_func=home)

No source code transformations take place, either: @login_required doesn’t actually “inject” the if statement at the beginning of home function. What happens instead is that it takes the whole function and wraps it in a new one which also contains the crucial check:

def login_required(func):
    """Grossly simplified version of a decorator enforcing user login."""
    def wrapped(*args, **kwargs):
        if not current_user.is_authenticated:
            abort(403, "Login Required")
        return func(*args, **kwargs)

    return wrapped

Given this definition, decorating home simply means passing it to the login_required function, and calling its result a new home:

def home():
    return render_template('user/home.html')

home = login_required(home)

As you’ve probably guessed, the @ syntax is nothing else than a syntatic sugar for the above. But how sweet a sugar it is!

(The @app.route decorator is simultaneously simpler and more complicated. I recommend having a direct look at its source code for more insight).

What gophers can learn

Unlike Python, in Go, we are out of luck when it comes to dedicated language support for decorators. However, the general principle still applies: we can decorate functions by writing — ahem — decorator functions.

Consider, for example, a trivial net/http request handler:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello, world!\n")
}

Any real web application will have many similar handlers. They are usually wired to their corresponding URL paths during program startup:

func main() {
    http.HandleFunc("/hello", hello)
    // ...
}

This approach to routing configuration provides an opportunity to decorate some (or all) of the request handlers with any auxiliary functionality that the application may require.

Handler in, handler out

To do that, though, we need to write the necessary decorator functions first. For a simplest possible example, let’s create one that automatically fills in the Server: header of HTTP response with the name and version of our web application:

func WithServerHeader(h http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Server", "HelloServer v0.0.1")
        h(w, r)
    }
}

Using it is then a simple matter of wrapping the original handler in a decorator call:

http.HandleFunc("/hello", WithServerHeader(hello))

As it both accepts and returns a http.HandlerFunc — a function type matching request handlers’ signatures — we don’t need anything else to be able to wrap our handlers in as many decorators as necessary:

http.HandleFunc("/", WithServerHeader(index))
http.HandleFunc("/home", WithServerHeader(LoginRequired(home)))
http.HandleFunc("/api/share", WithServerHeader(LoginRequired(CsrfProtected(api.Share))))

It’s possible simply by the means of ordinary function composition.

Going meta

Looking at the last line of the example above — which is made-up but could very well come from actual production code — you probably can’t help but notice that stacking function calls like that creates a somewhat messy amalgamation of parentheses. Beyond three or four items, a decorator chain such as this one becomes rather unwieldy to follow.

If we’re concerned about readability, it’s possible to alleviate the issue by taking another step up the abstraction ladder. Rather than composing the decorators explicitly, we can write a function that does it for us:

type HttpHandlerDecorator func(http.HandlerFunc) http.HandlerFunc

func Handler(h http.HandlerFunc, decors ...HttpHandlerDecorator) http.HandlerFunc {
    for i := range decors {
        d := decors[len(decors) - 1 - i]  // iterate in reverse
        h = d(h)
    }
    return h
}

and thus eliminate all the parentheses:

http.HandleFunc("/api/share", Handler(api.Share,
    WithServerHeader, LoginRequired, CsrfProtected))

This technique proves especially valuable if the decorators themselves are parameterized:

http.HandleFunc("/api/notifications", Handler(api.Notifications,
    WithServerHeader, LoginRequired, Cached(time.Duration(5)*time.Minute)))

In practice, you may find it valuable to wrap the complete http.HandleFunc call to accept a request handler along with its decorator chain, or the equivalent of such a call in any of the numerous Go web frameworks.

Continue reading

Interruptible fade-out of DOM elements

Posted on Sun 30 August 2015 in Code • Tagged with HTML, JavaScript, DOM, jQuery, animation, promisesLeave a comment

Here’s a nice animated effect you may have seen in some applications, quite often games. An ephemeral UI element is displayed, either in a corner or pretty prominently, and after a short while it slowly fades out to transparency over several seconds:

"Ding" with full opacity
"Ding" after fading out

If you hover your mouse over it, though, it turns opaque right away and stays like that until you move away with the cursor. It then tries to disappear again, lest you stop it once more and restore to full opacity — and so on. Leave it for a moment, though, and it eventually vanishes.

Cool, eh? Wouldn’t it be nice to have a similar mechanism for, say, notifications displayed within a web app? Sure it would be! And it doesn’t even seem all that complicated, so let’s give it a try.

A promising API

Before delving into implementation details, it’s a good practice think for a moment about an API that we’ll expose to the user. Since it looks like a relatively simple problem, we don’t need no classes or frameworks. All that’s necessary is a simple function:

function interruptibleFadeOut(element, options) {
    // ...
}

Surely, however, whoever calls it would like to be able to tell when the animation finishes (e.g. to remove the element they’ve passed from the DOM tree). Simply waiting a predefined number of seconds is not sufficient, because — as described above — the effect could be restarted arbitrary many times through mouse interaction.

We could pass a callback, of course, but the modern JavaScript way of dealing with asynchronicity and concurrency is through promises. Following this pattern, our function shall return a promise that resolves when the effect ends. Disregarding the possible user interaction for now, a minimal implementation of the fade-out alone would simply use the jQuery.fadeOut method and look something like this:

function interruptibleFadeOut(element, options) {
    if (typeof options === 'number') {
        options = {fadeOut: options};
    }

    element = $(element);
    return new Promise(function(resolve) {
        element.fadeOut(options.fadeOut, function() {
            resolve();
        });
    });
}

The constructor of Promise is admittedly a little weird, as it employs a level of abstraction and indirection that is indicative of (more) functional programming languages. You pass it a function that’s invoked immediately with an argument that itself is a function. (Actually two arguments, but we ignore the other one here). That input function, resolve, should be called whenever the new promise “completes”, in whatever sense it’s appropriate for the particular use case.

Here, we’re resolving the promise when our animation ends. This enables callers to react to this in a very straightforward way:

var elem = $('#foo');
interruptibleFadeOut(elem, 400 /* ms */).then(function() {
    elem.remove();
});

As a small aside, the Promise class is a ECMAScript 6 feature, which means it may not be available in all the browsers. The open-source Q library is often used as a compatibility shim, among many other libraries implementing the Promises/A+ recommendation.

Interaction handling

There’s little value in just wrapping an existing jQuery method, so let’s make it more interesting through mouse events. We want hovering on the element to pause the animation, while moving the cursor away should resume it:

return new Promise(function(resolve) {
    element.on('mouseenter', function() {
        element.stop(true);  // true == discard remaining animation stages
        element.css('opacity', 1.0);
    });
    element.on('mouseleave', function() {
        element.fadeOut(options.fadeOut, function() {
            resolve();
        });
    });

    element.fadeOut(options.fadeOut, function() {
        resolve();
    });
});

That will mostly work even with the above code, but there are several problems that need to be addressed immediately:

  • The mouseenter and mouseleave event handlers are should only fire while the fade-out effect is being played. Currently, they “leak”, and remain bound even after it finishes, interfering with given DOM element for as long as it exists.
  • The whole concept of hovering is contingent upon the user having a pointing device. In today’s mobile world, this excludes a significant fraction of clients. We need an alternative interaction pattern for touchscreen devices, and one possible option is restart the effect on click/tap.
  • There is a fair amount of repetition here, and it will only get worse once the previous problems are dealt with.

Cleaning up

A correct (and cleaner) version is quite a bit longer, but shouldn’t be too hard to follow:

return new Promise(function(resolve) {
    // Event handlers used by the effect.
    var events = {
        mouseenter: function() { interruptAnimation(); },
        mouseleave: function() { delayedFadeOut(); },
        click: function() {
            interruptAnimation();
            delayedFadeOut();
        },
    };
    Object.keys(events).forEach(function(name) {
        element.on(name, events[name]);
    });

    // Helper functions.
    var interruptAnimation = function() {
        element.stop(true);
        element.css('opacity', 1.0);
    };
    var delayedFadeOut = function() {
        if (options.delay) {
            element.delay(options.delay);
        }
        element.fadeOut(options.fadeOut, function() {
            Object.keys(events).forEach(function(name) {
                element.off(name, events[name]);
            });
            resolve();
        });
    };

    // Start the animation.
    if (options.fadeIn) {
        element.fadeIn(options.fadeIn);
    }
    delayedFadeOut();
});

The main part is of course the delayedFadeOut function. It is invoked right at the beginning, as well as whenever the animation has to be started again.

We also put the event handlers in a “map” (JavaScript object). This makes it easy to initially bind them to the element, and — more importantly — unbind them when the effect ends.

As a final touch, we also allow the caller to specify how long the element should remain at its full opacity before it starts to fade out (delay), and to optionally add a fadeIn stage at the very beginning to make everything look a little nicer. (I recommend no more than 300-400ms for that part, though).

Practical example

A complete code sample for the interruptibleFadeOut function can be seen in this gist. To use it in practice, you’d most likely need at least a little bit of CSS and additional JavaScript to position the element appropriately:

<div id="toast">Hello, world!</div>
#toast {
    position: fixed;
    display: none;

    /* These are arbitrary */
    top: 100px;
    width: 80%;
    height: 50px;
}
var toast = $('#toast');
toast.offset({
    left: Math.round($(window).width() - element.outerWidth() / 2),
});
toast.show();
interruptibleFadeOut(toast, { fadeIn: 200, delay: 1000, fadeOut: 3000 })
    .then(function() { toast.remove() });

Styling it to look like a level-up ding is left as an exercise for the reader :)

Continue reading

Querying multiple scalar values in SQLAlchemy

Posted on Wed 26 August 2015 in Code • Tagged with SQLAlchemy, PythonLeave a comment

SQLAlchemy is probably the greatest ORM library ever invented — and not just for Python. Like everything, though, it could sometimes use an improvement.

One typical pattern that I’ve seen repeated many times is querying for values of a single column from multiple rows. Almost always, the desired outcome is to have those values in a Python iterable. Unfortunately, when returning multiple rows, the Query class can only give them out as tuples, making it necessary to unpack them explicitly every time:

active_users_ids = [
    uid for (uid,) in session.query(User.id).filter(User.is_active).all()
]

It’s worth noting that a very similar operation — retrieving a single column value from one row — is comparatively cleaner thanks to a dedicated Query.scalar method. So why not have a similar one for the use case above?…

Turns out that SQLAlchemy is so amazingly extensible that we can easily outfit Query with such a method ourselves.

Our own Query

The officially ordained way to do something like that is to extend the original sqlalchemy.orm.query.Query class with any additional functionality we require. We can then introduce a method in the subclass — let’s call it values — that implements our logic:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sqlalchemy.orm.exc import MultipleResultsFound
from sqlalchemy.orm.query import Query as _Query


class Query(_Query):
    """Custom SQLAlchemy query class."""

    def values(self):
        """Return an iterable of all scalar, singleton element values
        from rows matched by this query.

        :raise MultipleValuesFound: If result rows have more than one element
        """
        try:
            return [x for (x,) in self.all()]
        except ValueError as e:
            raise MultipleValuesFound(str(e))


class MultipleValuesFound(ValueError, MultipleResultsFound):
    """Exception raised by :meth:`Query.values`
    when multiple values were found in a single result row.
    """

There is a special erroneous condition that occurrs when the Query returns rows with more than one column value. It would be possible to detect it preemptively by inspecting certain attributes of the query object, but it’s simpler to just catch the exception caused by unsuccessful tuple unpacking.

In any case, I recommend re-raising it as a custom exception to enable more robust error handling in the client code.

Wiring it

The last piece of the puzzle is to make Session objects in our application use the new Query class. It’s easy: we simply pass it as query_cls parameter to the Session constructor. In more realistic scenarios — such as web applications with per-request database sessions — it means giving it directly to the sessionmaker:

from sqlalchemy import create_engine
from sqlalchemy import scoped_session, sessionmaker

from myapp.ext.sqlalchemy import Query


session = scoped_session(sessionmaker(bind=create_engine(DATABASE_URL),
                                      query_cls=Query))

Of course, actual session setup in your app may differ in few details from the sample above.

Usage example

With the new Query class wired in, the values method becomes immediately usable:

active_user_ids = session.query(User.id).filter(User.is_active).values()

and the ugly manual unpacking of row tuples is no longer necessary.

Continue reading

Custom errors in Jinja templates

Posted on Sun 23 August 2015 in Code • Tagged with Jinja, templates, Python, errorsLeave a comment

Jinja is a pretty great templating engine for Python. Unlike the likes of Mustache or Handlebars, it doesn’t try to constrain overmuch the kind of logic that the programmer can put in their templates. Most Python expressions, for example, are supported, as are variables and functions (or macros in Jinja’s parlance).

One conspicously absent feature is throwing exceptions directly from template code. (It’s obviously possible from custom filters or tags). If we had it, we could add some more robust error checking to the template input values or macro paramaters.

Example

Let’s say you have extracted a {% macro %} for rendering a button, like the one from Twitter Bootstrap:

{% macro button(text=none, style='default', type='button') %}
  <button class="btn btn-{{ style }}" type="{{ type }}">
    {% if text is not none %}
      {{ text }}
    {% else %}
      {{ caller() }}
    {% endif %}
  </button>
{% endmacro %}

The benefit of this conditional definition is the relative ease of creating buttons with either just a text label:

{{ button("Load More...") }}

or some more complicated markup:

{% call button(style='success', type='submit') %}
  <i class="fa fa-check"></i>Finish
{% endcall %}

Supplying both, however, is an ambiguity that the macro currently “resolves” by preferring text over a {% call %} block. It should rather be an error instead:

{% if caller and caller is defined and text is not none %}
  {% error "Cannot supply text= parameter to button() when invoking it through {% call %}" %}
{% endif %}

But {% error %} isn’t a tag that Jinja supports by default. To make it available, we need to implement the logic ourselves.

Adding new Jinja tags

Don’t sweat, though! It won’t be necessary to fork Jinja itself and modify its core code. Custom tags may just as well be added with extensions, which is a dedicated Jinja mechanism.

An extension is just a Python class that declares tags it intends to support and implements a parse method:

from jinja2.ext import Extension

class ErrorExtension(Extension):
    tags = frozenset(['error'])

    def parse(self, parser):
        # ...

What can be a little tricky is that parse method itself shouldn’t take any direct action. Instead, it shall return a piece of ASTabstract syntax tree — that Jinja will include in the compiled template. All regular Jinja features are thus available, but the power of extensions doesn’t end here.

Handling the {% error %} tag

The argument to parse is a parser object, which we can use to extract tokens from the template source code. The error tag identifier is one such token, and the string following it is another. As it turns out, we are only tenuously interested in the former, but we definitely want to pick the latter, because it’s the error message we’ll raise an exception with:

tag = parser.stream.next()
message = parser.parse_expression()

As it was mentioned previously, the parse method itself won’t be raising this exception immediately. If we did that, no template with the {% error %} tag would ever parse successfully! What we need instead is an AST node that throws the exception when it’s evaluated. This way, it will be deferred until the template is being rendered and its execution point reaches the {% error "..." %} stanza.

Jinja already has a correct node type handy: it’s named CallBlock, and it represents a statement that {% call %}s given method of the Extension class:

from jinja2.nodes import CallBlock, Const

# (in ErrorExtension.parse)
node = CallBlock(
    self.call_method('_exec_error', [message, Const(tag.lineno)]),
    [], [], [])
node.set_lineno(tag.lineno)
return node

This method, _exec_error, should do the crux of what this extension is about: raise an exception. Let’s define a distinct error class for it, to tell user errors apart from those thrown by Jinja itself:

from jinja2 import TemplateAssertionError

class ErrorExtension(Extension):
    # ...
    def _exec_error(self, message, lineno, caller):
        raise TemplateUserError(message, lineno)

class TemplateUserError(TemplateAssertionError):
    pass

Using the extension

The last step is to tell Jinja to use our extension when compiling and rendering templates. For that, we simply add it to the Environment:

jinja_env.add_extension(ErrorExtension)

If you are using the Flask framework, jinja_env is an attribute on the Flask application object.

To see the complete code sample for ErrorExtension, have a look at this gist.

Continue reading