neat — WSGI, neat — neat v0.4.1 documentation

### Navigation

- index
- modules |
- neat v0.4.1 documentation »

# `neat` — WSGI, neat

neat is a WSGI micro framework that encourages API-centric development of web applications. The framework is especially compatible with REST services and APIs, though it can conceivably be used for more or less anything. Applications implemented with neat are easy to test and produce data that is easy for clients to consume.

## Installing `neat`

You can install the latest stable version of `neat` using pip:

    $ pip install neat

Public repositories for the project are hosted at github and bitbucket, so you can use either git or Mercurial to get a copy of the project’s code and history:

    $ hg clone http://bitbucket.org/wcmaier/neat
    $ git clone git://github.com/wcmaier/neat.git

If you notice a problem with `neat`, please report it using the github issue tracker (or, if you have a fix, send a pull request).

### A note about versions

`neat` is developed along two branches. The first, ‘default’ (or ‘master’ in git) contains new features and possible bugs – this branch is the active development branch. The second, ‘stable’, contains releases both major and minor as well as bugfixes. If you’d like to help improve `neat`, take a look at default/master. Otherwise, stick with stable.

## A quick tour of `neat`‘s features

Hello world:

    >>> from neat import Resource, Dispatch
    >>> from webob import Request

    >>> class Hello(Resource):
    ...     collection = "hello"
    ...
    ...     def retrieve(self, req):
    ...         return "Hello, %s" % req.path_info_pop()

    >>> dispatch = Dispatch(Hello())
    >>> req = Request.blank("/hello/you")
    >>> req.get_response(dispatch).body
    'Hello, you'

Easily add support for new media types:

    >>> import json
    >>> class JsonHello(Hello):
    ...
    ...     mimetypes = {"application/javascript": "json"}
    ...
    ...     def retrieve_json(self, req):
    ...         req.response.content_type = "application/json"
    ...         return json.dumps({"message": self.retrieve(req)})
    ...

    >>> dispatch = Dispatch(JsonHello("hello"))
    >>> req = Request.blank("/hello/you")
    >>> req.get_response(dispatch).body
    '{"message": "Hello, you"}'

## Basic usage

`neat` is a simple framework for modeling and representing resources via HTTP. This approach takes full advantage of the structure of the web, described by Roy Fielding in his famous REST paper. `neat` applications include a single `Dispatch` that combines any number of resources (usually subclasses of `Resource`). When a `Dispatch` receives a HTTP request, it routes the request to `Resource` methods using rules defined by the `Resource` itself. The `Resource` methods then interact with the data or state of the actual resource (for example, a database) and return a representation of the current state to the client. `Resource` can support a variety of representations (like JSON, HTML, CSV, XML), so the framework chooses the representation that best matches the HTTP request’s Content header.

Note

The rules for routing requests and choosing representation formats are all defined by the `Resource`, so different resources may define different rules. If the default rules don’t suit you, simply override `match()`.

## API

class `neat.neat.` `Resource`

  Bases: `object`

  `extensions`

    Maps URI file extensions to media types.

    For example:

    > .html -> text/html .json -> application/vnd.my.resource+json

    The media types should be present in `media`.

  `media`

    Maps media types to local method suffixes.

    For example:

    > text/html -> html application/vnd.my.resource+json -> json

  `methods`

    Maps HTTP methods to local method base names.

    For example:

    > GET -> get POST -> post

  `params`

    A dictionary of ‘magic’ parameters.

    These GET parameters allow less-than-perfect clients to use interesting HTTP features even if the client itself doesn’t support them at the protocol level. Keys in the dictionary represent the feature to be supported (ie “method”); the value indicates the name of the GET parameter used to signal the feature. For example, params = {“method”: “_method”} would allow clients to set the HTTP method using the “_method” get parameter. By default, no magic parameters are supported. Possible keys include:

    > - method (HTTP method)
    > - accept (desired response media type)
    > - content-type (request content type)

  `prefix`

    The URI space for which this resource is responsible.

  `req`

    A `webob.Request` instance.

    `__call__()` sets this attribute before calling one of the <method>_<media> methods. It also sets the following attributes of the request object:

    > - response, a `webob.Response` instance;
    > - content, an object produced by a handle_<media> method.

class `neat.neat.` `Dispatch`(*resources)

  Bases: `object`

  A WSGI application that dispatches to other WSGI applications.

  Incoming requests are passed to registered `Resource` subclasses. Resources can be registered by passing them as arguments on initialization or by adding them to `resources` later.

  `match`(req, resources)

    Return the resource that matches req.

    req should be a `webob.Request` instance; resources should be an iterable of `Resource` subclasses. Returns None if no resource matches the request.

    A request matches if:

    > - PATH_INFO ends in ‘/’ and starts with the resource’s `Resource.prefix` attribute; or
    > - PATH_INFO is the same as the resource’s `Resource.prefix` attribute.

    The first match wins.

  `resources`

    A list of `Resource` subclasses.

## Developing `neat`

### Running the tests

`neat` ships with a number of unit tests that help ensure that the code runs correctly. The tests live in the `tests` package and can be run by `setup.py`:

    $ python setup.py test

All new code in `neat` should be accompanied by unit and/or functional tests. You can get a sense for how completely the unit tests exercise `neat` by running the coverage tool:

    $ coverage run --branch setup.py test

`coverage` tracks the code statements and branches that the test suite touches and can generate a report listing the lines of code that are missed:

    $ coverage report -m --omit "tests,/home/will/lib,lib/neat/ext,setup"

It’s useful to omit the third party code directory (`ext`) as well as the path to the Python standard library as well as `setup.py` and the tests themselves.

### Navigation

- index
- modules |
- neat v0.4.1 documentation »