or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# sphinx-click

1

2

A Sphinx extension that automatically extracts documentation from Click-based command-line applications and integrates it into Sphinx documentation systems. It enables developers to document their CLI tools by automatically generating formatted help text, command descriptions, and option details directly from the Click application code.

3

4

## Package Information

5

6

- **Package Name**: sphinx-click

7

- **Language**: Python

8

- **Installation**: `pip install sphinx-click`

9

- **Requires**: Python >=3.8

10

11

## Core Imports

12

13

```python

14

import sphinx_click

15

```

16

17

For Sphinx extension setup:

18

19

```python

20

# In your Sphinx conf.py

21

extensions = ['sphinx_click']

22

```

23

24

## Basic Usage

25

26

### 1. Enable the Extension

27

28

Add sphinx-click to your Sphinx configuration file (`conf.py`):

29

30

```python

31

extensions = ['sphinx_click']

32

```

33

34

### 2. Document a Click Application

35

36

Use the `.. click::` directive in your documentation:

37

38

```rst

39

.. click:: mypackage.cli:main

40

:prog: my-cli-tool

41

:nested: full

42

```

43

44

### 3. Complete Example

45

46

Given a Click application like this:

47

48

```python

49

# mypackage/cli.py

50

import click

51

52

@click.group()

53

def main():

54

"""A sample CLI application."""

55

pass

56

57

@main.command()

58

@click.option('--name', '-n', help='Name to greet')

59

@click.option('--count', default=1, help='Number of greetings')

60

def hello(name, count):

61

"""Say hello to someone."""

62

for _ in range(count):

63

click.echo(f'Hello {name}!')

64

65

@main.command()

66

def goodbye():

67

"""Say goodbye."""

68

click.echo('Goodbye!')

69

```

70

71

Document it with:

72

73

```rst

74

.. click:: mypackage.cli:main

75

:prog: my-cli-tool

76

:nested: full

77

```

78

79

This automatically generates formatted documentation showing the command structure, options, arguments, and help text.

80

81

## Capabilities

82

83

### Sphinx Extension Setup

84

85

Register the extension with Sphinx and configure its behavior.

86

87

```python { .api }

88

def setup(app: Sphinx) -> Dict[str, Any]:

89

"""

90

Set up the sphinx-click extension.

91

92

Args:

93

app: The Sphinx application instance

94

95

Returns:

96

Dict containing extension metadata with keys:

97

- 'parallel_read_safe': True

98

- 'parallel_write_safe': True

99

"""

100

```

101

102

### Click Directive

103

104

The main Sphinx directive for documenting Click applications.

105

106

```python { .api }

107

class ClickDirective(rst.Directive):

108

"""

109

A Sphinx directive for documenting Click commands.

110

111

Usage:

112

.. click:: module:parser

113

:prog: program-name

114

:nested: full|short|none

115

:commands: cmd1,cmd2,cmd3

116

"""

117

118

has_content = False

119

required_arguments = 1

120

option_spec = {

121

'prog': 'directives.unchanged_required',

122

'nested': 'nested', # Custom validation function

123

'commands': 'directives.unchanged',

124

'show-nested': 'directives.flag'

125

}

126

127

def _load_module(self, module_path: str) -> Union[click.Command, click.Group]:

128

"""Load the module and return the Click command/group."""

129

130

def _generate_nodes(

131

self,

132

name: str,

133

command: click.Command,

134

parent: Optional[click.Context],

135

nested: NestedT,

136

commands: Optional[List[str]] = None,

137

semantic_group: bool = False,

138

) -> List[nodes.section]:

139

"""Generate the relevant Sphinx nodes for documentation."""

140

141

def run(self) -> Sequence[nodes.section]:

142

"""Execute the directive and return documentation nodes."""

143

```

144

145

### Configuration

146

147

Extension configuration options available in Sphinx conf.py.

148

149

```python { .api }

150

# Configuration value for mocking imports during documentation build

151

sphinx_click_mock_imports: List[str]

152

"""

153

List of module names to mock during import.

154

Defaults to autodoc_mock_imports if not specified.

155

156

Example in conf.py:

157

sphinx_click_mock_imports = ['some_module', 'another_module']

158

"""

159

```

