Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,11 @@ Async test mode is `auto` (via `asyncio_mode = "auto"` in pyproject.toml).

```
src/nf_docs/
├── __init__.py # Version from importlib.metadata, re-exports models
├── __init__.py # Version, public API re-exports (__all__)
├── api.py # High-level library API: extract() / render() / generate()
├── cache.py # XDG-compliant caching with content hashing
├── cli.py # CLI entry point (rich-click)
├── output.py # Source/output path policy shared by the CLI and api.py (leaf module)
├── config.py # User config from ~/.config/nf-docs/config.yaml
├── config_parser.py # Parse nextflow.config via `nextflow config -flat`
├── extractor.py # Main extraction orchestration
Expand Down Expand Up @@ -216,9 +218,24 @@ src/nf_docs/
- **Rendering**: Strategy pattern via `BaseRenderer` ABC with `render()`, `render_to_file()`,
`render_to_directory()`. Factory function `get_renderer(format)` returns the appropriate renderer.
HTML uses a single Jinja2 template with inline CSS (Tailwind) and JavaScript for search. Adding a
new output format means updating `get_renderer()`, the CLI's `--format` choices, and tests.
new output format means updating `RENDERERS` in `renderers/__init__.py`,
`SINGLE_FILE_OUTPUT_POLICY` and (if it writes a directory) `DIRECTORY_FORMATS` in `output.py`, the
CLI's `--format` choices, and tests. Format aliases live only in `output.FORMAT_ALIASES`;
`get_renderer()` resolves through `normalize_format()` so there is one alias table.
- **Config parsing**: `config_parser.py` shells out to `nextflow config -flat`. `nextflow_env.py`
sets an isolated `NXF_HOME` so this doesn't pollute the user's Nextflow state.
- **Two entry points**: `cli.py` (rich-click) and `api.py` (library). All source/output path and
format decisions live in `output.py`, and `cli.py` extracts via `api.extract()`, so the two stay
in sync by construction rather than by discipline. Keep console output and `sys.exit()` in
`cli.py` only — core modules log via `logging` and raise exceptions. The CLI reads the user's
`~/.config/nf-docs/config.yaml` and passes it to `PipelineExtractor(config=...)`; `api.py` uses
`NfDocsConfig()` defaults so library calls are reproducible. There is deliberately no global
config accessor — inject an `NfDocsConfig` instead of reintroducing ambient state.
- **Public API**: everything in `nf_docs.__all__` plus `nf_docs.models`. Adding to it is a
commitment — update `docs/python-api.md` and `tests/test_api.py` alongside. `__init__.py`
re-exports eagerly, which costs ~170 ms on `import nf_docs` (it pulls in jinja2, httpx and
friends). That's deliberate: a plain import list is worth more than the startup time for a tool
that spends seconds waiting on the Language Server. Don't make it lazy.
- **Pre-commit hook entry**: `.pre-commit-hooks.yaml` exposes the CLI as the `nf-docs` hook with
default `args: [., --format, html]`, triggered by changes to `.nf`, `nextflow.config`,
`nextflow_schema.json`, `meta.yml`, or README files. Guarded by `tests/test_pre_commit_hooks.py`.
Expand Down
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Changelog

## Unreleased

### Added

- Supported Python API for using nf-docs as a library: `nf_docs.extract()`, `nf_docs.render()` and
`nf_docs.generate()`, alongside a wider set of exports from the top-level `nf_docs` namespace
- `py.typed` marker so type hints reach downstream users
- `PipelineExtractor` accepts a `config=` argument, so callers can supply an `NfDocsConfig` instead
of relying on the global instance
- New "Python API" documentation page

### Fixed

- The extraction cache is now keyed on the configuration as well as the pipeline contents.
Previously a CLI run (which loads `~/.config/nf-docs/config.yaml`) and a library call (which uses
defaults) shared a cache entry for the same unchanged pipeline and returned each other's results
- A config file containing valid YAML of the wrong shape (e.g. a top-level list) falls back to
defaults with a warning instead of raising
- `nf_docs.extract()` and `nf_docs.generate()` raise `ValueError` for a path that doesn't exist,
rather than returning an empty `Pipeline` named after the missing directory

### Changed

- Output path policy (format aliases, single-module detection, default filenames) moved from
`cli.py` into a new `nf_docs.output` module so the CLI and the Python API share one implementation
- Library callers now get `NfDocsConfig()` defaults rather than the user's
`~/.config/nf-docs/config.yaml`, which the CLI continues to read. This keeps programmatic use
reproducible.

## [Version 0.4.0](https://github.com/ewels/nf-docs/releases/tag/v0.4.0) - 2026-05-29

### Added
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
recursive-include src/nf_docs/templates *.html *.css
include src/nf_docs/py.typed
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,23 @@ nf-docs generate modules/mytool/subtools/main.nf --format md
By default this writes `README.md` next to `main.nf`. Use `--output` to pick a different path, or
`--format json` / `--format yaml` to print structured output to stdout instead.

## Use as a Python library

`nf-docs` is a CLI tool first, but it's also an importable Python package. Useful for feeding
pipeline data into your own tooling, or generating docs as part of a site build:

```python
import nf_docs

pipeline = nf_docs.extract("./my_pipeline")
print([p.name for p in pipeline.processes])

markdown = nf_docs.render(pipeline, "markdown")
files = nf_docs.generate("./my_pipeline", output_format="html", output="site/")
```

See the [Python API docs](https://ewels.github.io/nf-docs/python-api/) for the full reference.

## Prek / pre-commit hook

`nf-docs` can generate pipeline documentation automatically before each commit using
Expand Down
Loading