Documentation
We write documentation in plain text that utilizes the reStructured Text markup language. You can compile it to HTML with Sphinx, and you can also read it as plain text.
Reading Documentation
You’re welcome to read the plain text documentation in the docs
folder,
but you’ll probably enjoy the pretty HTML version more. We use GitHub
Actions to build the HTML and deploy it to GitHub Pages here:
https://covertlab.github.io/vEcoli.
If you want to generate the HTML documentation yourself, check out the instructions on building documentation below.
Writing Documentation
Where to Write
The source code for the non-API documentation is in reStructuredText (.rst
)
files located in the docs
folder of the repository. Please feel free to edit
those files to fix errors, add information, and clarify things as you see fit.
API Reference Documentation
We currently mostly have API reference documentation. The API reference is auto-generated from docstrings in the code. These docstrings can take advantage of all the reStructuredText syntax we use elsewhere in Vivarium. Eventually, we will remove from the reference material the stubs for functions that aren’t user-facing and the auto-generated titles on each page.
Note
From the compiled HTML reference documentation, you can click on
[source]
to see the source code, including the docstrings. This
can be helpful for looking up reStructuredText syntax.
Warning
For each class, include at most one of the class and constructor docstrings. They are concatenated when the HTML is compiled, so you can provide either one.
class MyClass:
'''This is the class docstring'''
def __init__(self):
'''This is the constructor docstring'''
The “API Reference” link in the sidebar of the documentation links to
the full API reference under reference/api/
which is generated
automatically.
Note
Many files are excluded from documentation auto-generation by
docs/conf.py
because they don’t have headers in their
docstrings. These headers are required by Sphinx for a page to be
included in a table of contents.
Check out the Sphinx documentation
on cross-links and make use of them when writing your docstrings where appropriate. For example,
the following renders as
ParquetEmitter
:
:py:class:`~ecoli.library.parquet_emitter.ParquetEmitter`
Additionally, we strongly recommend that you add type hints to your code where possible.
This enhances the autogenerated documentation by adding type information for function
arguments and return values. It also allows mypy
to do a better job of type
checking when submitting pull requests, reducing the likelihood of bugs. Finally, it
improves the overall developer experience by allowing code editors to show more
information when you, for example, hover over code. Refer to the official
Python documentation
for an introduction to type hints.
Pointers for Technical Writing
Here are resources for writing good documentation and technical writing in general:
Quick Overview of reStructuredText Syntax
This is just a quick overview of some of the reStructuredText (reST) features you might use most often. For a more complete introduction, see:
reST Is not Markdown
Before we get started, remember that reStructuredText is not markdown!. For example, a common error is to try and use back-ticks for inline preformatted text like this:
`preformatted text`
However, in reStructuredText, this produces italicized text: preformatted text. For preformatted code, you need to use double back-ticks:
``preformatted text``
This code creates text like this: preformatted text
.
Here are some other useful markup features:
Inline Markup
Italics:
*this text is italicized*
This gets rendered as:
this text is italicized
Bold:
**this text is bold**
This gets rendered as:
this text is bold
Preformatted:
``this text is preformatted``
This gets rendered as:
this text is preformatted
Links:
`this is a link <https://example.com>`_
This gets rendered as:
Block Elements
For block elements, it’s important to remember that just like Python, reST cares about indentation.
Paragraphs are just blocks of text separated from other text by blank lines. These get rendered as paragraphs that are separated by space from each other, but they are not indented.
Code blocks begin with
.. code-block::
and are then indented after a blank line. For example:.. code-block:: python def my_function(text): print(text)
This code block gets rendered like this:
def my_function(text): print(text)
The string after
.. code-block::
specifies the language and is used for syntax highlighting. The block defaults to Python, so specifytext
if you don’t want any highlighting.Images can be included like this:
.. image:: ./_static/ecoli_master_topology.png :width: 100% :alt: A graph with blue, database symbol nodes at the top and orange, square nodes on the bottom. The blue nodes are connected by solid edges, while the orange nodes are connected to the blue nodes by broken edges.
This would be rendered like this:
The
:width:
argument specifies the width of the image, and the:alt:
provides alt text for people who can’t see the image (e.g. blind users).Doctest blocks are blocks of Python code from an interactive Python session. For example:
>>> print('Hello, world!') Hello, world! >>> def hello(): ... print('Hello') >>> hello() Hello
This would be rendered as:
>>> print('Hello, world!') Hello, world! >>> def hello(): ... print('Hello') >>> hello() Hello
Pytest can also be configured so that it runs these code snippets as tests. This helps make sure that the examples in your documentation are always up to date!
Quoted blocks are created by just indenting:
Here is a quote: My words of wisdom. This comes after the quote.
This gets rendered as:
Here is a quote:
My words of wisdom.
This comes after the quote.
Headings
reST handles headings in an unusual way. Unlike markdown or HTML where there is a heading syntax for each level of heading, reST determines heading order based on the order in which they appear. Any punctuation character can be used to underline or overline text to make that text a heading. For example, these all work:
=======
Heading
=======
Heading
=======
Heading
*******
Heading
^^^^^^^
-------
Heading
-------
We usually stick to using =
and -
characters with the headings
in this order:
===============
Level 1 Heading
===============
---------------
Level 2 Heading
---------------
Level 3 Heading
===============
Level 4 Heading
---------------
Note that the heading must be at least as long as the text!
Lists
Unordered lists use asterisks:
* Item 1 * Item 2 * Item 3, which is really long and spans multiple lines. * Item 4
This gets rendered as:
Item 1
Item 2
Item 3, which is really long and spans multiple lines.
Item 4
Ordered lists can use numbers:
1. Item 1 2. Item 2 3. Item 3, which is really long and spans multiple lines. 4. Item 4
This gets rendered as:
Item 1
Item 2
Item 3, which is really long and spans multiple lines.
Item 4
Ordered lists can also figure out the numbers automatically:
#. Item 1 #. Item 2 #. Item 3, which is really long and spans multiple lines. #. Item 4
This gets rendered as:
Item 1
Item 2
Item 3, which is really long and spans multiple lines.
Item 4
Lists can be nested, but they must be indented and separated from other levels of nesting by blank lines:
* Item 1
* Item 2
* Item 3, which is really long
and spans multiple lines.
* Item 4
This gets rendered as:
Item 1
Item 2
Item 3, which is really long and spans multiple lines.
Item 4
Math
You can render math using LaTeX either inline or as a block:
Inline:
:math:`x = \frac{1}{2}`
This gets rendered as: \(x = \frac{1}{2}\).
Block:
.. math:: x = \frac{1}{2}
This gets rendered as:
\[x = \frac{1}{2}\]
Admonitions
Admonitions are like banners that highlight important points for the reader. For example:
.. note:: This is a really important note.
This looks like:
Note
This is a really important note!
The style guide below lists which admonitions we use.
Style Guide
Here we document the stylistic decisions we have made for this documentation:
We use first-person plural pronouns to refer to ourselves (e.g. “We decided”).
We write tutorials in the second-person, future tense, for example “First, you’ll need to install”. We also frequently use the imperative (“Install this”).
We use the following admonitions. We don’t want to overload our users with admonitions, so we don’t use any others.
We warn users about potential problems with warning admonitions. These often describe important steps that we think users might forget.
Warning
.. WARNING::
We use notes to highlight important points. These should not be used for asides that aren’t important enough to integrate directly into the text.
Note
.. note::
We give users helpful tips using the tip admonition. These help highlight tips that some users might not use but that will help users who are debugging problems.
Tip
.. tip::
We use danger admonitions for the most critical warnings. Use these sparingly.
Danger
.. DANGER::
Building the Documentation
To build the documentation, we will use Sphinx to generate HTML files from plain text. Here are stepwise instructions:
(optional) Create a virtual environment for the documentation-building packages. You might want this to be separate from the environment you use for the rest of Vivarium E. coli.
Setup Vivarium E. coli. We need it to be setup so that we can import its Cython code.
Install dependencies:
$ pip install -r doc/requirements.txt
Build the HTML!
$ cd doc $ make html
Your HTML will now be in
doc/_build/html
. To view it, opendoc/_build/html/index.html
in a web browser.