How PyDoc Helps Your Python Development
Tags: beginners, python, 100daysofpython
Published: 2021-09-13 10:15:14

_**I write content for AWS, Kubernetes, Python, JavaScript and more. To view all the latest content, be sure to [visit my blog](https://blog.dennisokeeffe.com) and subscribe to my newsletter. [Follow me on Twitter](https://twitter.com/dennisokeeffe92).**_

> This is Day 19 of the #100DaysOfPython challenge.

This post will use the [`pydoc`](https://docs.python.org/3/library/pydoc.html) module from the standard library to to explore how we can navigate documentation as well as create our own.

The code can be found on my [GitHub repo](https://github.com/okeeffed/how-pydoc-helps-your-python-development).

## Getting started

Let's create the `hello-pydoc` directory and set up the required files.

```s
# Make the `hello-pydoc` directory
$ mkdir hello-pydoc
$ cd hello-pydoc
# Create a folder to place our example files
$ mkdir src
# Create the required files
$ touch src/math.py main.py src/__init__.py
```

At this stage, we have our files sorted and we can start to write some code.

## Exploring PyDoc from the command line

PyDoc is a tool that allows us to explore the documentation of a module.

As a simple starter, we can use PyDoc to explore the documentation of the [`datetime`](https://docs.python.org/3/library/datetime.html) module from the command line.

To do so, we can run `python -m pydoc [module]` and we should see the output based on the doc strings for each of the functions in the module.

Let's explore this for the `datetime` module. From the command line, we can run the following command:

```s
$ python -m pydoc datetime
Help on module datetime:

NAME
    datetime - Fast implementation of the datetime type.

FILE
    /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/datetime.so

MODULE DOCS
    https://docs.python.org/library/datetime

CLASSES
    __builtin__.object
        date
            datetime
        time
        timedelta
        tzinfo

    class date(__builtin__.object)
     |  date(year, month, day) --> date object
     |
     |  Methods defined here:
     |
     |  __add__(...)
    x.__add__(y) <==> x+y
     |
     |  __eq__(...)
# ... reset omitted for brevity ...
```

When you run the command, it opens up the documentation for the `datetime` module that can be traversed in the command-line.

It gives us information on the following:

| Heading       | Description                                   |
| ------------- | --------------------------------------------- |
| `NAME`        | The name of the module.                       |
| `FILE`        | The file that the module is defined in.       |
| `MODULE DOCS` | The link to the documentation for the module. |
| `CLASSES`     | The classes defined in the module.            |

We can search within the docs by using the `/` or `?` operator followed by a search term.

For example, in my previous blog post [`Datetime in Python`](https://blog.dennisokeeffe.com/blog/2021-08-04-datetime-in-python), we heavily relied upon the `datetime.datetime.now` function.

To search for that documentation, I can run `/` followed by `now` and one of the search results will return the following:

```s
now(tz=None) from builtins.type
    Returns new datetime object representing current time local to tz.

      tz
        Timezone object.

    If no tz is specified, uses local timezone.
```

> Tip: after searching, you can use the `n` key to navigate to the next result.

The above documentation tells us that the `now` function returns a `datetime` object with the timezone's local time and date (with an optional argument of the timezone).

Given this, we know that we could can the function both with and without an argument:

```py
from datetime import datetime, timezone

datetime.now() # datetime.datetime(2021, 8, 7, 7, 22, 37, 216899)
datetime.now(timezone.utc) # datetime.datetime(2021, 8, 6, 21, 22, 30, 841500, tzinfo=datetime.timezone.utc)
```

If we go searching for the synonymous function `utcnow`, we can see the following:

```s
utcnow(...) from builtins.type
    Return a new datetime representing UTC day and time.
```

This tells us that there are no arguments but the returned value is a `datetime` object with the timezone of UTC.

```py
from datetime import datetime

datetime.utcnow() # datetime.datetime(2021, 8, 6, 21, 24, 2, 865402)
```

Now that we know the basics of searching PyDoc, let's now document our `math` module.

## Writing our own documented code

We can write and search for our own `docstrings`.

To demonstrate, add the following code to `src/math.py`:

```py
def add(x, y):
    """add together two numbers

    Args:
        x (int): First number to add
        y (int): Second number to add

    Returns:
        int: sum of x and y
    """
    return x + y
```

The `docstring` is a string that is used to document the function and is denoted as the comment between lines 2 and 10 of the code above.

> Tip: if you use VSCode, check out the [`docstring generator`](https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring)

Once we have that code in place, it is enough to view our own documentation for the module!

## Exploring our documented code

We can run `python -m pydoc src.math` and we should see the output of the `docstring`:

```s
Help on module src.math in src:

NAME
    src.math

FUNCTIONS
    add(x, y)
        add together two numbers

        Args:
            x (int): First number to add
            y (int): Second number to add

        Returns:
            int: sum of x and y

FILE
    /path/to/code/blog-projects/hello-pydoc/src/math.py
```

How easy was that!

## Viewing PyDoc in the browser

If we run `pydoc -h`, we see the following:

```s
-h
pydoc - the Python documentation tool

pydoc <name> ...
    Show text documentation on something.  <name> may be the name of a
    Python keyword, topic, function, module, or package, or a dotted
    reference to a class or function within a module or module in a
    package.  If <name> contains a '/', it is used as the path to a
    Python source file to document. If name is 'keywords', 'topics',
    or 'modules', a listing of these things is displayed.

pydoc -k <keyword>
    Search for a keyword in the synopsis lines of all available modules.

pydoc -p <port>
    Start an HTTP server on the given port on the local machine.  Port
    number 0 can be used to get an arbitrary unused port.

pydoc -g
    Pop up a graphical interface for finding and serving documentation.

pydoc -w <name> ...
    Write out the HTML documentation for a module to a file in the current
    directory.  If <name> contains a '/', it is treated as a filename; if
    it names a directory, documentation is written for all the contents.
```

This gives us a list of the options that we can use to view our own documentation.

First of all, we will use the `pydoc -p 4000` option to start a server on port 4000.

From here, you can open up `http://localhost:4000` in your browser and explore the documentation. The interface isn't pretty, but the job gets done.

## Outputting PyDoc as HTML

Finally, we can output the documentation as HTML by passing the `-w` option to `pydoc`.

Running `pydoc -w src.math` outputs HTML into `src.math.html` which contains the following:

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>Python: module src.math</title>
    
  </head>
  <body bgcolor="#f0f0f8">
    <table
      width="100%"
      cellspacing="0"
      cellpadding="2"
      border="0"
      summary="heading"
    >
      <tr bgcolor="#7799ee">
        <td valign="bottom">
          &nbsp;
          <font color="#ffffff" face="helvetica, arial"
            >&nbsp;<big
              ><big
                ><strong
                  ><a href="src.html"><font color="#ffffff">src</font></a
                  >.math</strong
                ></big
              ></big
            ></font
          >
        </td>
        <td align="right" valign="bottom">
          <font color="#ffffff" face="helvetica, arial"
            ><a
              href="file:/path/to/code/blog-projects/hello-pydoc/src/math.py"
              >/path/to/code/blog-projects/hello-pydoc/src/math.py</a
            ></font
          >
        </td>
      </tr>
    </table>
    <p></p>
    <p></p>
    <table
      width="100%"
      cellspacing="0"
      cellpadding="2"
      border="0"
      summary="section"
    >
      <tr bgcolor="#eeaa77">
        <td colspan="3" valign="bottom">
          &nbsp;
          <font color="#ffffff" face="helvetica, arial"
            ><big><strong>Functions</strong></big></font
          >
        </td>
      </tr>

      <tr>
        <td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td>
        <td>&nbsp;</td>
        <td width="100%">
          <dl>
            <dt>
              <a name="-add"><strong>add</strong></a
              >(x, y)
            </dt>
            <dd>
              <tt
                >add&nbsp;together&nbsp;two&nbsp;numbers
                &nbsp;
                Args:
                &nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;(int):&nbsp;First&nbsp;number&nbsp;to&nbsp;add
                &nbsp;&nbsp;&nbsp;&nbsp;y&nbsp;(int):&nbsp;Second&nbsp;number&nbsp;to&nbsp;add
                &nbsp;
                Returns:
                &nbsp;&nbsp;&nbsp;&nbsp;int:&nbsp;sum&nbsp;of&nbsp;x&nbsp;and&nbsp;y</tt
              >
            </dd>
          </dl>
        </td>
      </tr>
    </table>
  </body>
</html>
```

## Summary

Today's post demonstrated how to use the `pydoc` package to explore built-in and custom documentation.

Albeit a shallow exploration, the best way to improve on your searching capability is to use the command line in practice.

## Resources and further reading

1. [`pydoc`](https://docs.python.org/3/library/pydoc.html)
2. [GitHub repo](https://github.com/okeeffed/how-pydoc-helps-your-python-development)

_Photo credit: [`milada_vigerova`](https://unsplash.com/@milada_vigerova)_


_Originally posted on my [blog](https://blog.dennisokeeffe.com/blog/2021-08-07-how-pydoc-helps-your-python-development). To see new posts without delay, read the posts there and subscribe to my newsletter._