:mod:`neat` --- WSGI, neat
==========================

.. automodule:: neat

Installing :mod:`neat`
----------------------

.. highlight:: none

You can install the latest stable version of :mod:`neat` using :command:`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

.. _github:     http://github.com/wcmaier/neat
.. _bitbucket:  http://bitbucket.org/wcmaier/neat
.. _git:        http://git-scm.com/
.. _Mercurial:  http://mercurial.selenic.com/

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

.. _issue tracker:  http://github.com/wcmaier/neat/issues
.. _pull request:   http://github.com/wcmaier/neat/pull/new/master

A note about versions
+++++++++++++++++++++

:mod:`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 :mod:`neat`, take a look at
default/master. Otherwise, stick with stable.

A quick tour of :mod:`neat`'s features
-------------------------------------------

.. highlight:: python

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
-----------

:mod:`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. :mod:`neat`
applications include a single :class:`~neat.neat.Dispatch` that combines any
number of resources (usually subclasses of :class:`~neat.neat.Resource`).
When a :class:`~neat.neat.Dispatch` receives a HTTP request, it routes the
request to :class:`~neat.neat.Resource` methods using rules defined by the
:class:`~neat.neat.Resource` itself. The :class:`~neat.neat.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.
:class:`~neat.neat.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.

.. _REST:   http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

.. note::
    The rules for routing requests and choosing representation formats are all
    defined by the :class:`~neat.neat.Resource`, so different resources may define
    different rules. If the default rules don't suit you, simply override
    :meth:`~neat.neat.Resource.match`.

API
---

.. automodule:: neat.neat
    :show-inheritance:

    .. autoclass:: Resource
        :members:
        :show-inheritance:

    .. autoclass:: Dispatch
        :members:
        :show-inheritance:

Developing :mod:`neat`
----------------------

Running the tests
+++++++++++++++++

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

All new code in :mod:`neat` should be accompanied by unit and/or functional
tests. You can get a sense for how completely the unit tests exercise
:mod:`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.

.. _coverage:   http://nedbatchelder.com/code/coverage/
