API

APIs for functions and classes in the akhet package.

Config include function

akhet.includeme(config)

Add certain useful methods to a Pyramid Configurator instance.

Currently this adds the .add_static_route() method. (See pyramid_sqla.static.add_static_route().)

Static route

akhet.static.add_static_route(config, package, subdir, cache_max_age=3600, **add_route_args)

Add a route and view to serve static files from a directory.

I create a catchall route that serves all URLs from a directory of static files if the corresponding file exists. Subdirectories are also handled. For example, the URL “/robots.txt” corresponds to file “PACKAGE/SUBDIR/robots.txt”, and “/images/header/logo.png” corresponds to “PACKAGE/SUBDIR/images/header/logo.png”. If the file doesn’t exist, the route won’t match the URL, and Pyramid will continue to the next route or traversal. The route name is ‘static’, which must not conflict with your application’s other routes.

Usage in the application’s __init__.py:

from akhet.static import add_static_route
add_static_route(config, "myapp", "static")

Or, more conveniently:

config.include("akhet")
config.add_static_route("myapp", "static")

This serves URLs from the “static” directory in package “myapp”.

Arguments:

  • config: a pyramid.config.Configurator instance.
  • package: the name of the Python package containing the static files.
  • subdir: the subdirectory in the package that contains the files. This should be a relative directory with ‘/’ separators regardless of platform.
  • cache_max_age: influences the Expires and Max-Age response headers returned by the view (default is 3600 seconds or five minutes).
  • **add_route_args: additional arguments to config.add_route. ‘name’ defaults to “static” but can be overridden. (Every route in your application must have a unique name.) ‘pattern’ and ‘view’ may not be specified and will raise TypeError if they are.

URL generator

Convenience methods for generating URLs in templates.

I shadow various URL-generating functions in pyramid.url and attributes in the request. My main use is in templates where my method names are shorter than the originals and you don’t have to pass a request argument. In Akhet, a subscriber callback registers an instance of me as request.url_generator, and another callback aliases me to the url global in templates. These callbacks are defined in myapp/subscribers.py.

The source code contains commented examples of “static_url” methods. We’re not sure what’s best here so we’re leaving them commented and you can define them in a subclass however you wish. That’s better than releasing a bad API which we’ll then have to change and break existing apps.

Contributed by Michael Merickel. Modified by Mike Orr.

class akhet.urlgenerator.URLGenerator(context, request, qualified=False)
__call__(*elements, **kw)

Same as the .route method.

__init__(context, request, qualified=False)

Instantiate a URLGenerator based on the current request.

  • request: a Pyramid Request.
  • context: a Pyramid Context.
  • qualified: If true, return fully-qualified URLs with the “scheme://host” prefix. If false (default), return only the URL path if the underlying Pyramid function allows it.
app

The application URL or path.

I’m a “reified” attribute which means I start out as a property but I turn into an ordinary string attribute on the first access. This saves CPU cycles if I’m accessed often.

I return the application prefix of the URL. Append a slash to get the home page URL, or additional path segments to get a sub-URL.

If the constructor arg ‘qualified’ is true, I return request.application_url, otherwise I return request.script_name.

ctx

The URL of the default view for the current context.

I’m a “reified” attribute which means I start out as a property but I turn into an ordinary string attribute on the first access. This saves CPU cycles if I’m accessed often.

I am mainly used with traversal. I am different from .app when using context factories. I always return a qualified URL regardless of the constructor’s ‘qualified’ argument.

route(route_name, *elements, **kw)

Generate a route URL.

I return a URL based on a named route. Calling the URLGenerator instance is the same as calling me. If the constructor arg ‘qualified’ is true, I call pyramid.url.route_url, otherwise I call pyramid.url.route_path.

Arguments:

  • route_name: the name of a route.
  • *elements: additional segments to append to the URL path.

Keyword arguments are passed to the underlying function. The following are recognized:

  • _query: the query parameters. May be a dict-like object with a .items() method or a sequence of 2-tuples.
  • _anchor: the URL’s “#ancor” fragment without the “#”.
  • _app_url: override the “scheme://host” prefix. (This also causes the result to be qualified if it wouldn’t otherwise be.)
  • Other keyword args override path variables defined in the route.

