Reflection and introspection: an analysis of µWeb (part 2)

In the previous post we reviewed the overall design of µWeb and dove deep into the provided template language. We will continue where we left off and cover the remaining parts of the system: the presenter, the model and the application server.

Presentation layer / Pagemaker

The part where most of the actual application work will happen is in the presentation layer of µWeb, also referred to as the PageMaker. This is largely represented by the class PageMaker, or typically subclass in µWeb projects. When the routes for a project are defined, each route gets assigned a handler method, which will be looked up on the class which is assigned to the router’s PAGE_CLASS. [1]

When the application has been set up and requests are handled, the request dispatcher will go through the defined routes until it finds a match, and immediately delegate the request to the method specified on the route. This is also the first shortcoming of the PageMaker and request router system.

Request handler selected only by route match

While route matching itself works fine for many frameworks, the direct coupling of a route to a handling method leaves very little flexibility in the system. There is no built-in functionality to discriminate and delegate requests based on

  • request method (GET, POST, PUT etc);
  • match-values from the route regex;
  • content type of the request body;
  • accept headers (for content negotiation);
  • whether or not the request is an XMLHttpRequest.
more ...

Reflection and introspection: an analysis of µWeb

This follow-up to the initial post about µWeb’s development history is running on the long side, so I’ve split it up into two parts. This one will deal with the high-level view and an in-depth analysis of the template system. The next part will deal with the presenter, database interaction layer and the standalone server.

µWeb is tagged as a minimal-size micro web-framework, and it does deliver on that promise. The code is spread out over a core of a dozen files and some included libraries and weighs in at a bit under 5000 lines of code (see Appendix A). While small, it’s certainly not the smallest out there. The smallest (in popular use) I’ve seen so far is Bottle. It provides a full web-framework in a single file, clocking in at just over 2300 lines of code. While less code is preferred, it’s not a compelling reason to pick one framework over another. Features and the ease with which you can get things done are.

We started development of µWeb without a clear set of design goals, and a number of decisions were made with a lack of information, experience and clairvoyance (though the latter is a common problem). This means that the current product suffers a number of unfortunate flaws. A good few of these can be easily fixed and improved upon, but others would require rewriting major portions of the code base. While a rewrite is an option, it would take a serious effort and there are other, more complete and functional web frameworks readily available for use. For my own day to day work I’ve migrated to Pyramid, which provides a simple and easy interface which contains solutions for all of the most common requirements, and is easy to extend.

more ...

Reflection and introspection: µWeb in review

This is the first part of a series that looks back on previous projects. There is a lot to learn from looking critically at ourselves, both admitting mistakes and acknowledging achievements. The first project will be µWeb, and will likely take up more than one installment. The foundations for this were laid in 2009, and that’s where the story starts.

During my time at Google, even working on the operations (hardware) side, there was a good bit of software involved. We made small scripts and applications that made everyday life go better and smoother. The tool of the trade was Python, and I quickly developed a strong liking for it. My fondness for it turned out to be infectious and my partner in programming developed a similar preference. To be fair, coming from a PHP background, what was there not to like…

Where it all began

In early 2009, we had started to become fond of pylint for analysis of our codebase. Static analysis in a dynamic language like Python isn’t perfect. In fact, it’s very far from it, but it still makes life easier, and a useful tool. It will point out a fair amount of type mismatches (sometimes ones that aren’t), unreachable code, unused or missing arguments, name- and style errors.

We liked it enough in fact, that a script was written to run pylint on our entire codebase in a comprehensive manner. The script would run periodically, checking out each of the new revisions and linting all the (Python) source files that were changed in each revision. The messages and final score would be stored in a database, providing a look at code quality over the course of development of the code.

Of course, storing data is no good if you’re not …

more ...

Mutation tracking in nested JSON structures using SQLAlchemy

This is part two of a two-part post on storage of JSON using SQLAlchemy. The first post covered the basics of creating a JSON column type and tracking mutations. In this post, we will continue from there to cover mutation tracking in arbitrarily nested structures.

