Documenting Components

Some hopefully helpful guidelines!

These are the current guidelines for documenting Kamaelia components, covering:

  • Writing style
  • Structure and format
  • Example(s)
  • A template for your reference

It is better for there to be some documentation than none at all ... even if it breaks these guidelines or is incomplete. Don't let these guidelines stop you writing! Documentation can be developed iteratively, just like code. No documentation is perfect. Much of our existing documentation probably breaks many of these guidelines! Think of this as documentation of our current best practice. This is a descriptive set of guidelines explaining "how we have done it and what works for us". This is not a prescriptive demand that "things must be documented this way".

In these guidelines, examples of good ways to write are green. Examples of how not to write are red.

Why document? Who is the Reader?

Documentation should serve two different sets of readers:

  • USERS - I want to use this component: what does it do? how do I plug it together with other components? how does it behave?
  • Component Developers/Maintainers - I want to modify this component: how does the component work inside? why does it work that way and not another?

Because most components are small and lightweight, the main focus of these guidelines is on documenting for usage. Pretend you are the reader: what questions would you ask if you were seeing this component for the first time? What would a developer need to know?

Writing style

Aim to write in the following way:

  • Write as if you are talking to the reader
    • You are talking to the reader - they are reading your words!
  • Use consistent, short, clear and unambiguous statements.
    • A sentence of more than 10 words is probably too long. Keep it Short and Simple! It may sound patronising, but it makes it much easier to understand.
    • Don't skip words.
  • Use the present tense
    • say "ConsoleEchoer is designed to"
    • don't say "ConsoleEchoer was designed to"
  • Use the imperative - tell the reader what to do:
    • say "Do X to make Y happen"
    • don't say "When you do X, Y happens"
  • Refer to inboxes, outboxes and components by name
    • state whether it is an inbox or outbox!
    • say: the "inbox" inbox or: ConsoleEchoer

A reasonably good example:

  • The TopologyViewerComponent renders to a pygame display surface. Send topology information to its "inbox" inbox, and nodes with links between them will appear.

It could have been much unnecessarily wordy:

  • A pygame display surface is used by the TopologyViewerComponent. When topology information has been sent by another component, this one will display the nodes and linkages between them.

This is clear and explains precisely what happens:

  • If a shutdownMicroprocess or producerFinished message is received on this component's "control" inbox, it will pass it on out of its "signal" outbox and immediately terminate.

But this is much more ambiguous (what is a shutdown message? where do I send it?):

  • The component shuts down when it receives a shutdown message.

This can often simply be a matter of taste of course. Terse is often good, but unnecessarily terse is bad. Always aim for clarity above all else.

Structure and format

The formatting style being used is broadly the reStructured Text format. For an overview of this, see the primer. This has been chosen because of its simplicity and readability, but also because it can be machine processed to automate the generation of, for example, website documentation.