160

161

### Events

162

163

Custom Sphinx events emitted during documentation generation for customization.

164

165

```python { .api }

166

# Event: sphinx-click-process-description

167

def on_process_description(ctx: click.Context, lines: List[str]) -> None:

168

"""

169

Emitted when processing command descriptions.

170

171

Args:

172

ctx: Click context for the command

173

lines: List of description lines (modifiable)

174

"""

175

176

# Event: sphinx-click-process-usage

177

def on_process_usage(ctx: click.Context, lines: List[str]) -> None:

178

"""

179

Emitted when processing usage information.

180

181

Args:

182

ctx: Click context for the command

183

lines: List of usage lines (modifiable)

184

"""

185

186

# Event: sphinx-click-process-options

187

def on_process_options(ctx: click.Context, lines: List[str]) -> None:

188

"""

189

Emitted when processing command options.

190

191

Args:

192

ctx: Click context for the command

193

lines: List of option lines (modifiable)

194

"""

195

196

# Event: sphinx-click-process-arguments

197

def on_process_arguments(ctx: click.Context, lines: List[str]) -> None:

198

"""

199

Emitted when processing command arguments.

200

201

Args:

202

ctx: Click context for the command

203

lines: List of argument lines (modifiable)

204

"""

205

206

# Event: sphinx-click-process-envars

207

def on_process_envvars(ctx: click.Context, lines: List[str]) -> None:

208

"""

209

Emitted when processing environment variables.

210

211

Args:

212

ctx: Click context for the command

213

lines: List of environment variable lines (modifiable)

214

"""

215

216

# Event: sphinx-click-process-epilog

217

def on_process_epilog(ctx: click.Context, lines: List[str]) -> None:

218

"""

219

Emitted when processing command epilog text.

220

221

Args:

222

ctx: Click context for the command

223

lines: List of epilog lines (modifiable)

224

"""

225

```

226

227

## Directive Options

228

229

### Required Options

230

231

```python { .api }

232

# :prog: option (required)

233

prog: str

234

"""

235

The program name to display in usage examples.

236

237

Example:

238

.. click:: mypackage.cli:main

239

:prog: my-tool

240

"""

241

```

242

243

### Validation Functions

244

245

```python { .api }

246

def nested(argument: Optional[str]) -> NestedT:

247

"""

248

Validate nested directive option values.

249

250

Args:

251

argument: The option value from the directive

252

253

Returns:

254

Validated nested option value

255

256

Raises:

257

ValueError: If argument is not a valid nested value

258

"""

259

```

260

261

### Optional Options

262

263

```python { .api }

264

# :nested: option

265

nested: Literal['full', 'short', 'none', None]

266

"""

267

Control the level of nested command documentation.

268

269

Values:

270

- 'full': Show complete documentation for all subcommands

271

- 'short': Show only command names and short descriptions

272

- 'none': Don't show subcommands at all

273

- None: Default behavior (same as 'short')

274

275

Example:

276

.. click:: mypackage.cli:main

277

:prog: my-tool

278

:nested: full

279

"""

280

281

# :commands: option

282

commands: str

283

"""

284

Comma-separated list of specific commands to document.

285

If not specified, all commands are documented.

286

287

Example:

288

.. click:: mypackage.cli:main

289

:prog: my-tool

290

:commands: hello,goodbye

291

"""

292

293

# :show-nested: option (deprecated)

294

show_nested: bool

295

"""

296

Deprecated: Use :nested: full instead.

297

When present, shows full nested command documentation.

298

299

Example (deprecated):

300

.. click:: mypackage.cli:main

301

:prog: my-tool

302

:show-nested:

303

"""

304

```

305

306

### Utility Functions

307

308

Helper functions for formatting and processing Click command data.

309

310

