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.
Now using bitbucket.org
Read and subscribe to static
updates and info.
Command
Static can also be used to expose files via HTTP, ad hoc.
$ static --help
usage: static DIR [HOST][:][PORT]
options:
--version show program's version number and exit
-h, --help show this help message and exit
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... : luke.arno@gmail.com