In the previous post we ended with an example of appending to an existing list. Upon committing the changes in the session and reloading the object, it was shown the appended string had not been stored. This happened because changing the list in-place did not trigger the changed() method of the class MutableDict. Only setting or deleting a key from the dictionary marks it as changed, and marking it as changed upon access (which is all we did on the dictionary itself) would cause far too many updates of the database.

What we wanted (and perhaps expected) is behavior where changing the list marks the dictionary it’s part of as changed. And for completeness, if the dictionary contained a number of nested dictionaries, changing any of them at any level should mark the class MutableDict as changed. To achieve this, we need a solution that consists of the following parts:

  1. Replacement types for list and dict where all methods that change the object in-place flag it as having changed.
  2. A means to propagate the notification of change up to the top so that it reaches the class MutableDict.
  3. Conversion of all mutable types to the defined replacement types. Both when they are added to the existing structure, as well as on load from the database.
more ...

Creating a JSON column type for SQLAlchemy

This is part one of a two-part post on storage of JSON using SQLAlchemy. This post will touch on the basics of creating a JSON column type and tracking mutability, and is mostly a rehash of the SQLAlchemy documentation. The second post will cover the tracking of mutability in arbitrarily nested JSON structures, and goes beyond what is covered in the documentation.

The past weeks have been pretty busy. We moved from Leeuwarden to Hoofddorp, which in and of itself went pretty smooth, but the new apartment is still very much unfinished. In between work and getting the apartment in order, there hasn’t been a lot of time to spend on side projects, but this seemed interesting enough.

A while ago I needed to store a relatively small amount of variable-format data. The requirements are only to store the data, not search in parts of it or anything else. Additionally, it’s of such a small volume that it doesn’t warrant setting up a document database like MongoDB next to the existing SQLA+Postgres setup. The data itself consisted of a flat mapping of strings to basic scalar types. Something roughly like this:

{
    'title': 'Example data object',
    'description': 'Information about this example object',
    'storage_location': 'Top shelf in the back',
}
more ...

Fixing bad value “X-UA-Compatible” with Pyramid

When you’re making a website for the general public, you need to support the browsers of that general public. One of the things that can make that particularly difficult is the large install-base of older versions of Internet Explorer that don’t run in standards mode by default. Specifically, IE8 and 9 still have a combined market share of about 30 percent.

By default these versions of Internet Explorer will run in Quirks mode rather than Standards mode. This is good for websites that were made over a decade ago and targeted IE6, but it’s a disaster for modern web development because the amount of corrective CSS required is astounding. The fix is to tell them to use their edge rendering mode; that is, the closest they can get to actual standards. From there the path to proper behavior is manageable. Microsoft has explained how to do all of this in their knowledge base, but in practice it comes down to this:

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

This will instruct Internet Explorer to use a Chrome Frame if available, and if not, use the latest rendering mode available (edge). With Google having discontinued Chrome Frame though, it’s probably best to help those users to upgrade away from older Internet Explorer versions, though that’s outside the scope of this article.

So what’s the problem?

There are a few problems with the meta tag approach, the most obvious being that it doesn’t validate. It’s a Microsoft specific meta tag that isn’t part of the specification.

Does validation really matter? The answer depends on who you ask, and the context of the question. Obviously some don’t mind the lack of validation and will use this meta tag, but if validation is …

more ...

Hello world

def main():
    print 'Hello world!'

if __name__ == '__main__':
    main()

Now that we have the inevitable first lines out of the way, let’s move on. This blog will focus on programming subjects, primarily the Python programming language. My current work involves a healthy amount of web framework in the form of Pyramid, which I’ve become a great fan of. Other parts of the technology stack employed may also feature in articles here.

Aside from work-inspired interests, there are other programming related topics that may feature. I occasionally tinker with Arduinos (most of the code is up on GitHub) and they may feature here. JavaScript, necessary evil that it is, may end up as a subject as well. I’m predicting this based on my many conversations with herrieii about JavaScript.

more ...