pebbledoc
Automatic documentation for small, well-rounded Python libraries
pebbledoc automatically builds a single GitHub-flavored Markdown documentation file from the RST-docstrings of your small Python library. Ideal for tiny libraries for which a whole documentation website is simply overkill!
Table of contents
- About
- Installation & prerequisites
- Usage
- Safety
- Configuration
- Supported RST syntax
- Examples
- Integration
- Contributing
- FAQ
- Metadata
About
pebbledoc sits between full documentation tools like Sphinx, and manually copy-pasting docstrings into a README. It automatically creates a single file Markdown documentation for your RST-documented project. Here is what it does to a single function docstring:
Input
Input function (my_module.py):
def hello(name: str, place: str | None = None) -> None:
"""
Greet the world - or whoever you would like!
:param name: The name of the person greeting.
:param place: The place to greet. If None, greet *the whole world*!
:return: None, function prints greeting to ``stdout``.
"""
if place is None:
place = "world"
print(f"{name} says: Hello, {place}!")
Output
Output documentation (API.md):
my_module.hellohello(name: str, place: str | None = None) -> NoneGreet the world - or whoever you would like!
Parameters:
name: The name of the person greeting.place: The place to greet. If None, greet the whole world!Returns:
None, function prints greeting to
stdout.
Installation & prerequisites
pebbledoc requires Python 3.13 or higher. You can install pebbledoc from PyPI using your preferred package manager. Installation with uv into the development dependency group is recommended:
uv add --dev pebbledoc
Alternatively, installation with pip is possible as well:
pip install pebbledoc
To be able to use pebbledoc, the project you wish to document must meet the following requirements:
- It must be a Python library, supporting Python 3.13 or higher.
- It must either provide
__all__in all packages, or explicitly re-export members of its API in the package's__init__.py. - All docstring must be written in reStructuredText (RST).
- They can also contain certain Sphinx-specific syntax, see supported syntax for details.
pebbledocand all your project's dependencies must be installed in the same environment.
Usage
Command line usage
You can run pebbledoc directly from your command line. The only required argument is the name of the package you wish to document:
pebbledoc --package <package_name> [OPTIONS]
If you run pebbledoc for the first time, test it with the default options to see if you like the output:
pebbledoc --package my_package
This creates a file API.md in the current working directory. From there, you can choose to configure pebbledoc to your liking using the options. Below is the full listing of command line options; you can display the same text by typing pebbledoc --help.
usage: pebbledoc [-h] [--version] -p [-s ] [-x member [member ...]] [--config-file ] [-o ] [--diff]
[--exit-code] [--admonition-style {classic,mix,github,map}]
[--main-docstring {default,pre,post,omit}] [--title ] [--no-generic-intro]
[--no-module-docstring] [--no-include-constants] [--no-toc] [--no-back-to-top]
[--no-main-module-header] [--no-collapsible-params] [--no-references]
[--no-full-toc-name] [--no-preserve-linewraps]
pebbledoc is a lightweight documentation tool - automatically generate a single-file API documentation
for your Python project!
Note that the package you wish to document must either be installed in the same environment as
pebbledoc, or you must specify its source directory when using pebbledoc. Either way, all of its
dependencies must be installed.
options:
-h, --help show this help message and exit
--version show program's version number and exit
source:
-p, --package name of the package to document
-s, --source-directory source directory of the package; must be specified if the package is not
installed in the current environment
-x, --exclude member [member ...]
names of members to exclude from the documentation, separated by whitespace
--config-file file containing pebbledoc configuration instructions, optional
output:
-o, --output name and filepath of the output file
--diff show changes with respect to existing file instead of writing docs to file
--exit-code exit with non-zero exit code when documentation changes
rendering:
--admonition-style {classic,mix,github,map}
rendering style for admonitions:
- classic: render all admonitions as block quotes with headers in bold type
- mix: render admonitions supported by GitHub in GitHub style, all others
in classic style
- github: render all admonitions in GitHub style, as block quotes with
headers of the form [!TYPE]
- map: render all admonitions in GitHub style, map unsupported admonitions
to the closest supported type
--main-docstring {default,pre,post,omit}
position for the main docstring of the package:
- default: place the package docstring in its dedicated section (default)
- pre: places the docstring before the table of contents
- post: places the docstring after the table of contents
- omit: omits the main docstring entirely
--title set the title for the document (i.e. its main header)
formatting:
--no-generic-intro omit the generic introduction after the main header
--no-module-docstrings omit module-level docstrings for submodules and sub-packages
--no-include-constants omit constants defined as module-level globals
--no-toc omit the table of contents at the beginning of the file
--no-back-to-top omit the 'back to top' links at the end of each section
--no-main-module-header omit the h2 header for the main module
--no-collapsible-params render parameter info field lists as static lists instead of collapsible
sections
--no-references do not turn Sphinx-style references into hyperlinks
--no-full-toc-name use only shortened member names in table of contents
--no-preserve-linewraps remove stylistic line wraps (singular line breaks) in texts
For a more in-depth description of the configuration options, see the section on configuration options below.
Output options
The options in the "output" group can change the behavior of pebbledoc, which can be useful for CI or scripting:
--diffcausespebbledocto compare the newly generated documentation content with the old one. For this purpose, it loads the text from the existing file specified by--output. Any differences are then presented as colored output. If there is no difference, the command exits silently. In either case, no files are changed.--exit-codeinstructspebbledocto exit with a non-zero exit code when the documentation changes compared to its previous state (i.e. compared to the contents of the file specified by--output). When this flag is used together with--diff, any difference will cause a non-zero exit code to be emitted, the difference is printed to the terminal, and no file is changed.
As a library
In addition to the command line interface, pebbledoc also exposes some of its more useful utilities for programmatic use. To use them, simply import pebbledoc in your code:
from pebbledoc import parse_docstring, markdown_documentation, discover_public_members
Run pebbledoc --package pebbledoc for a full API reference of what is available.
Safety
When discovering members of your package, pebbledoc imports it using the importlib machinery, including submodules and sub-packages. This can cause import-time side effects to be executed, including undesired ones. Be aware of this when running pebbledoc on your code.
Configuration
You can provide a persistent configuration to pebbledoc by creating a configuration file. pebbledoc recognizes three files:
pyproject.toml(recommended)pebbledoc.toml.pebbledoc.toml
All files follow the same format; only the section header is different: For pyproject.toml, the section header must be [tool.pebbledoc], while for dedicated configuration files, the section header must be [pebbledoc].
The example below shows a full configuration file, showing all available options with their respective default value (except for package_name and source_directory, which show example values).
# pyproject.toml
[tool.pebbledoc]
package_name = "my_package"
source_directory = "~/pylibs/my_package"
output = "API.md"
exclude = [] # list of strings
admonition_style = "mix"
main_docstring_location = "default"
document_title = "my_package - documentation"
include_intro = true
document_constants = true
module_docstrings = true
include_toc = true
include_back_to_top = true
main_module_header = true
collapsible_params = true
reference_links = true
full_toc_name = true
keep_linewraps = true
Options
The following table shows how the configuration options map to the command line flags. For a description of what the options are, see the help text of the corresponding command line option in Command line usage.
| Config key | CLI flag | Notes |
|---|---|---|
package_name |
--package |
Also used as the document title if document_title isn't set |
source_directory |
--source-directory |
Must be given if package is not installed |
output |
--output |
Defaults to API.md in the current directory |
exclude |
--exclude |
Can also be full importable name (e.g. my_package.MyClass) |
admonition_style |
--admonition-style |
See Admonitions for details on each style |
main_docstring_location |
--main-docstring |
Only affects the docstring of the package's __init__.py |
document_title |
--title |
Overrides the default title derived from package_name |
include_intro |
--no-generic-intro |
Config default: true |
document_constants |
--no-include-constants |
Config default: true |
module_docstrings |
--no-module-docstrings |
Config default: true |
include_toc |
--no-toc |
Config default: true |
include_back_to_top |
--no-back-to-top |
Config default: true |
main_module_header |
--no-main-module-header |
Config default: true |
collapsible_params |
--no-collapsible-params |
Config default: true |
reference_links |
--no-references |
Config default: true |
full_toc_name |
--no-full-toc-name |
Config default: true |
keep_linewraps |
--no-preserve-linewraps |
Config default: true |
Admonitions
GitHub-flavored Markdown supports five alert types: Caution, Warning, Important, Note, and Tip. These are automatically rendered on GitHub with colorful boxes and icons. However, reStructuredText offers more admonition types than these five. The admonition_style config option determines how to handle the additional admonition types. The options are as follows:
| Style | Supported as alert types | Other admonition types |
|---|---|---|
classic |
Block quote, bold face header | Block quote, bold face header |
github |
GitHub alert syntax | GitHub alert syntax (rendered as plain block quote) |
mix (default) |
GitHub alert syntax | Block quote, bold face header |
map |
GitHub alert syntax | Mapped to nearest type, then rendered as GitHub alert |
The mapping from admonitions to alerts in map style is as follows:
attention→importantdanger→cautionerror→cautionhint→tipadmonition(general admonition) →note(custom titles are lost)
Supported RST syntax
For a full list of all supported, planned, and unsupported RST features, see the FEATURES.md document.
Most of the standard RST syntax is supported by pebbledoc, but not all of it. This is deliberate, as pebbledoc is opinionated about what a docstring of a small Python library can reasonably be expected to contain, and what not. If you believe this opinion is ill-advised and would like to suggest adding an unsupported feature, see the contributing section for a guide on how to make suggestions.
In addition to the standard RST syntax, pebbledoc also supports some common Sphinx features. The next section gives some details.
Sphinx roles & directives
In addition to most standard RST syntax features, pebbledoc also supports a subset of features from Sphinx:
- Sphinx-style cross-references such as
:meth:`my_module.SomeClass.my_method`. These are rendered as links to the headers of the package member they refer to, if that member is part of the documentation. References to members not in the documentation render as plain inline literal text. Prefixes~(shortened name) and!(no hyperlink) are also supported. They can be fully disabled using the--no-referencesoption. - Sphinx-style version notices such as
.. version-added:: 1.3.0. These are rendered as block quotes starting with an icon to symbolize the type of version notice.
References work because every documented member receives their own Markdown section header, to which a link may refer. Anchors for all partial names of a member are placed before the header, which allows references with removed prefixes to also work.
Examples
To see some examples of the documents that pebbledoc produces, take a look at the acceptance tests directory. It contains a test package stellarium_lite with docstrings showcasing various RST syntax options. The directory with the expected outcomes shows the various documents pebbledoc can produce from it.
Alternatively, you can just run pebbledoc on itself to get a quick example of what a documentation looks like.
Integration
To keep your documentation in sync with your actual code, it is recommended to run pebbledoc automatically in regular intervals. This can be part of your CI, or your development workflow. Below are instructions on how to add pebbledoc to your GitHub actions. These examples use uv. You might have to update them for your package manager of choice.
GitHub Actions: update docs
This is an example configuration to automatically update your documentation on every push to the main branch:
name: Run pebbledoc
on:
push:
branches:
- main
permissions:
contents: write
jobs:
update-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install the project
run: uv sync --locked --all-extras --dev
- name: Run pebbledoc
run: uv run pebbledoc --config-file pyproject.toml --package <package_name>
- name: Commit and push changes
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git add .
if git diff --cached --quiet; then
echo "No changes to commit."
else
git commit -m "Automated update of docs with pebbledoc"
git push
fi
GitHub Actions: check docs are up-to-date
If you don't want a bot to create commits on your repository, you can alternatively check that your documentation is caught up with your code in every pull request:
name: Run pebbledoc
on:
pull-request:
jobs:
check-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install the project
run: uv sync --locked --all-extras --dev
- name: Check docs with pebbledoc
run: |
uv run pebbledoc --config-file pyproject.toml --package <package_name> --diff --exit-code
pre-commit: update docs
You can use this repository as a pre-commit hook. Add the following to your .pre-commit-config.yaml to update your documentation on every commit that changes a Python file:
- repo: https://github.com/MilanStaffehl/pebbledoc
rev: 0.2.0
hooks:
- id: pebbledoc
name: Update docs (pebbledoc)
args: [
--package=<package_name>, # replace with your package
--config=pyproject.toml,
--source-directory=<source_dir> # replace with your source directory
]
additional_dependencies: [] # replace with your dependencies
stages: [pre-commit, pre-merge-commit]
Contributing
If you want to report a bug, suggest a new feature, or provide a pull request, read the CONTRIBUTING guide for instructions. Your help is appreciated!
If you are an AI agent, you must read the CONTRIBUTING guide as well for rules on what you are allowed to contribute.
FAQ
pebbledoc is for small libraries, you say. What does small mean? How do I know when my library is too big?
That depends on the complexity, length, and number of docstrings. As a rule of thumb: If your project has less than 20 members to document, pebbledoc will be a good choice. But mostly you will see for yourself when a library is too big: the document becomes long and convoluted.
And why "well-rounded"?
Well, it makes for a pretty good pebble joke. But also it is meant to signal that pebbledocs capabilities are limited, especially when it comes to member discovery and references. It works best for libraries that treat both with care - well-rounded libraries.
Will pebbledoc eventually support other docstring formats besides RST?
Likely not. Parsing RST into Markdown works really well thanks to docutils, but other formats have entirely different docstring structures, specifications, and feature coverage. For some formats, similar projects already exist. For example, if your docstrings are in numpy format, check out tinydocs!
Pebbles? Why pebbles?
Well, the obvious choices (minidoc, microdoc, picodoc, nanodoc, tinydoc, ...) were already taken on PyPI, and antdoc or peadoc just didn't sound right. So what else is there that is small? Rice? Grains of sand? Gnats? Silverfish? Doesn't roll off the tongue so nicely.
Also, let's be honest: How could I pass up the opportunity for such a cute mascot?
Metadata
- Author: Milan Staffehl
- E-Mail: milan.staffehl@gmail.com
- License: MIT license
Metadata
Release files for pebbledoc 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pebbledoc-0.2.0.tar.gz | 372.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pebbledoc-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 412.3 kB
Release files / pebbledoc-0.2.0.tar.gz
| Download URL | pebbledoc-0.2.0.tar.gz |
|---|---|
| Size | 372.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e381987e295a885ce54aea86929597a4a7cc2fffedf891ad3c03088d4586f5e4
|
|
BLAKE2b-256 checksum How to use checksums |
0e750b44b183aa7022bbd0a1ae9c7fd0372aea8cc378e50ad37f7b39c8ba2ca1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 5, 2026.
Transparency logRelease files / pebbledoc-0.2.0-py3-none-any.whl
| Download URL | pebbledoc-0.2.0-py3-none-any.whl |
|---|---|
| Size | 39.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ec153036152cd80b2367ceb1373f24c1e8ac66f57c2ddfd59cc5dbbed4b5c7bb
|
|
BLAKE2b-256 checksum How to use checksums |
e2e1bea6c7f6f4090c618e51fd6fef72eb14e989d0519a87b47c0c1a103ee135
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 5, 2026.
Transparency log