Skip to main content

A pyramid plugin that describes a pyramid application URL hierarchy via inspection.

Project description

===================================
Self-Documentation for Pyramid Apps
===================================

A Pyramid plugin that makes a Pyramid application self-documenting via
inspection/reflection to:

1. Describe the application URL structure,
2. Extract documentation from Python comments, and
3. Generate formal syntax using commenting conventions.

The resulting documentation can be served by the application to an
HTTP request or displayed on the command line. It has built-in support
for plain-text hierachies, reStructuredText, HTML, PDF, JSON, YAML,
WADL, and XML, however other custom formats can be added easily.

Exposing an application's structure via HTTP is useful to dynamically
generate an API description (via WADL, JSON, or YAML) or to create
documentation directly from source code.

On the command-line it is useful to get visibility into an
application's URL structure and hierarchy so that it can be understood
and maintained.

.. note::

Although pyramid-describe is intended to be able to describe any
kind of pyramid application, currently it only supports
pyramid-controllers_ based dispatch.

.. note::

Currently, pyramid-describe can only inspect the first Controller
it finds -- this will eventually be fixed to correctly implement
the `inspect` option.


Project Info
============

* Project Page: https://github.com/cadithealth/pyramid_describe
* Bug Tracking: https://github.com/cadithealth/pyramid_describe/issues


TL;DR
=====

Install:

.. code-block:: bash

$ pip install pyramid-describe

Command-line example:

.. code-block:: bash

$ pdescribe example.ini --format txt
/ # The application root.
├── contact/ # Contact manager.
│ ├── <POST> # Creates a new 'contact' object.
│ └── {CONTACTID} # RESTful access to a specific contact.
│ ├── <DELETE> # Delete this contact.
│ ├── <GET> # Get this contact's details.
│ └── <PUT> # Update this contact's details.
├── login # Authenticate against the server.
└── logout # Remove authentication tokens.

.. TODO - figure out how to serve these assets with the correct Content-Type...

Examples of the above application in all other formats with built-in
support are available at:
`text (pure-ASCII) <https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.txt.asc>`_,
`reStructuredText <https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.rst>`_,
`HTML <http://htmlpreview.github.io/?https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.html>`_,
`PDF <https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.pdf>`_,
`JSON <https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.json>`_,
`YAML <https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.yaml>`_,
`WADL <https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.wadl>`_,
and `XML <https://raw.github.com/cadithealth/pyramid_describe/master/doc/example.xml>`_.

Enable the plugin:

.. code-block:: python

def main(global_config, **settings):
# ...
config.include('pyramid_describe')
# ...

And make the documentation available publicly at "/describe":

.. code-block:: ini

[app:main]
describe.attach = /describe
describe.formats = html pdf
describe.format.html.default.cssPath = myapp:style/doc-html.css
describe.format.html+pdf.default.cssPath = myapp:style/doc-pdf.css
describe.format.default.pdfkit.options = {page-size: Letter}

Note that there are **many** options to control how the resulting
documentation is made available -- see Options_.


Installation
============

Install with the usual python mechanism, e.g. here with ``pip``:

.. code-block:: bash

$ pip install pyramid-describe


Usage
=====

There are three mechanisms to use pyramid-describe: via standard
pyramid inclusion which will add routes to the current application, by
explicitly embedding a ``pyramid_describe.DescribeController``
instance, or by directly calling the ``pyramid_describe.Describer``
object methods.


Pyramid Inclusion
=================

Pyramid-describe can be added via standard pyramid inclusion, either
in the INI file or directly in your `main` function. For example:

.. code-block:: python

def main(global_config, **settings):
# ...
config.include('pyramid_describe')

When using pyramid inclusion, pyramid-describe expects to find
configuration options in the application settings. See the `Options`_
section for a list of all supported options, with a short example
here:

.. code-block:: ini

[app:main]

describe.attach = /doc
describe.formats = html json pdf
describe.format.default.title = My Application
describe.format.html.default.cssPath = myapp:static/doc.css
describe.entries.filters = myapp.describe.entry_filter

Note that multiple describers, each with different configurations, can
be added via pyramid inclusion by using the `describe.prefixes`
option.


DescribeController
==================

Pyramid-describe can also be added to your application by embedding a
DescribeController object. The DescribeController constructor takes
the following parameters:

`view`:

An instance of ``pyramid.interfaces.IView``, which is the view that
should be inspected and reflected.

`root`:

The root path to the specified URL, so that host-relative URLs can
be generated to the views found.

`settings`:

A dictionary of all the options to apply to this describer. Note that
in this case, the options should not have any prefix.

Example:

.. code-block:: python

from pyramid_describe import DescribeController

def main(global_config, **settings):
# ...
config.include('pyramid_controllers')

settings = {
'formats' : ['html', 'json', 'pdf'],
'format.default.title' : 'My Application',
'format.html.default.cssPath' : 'myapp:static/doc.css',
'entries.filters' : 'myapp.describe.entry_filter',
}

config.add_controller('MyAppDescriber', '/doc', DescribeController(settings))


Describer
=========

Pyramid-describe can also be added to your application by directly
calling the Describer's functionality. This is an even lower-level
approach than, but still quite similar to, embedding the
`DescribeController`_; the constructor takes the same `settings`
parameter as the DescribeController, and then a call to the `describe`
method actually generates the output. The `describe` method takes as
parameters a `context` and a `format`, and returns a dictionary with
the following attributes:

.. TODO - document `context` and `format`...

