epythet.config¶
Single source of truth for a project’s documentation configuration.
Everything epythet needs to build a site comes from two places, read in this order of precedence:
pyproject.toml: the[project]table for name, version and authors, and the[tool.epythet]table for documentation choices.setup.cfg: the[metadata]section (legacy projects).
When both files exist, pyproject.toml wins as soon as it has a [project]
table. (epythet 0.1.x silently preferred setup.cfg, which was wrong for the
projects that had migrated to pyproject.toml but kept a stale setup.cfg.)
The result is a DocsConfig, an immutable dataclass. The legacy 5-tuple
accessor epythet.config_parser.parse_config() is derived from it and keeps
its signature, so old docsrc/conf.py copies keep working.
The [tool.epythet] keys, all optional:
[tool.epythet]
display_name = "Dol" # site title; default: the project name
copyright = "2024, Jane Doe" # footer line; default: none rendered
theme = "auto" # "auto" | "furo" | "shibuya" | ... | any installed theme
accent = "#3661ac" # default: derived from the package name (OKLCH)
mode = "auto" # "auto" | "light" | "dark"
ignore = ["tests/", "scrap/", "examples/"] # path substrings to skip
api_generator = "auto" # "auto" | "autosummary" (imports the package) | "autoapi" (static)
agent_outputs = true # llms.txt + .md twins of every page
aggregates = ["md"] # flat single-document twins at the site root
ai_artifacts = true # "For AI agents" page when skills/agents/CLAUDE.md exist
ai_artifacts_template = "" # project-relative file overriding that page's template
provenance = true # build footer, about-this-build page, build_info.json; "minimal": no page
provenance_template = "" # project-relative file overriding the about-this-build page template
package_dir = "src/dol" # default: found by convention
docs_dir = "docsrc" # where the Sphinx sources live
[tool.epythet.theme_options] # verbatim passthrough into html_theme_options
[tool.epythet.readme] # project override of the user-level README policy (see epythet.userconfig)
announcement = "v2 is in beta"
>>> import tempfile, pathlib
>>> d = pathlib.Path(tempfile.mkdtemp())
>>> _ = (d / "pyproject.toml").write_text('''
... [project]
... name = "my-pkg"
... version = "1.2.3"
... authors = [{name = "Jane Doe"}]
... [tool.epythet]
... theme = "furo"
... ''')
>>> _ = (d / "my_pkg").mkdir()
>>> _ = (d / "my_pkg" / "__init__.py").write_text("")
>>> cfg = load_config(d)
>>> cfg.name, cfg.version, cfg.author, cfg.theme, cfg.package_dir.name
('my-pkg', '1.2.3', 'Jane Doe', 'furo', 'my_pkg')
Module Attributes
Path substrings skipped by default when discovering modules to document. |
|
a |
|
Directory under the project root holding the Sphinx sources. |
|
Directory candidates (relative to the project root) that may hold the package. |
|
Top-level directories never taken for the package when guessing by convention. |
|
Seconds allowed for the import probe behind |
Functions
|
Locate the package directory for |
|
Read a project's documentation configuration. |
|
The generator to run: |
|
Normalise ignore patterns: each item may itself be a comma-separated list. |
Classes
|
Everything needed to generate a project's documentation. |
Exceptions
A project's documentation configuration is missing or invalid. |
- epythet.config.ALWAYS_IGNORE: tuple[str, ...] = ('__main__',)¶
a
__main__is a command line, not an API. (autosummary still imports it once while discovering the package, as it does every submodule; a__main__that runs argparse at import survives that because Sphinx turns itsSystemExitinto a skipped import.)- Type:
Modules that never get a page, whatever
ignoresays
- exception epythet.config.ConfigError[source]¶
Bases:
ValueErrorA project’s documentation configuration is missing or invalid.
- epythet.config.DEFAULT_DOCS_DIR = 'docsrc'¶
Directory under the project root holding the Sphinx sources.
- epythet.config.DEFAULT_IGNORE: tuple[str, ...] = ('tests/', 'scrap/', 'examples/')¶
Path substrings skipped by default when discovering modules to document.
- class epythet.config.DocsConfig(project_dir, name, version='', author='', description='', display_name='', copyright='', repo_url='', theme='auto', accent='', mode='auto', theme_options=<factory>, readme=<factory>, ignore=('tests/', 'scrap/', 'examples/'), api_generator='auto', agent_outputs=True, aggregates=('md', ), ai_artifacts=True, ai_artifacts_template='', provenance=True, provenance_template='', package_dir=None, docs_dir='docsrc')[source]¶
Bases:
objectEverything needed to generate a project’s documentation.
Attributes mirror the
[tool.epythet]keys; see the module docstring.project_dirandpackage_dirare absolute paths.- property api_ignore: tuple[str, ...]¶
what the API generators skip.
>>> DocsConfig(project_dir="/tmp/x", name="x", ignore=["tests/"]).api_ignore ('tests/', '__main__')
- Type:
ignoreplusALWAYS_IGNORE
- property legacy_tuple: tuple[str, str, str, str, str]¶
The 5-tuple that
epythet.config_parser.parse_config()returns.
- epythet.config.IMPORT_PROBE_TIMEOUT = 120¶
Seconds allowed for the import probe behind
api_generator = "auto".
- epythet.config.NON_PACKAGE_DIRS = frozenset({'docs', 'docsrc', 'examples', 'misc', 'scrap', 'test', 'tests'})¶
Top-level directories never taken for the package when guessing by convention.
- epythet.config.PACKAGE_DIR_CANDIDATES: tuple[str, ...] = ('{name}', 'src/{name}')¶
Directory candidates (relative to the project root) that may hold the package.
- epythet.config.find_package_dir(project_dir, name)[source]¶
Locate the package directory for
nameunderproject_dirby convention.Tries
<name>/thensrc/<name>/(with-mapped to_), returning the first that contains an__init__.py;Nonewhen nothing matches.>>> find_package_dir("/nonexistent", "nothing") is None True
- epythet.config.load_config(project_dir, **overrides)[source]¶
Read a project’s documentation configuration.
- Parameters:
- Raises:
ConfigError – when neither configuration file is found.
- Return type:
- epythet.config.resolve_api_generator(config)[source]¶
The generator to run:
autosummarywhen the package imports, elseautoapi.autosummaryimports the package and documents what it finds (aliases, partials, re-exports); when the import fails, in CI typically because an optional dependency is missing, it produces an empty API section and a successful build.autoprobes the import once, in a subprocess with the project root onsys.path(as the build has it), and falls back to the staticautoapigenerator, printing why. An explicit value is returned as is, and so is"auto"when the package directory is unknown.- Return type:
- epythet.config.split_ignore(ignore)[source]¶
Normalise ignore patterns: each item may itself be a comma-separated list.
The publish action passes its
ignoreinput verbatim as one argument,--ignore tests/,scrap/,examples/, andsetup.cfgvalues are strings; both must mean three patterns, not one that never matches.>>> split_ignore(["tests/,scrap/", " examples/ ", "", "tests/"]) ('tests/', 'scrap/', 'examples/')