npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vantagecompute/docusaurus-plugin-pydoc

v0.1.2

Published

Docusaurus plugin that auto-generates SDK reference docs from Python docstrings, by parsing source rather than importing it

Downloads

55

Readme

@vantagecompute/docusaurus-plugin-pydoc

Docusaurus plugin that generates an SDK reference from Python docstrings.

The Python counterpart to @vantagecompute/docusaurus-plugin-godoc, with the same option shape and the same page furniture, so a reader moving between a Go spoke and a Python spoke on docs.vantagecompute.ai sees the same thing in the same places.

It parses, it does not import

Most Python autodoc tooling imports the module it documents. This does not, and that is the main design decision in the package:

  • Importing runs the module. A docs build that imports the project inherits every import-time side effect that project has, and a project that reads configuration at import time cannot be documented at all without supplying that configuration.
  • Importing needs the dependency tree installed and importable in whatever interpreter the docs build uses. Parsing needs only the source, so the plugin runs under any modern python3 rather than the project's own virtualenv.
  • An import failure is hard to attribute. A parse failure is local to one file and names that file.

The cost is that anything only knowable at runtime is invisible: attributes attached dynamically, values computed by decorators, members inherited from a base class in another module. For documenting hand-written docstrings, that trade is worth taking.

Install

yarn add -D @vantagecompute/docusaurus-plugin-pydoc

Published to npm from a tag by publish.yml, with provenance: every release is signed with the workflow and commit it was built from, so a consumer can check that the tarball came from this repository rather than from someone with a token.

A git dependency on a tag still works and needs no build step, since there is nothing to compile and no prepare script:

yarn add -D "@vantagecompute/docusaurus-plugin-pydoc@git+https://github.com/vantagecompute/docusaurus-plugin-pydoc.git#v0.1.1"

Reach for that when you need an unreleased commit. Prefer npm otherwise: it is the version with provenance attached, and a git dependency over SSH needs a key on every CI runner that installs it.

The introspector runs under python3 from PATH. It uses only the standard library.

Use

// docusaurus.config.ts
import * as path from 'path';

plugins: [
  [
    '@vantagecompute/docusaurus-plugin-pydoc',
    {
      projectRoot: path.join(__dirname, '..'),
      modules: [
        {module: 'myproject.app', label: 'app'},
        {module: 'myproject.auth', label: 'auth'},
      ],
      outputDir: './docs/sdk-reference',
      label: 'myproject',
      position: 1,
    },
  ],
],

| Option | Default | Meaning | |---|---|---| | projectRoot | required | Project root, relative to the Docusaurus site directory. Both a src/ layout and a package at the root are found without configuration. | | modules | [] | Dotted module names to document. A bare string works; {module, label} sets the display name. | | outputDir | ./docs/sdk-reference | Where pages are written. One page per module, plus index.md. | | label | SDK Reference | Title of the generated index page, and so the sidebar label of the category built from outputDir. Set it per instance when a site runs more than one. | | position | none | sidebar_position for that category. Absent, sibling categories are ordered alphabetically by directory name. | | python | python3 | Interpreter used to run the introspector. It never imports your project, so this need not be your virtualenv. | | strict | true | Fail the build on an introspection failure. See below. |

The sidebar is generated, so the front matter has to carry it

Docusaurus builds an autogenerated sidebar from the files on disk, and it reads the sidebar label and the ordering out of each page's front matter. The generator therefore emits both:

  • sidebar_label is the bare module label. title keeps its Module: prefix, because a browser tab and a search result want the longer form; a sidebar does not. Falling back to title puts a column of identical prefixes down the nav and pushes the part that distinguishes one entry from the next past the edge of a narrow sidebar.
  • sidebar_position is the module's index in the configured modules list. That list is usually ordered to read as an introduction -- settings, then auth, then the clients that use both. Without a position, Docusaurus orders alphabetically by filename and the reader gets aggregate, attachments, auth instead.

The index page carries label and position for the same reason, and it carries them for the category, not only for itself: Docusaurus consumes index.md as the category index for its directory and defaults the category's label and position to that document's. A site running one instance of this plugin per package needs that, or every one of those categories is labelled SDK Reference and the reader gets identically named siblings with no way to tell which package each holds.

No _category_.json is written. One generated page carrying its own front matter is a smaller contract with the consuming site than a second generated file it has to know about.

Failing loudly is the default

strict: true means an introspection failure fails the build, and a run in which every requested module documented zero classes and zero functions also fails the build. That second check exists because the usual cause is a wrong projectRoot or a src/ layout mismatch, not genuinely empty modules.

This is a deliberate difference from the Go sibling, which warns and continues on a per-package failure. That behaviour means a missing toolchain or a bad credential produces a green build that publishes a reference with nothing in it, and every consuming repository has to add its own verification step to notice. Failing the build is the behaviour that needs no workaround downstream.

Set strict: false if you want warn-and-continue anyway.

What appears in the output

Per module: the module docstring as an Overview, public upper-case module constants, public classes with their bases, decorators, annotated attributes and public methods, and public module-level functions. Signatures are rendered from source, so annotations, defaults, positional-only and keyword-only markers, *args and **kwargs all survive.

A name starting with an underscore is private and skipped, except for the dunders worth documenting when they carry a docstring: __init__, __call__, and the sync and async context-manager pairs.

Docstrings are emitted verbatim. They are prose written by the same people who wrote the code, and reflowing them here would mangle the indented blocks, tables and reStructuredText roles many of them contain.

Standalone use

Without a Docusaurus build:

node node_modules/@vantagecompute/docusaurus-plugin-pydoc/src/generate.js \
  --project-root .. \
  --output-dir ./docs/sdk-reference \
  --modules myproject.app,myproject.auth \
  --label myproject --position 1

Or the introspector alone, which prints JSON and is the thing to reach for when the rendered output looks wrong and you want to see what was actually extracted:

python3 node_modules/@vantagecompute/docusaurus-plugin-pydoc/src/introspect.py \
  --root .. --module myproject.app

Releasing

just release 0.1.1 bumps, tags, pushes and creates the GitHub release. Publishing that release to npm is publish.yml, which runs on release: published and can also be fired by hand against a tag.

It publishes with --provenance, which needs id-token: write on the job and a release built by Actions rather than from a laptop. That is the reason to keep publishing here rather than running npm publish locally: a local publish is unattested, and once one version in a package is unattested the guarantee is only as good as the weakest release.

License

MIT