Sphinx Integration
Cyclopts provides builtin Sphinx support.
Quick Start
Add the extension to your Sphinx configuration (
docs/conf.py):extensions = [ 'cyclopts.sphinx_ext', # Add this line # ... your other extensions ]
Use the directive in your RST files:
.. cyclopts:: mypackage.cli:app
Directive Usage
Basic Syntax
The cyclopts directive accepts a module path to your Cyclopts App object:
.. cyclopts:: mypackage.cli:app
Module Path Formats
The directive accepts two module path formats:
Explicit format (
module.path:app_name):.. cyclopts:: mypackage.cli:app .. cyclopts:: myapp.commands:main_app .. cyclopts:: src.cli:cli
This explicitly specifies which
Appobject to document.Automatic discovery (
module.path):.. cyclopts:: mypackage.cli .. cyclopts:: myapp.main
The extension will search the module for an
Appinstance, looking for common names likeapp,cli, ormain.
Directive Options
The directive supports several options to customize the generated documentation:
:heading-level: - Heading Level
Set the starting heading level for the generated documentation (1-6, default: 2):
.. cyclopts:: mypackage.cli:app
:heading-level: 3
This is useful when you need to adjust the heading hierarchy. The default of 2 works well for most cases where the directive is placed under a page title.
:recursive: - Include Subcommands
Control whether to document subcommands recursively (default: true):
.. cyclopts:: mypackage.cli:app
:recursive: false
Set to false to only document the top-level commands.
:flatten-commands: - Generate Flat Command Hierarchy
Generate all commands at the same heading level instead of nested hierarchy:
.. cyclopts:: mypackage.cli:app
:flatten-commands: true
This creates distinct, equally-weighted headings for each command and subcommand, making them easier to reference and navigate in the documentation. Without this option, subcommands are nested with incrementing heading levels.
:command-prefix: - Add Prefix to Command Headings
Add a prefix to all command headings in the generated documentation:
.. cyclopts:: mypackage.cli:app
:command-prefix: Command:
This will prefix all command headings with "Command:" (e.g., "Command: deploy", "Command: init"). Useful for consistent formatting or when integrating CLI docs with other content.
:commands: - Filter Specific Commands
Document only specific commands from your CLI application:
.. cyclopts:: mypackage.cli:app
:commands: init, build, deploy
This will only document the specified commands. You can also use nested command paths with dot notation:
.. cyclopts:: mypackage.cli:app
:commands: db.migrate, db.backup, api
db.migrate- Documents only themigratesubcommand underdbdb.backup- Documents only thebackupsubcommand underdbapi- Documents theapicommand and all its subcommands
You can use either underscore or dash notation in command names - they will be normalized automatically.
:exclude-commands: - Exclude Specific Commands
Exclude specific commands from the documentation:
.. cyclopts:: mypackage.cli:app
:exclude-commands: debug, internal-test
This is useful for hiding internal or debug commands from user-facing documentation. Like :commands:, this also supports nested command paths with dot notation.
Automatic Reference Labels
The Sphinx directive automatically generates RST reference labels for all commands, enabling cross-referencing throughout your documentation. The anchor format is cyclopts-{app-name}-{command-path}, which prevents naming conflicts when documenting multiple CLIs.
For example:
- Root application: cyclopts-myapp
- Subcommand: cyclopts-myapp-deploy
- Nested subcommand: cyclopts-myapp-deploy-production
You can reference these commands elsewhere in your documentation using :ref:`cyclopts-myapp-deploy`.
Complete Example
Here's a complete example showing a CLI application and its Sphinx documentation:
CLI Application (myapp/cli.py):
from pathlib import Path
from typing import Optional
from cyclopts import App
app = App(
name="myapp",
help="My awesome CLI application",
version="1.0.0"
)
@app.command
def init(path: Path = Path("."), template: str = "default"):
"""Initialize a new project.
Parameters
----------
path : Path
Directory where the project will be created
template : str
Project template to use
"""
print(f"Initializing project at {path}")
@app.command
def build(source: Path, output: Optional[Path] = None, *, minify: bool = False):
"""Build the project.
Parameters
----------
source : Path
Source directory
output : Path, optional
Output directory (defaults to source/dist)
minify : bool
Minify the output files
"""
output = output or source / "dist"
print(f"Building from {source} to {output}")
if __name__ == "__main__":
app()
Sphinx Configuration (docs/conf.py):
import sys
from pathlib import Path
# Add your package to the path
sys.path.insert(0, str(Path(__file__).parent.parent))
# Extensions
extensions = [
'cyclopts.sphinx_ext',
'sphinx.ext.autodoc', # For API docs
'sphinx.ext.napoleon', # For NumPy-style docstrings
]
# Project info
project = 'MyApp'
author = 'Your Name'
version = '1.0.0'
# HTML theme
html_theme = 'sphinx_rtd_theme'
Documentation File (docs/cli.rst):
CLI Reference
=============
This section documents all available CLI commands.
.. cyclopts:: myapp.cli:app
:prog: myapp
:recursive: true
The above directive will automatically generate documentation for all
commands, including their parameters, types, defaults, and help text.
Advanced Usage
Using Distinct Command Headings
When you want each command to have its own distinct heading for better navigation and referencing:
CLI Command Reference
=====================
.. cyclopts:: myapp.cli:app
:prog: myapp
:flatten-commands: true
:command-prefix: "Command: "
This generates:
- All commands at the same heading level (not nested)
- Each command prefixed with "Command: "
- Automatic reference labels for cross-linking
You can then reference specific commands:
See :ref:`cyclopts-myapp-deploy` for deployment options.
The :ref:`cyclopts-myapp-init` command sets up your project.
Selective Command Documentation
Split your CLI documentation across multiple sections or pages:
Database Commands
=================
The following commands manage database operations:
.. cyclopts:: myapp.cli:app
:commands: db
:recursive: true
API Management
==============
Commands for controlling the API server:
.. cyclopts:: myapp.cli:app
:commands: api
:recursive: true
Development Tools
=================
Utilities for development (excluding internal debug commands):
.. cyclopts:: myapp.cli:app
:commands: dev
:exclude-commands: dev.debug, dev.internal
:recursive: true
This approach allows you to:
Organize large CLI applications into logical sections
Document different command groups on separate pages
Exclude internal or debug commands from user documentation
Create targeted documentation for different audiences
Output Formats
While the Sphinx directive uses RST internally, you can also generate documentation programmatically in multiple formats:
from myapp.cli import app
# Generate reStructuredText
rst_docs = app.generate_docs(output_format="rst")
# Generate Markdown
md_docs = app.generate_docs(output_format="markdown")
# Generate HTML
html_docs = app.generate_docs(output_format="html")
This is useful for generating documentation outside of Sphinx, such as for GitHub README files or other documentation systems.
See Also
Help - Customizing help output
Commands - Creating commands and subcommands
Parameters - Parameter types and validation
Sphinx Documentation - Official Sphinx documentation