```python { .api }

311

def _get_usage(ctx: click.Context) -> str:

312

"""

313

Alternative, non-prefixed version of 'get_usage'.

314

315

Args:

316

ctx: Click context for the command

317

318

Returns:

319

Usage string without command name prefix

320

"""

321

322

def _get_help_record(ctx: click.Context, opt: click.core.Option) -> Tuple[str, str]:

323

"""

324

Re-implementation of click.Option.get_help_record compatible with Sphinx.

325

326

Formats option arguments using angle brackets instead of uppercase,

327

and uses comma-separated opts instead of slashes for Sphinx compatibility.

328

329

Args:

330

ctx: Click context for the command

331

opt: Click option to format

332

333

Returns:

334

Tuple of (option_signature, help_text)

335

"""

336

337

def _format_help(help_string: str) -> Generator[str, None, None]:

338

"""

339

Format help string by cleaning ANSI sequences and processing special markers.

340

341

Args:

342

help_string: Raw help text from Click command

343

344

Yields:

345

Formatted help lines

346

"""

347

348

def _indent(text: str, level: int = 1) -> str:

349

"""

350

Indent text by specified number of levels (4 spaces per level).

351

352

Args:

353

text: Text to indent

354

level: Number of indentation levels

355

356

Returns:

357

Indented text

358

"""

359

360

def _filter_commands(

361

ctx: click.Context,

362

commands: Optional[List[str]] = None,

363

) -> List[click.Command]:

364

"""

365

Return filtered list of commands from a Click group.

366

367

Args:

368

ctx: Click context for the command group

369

commands: Optional list of specific command names to include

370

371

Returns:

372

List of Click commands, sorted by name

373

"""

374

375

def _get_lazyload_commands(ctx: click.Context) -> Dict[str, click.Command]:

376

"""

377

Get lazy-loaded commands from a Click multi-command.

378

379

Args:

380

ctx: Click context for the multi-command

381

382

Returns:

383

Dictionary mapping command names to command objects

384

"""

385

386

def _process_lines(event_name: str) -> Callable[[_T_Formatter], _T_Formatter]:

387

"""

388

Decorator that emits Sphinx events during line processing.

389

390

Args:

391

event_name: Name of the event to emit

392

393

Returns:

394

Decorator function for formatter functions

395

"""

396

```

397

398

### Formatter Functions

399

400

Internal functions that generate reStructuredText for different parts of Click commands.

401

402

```python { .api }

403

def _format_description(ctx: click.Context) -> Generator[str, None, None]:

404

"""

405

Format the description for a given Click Command.

406

407

Parses help text as reStructuredText, allowing rich information

408

in help messages.

409

410

Args:

411

ctx: Click context for the command

412

413

Yields:

414

Formatted description lines

415

"""

416

417

def _format_usage(ctx: click.Context) -> Generator[str, None, None]:

418

"""

419

Format the usage for a Click Command.

420

421

Args:

422

ctx: Click context for the command

423

424

Yields:

425

Formatted usage lines as code block

426

"""

427

428

def _format_options(ctx: click.Context) -> Generator[str, None, None]:

429

"""

430

Format all Click Options for a Click Command.

431

432

Args:

433

ctx: Click context for the command

434

435

Yields:

436

Formatted option documentation lines

437

"""

438

439

def _format_arguments(ctx: click.Context) -> Generator[str, None, None]:

440

"""

441

Format all Click Arguments for a Click Command.

442

443

Args:

444

ctx: Click context for the command

445

446

Yields:

447

Formatted argument documentation lines

448

"""

449

450

def _format_envvars(ctx: click.Context) -> Generator[str, None, None]:

451

"""

452

Format all environment variables for a Click Command.

453

454

Args:

455

ctx: Click context for the command

456

457

Yields:

458

Formatted environment variable documentation lines

459

"""

460

461

def _format_epilog(ctx: click.Context) -> Generator[str, None, None]:

462

"""

463

Format the epilog for a given Click Command.

464

465

Parses epilog text as reStructuredText.

466

467

Args:

468

ctx: Click context for the command

469

470

Yields:

471

Formatted epilog lines

472

"""

473

474

def _format_command(

475

ctx: click.Context,

476

nested: NestedT,

477

commands: Optional[List[str]] = None,

478

) -> Generator[str, None, None]:

479

"""

480

Format the complete output of a Click Command.

481

482

Args:

483

ctx: Click context for the command

484

nested: The granularity of subcommand details

485

commands: Optional list of specific commands to document

486

487

Yields:

488

Complete formatted command documentation lines

489

"""

490

491

def _format_option(

492

ctx: click.Context, opt: click.core.Option

493

) -> Generator[str, None, None]:

494

"""

495

Format the output for a single Click Option.

496

497

Args:

498

ctx: Click context for the command

499

opt: Click option to format

500

501

Yields:

502

Formatted option lines

503

"""

504

505

def _format_argument(arg: click.Argument) -> Generator[str, None, None]:

506

"""

507

Format the output of a Click Argument.

508

509

Args:

510

arg: Click argument to format

511

512

Yields:

513

Formatted argument lines

514

"""

515

516

def _format_envvar(

517

param: Union[click.core.Option, click.Argument]

518

) -> Generator[str, None, None]:

519

"""

520

Format the environment variables of a Click Option or Argument.

521

522

Args:

523

param: Click parameter with environment variable

524

525

Yields:

526

Formatted environment variable lines

527

"""

528

529

def _format_subcommand(command: click.Command) -> Generator[str, None, None]:

530

"""

531

Format a sub-command of a Click Command or Group.

532

533

Args:

534

command: Click subcommand to format

535

536

Yields:

537

Formatted subcommand lines

538

"""

539

```

