Getting started
Name a Python package. The plugin generates an API reference page for each of its modules. The pages appear in the Starlight sidebar as a tree that mirrors the package layout, and the site’s own search indexes them like any other page.
Griffe extracts the API. It reads the package’s source files directly and never imports them. So the machine that builds your docs does not need a working install of the package it documents.
-
Install the plugin.
npm install starlight-pydocspnpm add starlight-pydocsyarn add starlight-pydocs -
Check that the build process can run Griffe.
By default, the plugin runs Griffe at site build time to read your package. We recommend uv for this. The plugin uses
uvautomatically when it is on yourPATH. Otherwise, it falls back topython -m griffe.You can also run Griffe separately and point the plugin at the JSON file it writes. See Without Python for more information.
Terminal window # Check if uv is availableuv --version# If not, on macOS and Linux:curl -LsSf https://astral.sh/uv/install.sh | sh -
Add the plugin to Starlight, name the package, and reserve a spot in the sidebar for the pages it will generate.
astro.config.mjs import starlight from '@astrojs/starlight';import { defineConfig } from 'astro/config';import starlightPydocs, { pydocsSidebarGroup } from 'starlight-pydocs';export default defineConfig({integrations: [starlight({title: 'My project',// Name the package and point griffe at its source.plugins: [starlightPydocs({packages: [{ name: 'mypkg', search: ['../src'] }],}),],// Reserve the sidebar spot for the generated pages.sidebar: [{ label: 'API reference', items: [pydocsSidebarGroup] }],}),],});Starlight reads the sidebar from your config before the plugin parses the package. At that point, Starlight does not yet know what pages exist.
pydocsSidebarGroupis an empty group that holds a place in the tree. Route middleware replaces it with the generated links when each page renders. Put it wherever you want the API reference to appear.searchis the list of directories passed togriffe --search. It is relative to the Astro project root. Point it at the parent of the package directory: use../srcfor../src/mypkg. -
Start the dev server.
npm run dev/api/mypkg/now exists. This page documents the package’s top-level module, and the plugin creates one page per submodule below it. The API reference group in the sidebar is now filled in.Every class, function and attribute has an anchor named after its dotted path. For example,
/api/mypkg/report/#mypkg.report.Report.generatelinks straight to one method.
Each package also gets three files, served next to its pages. symbols.json is the
index behind symbol search. objects.inv is a
Sphinx inventory: it lets other projects link into
yours. And
llms.txt is the whole surface as plain
Markdown.
Docstring style
Section titled “Docstring style”Set this now if your docstrings are not google style. Griffe parses one flavour per package and does not guess. The wrong style leaves parameters and return values as plain, undifferentiated prose.
8 collapsed lines
import starlight from '@astrojs/starlight';import { defineConfig } from 'astro/config';import starlightPydocs, { pydocsSidebarGroup } from 'starlight-pydocs';
export default defineConfig({ integrations: [ starlight({ title: 'My project', plugins: [ starlightPydocs({ packages: [ { name: 'mypkg', search: ['../src'], docstringStyle: 'numpy', }, ],6 collapsed lines
}), ], sidebar: [{ label: 'API reference', items: [pydocsSidebarGroup] }], }), ],});The default is google. numpy and sphinx are the alternatives. auto lets griffe
guess the style per docstring: use it for a package whose docstrings disagree with
each other. Docstring styles covers
which sections each style recognises.
Linking to other projects
Section titled “Linking to other projects”Add this once the pages exist. Type annotations that name something outside your
package, such as pathlib.Path or a pandas DataFrame, render as plain text. To link
them, give the plugin a Sphinx inventory to resolve them against. An inventory is the
objects.inv file that most Python documentation sites publish. It maps object paths
to page URLs.
8 collapsed lines
import starlight from '@astrojs/starlight';import { defineConfig } from 'astro/config';import starlightPydocs, { pydocsSidebarGroup } from 'starlight-pydocs';
export default defineConfig({ integrations: [ starlight({ title: 'My project', plugins: [ starlightPydocs({ packages: [{ name: 'mypkg', search: ['../src'] }], inventories: [ 'python', { url: 'https://pandas.pydata.org/docs/objects.inv' }, { file: './vendor/internal.inv', base: 'https://docs.internal.example/' }, ],6 collapsed lines
}), ], sidebar: [{ label: 'API reference', items: [pydocsSidebarGroup] }], }), ],});inventories is a top-level option, shared by every package. 'python' is a preset
for the CPython standard library. Any other project that publishes an objects.inv
file works too, by URL or as a local file.
base is the URL that the inventory’s relative links resolve against. It defaults to
the objects.inv URL with its last segment removed. Set it explicitly for a local
file, because a local file has no URL to derive it from.
Source links
Section titled “Source links”Give the plugin your forge. Then every documented object links to the lines where it is defined.
8 collapsed lines
import starlight from '@astrojs/starlight';import { defineConfig } from 'astro/config';import starlightPydocs, { pydocsSidebarGroup } from 'starlight-pydocs';
export default defineConfig({ integrations: [ starlight({ title: 'My project', plugins: [ starlightPydocs({ packages: [ { name: 'mypkg', search: ['../src'], sourceLink: { host: 'github', repo: 'you/mypkg', ref: 'main', root: '..', }, }, ],6 collapsed lines
}), ], sidebar: [{ label: 'API reference', items: [pydocsSidebarGroup] }], }), ],});host is github, gitlab or bitbucket. root is the directory that the paths in
the URL are relative to. Set it to your repository root when the Astro project is a
subdirectory, as it is for a docs/ site. For forges without a preset, use a URL
template instead. See Source links.
Without Python
Section titled “Without Python”If the build machine has no Python, or you would rather not run extraction on every docs build, generate the dump where the package already lives. Run this in the Python project. It writes exactly the JSON that the plugin would otherwise produce itself:
griffe dump -f -d google --search src mypkg -o mypkg.jsonPublish mypkg.json from the Python project’s CI. Then fetch it into your Astro
project before the docs build. The example below uses api/mypkg.json, a path
resolved against the Astro project root. The package entry then points at that copy
instead of a search path:
packages: [ { name: 'mypkg', search: ['../src'] }, { name: 'mypkg', source: { file: './api/mypkg.json' } },];source: { url: '…' } fetches it instead. It revalidates the cached copy with its
ETag, so it does not re-download on every build. Pre-generated
dumps covers the CI side of this.