Home / Alt manpages / pydoc3.12(1)

  • pydoc3.12(1)
  • User command
  • linux

Read and Serve Python Docs Locally with pydoc3.12

Skip the browser tab hunt: pydoc3.12 reads a module's actual docstrings from your shell, on the exact interpreter you are about to run code on. This walks through finding an installed module, saving documentation as HTML and serving it through a local browser. The examples use the installed pydoc3.12 command and Python 3.12.3.

Allow about fifteen minutes. You need the python3.12 package and a normal shell account. Inspection and HTML generation need no elevated privileges. Do not reach for sudo to make a module appear; check the interpreter and import path instead.

1. Confirm the interpreter behind the command

Check the executable and package version, read-only:

$ command -v pydoc3.12
/usr/bin/pydoc3.12
$ /usr/bin/python3.12 --version
Python 3.12.3
$ dpkg-query -W -f='${Package} ${Version}\n' python3 python3.12
python3 3.12.3-0ubuntu2.1
python3.12 3.12.3-1ubuntu0.17

On this system, /usr/bin/pydoc3.12 is the Python 3.12 launcher, and pydoc3 is just an alias for it. Keep the versioned name in scripts when the interpreter version actually matters: plain python3 can point at a different install entirely, so do not use its version as a stand-in for this check.

Checkpoint

Only carry on once the executable and interpreter are the pair you actually meant to document.

2. Read a module or object in the terminal

Give a module name as the positional argument and pydoc generates output from its docstrings and members:

$ pydoc3.12 sys
Help on built-in module sys:

NAME
    sys

MODULE REFERENCE
    https://docs.python.org/3.12/library/sys.html

The real output is longer than this excerpt. A dotted name narrows the request to an object, for example pathlib.Path.exists. You can also ask for the built-in indexes keywords, topics or modules. A name containing a slash gets treated as a source path rather than an import name.

Pipe long output to a pager, but remember the pipe's exit status describes the pager, not pydoc:

$ pydoc3.12 pathlib.Path | less
$ pydoc3.12 sys | sed -n '1,18p'

If a module cannot be found, check which interpreter owns the command and whether that interpreter can actually import it. A package installed for a different virtual environment will not show up here.

3. Search synopsis lines when you know the concept, not the name

Use -k to search the short descriptions of every available module:

$ pydoc3.12 -k json
json - JSON (JavaScript Object Notation) <https://json.org> is a subset of
json.decoder - Implementation of JSONDecoder
json.encoder - Implementation of JSONEncoder
json.scanner - JSON token scanner

The list depends on what is installed on the host, and ordering can vary. This is not a full-text search of every docstring, so an empty result does not prove a feature is missing. Try a shorter, more distinctive term, then check a likely module directly.

Checkpoint

Use -k to pick a candidate, then run pydoc3.12 MODULE to actually read its interface.

4. Generate HTML somewhere you chose on purpose

-w writes HTML documentation to the current directory, for one or more modules, and treats a slash-containing name as a file path. Pick the destination before you run it, because it writes files without asking:

$ work_dir=$(mktemp -d /tmp/pydoc-html.XXXXXX)
$ cd "$work_dir"
$ pydoc3.12 -w pathlib
wrote pathlib.html
$ test -s pathlib.html && printf 'created: %s\n' "$PWD/pathlib.html"
created: /tmp/pydoc-html.A1b2C3/pathlib.html

That random directory name is only an example. Keep generated files out of a source tree unless you deliberately want them there. If you generated something in the wrong place, remove just the known file or directory after checking it, never a broad recursive delete.

Generated HTML reflects whatever interpreter and imports pydoc had at hand. It is documentation produced from code, not a security review: treat third-party docstrings and source comments as untrusted text before publishing the result anywhere.

5. Serve documentation on the local machine

-p starts an HTTP server on a chosen port. Port 0 asks the OS for a free one, which suits a short test:

$ pydoc3.12 -p 0
Server ready at http://localhost:NNNN/
Server commands: [b]rowser, [q]uit

Swap NNNN for the port it actually printed and open that URL on the same machine. Type b in the server terminal to open a browser, or q to stop it; closing the terminal also stops this foreground server. Confirm the listener before you share anything:

$ curl --fail --silent --show-error http://localhost:NNNN/ | sed -n '1,8p'

Warning

Do not bind this to a public address without a specific access-control plan. Local-only is the safer default, since source and docstrings can carry internal paths, credentials accidentally left in examples, or other private details. The command also accepts -n HOSTNAME, which makes the exposure decision much more consequential if you change it.

The server is a running process, not a permanent docs site. Stop it with q and confirm it has actually exited. If you launched it from a script, terminate that exact process and check its status rather than killing every Python process you can find.

6. Use the graphical browser only when it actually helps

-b starts the server on an unused port and opens a browser automatically. Convenient on a desktop, distracting on a remote shell, and it can fail outright where no graphical session exists:

$ pydoc3.12 -b

For a server-only workflow, prefer -p 0 and the printed URL instead. The short manpage shipped here documents -p, -g, -k and -w, while the installed launcher's own help output also lists -n and -b. When the manpage and the executable disagree, trust what the executable actually does, and record the version when you write it up.

Done means

  • Confirmed the interpreter. You know pydoc3.12 invokes the intended Python 3.12 install.
  • Read a module or object. Done with a normal, non-privileged command.
  • Searched, then checked. -k found a candidate, and you confirmed it by reading the module directly.
  • Generated HTML deliberately. Into a chosen directory, and verified the file is non-empty.
  • Know how to stop the server. Nothing was left exposed beyond the host by accident.