Document component(s) within a sourcefile by writing:

  1. Write a detailed docstring at the top, containing:
    • One short paragraph introduction
    • "Example Usage" section
    • "How does it work" section
    • Extra sections/sub sections if needed
  2. A docstring for the class, containing:
    • Constructor syntax:
         MyComponent(arg1,arg2[,optarg3]) -> new MyComponent component. 
    • One sentence description:
      	Component that does X. 
    • Description of initializer arguments:
          Keyword arguments:

      - arg1 -- what this is
      - arg2 -- what this is
      - optarg3 -- None, or what value it takes (default=None)
  3. A docstring for each inbox and outbox, as the value of the key:value pair
        Inboxes = { "inbox" : "Items to be xxxx'ed",
    "control" : "Shutdown signalling",

    unused boxes should be documented as such
  4. A standard docstring for the initalizer method:
     """x.__init__(...) initializes x; see x.__class__.__doc__ for signature""" 
    • I'm not totally convinced about this. Having nothing there is occasionally a pain -- Michael.
  5. Docstrings for other methods and comments within the code, to assist developers

See the example(s) and template below for the recommended syntax for these parts.

If your sourcefile contains more than one component, then concatenate the detailed docstrings for each component into one. Preface it with a top level heading and one or two paragraphs of introduction.

Some general consistency rules:

  • Wordwrap at 80 columns to aid readability
    • exceptions can be made for list items and other short indented pieces.
  • Leave 3 blank lines between the end of a section and the heading for the next.
  • Write python data structures in the language's own syntax. For example, a python list:
  • [ "moveto", width, height ]


The best examples are within the Kamaelia codebase itself. Here is a snapshot (April 2006) of Kamaelia/Internet/ containing the TCPClient component. The documentation is highlighted in green:

Simple TCP Client

This component is for making a TCP connection to a server. Send to its "inbox"
inbox to send data to the server. Pick up data received from the server on its
"outbox" outbox.

Example Usage

Sending the contents of a file to a server at address on port 1000::

pipeline( RateControlledFileReader("myfile", rate=100000),
TCPClient("", 1000),

How does it work?

TCPClient opens a socket connection to the specified server on the specified
port. Data received over the connection appears at the component's "outbox"
outbox as strings. Data can be sent as strings by sending it to the "inbox"

An optional delay (between component activation and attempting to connect) can
be specified. The default is no delay.

It creates a ConnectedSocketAdapter (CSA) to handle the socket connection and
registers it with a selectorComponent so it is notified of incoming data. The
selectorComponent is obtained by calling
selectorComponent.getSelectorService(...) to look it up with the local
Coordinating Assistant Tracker (CAT).

TCPClient wires itself to the "FactoryFeedback" outbox of the CSA. It also wires
its "inbox" inbox to pass data straight through to the CSA's "DataSend" inbox,
and its "outbox" outbox to pass through data from the CSA's "outbox" outbox.

Socket errors (after the connection has been successfully established) may be
sent to the "signal" outbox.

This component will terminate if the CSA sends a socketShutdown message to its
"FactoryFeedback" outbox.

Messages sent to the "control" inbox are ignored - users of this component
cannot ask it to close the connection.

class TCPClient(component):
    TCPClient(host,port[,delay]) -> new TCPClient component.
    Establishes a TCP connection to the specified server.
    Keyword arguments:
    - host -- address of the server to connect to (string)
    - port -- port number to connect on
    - delay -- delay (seconds) after activation before connecting (default=0)

    Inboxes = { "inbox" : "data to send to the socket",
                "_socketFeedback" :
"notifications from the ConnectedSocketAdapter",
                "control" :
    Outboxes = { "outbox" :
"data received from the socket",
                 "signal" :
"socket errors",
                 "_selectorSignal" :
"communicating with a selectorComponent",

    def __init__(self,host,port,delay=0):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        super(TCPClient, self).__init__() = host
        self.port = port


A template

The following 'template' points out some of the formatting and stylistic points already described:

#!/usr/bin/env python
# <>

What it does

Short, one paragraph description of what this component does, or the task it achieves.

Example Usage
What this shows followed by double colon::

    def func():
    print "really really simple minimal code fragment"

Indicate any runtime user input with a python prompt::

    >>> func()
    really really simple minimal code fragment

Optional comment on any particularly important thing to note about the above

How does it work?

Statements, written in the present tense, describing in more detail what the
component does.

Explicitly refer to "named" inbox an "named" outbox to avoid ambiguity.

Does the component terminate? What are the conditions?

If the 'xxxx' argument is set to yyy during initialization, then something
different happens.

What does the component *not* do?

A subheading for a subtopic

Lists of important items might be needed, such as commands:

    the item
        A description of the item, what it is and what it does, and maybe
        consequences of that.

    another item
        A description of the item, what it is and what it does, and maybe
        consequences of that.

You may also want bullet lists:

 - first item
 - second item

Optional extra topics

May be necessary to describe something separately, eg. a complex data structure
the component expects to receive, or the GUI interface it provides.

class TheComponent(...):
    TheComponent(arg[,optarg]) -> new TheComponent component.
    Component that does something.
    Keyword arguments:
    - arg -- specifys something
    - optarg -- None, or something else (default=None)
    Inboxes = { "inbox" : "What you send to here",
                "control" : "Shutdown signalling",
    Outboxes = { "outbox" : "What comes out of here,
                 "something" : "NOT USED",
                 "signal" : "Shutdown signalling",

    def __init__(self, ...):
        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
        ... of the component...


Kamaelia is an open source project originated from and guided by BBC Research. For more information browse the site or get in contact.

This is an ongoing community based development site. As a result the contents of this page is the opinions of the contributors of the pages involved not the organisations involved. Specificially, this page may contain personal views which are not the views of the BBC. (the site is powered by a wiki engine)

(C) Copyright 2008 Kamaelia Contributors, including the British Broadcasting Corporation, All Rights Reserved

This web site is powered by the same code created for the bicker manor project. For more details, contact Michael Sparks at BBC Research directly (cf contact)