`content_type`:

The MIME content-type associated with the rendered output.

`charset`:

The character set that the output is encoded in.

`content`:

The actual rendering output.

Example:

.. code-block:: python

from pyramid_describe import Describer

def my_describer(request):

settings = {
'formats' : ['html', 'json', 'pdf'],
'format.default.title' : 'My Application',
'format.html.default.cssPath' : 'myapp:static/doc.css',
'entries.filters' : 'myapp.describe.entry_filter',
}

describer = Describer(settings=settings)
context = dict(request=request)
result = describer.describe(context=context, format='pdf')

request.response.content_type = result['content_type']
request.response.charset = result['charset']
request.response.body = result['content']

return request.response


Documentation Conventions
=========================

By default, the documentation that is extracted from your handlers'
pydocs is parsed and converted using:

* Docorator extraction
* Common text-role definitions
* Field-list aliasing of numpydoc sections
* Numpydoc parsing
* Inter-endpoint linking and referencing

This behavior can be disabled or extended by setting the
`entries.parsers` setting (see Options_). Here is an example that
employs each of these functions (see below for an in-depth
explanation):

.. code-block:: python

class MyController(RestController):

@expose
def deactivate(self, request):
'''
@PUBLIC, @DEPRECATED(1.3.23)

The current object is deleted. Please note that this endpoint is
deprecated; please use the more RESTful :doc.link:`DELETE:..`
endpoint instead.

@INTERNAL: OOPS! This method was accidentally carried over from
the Java implementation. The `soap-to-rest` tool needs to be
analyzed to figure out why this happened.

:doc.copy:`DELETE:..`
'''

@expose
def get(self, request):
'''
:doc.import:`myapp:doc/mycontroller.rst`
'''

@expose
def delete(self, request):
'''
@PUBLIC, @FROZEN

The current object is deleted.

:Parameters:

recursive : bool, optional, default: false

If true, recursively deletes any dependent objects too.

permanent : bool, optional, default: false, @INTERNAL

If true, the objects and all records are permanently purged
from the network. Reserved for internal administrators.

:Returns:

HTTPOk

The object(s) were successfully deleted.

:Raises:

HTTPForbidden

The current user does not have sufficient privileges.

HTTPNotFound

The specified object does not exist.
'''


Docorator Extraction
--------------------

Docorators are decorators for documentation. For example, you may
decorate a particular endpoint with ``@BETA`` to declare that this
endpoint is not finalized yet.

Pyramid-describe will inspect an entry's ``.doc`` text and convert
them to class names. The class names are applied to different element
levels depending on where they are found:

* Docorators on the first line apply to the entire entry.

* Docorators at the beginning of a paragraph apply to that paragraph
only.

* Docorators at the beginning of a section title apply to that
section.

* Docorators in the numpydoc `type` specification apply to that
parameter/return/raise or other formal numpydoc object.

Docorators must follow one of the following syntaxes:

* Simple tag style: ``@TAG``, where ``TAG`` can be any alphanumeric
sequence.

* Parameterized declaration style: ``@TAG(PARAMS)``, where ``TAG`` can
be any alphanumeric sequence, and ``PARAMS`` can be anything except
the closing parenthesis.

Docorators are converted to class names using the following rules:

* Prefixed with ``doc-``.

* All letters are lowercased.

* All non-alphanumeric characters are replaced with a dash ("-").

* Consecutive dashes are replaced with one dash.

* Terminating dashes are dropped.

Thus the docorator ``@DEPRECATED(1.3.23)`` becomes
``doc-deprecated-1-3-23``.

**IMPORTANT**: pyramid-describe does not apply any special processing
to docorators beyond identifying them and applying the class names to
the appropriate content. It is therefore up to the calling application
to filter these in any way, for example hiding entries (or portions
thereof) that have the ``doc-internal``, i.e. that were marked with
``@INTERNAL``.


Common Text-Role Definitions
----------------------------

The text-roles `class`, `meth`, and `func` are not by default defined
by docutils_. Pyramid-describe gives a *very* bare-bones
implementation (it just aliases them as "literal" style nodes). If
these text-roles are used by the calling application, a more thorough
implementation (that actually performs linking to API documentation)
is probably desirable. Pyramid-describe does not have access to this
information and is therefore outside of its scope.


Field List Aliasing of Sections
------------------------------

All of the section headers that are specially processed by numpydoc
can also be specified as lone "field list" elements. For example, the
following two declarations are treated identically:

.. code-block:: python

def function_name(self, request):
'''
Parameters
----------

This endpoint does not take any parameters.
'''

.. code-block:: python

def function_name(self, request):
'''
:Parameters:

This endpoint does not take any parameters.
'''

The list of supported headers is extracted at runtime from
``numpydoc.docscrape.NumpyDocString()._parsed_data.keys()``.


Numpydoc
--------

By default, the pydoc text is parsed by numpydoc, and the Parameters,
Other Parameters, Returns, and Raises sections are extracted and
converted into formal structured properties of the entry. See
numpydoc_ for format and syntax details.


Options
=======


.. _pyramid-controllers: https://pypi.python.org/pypi/pyramid_controllers
.. _numpydoc: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
.. _pdfkit: https://pypi.python.org/pypi/pdfkit
.. _wkhtmltopdf: http://code.google.com/p/wkhtmltopdf/
.. _docutils: http://docutils.sourceforge.net/
.. _globre: https://pypi.python.org/pypi/globre

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyramid_describe-0.4.0b.tar.gz (114.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page