Status: Needs Review
This page has not been reviewed for accuracy and completeness. Content may be outdated or contain errors.
CUV¶
IS.AI Documentation Guidelines
Created: 2026-02-05 Last Updated: 2026-02-05
Table of Contents¶
- Documentation Philosophy
- Documentation Architecture
- Docstring Guidelines
- Maintaining Curated API Pages
- Adding New Modules
- Missing Anchor Fix Strategy
- Build and Verification
Documentation Philosophy¶
Following PyTorch's Model¶
Cuvis.AI follows the PyTorch documentation model:
"Autosummary generates concise summary tables for modules, classes, and functions... making it easier for users to get an overview of the API. Autodoc generates a one pager documentation for all functions in a class which is often overwhelming and hard for users to read. In most cases, autosummary is a better way of organizing API documentation."
Core Principles¶
- Hybrid Approach: Combine hand-written structure with auto-generated content
- User-Centered: Organize documentation for discoverability, not just completeness
- Single Source of Truth: Docstrings in code are the authoritative source
- Stay Current: Documentation auto-updates when code docstrings change
- Meaningful Organization: Group by functionality, not just alphabetically
Documentation Architecture¶
Two-Layer System¶
┌─────────────────────────────────────────────────────────────┐
│ Layer 1: Curated Pages (Manual Structure) │
│ - docs/catalogs/nodes/*.md │
│ - docs/reference/python-api/*.md │
│ - Organized categories, context, navigation │
│ - Uses ::: directives to pull API content │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 2: Python Docstrings (Auto-Generated Content) │
│ - cuvis_ai/anomaly/rx_detector.py │
│ - cuvis_ai/node/losses.py │
│ - Google-style docstrings │
│ - Pulled at build time via mkdocstrings │
└─────────────────────────────────────────────────────────────┘
What's Manual vs Auto-Generated¶
| Aspect | Manual | Auto-Generated |
|---|---|---|
| Organization | ✅ Category headers, navigation | ❌ |
| Context | ✅ Overview sections, explanations | ❌ |
| API Content | ❌ | ✅ Pulled from docstrings |
| Parameter Docs | ❌ | ✅ Pulled from docstrings |
| Examples | ❌ | ✅ Pulled from docstrings |
| Stays Current | ⚠️ When adding new modules | ✅ Automatically |
Docstring Guidelines¶
Style: Google Format¶
Cuvis.AI uses Google-style docstrings (same as PyTorch).
Module-Level Docstrings¶
Purpose: Provide overview, context, and references
"""RX anomaly detection nodes for hyperspectral imaging.
This module implements the Reed-Xiaoli (RX) anomaly detection algorithm, a widely used
statistical method for detecting anomalies in hyperspectral images. The RX algorithm
computes squared Mahalanobis distance from the background distribution, treating
pixels with large distances as potential anomalies.
The module provides two variants:
- **RXGlobal**: Uses global statistics (mean, covariance) estimated from training data.
Supports two-phase training: statistical initialization followed by optional gradient-based
fine-tuning via unfreeze().
- **RXPerBatch**: Computes statistics independently for each batch on-the-fly without
requiring initialization. Useful for real-time processing or when training data is unavailable.
Examples:
Basic usage with global statistics:
```python
from cuvis_ai.anomaly.rx_detector import RXGlobal
detector = RXGlobal(
in_channels=224,
normalize=True,
epsilon=1e-6
)
```
Reference:
Reed, I. S., & Yu, X. (1990). "Adaptive multiple-band CFAR detection of an optical
pattern with unknown spectral distribution." IEEE Transactions on Acoustics, Speech,
and Signal Processing, 38(10), 1760-1770.
"""
Required Sections:
- Brief description (1-2 sentences)
- Detailed explanation
- Available classes/functions overview
- Examples (optional but recommended)
- References (for research-based implementations)
Class-Level Docstrings¶
class RXGlobal(Node):
"""RX anomaly detector using global statistics.
Computes anomaly scores using the Reed-Xiaoli (RX) algorithm with global
mean and covariance estimated during training. Supports two-phase training
where statistical initialization is followed by optional gradient-based
fine-tuning.
Attributes:
in_channels: Number of input spectral channels
normalize: Whether to normalize anomaly scores
epsilon: Small constant for numerical stability
Examples:
Create and initialize detector:
```python
detector = RXGlobal(in_channels=224)
detector.init(data_iterator)
```
"""
Method/Function Docstrings¶
def forward(self, x: torch.Tensor) -> torch.Tensor:
"""Compute RX anomaly scores.
Args:
x: Input tensor of shape (B, H, W, C) where:
- B: batch size
- H: height
- W: width
- C: channels (must equal in_channels)
Returns:
Anomaly score tensor of shape (B, H, W, 1). Higher scores
indicate greater likelihood of anomaly.
Raises:
ValueError: If input channels don't match in_channels.
RuntimeError: If detector hasn't been initialized.
"""
Required Sections:
- Brief description
- Args: All parameters with types and descriptions
- Returns: Return value with type and meaning
- Raises: Exceptions that can be raised (if applicable)
- Examples: Usage examples (optional but recommended)
Docstring Best Practices¶
- Be Specific About Tensor Shapes: Use notation like
(B, H, W, C)with legend - Explain Units: If values have units (meters, seconds, etc.), specify them
- Link Related Components: Reference related classes/functions
- Provide Context: Explain when/why to use this over alternatives
- Include Equations: For algorithms, show key equations in LaTeX
- Add Warnings: Document gotchas, performance considerations, limitations
Maintaining the Nodes Catalog¶
The Nodes catalog at docs/catalogs/nodes/index.md
is generated at build time by scripts/generate_node_catalog.py (registered
as a mkdocs-gen-files script in mkdocs.yml). Each row in the rendered page
is a collapsible <details> element keyed off the node class's metadata.
How a node enters the catalog¶
For a built-in cuvis_ai.node.<module>.ClassName:
- Add
_category = NodeCategory.<X>and_tags = frozenset({NodeTag.<...>})on the class — the generator reads these via livecls.get_category()/cls.get_tags()calls (no doc edit required). - Make sure the class has a docstring whose first non-empty line summarises what it does. That line becomes the row's collapsed summary; the full docstring is rendered inside the row by mkdocstrings when expanded.
For a plugin class in a sibling repo:
- Add the same
_category/_tagsassignments to the class. - Add an entry under
docs/data/plugin_sources.yamlpointing at the plugin repo's on-disk path and listing the dotted class names. The generator reads the source viaastand never imports the plugin — so torch / ultralytics / SAM3 dependencies stay out of the docs venv.
Don't edit the catalog page on disk¶
docs/catalogs/nodes/index.md is overridden at build time. Edits there are
silently ignored. Change the generator (scripts/generate_node_catalog.py),
the node's class attributes, or its docstring instead.
After changes, re-run the build¶
Note: mkdocs serve does not reliably auto-reload when only the
generator script changes. Restart serve after editing the generator.
Adding New Modules¶
Checklist for New Modules¶
When adding a new module to Cuvis.AI:
- Write module-level docstring with overview and examples
- Write class/function docstrings following Google style
- Add to appropriate curated page (
docs/catalogs/nodes/*.mdordocs/reference/python-api/*.md) - Place in correct category section
- Build docs locally to verify
- Check for broken cross-references
- Update related tutorial/guide if applicable
Choosing the Right Curated Page¶
| Module Type | Curated Page | Example |
|---|---|---|
| Node implementations | Auto-generated from Node._category + class docstring into docs/catalogs/nodes/index.md |
RXDetector, DeepSVDD |
| Training components | Same — set _category = NodeCategory.LOSS or NodeCategory.METRIC |
Loss functions, metrics |
| Data handling | Same — set _category = NodeCategory.SOURCE |
Datasets, data loaders |
| Pipeline building | docs/reference/python-api/pipeline.md |
Graph, Pipeline |
| Port definitions | docs/reference/python-api/ports.md |
PortSpec, StreamType |
| Utilities | docs/reference/python-api/utilities.md |
Helpers, factories |
Missing Anchor Fix Strategy¶
Understanding the Issue¶
MkDocs generates anchors from headings:
- Heading:
## Data Loading with LentilsAnomalyDataNode - Anchor:
#data-loading-with-lentilsanomalydatanode
Links break when:
- Heading doesn't exist
- Heading text doesn't match link
- Heading uses unexpected formatting
Anchor Naming Rules¶
MkDocs transforms headings to anchors by:
- Converting to lowercase
- Replacing spaces with hyphens
- Removing special characters
- Removing multiple consecutive hyphens
Examples:
| Heading | Anchor |
|---|---|
## DeepSVDD Nodes |
#deepsvdd-nodes |
## Two-Phase Training Workflow |
#two-phase-training-workflow |
## Step 1: Data Loading |
#step-1-data-loading |
Build and Verification¶
Standard Build Command¶
# Normal build (warnings displayed but not fatal)
uv run mkdocs build
# Strict build (warnings cause build failure)
uv run mkdocs build --strict
Expected Warnings¶
After fixes, expect 14 warnings for external file references:
WARNING - Doc file contains a link '../../examples/grpc/...'
WARNING - Doc file contains a link '../../configs/plugins/...'
These are acceptable - they reference legitimate source files outside docs/.
Verification Workflow¶
-
Baseline: Record current warning count
-
After changes: Rebuild and compare
-
Serve locally to visually verify:
Pre-Commit Checklist¶
Before committing documentation changes:
-
mkdocs build --strictpasses (or only expected warnings) - Docstrings follow Google style
- New modules added to curated pages
- Internal links verified
- Examples tested (if code examples included)
- Spelling checked
Quick Reference¶
Docstring Template¶
"""Brief one-line description.
Detailed multi-paragraph explanation of what this does, when to use it,
and how it fits into the larger system.
Args:
param1: Description with type info
param2: Description with type info
Returns:
Description of return value with type
Raises:
ErrorType: When this error occurs
Examples:
Basic usage:
```python
result = function(param1, param2)
```
See Also:
- RelatedClass: For related functionality
"""
Curated Page Template¶
# API Section Name
Brief introduction to this API section.
## Category 1
Description of what belongs in this category.
### Component A
::: module.path.component_a
options:
show_root_heading: true
heading_level: 4
For questions or suggestions, see: Contributing Guide