540

541

## Types

542

543

```python { .api }

544

from typing import Literal, Sequence, Dict, Any, List, Optional, Union, Callable, Generator, Pattern, Tuple

545

from sphinx.application import Sphinx

546

from docutils import nodes

547

from docutils.parsers.rst import Directive

548

import click

549

import logging

550

551

# Type aliases used in the API

552

NestedT = Literal['full', 'short', 'none', None]

553

_T_Formatter = Callable[[click.Context], Generator[str, None, None]]

554

555

# Constants for nested option values

556

NESTED_FULL: str = 'full'

557

NESTED_SHORT: str = 'short'

558

NESTED_NONE: str = 'none'

559

560

# Pattern for removing ANSI escape sequences

561

ANSI_ESC_SEQ_RE: Pattern[str]

562

563

# Logger instance

564

LOG: logging.Logger

565

```

566

567

## Error Handling

568

569

The extension handles several common error conditions:

570

571

### Import Errors

572

573

```python

574

# Module import failures are caught and reported with helpful messages

575

# Example error messages:

576

# - "Failed to import 'parser' from 'mymodule'. The following exception was raised: ..."

577

# - "Module 'mymodule' has no attribute 'parser'"

578

# - "The module appeared to call sys.exit()"

579

```

580

581

### Invalid Click Objects

582

583

```python

584

# Validates that imported objects are Click commands or groups

585

# Example error message:

586

# - "'<type>' of type 'str' is not click.Command or click.Group"

587

```

588

589

### Directive Option Errors

590

591

```python

592

# Validates directive options and provides clear error messages

593

# Example error messages:

594

# - ":prog: must be specified"

595

# - "'invalid' is not a valid value for ':nested:'; allowed values: full, short, none, None"

596

# - "':nested:' and ':show-nested:' are mutually exclusive"

597

```

598

599

## Dependencies

600

601

- **click** or **asyncclick**: For Click command/group support

602

- **sphinx**: Core documentation system (requires sphinx.ext.autodoc)

603

- **docutils**: reStructuredText processing utilities

604

605

## Advanced Usage

606

607

### Event Customization

608

609

Register event handlers to customize the generated documentation:

610

611

```python

612

# In your Sphinx conf.py

613

def customize_description(ctx, lines):

614

"""Modify command descriptions during processing."""

615

if ctx.command.name == 'special-command':

616

lines.insert(0, '**This is a special command!**')

617

lines.append('')

618

619

def setup(app):

620

app.connect('sphinx-click-process-description', customize_description)

621

```

622

623

### Mock Imports

624

625

Handle missing dependencies during documentation builds:

626

627

```python

628

# In your Sphinx conf.py

629

sphinx_click_mock_imports = [

630

'expensive_dependency',

631

'optional_module',

632

'development_only_package'

633

]

634

```

635

636

### Complex Command Structures

637

638

Document multi-level command groups:

639

640

```rst

641

.. click:: mypackage.cli:main

642

:prog: my-complex-tool

643

:nested: full

644

645

.. click:: mypackage.admin:admin_cli

646

:prog: my-complex-tool admin

647

:nested: short

648

:commands: user,permissions

649

```