static

A stupidly simple WSGI way to serve static (or mixed) content.

About

This distribution provides an easy way to include static content in your WSGI applications. There is a convenience method for serving files located via pkg_resources. There are also facilities for serving mixed (static and dynamic) content using "magic" file handlers. Python 2.4 string substitution and Kid template support are provided and it is easy to roll your own handlers. Note that this distribution does not require Python 2.4 or Kid unless you want to use those types of templates.

Download

Download the latest release from static's Cheese Shop Page. (Blessed are the cheesemakers!)

Browse static's public subversion repository.

Read and subscribe to static updates and info.

static.Cling

If you wanted to run a little local web server for yourself using wsgiref all you have to do is this:


from wsgiref.simple_server import make_server
import static

make_server('localhost', 9999, static.Cling('/var/www')).serve_forever()

cling_wrap()

There is also a convenience method called cling_wrap that takes a package name and a directory name, uses pkg_resources (part of setuptools) to locate the files and returns an appropriately configured Cling instance


from static import cling_wrap

cling = cling_wrap('my_package', 'www')

To Extract or Not to Extract

cling_wrap uses pkg_resources.resource_filename which is not the recommended way, since it extracts the files.

I think this works fine unless you have some very serious requirements for static content, in which case you probably shouldn't be serving those files through a WSGI app, IMHO. YMMV.

Etags and If-Modified-Since

Etags and If-Modified-Since are supported and both are simply based on the modified time on the file being served.

static.StatusApp

A class of WSGI app called StatusApp is used to send HTTP status back to the client. It takes a status line and optional message when being instantiated. If the message is not passed, the status line is used as the message. It is called with the usual signature for WSGI apps, plus a keyword argument for passing in headers.

Configuring a Cling Instance

A Cling instance has the following attributes that can be used to customize its behavior. They can be set directly, via keyword arguments to Cling's __init__ method, via keyword args to cling_wrap, or by overriding them when subclassing Cling.

Name Default Description
block_size 16 * 4096 The size of chuck to iterate over when sending the file.
index_file 'index.html' The file to look for when a directory is requested.
not_found StatusApp('404 Not Found') Handle requests for stuff that is not there.
not_modified StatusApp('304 Not Modified', "") Handle ETags and Not-Modified-Since.
moved_permanently StatusApp('301 Moved Permanently') Handle missing trailing slashes on directory names.
method_not_allowed StatusApp('405 Method Not Allowed') Handle HTTP methods other than GET or HEAD.

static.Shock

The Shock class extends Cling to support the addition of a little bit of dynamic content to a few files. It has one more configuration option than Cling: a list of "magic" file handlers called magics.

Name Default Description
magics () A list of "magic" file handlers.

Shock handles requests for files just like Cling unless the file does not exist. If the file does not exist it checks with each magic handler in order to see if one applies. Magic handlers have a simple protocol and you can easily create your own. Just take a look at the code in static.py to see how.

static.StringMagic

The StringMagic class provides simple templating using Python 2.4 string substitution. StringMagic.variables is a dictionary of, well, variables and is populated directly or by keyword arguments to StringMagic's __init__ method. A template will have the same name as the non-existent file being requested, but with an additional .stp extension on the end (like index.html.stp). All fields in environ are used as variables as well. StringMagic.variables override environ which is good because it keeps middleware surprises in environ from causing unexpected behavior.

static.KidMagic

KidMagic works very similarly to StringMagic only using the Kid templating language instead of string substitution. Another difference is that environ is passed in separately, by its own name. In other words, you would write things like ${environ['PATH_INFO']} instead of $PATH_INFO when getting things out of environ. The final difference is that KidMagic looks for files that end with .kid to use as templates.

A Simple Magic Example

If we have a file system that looks like this:


data/
|-- foo.css.stp
`-- index.html

... and foo.css.stp looks like this:


h1 {
  color: $color;
}

... and we set things in motion like this:


from static import Shock, StringMagic

string_magic = StringMagic(color='blue')
app = Shock('/data', magics=[string_magic])

from wsgiref.simple_server import make_server
make_server('localhost', 9999, app).serve_forever()

... when we do a GET on /foo.css we get this:


h1 {
  color: blue;
}

Questions, comments, suggestions, bugs... :