Source links
Griffe records the file path and the first and last line of every object it finds. Each object can
then link straight to the code that defines it. Set sourceLink on a package and every heading gets a
View source link:
import starlight from '@astrojs/starlight';import { defineConfig } from 'astro/config';import starlightPydocs from 'starlight-pydocs';
export default defineConfig({ integrations: [ starlight({ title: 'My docs', plugins: [ starlightPydocs({ packages: [ { name: 'mypkg', search: ['../src'],
// Paths are relative to the repository root. sourceLink: { host: 'github', repo: 'you/mypkg', ref: 'main', root: '..', }, }, ], }), ], }), ],});host picks a forge’s URL layout. repo is the owner/name slug. ref is the branch or tag to
link at. root is the directory the URL paths are computed against, and most configurations get
this wrong; see below.
Forge presets
Section titled “Forge presets”Three hosts have presets. host must be one of them. Any other value is a configuration error. For
any other forge, use a template.
host |
URL shape |
|---|---|
github |
https://github.com/{repo}/blob/{ref}/{path}#L{start}-L{end} |
gitlab |
https://gitlab.com/{repo}/-/blob/{ref}/{path}#L{start}-{end} |
bitbucket |
https://bitbucket.org/{repo}/src/{ref}/{path}#lines-{start}:{end} |
ref defaults to main. Point it at a tag to pin the links to a release, or at a branch to keep
them current.
root, and why you probably need it
Section titled “root, and why you probably need it”Griffe reports file paths relative to the directory it ran in, which is the Astro project root.
These paths are repository-relative only when the project root and the repository root are the
same directory. A documentation site in docs/, with its Python sources one level up, gets paths
that are not repository-relative. When the sources are outside the project entirely, the paths are
absolute.
This is the common layout:
Directorysrc/
Directorymypkg/
- report.py a link should point here
Directorydocs/ the Astro project, where griffe runs
- astro.config.mjs
Directorysrc/
- …
- pyproject.toml
root names the directory that {path} is computed against. This directory is itself relative to
the Astro project root. For this layout, the repository root is one level up:
6 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: '..', }, },7 collapsed lines
], }), ], sidebar: [{ label: 'API reference', items: [pydocsSidebarGroup] }], }), ],});With root: '..', {path} becomes src/mypkg/report.py. This is what the forge expects. Without
root, the link would point at mypkg/report.py, or it would carry the absolute path of the
machine that ran the build.
Set root to your repository root whenever the Astro project is a subdirectory. This
documentation site does exactly that.
A template of your own
Section titled “A template of your own”For a self-hosted forge, Gitea, Sourcehut, or an internal code browser, give a template instead of a host.
6 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: { template: 'https://git.internal.example/mypkg/-/blob/{ref}/{path}#L{start}-L{end}', ref: 'v2.1.0', root: '..', },8 collapsed lines
}, ], }), ], sidebar: [{ label: 'API reference', items: [pydocsSidebarGroup] }], }), ],});| Placeholder | Value |
|---|---|
{path} |
Path of the file the object is defined in |
{start} |
First line of the object |
{end} |
Last line of the object, or the first when griffe knows only one |
{ref} |
The ref option |
{path} is required. A template without it is a configuration error, because a link to a whole
repository is not a source link. The other placeholders are optional. Drop the line fragment if
your browser does not support line anchors. Paths always use forward slashes, regardless of the
operating system the build ran on.
What renders
Section titled “What renders”Each documented object gets a link next to its heading. The link’s title shows the file and line
range:
<a class="pyd-source-link" href="https://github.com/you/mypkg/blob/main/src/mypkg/report.py#L57-L160" title="src/mypkg/report.py:57-160">View source</a>The label comes from the viewSource string. It follows the site’s locale, and you can replace it
per component with labels={{ viewSource: 'Source' }}.
Without any configuration
Section titled “Without any configuration”Griffe 2 records a source_link per object: a blob URL at the commit it extracted from, derived
from the repository’s own git remote. When you don’t configure sourceLink, starlight-pydocs uses
that link as-is. It needs no configuration from you, but it has two limits. First, it is pinned to
the commit that was checked out when the dump was made. Second, it only exists when griffe ran
inside a git checkout with a recognisable remote, so a pre-generated dump from someone else’s CI
may or may not carry one.
That second limit is why an explicit sourceLink with an explicit ref is the safer choice.
Griffe detects the ref for itself in a git checkout. A build from a git archive, such as a source
tarball with no .git directory, has nothing to detect, so the links disappear. Configuring
sourceLink also gives you links that follow a branch or a tag, and it lets you point links at a
remote other than the one griffe happened to see.