If the relevant route has a pregenerator defined, it may modify the elements or keyword args.

current(*elements, **kw)

Generate a URL based on the current request’s route.

I call pyramid.url.current_route_url. I’m the same as calling .route with the current route name. The result is always qualified regardless of the constructor’s ‘qualified’ argument.

resource(*elements, **kw)

Return a “resource URL” as used in traversal.

*elements is the same as with .route. Keyword args query and anchor are the same as the _query and _anchor args to .route.

When called without arguments, I return the same as .ctx.

MultiDict

MultiDict is defined in WebOb (webobb.multidict.MultiDict) but its documentation is so sparse that we have written our own documentation here. Pyramid’s request.params, request.GET and request.POST are MultiDicts.

A MultiDict is like a regular dict except that each key can have multiple values. This is necessary to represent query parameters and form variables, which can be multiple. request.params, request.GET and request.POST are MultiDicts.

class akhet.urlgenerator.MultiDict(dic=None, **kw)

An ordered dict that can have multiple values for each key. All the regular dict methods are supported. “Ordered” means that .keys() will return the keys in the order they were defined.

Like a regular dict, the constructor can be called with an existing dict, an iterable of key-value tuples, or keyword args representing the dict keys. If the combination of args contain duplicate keys, all the impled values will be added to the dict, the keyword args last.

add(key, value)

Add the value to the dict, not overriding any previous values.

Note: dic[key] = value will replace all existing values for the key.

getall(key)

Return all values for the key as a list. The list will be empty if the key is not present in the dict.

Note: dic[key] and dic.get(key) return one arbitrary value, the last value added for the key.

getone(key)

Return exactly one value for the key. Raise KeyError if the key has zero values or more than one.

mixed()

Return a dict whose values are single values if the key appears once in the MultiDict, or lists if the key appears multiple times.

dict_of_lists()

Return a dict where each key is associated with a list of values.

extend(dic=None, **kw)

Add items to the MultiDict. The arguments are the same as the constructor’s.

classmethod view_list(lis)

Create a dict that is a view on the given list

classmethod from_fieldstorage(fs)

Create a MultiDict from a cgi.FieldStorage instance

class akhet.urlgenerator.UnicodeMultiDict(multi, encoding=None, errors="strict", decode_keys=False)

A MultiDict subclass that decodes returned values to unicode on the fly. Decoding is not applied to assigned values.

The key/value contents are assumed to be str/strs or str/FieldStorages (as is returned by the paste.request.parse_ functions).

Can optionally also decode keys when the decode_keys argument is True.

FieldStorage instances are cloned, and the clone’s filename variable is decoded. Its name variable is decoded when decode_keys is enabled.

class akhet.urlgenerator.NestedMultiDict(*dicts)

A MultiDict subclass that wraps several MultiDict objects, treating them as one large MultiDict. A NestedMultiDict is read-only, although the contained MultiDicts are not.

class akhet.urlgenerator.TrackableMultiDict(dic=None, **kw)

This is a MultiDict that functions as an observable. It’s used internally in WebOb where other parts of the API need to know when a GET or POST variable changes.

In addition to the regular MultiDict constructor args, you can pass __tracker (two leading underscores) which is a callback function, and __name which is the object’s repr() name.

The callback function is called with zero to three positional args: self, key, and value (although the callback can name them differently, but it should give default values to all of them). self is the MultiDict’s self. key is passed if the method deletes a particular key. value is passed if the method sets a particular key or adds an additional value to a key.

The .copy method returns a regular MultiDict. The tracker is not propagated to it.

There appears to be a bug in the source, that if you instantiate a TrackableMultiDuct without a tracker, it defaults to None and you’ll get an exception when a routine tries to call it.

class akhet.urlgenerator.NoVars(reason=None)

This is an always-empty MultiDict. Adding an item item raises KeyError. It’s used internally in WebOb to distinguish between dicts that happen to be empty vs dicts that must be empty; e.g., request.POST in a GET request.

Table Of Contents

Previous topic

Migrating a Pylons Application to Akhet

Next topic

Other Pyramid features