bundles / papyri latest / docs
Doc
Papyri configuration reference
docs/configuration
papyri gen is driven by a TOML configuration file — one file per library. The file has two top-level sections:
[global]— controls howpapyri gencollects and processes the library. All keys described below live here unless stated otherwise.[meta]— human-readable metadata attached to the published bundle (URLs, PyPI slug, version tag).
The module key inside [global] is the only required key. Everything else has a sensible default or is simply omitted when not needed.
Minimal example
[global] module = 'mylib' [meta] github_slug = 'myorg/mylib' tag = 'v{version}' pypi = 'mylib'
Running papyri gen mylib.toml against this file discovers mylib, processes every public object it finds, executes the docstring examples, and writes the DocBundle to ~/.papyri/data/mylib_<version>/.
[global] reference
module
Type: str — required
The importable root package name. papyri gen imports this name and walks its public API.
module = 'numpy' submodules
Type: list[str] — default []
Extra submodules to collect in addition to the root. Use this when public objects live under subpackages that are not reachable just by importing the root. Names are relative to module; 'fft' means numpy.fft.
submodules = ['core', 'fft', 'linalg', 'ma', 'random'] execute_doctests
Type: bool — default true
Whether to attempt to execute the code examples found in docstrings. Set to false to skip execution entirely (faster builds, no side-effects). execute_exclude_patterns and exclude_jedi refine which objects are executed when this is true.
Can be overridden on the command line with --exec / --no-exec.
execute_doctests = false exec_failure
Type: 'raise' | 'fallback' | null — default null
Controls what happens when a docstring example raises an exception during execution.
'raise'Re-raise the exception; the whole gen run aborts unless the object is listed in
expected_errors.'fallback'Log the failure and continue; the example is stored unevaluated. Recommended for large third-party libraries where some examples are known to break outside their own test environment.
omitted /
nullSame as
'raise'.
exec_failure = 'fallback' execute_exclude_patterns
Type: list[str] — default []
Qualified name prefixes (dotted, with optional :-separated attribute path) whose docstring examples must not be executed. Matching uses str.startswith, so 'numpy._' excludes every private submodule of numpy.
Use this instead of exclude when you only want to skip execution but still want the object documented in the bundle.
execute_exclude_patterns = [ 'numpy._', # all private submodules 'numpy.testing._priv', # a specific private subpackage 'numpy.errstate', # a single class 'numpy.core._multiarray_umath.bincount', # a single function ]
exclude
Type: list[str] — default []
Fully-qualified names of objects to omit entirely from the bundle. The format is 'package.module:ClassName' or 'package.module'. Objects in this list are not collected, not executed, and not written to the IR.
exclude = [ 'numpy:tensordot', 'numpy.ma.core:MaskedArray.resize', ]
exclude_jedi
Type: list[str] — default []
Qualified names for which Jedi type-inference should be skipped. Use when Jedi hangs, crashes, or produces wrong results for a specific object. The object is still collected and executed (unless also in exclude or execute_exclude_patterns); only the Jedi inference step is bypassed.
exclude_jedi = [ 'scipy.linalg._sketches.clarkson_woodruff_transform', 'scipy.optimize._lsq.least_squares.least_squares', ]
jedi_failure_mode
Type: 'log' | 'raise' | null — default null
Controls what happens when Jedi raises an error for an object that is not in exclude_jedi.
'log'Log the error and continue.
'raise'Re-raise the error.
omitted /
nullSilently ignore.
jedi_failure_mode = 'log' infer
Type: bool — default true
Whether to run Jedi type-inference on code examples at all. When false, no Jedi calls are made and exclude_jedi has no effect.
Can be overridden on the command line with --infer / --no-infer.
infer = false early_error
Type: bool — default true
When true, the gen run aborts on the first unexpected error (i.e., any error not listed in expected_errors). Set to false to collect all errors and print a summary at the end.
Can be overridden on the command line with --fail-early.
early_error = false [global.expected_errors]
Type: dict[str, list[str]] — default {}
A mapping from exception class names to lists of fully-qualified object names that are expected to raise that exception during generation.
If a listed object does not raise the expected exception, the gen run fails.
If an object raises an exception whose class is not listed here, it is treated as an unexpected error (subject to
early_errorandexec_failure).
Use this to document known upstream issues without failing the build.
[global.expected_errors] VisitCitationReferenceNotImplementedError = [ 'numpy.fft', ] WrongTypeAtField = [ 'scipy.signal._ltisys:StateSpace', 'scipy.signal._ltisys:TransferFunction', ] IncorrectInternalDocsLen = [ 'matplotlib.dates:ConciseDateFormatter', ] AssertionError = [ 'scipy.optimize._linprog_ip:_ip_hsd', ] NumpydocParseError = [ 'distributed.client:default_client', ]
[global.implied_imports]
Type: dict[str, str] — default {}
Namespace aliases that are pre-imported before each example block is executed, so that short names used in examples resolve correctly.
Format
alias = 'package' # equivalent to: import package as alias alias = 'package:name' # equivalent to: from package import name as alias
Without this, examples like np.array([1, 2, 3]) fail because np is not in scope.
[global.implied_imports] np = 'numpy' pd = 'pandas' plt = 'matplotlib.pyplot' xr = 'xarray' get_ipython = 'IPython:get_ipython'
docs_path
Type: str | null — default null
Filesystem path to the narrative documentation source tree (the directory containing .rst files). ~ is expanded. When set, papyri gen walks this tree and includes the narrative pages in the bundle.
docs_path = '~/dev/numpy/doc/source' narrative_exclude
Type: list[str] — default []
Path fragments to skip inside docs_path. Any .rst file whose path contains one of these strings is excluded from the bundle.
narrative_exclude = [ 'doc/source/reference/arrays.ndarray.rst', 'doc/source/_templates/', 'doc/source/user/how-to-how-to.rst', ]
examples_folder
Type: str | null — default null
Filesystem path to a directory of Python example scripts to include in the bundle. ~ is expanded. The scripts are executed and their outputs (including plots) are captured.
examples_folder = '~/dev/matplotlib/examples/' examples_exclude
Type: list[str] — default []
Relative paths (inside examples_folder) to skip. The match is a suffix test against the example file's path string.
examples_exclude = [ 'logos2.py', 'multipage_pdf.py', 'units/artist_tests.py', ]
logo
Type: str | null — default null
Path to the package logo, relative to the config file. The logo is embedded in the bundle and displayed by the viewer.
logo = 'img/numpy_logo.png' wait_for_plt_show
Type: bool | null — default true
When true, papyri waits for matplotlib.pyplot.show() calls inside example blocks to complete before moving on, ensuring that figure output is captured. Set to false when matplotlib examples do not call plt.show() or when captures are handled another way.
wait_for_plt_show = false source
Type: str | null — default null
URL of the project's source repository. Informational; stored in the bundle metadata.
source = 'https://github.com/numpy/numpy' homepage
Type: str | null — default null
URL of the project's homepage. Informational; stored in the bundle metadata. If present in both [global] and [meta], the [meta] value is authoritative for the viewer.
homepage = 'https://numpy.org' docs
Type: str | null — default null
URL of the project's official rendered documentation. Informational; stored in the bundle metadata.
docs = 'https://numpy.org/doc/stable/' [global.directives]
Type: dict[str, str] — default {}
Custom RST directive handlers to register for this bundle. Keys are directive names as they appear in RST (e.g. mydirective for .. mydirective::); values are 'module:callable' strings pointing to the handler function.
[global.directives] mydirective = 'mylib.docs:_mydirective_handler'
To silently drop a directive instead of raising an error, map it to papyri.directives:drop:
[global.directives] testsetup = 'papyri.directives:drop' testcleanup = 'papyri.directives:drop' plot = 'papyri.directives:drop'
The handler callable must accept (argument, options, content) and return an IR node or None.
[meta] reference
The [meta] section holds metadata attached verbatim to the published bundle. All keys are optional but recommended for bundles intended for public consumption.
github_slug
Type: str
owner/repo slug of the project's GitHub repository. Used by papyri to construct links to source files and issues.
github_slug = 'numpy/numpy' tag
Type: str
Git tag template for this bundle's release. {version} is interpolated with the package version at gen time; {{version}} produces a literal {version} in the tag string (useful when the upstream tag format already contains braces).
tag = 'v{version}' # → v1.26.4 tag = '{{version}}' # → {version} tag = 'networkx-{version}' # → networkx-2.7.1
pypi
Type: str
PyPI distribution name. Used to construct links to the package on PyPI.
pypi = 'numpy' homepage
Type: str
URL of the project's homepage.
homepage = 'https://numpy.org/' docspage
Type: str
URL of the project's official documentation.
docspage = 'https://numpy.org/doc/1.26/' papyri gen CLI reference
All options override or supplement the TOML config.
papyri gen [OPTIONS] FILEOption | Default | Description |
|---|---|---|
| — | Path to the |
|
| Override |
| config value | Override |
|
| Enable debug-level logging. |
|
| Disable progress bars (useful in CI or with |
|
| Parse and collect, but do not write any output to disk. |
|
| Include / skip the API documentation pass. |
|
| Include / skip the examples pass. |
|
| Include / skip the narrative documentation pass. |
|
| Fail on the first error encountered. |
|
| Override |
|
| Fail if any exception type not listed in |
| all objects | Restrict generation to this qualified name (repeatable). |
|
| After generation, upload the bundle to |
|
| After generation, write a |
Environment variables read by --upload:
Variable | Description |
|---|---|
| Viewer ingest endpoint (default: |
| Bearer token for the ingest endpoint. Overridden by a named target's token or keychain entry if |
~/.papyri/config.toml — user upload config
papyri upload reads an optional user-level config file at ~/.papyri/config.toml. It lets you define named upload targets so you can type papyri upload --to staging instead of repeating a long URL and token on every invocation.
The file is separate from the per-library TOML config used by papyri gen.
# ~/.papyri/config.toml [upload] # Optional: use this target when --to is not given. default_target = "localhost" # ── targets ──────────────────────────────────────────────────────────── [upload.targets.localhost] url = "http://localhost:4321/api/bundle" # No token needed for a local dev instance. [upload.targets.staging] url = "https://staging.example.com/api/bundle" token = "my-staging-token" # plain-text — OK for dev/staging [upload.targets.production] url = "https://docs.example.com/api/bundle" keychain = true # read token from system keychain
[upload.targets.<name>] keys
Key | Required | Description |
|---|---|---|
| yes | Full URL of the viewer's |
| no | Bearer token as plain text. Cannot be combined with |
| no | When |
[upload] keys
Key | Description |
|---|---|
| Name of the target to use when |
Storing tokens in the system keychain
Setting keychain = true in a target tells papyri upload to look up the bearer token from the OS credential store at upload time, rather than storing it in the config file. The lookup uses the keyring package (macOS Keychain, Windows Credential Manager, Linux Secret Service / KWallet).
Install keyring support:
pip install "papyri[keychain]"Store a token (run once per machine / token rotation):
python -m keyring set papyri <target-name> # e.g. python -m keyring set papyri production
You will be prompted for the token value. It is then encrypted and stored in the OS credential store; papyri upload retrieves it automatically. The token never appears in ~/.papyri/config.toml.
If keyring is not installed or no entry is found, the upload fails with a clear message explaining the fix.
papyri upload CLI reference
papyri upload [OPTIONS] PATH [PATH ...]Each PATH may be a .papyri artifact (from papyri pack), a .zip containing exactly one .papyri artifact, or a DocBundle directory (packed on the fly).
Option | Default | Description |
|---|---|---|
| — | Named target from |
| see below | Viewer ingest endpoint. Overrides |
| see below | Bearer token. Overrides |
|
| Show per-step packing progress when building a bundle on the fly. |
URL resolution order (first match wins):
--urlflag--totarget'surl(ordefault_targetfrom config if--tois omitted)$PAPYRI_UPLOAD_URLenvironment variablehttp://localhost:4321/api/bundle
Token resolution order (first match wins):
--tokenflag--totarget'stoken/keychainentry$PAPYRI_UPLOAD_TOKENenvironment variable(no token — omit the ``Authorization`` header)
Typical workflows:
# Local dev (no config needed — hits localhost by default). papyri upload ~/.papyri/data/mylib_1.0/ # Named target from config (URL + token resolved automatically). papyri upload --to staging mylib-1.0.papyri # Named target but override URL for a one-off. papyri upload --to production --url https://override.example.com/api/bundle mylib.papyri # One-off with explicit credentials (no config file needed). papyri upload --url https://docs.example.com/api/bundle --token $MY_TOKEN mylib.papyri
papyri pack CLI reference
papyri pack [OPTIONS] [BUNDLE_DIR]Validates a DocBundle directory and writes a deterministic .papyri artifact (gzipped canonical-CBOR Bundle node). Running pack twice on the same input produces byte-identical output. If BUNDLE_DIR is omitted, every directory under ~/.papyri/data/ is packed in turn.
Option | Default | Description |
|---|---|---|
| all bundles under | DocBundle directory to pack. |
|
| Output file or directory (single-bundle mode only). |
|
| Show per-step progress. |
Full annotated example
The following file shows every [global] key in one place.
[global] # ── required ─────────────────────────────────────────────────────────── module = 'mylib' # ── discovery ────────────────────────────────────────────────────────── submodules = ['io', 'utils'] # Completely skip these objects (no collection, no execution, no IR entry). exclude = [ 'mylib.internal:_PrivateHelper', 'mylib.compat', ] # ── doctest execution ─────────────────────────────────────────────────── execute_doctests = true # What to do when a doctest raises unexpectedly: 'raise' or 'fallback'. exec_failure = 'fallback' # Skip execution for these prefixes (object still documented). execute_exclude_patterns = [ 'mylib._', # all private submodules 'mylib.heavy:slow_function', # a specific function ] # Skip Jedi inference for objects where it hangs or crashes. exclude_jedi = [ 'mylib.ffi:RawPointer', ] # What to do when Jedi errors: 'log' or 'raise'. jedi_failure_mode = 'log' # Run Jedi at all? infer = true # Wait for plt.show() before capturing figure output. wait_for_plt_show = true # ── error handling ────────────────────────────────────────────────────── # Abort on first unexpected error (override with --fail-early). early_error = false # ── narrative docs ────────────────────────────────────────────────────── docs_path = '~/dev/mylib/docs/source' narrative_exclude = [ '_build/', '_templates/', 'api/generated/', ] # ── examples ──────────────────────────────────────────────────────────── examples_folder = '~/dev/mylib/examples/' examples_exclude = [ 'slow_demo.py', 'requires_gpu/demo.py', ] # ── appearance ─────────────────────────────────────────────────────────── logo = 'img/mylib_logo.png' # ── informational URLs ─────────────────────────────────────────────────── source = 'https://github.com/myorg/mylib' homepage = 'https://mylib.readthedocs.io/' docs = 'https://mylib.readthedocs.io/en/stable/' # ── pre-imported aliases for example execution ─────────────────────────── [global.implied_imports] ml = 'mylib' np = 'numpy' pd = 'pandas' # ── known failures (build succeeds despite these errors) ───────────────── [global.expected_errors] WrongTypeAtField = [ 'mylib.io:read_csv', ] IncorrectInternalDocsLen = [ 'mylib.utils:_internal_helper', ] # ── custom RST directives ───────────────────────────────────────────────── [global.directives] myspecial = 'mylib.docs:_myspecial_handler' testsetup = 'papyri.directives:drop' testcleanup = 'papyri.directives:drop' # ── bundle metadata ─────────────────────────────────────────────────────── [meta] github_slug = 'myorg/mylib' tag = 'v{version}' pypi = 'mylib' homepage = 'https://mylib.readthedocs.io/' docspage = 'https://mylib.readthedocs.io/en/stable/'