Skip to main content

Configuration driven CLI builder with subcommands and script loading

Project description

Sigil

Declarative argparse, without the CLI boilerplate.

Sigil is a lightweight, declarative CLI framework for Python. Define your command tree in YAML (or any other format), and sigil builds the argparse parser on the fly. Complete with subcommands and dynamic script loading.
It plays nicely with argcomplete out of the box.

pypi PyPI Wheel Python 3.10+ License: MIT Downloads Tests Coverage Status


Features

  • Declarative command hierarchies (parents, subparsers, defaults)
  • Each command can point to a dynamically imported Python script
  • argcomplete integration for tab‑completion
  • Pluggable data sources – YAML is the default, but JSON, TOML, or a dict are trivial to swap in
  • No boilerplate argparse code in your main logic

Quick Start

Install

pip install sigil-cli

or include argcomplete

pip install sigil-cli[completion]

0. Recommended file structure

project_root/
├── mycli.py              # drop‑in entry script (alias this)
├── manifest.yml          # lists all YAML config files to load
├── yml/                  
│   ├── root.yml          # root command definition
│   ├── root_run.yml      # subcommand definition(s)
│   └── ...               
└── scripts/              
    ├── run.py            # implements the 'run' command
    └── ...               # other scripts

1. Entry script

Create mycli.py:

#!/usr/bin/env python3
from pathlib import Path
from sigil import run_from_config

if __name__ == "__main__":
    run_from_config(Path(__file__).parent)

2. Configuration files

List all your YAML definitions in manifest.yml:

---
- root.yml
- root_run.yml

Define the root command in root.yml:

root:
  name: mycli
  script_dir: scripts

Define a subcommand in root_run.yml:

root_run:
  name: run
  parent: root
  help: command utility to run containers
  script: run
  args:
    - help: port to run, autoincrements from 8080
      name:
        - -p
        - --port

3. Write the script

Create scripts/run.py:

import argparse
from typing import Any

def run(args: argparse.Namespace, ctx: dict[str, Any]) -> None:
    port = getattr(args, "port", 8080)
    port = find_next_free_port_logic(port)
    print(f"Running container on port {port}")

4. Run it

chmod +x mycli.py
./mycli.py run --port 9000
# Running container on port 9000

./mycli.py run
# Running container on port 8080

./mycli.py run
# Running container on port 8081

Configuration Reference

Root

Field Description
name Program name (used as prog in argparse)
script_dir Directory (relative to the config root) where command scripts are located

Command

Field Description
name Subcommand name
parent Parent command (must exist elsewhere in a config)
help Help text for this subcommand
script Python module name (without .py) inside script_dir or as absolute path
args List of argument definitions (see below)
default If true, this subcommand is used when no subcommand is given
any other parser kwarg except for dest and formatter_class they are all supported

Note that parent does not refer to argparse's parent parameter but is only used to resolve the parser tree. Parser (multi-)inheritance isn't supported but can be emulated by adding arguments to this command's parents in the tree.

Argument

Each argument entry can be a plain dict which maps 1-to-1 with argparse add_argument, except name which maps it's *args

- name: ["-p", "--port"]   # or a single string, e.g. "positional"
  required: false
  default: 8069
  help: "port number"

Groups and mutex groups are also suppored via the "kind" parameter (defaults to argument)

# mutex group
- kind: mutex
  args:
    - <any recursive args/group/mutex construct here>
    ...
  ... # any valid mutex group arguments go here

- kind: group
  ...  # same

The name field can be --flag for flags or a string for positional arguments. Both literal string and list of strings are supported.

Tab‑Completion (argcomplete)

Sigil registers itself with argcomplete automatically if available on your system.
To enable completion, install argcomplete and activate it for your entry script:

pip install argcomplete
activate-global-python-argcomplete

Then run your script and hit Tab – subcommands and flags will complete.

Pluggable Backends

Sigil uses yaml by default, but you can supply any loader that returns a dict[str, ParserConfig]:

from sigil import run_from_config

# Use JSON instead:
class JsonReader:
    @classmethod
    def load(cls, config_root):
        # read *.json, parse, convert to dict of ParserConfig
        ...

run_from_config("/path/to/config", loader_class=JsonReader)

You can also pass a pre‑loaded dictionary directly by wrapping it:

run_from_config(my_dict, loader_class=DictLoader)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sigil_cli-1.0.0.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sigil_cli-1.0.0-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file sigil_cli-1.0.0.tar.gz.

File metadata

  • Download URL: sigil_cli-1.0.0.tar.gz
  • Upload date:
  • Size: 16.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for sigil_cli-1.0.0.tar.gz
Algorithm Hash digest
SHA256 8c19dd886189d16b521cbfcf8fa7e60ab73f1c1774d8398d4e0ab27833c663ec
MD5 af6fe98ea706ab1f8dcf8bea60e4a53e
BLAKE2b-256 96f3c289bfb8494f7335165acfa85717a3b541b6e630fd8f79bcfd2c70f0b66e

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigil_cli-1.0.0.tar.gz:

Publisher: publish.yml on kenzo-staelens/sigil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sigil_cli-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: sigil_cli-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for sigil_cli-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f463a1dff94fd1136201d5284b9b15ac90e314ab650d56fdc48273588f3bcfa5
MD5 70ddb673b360919667ead2c62bc20428
BLAKE2b-256 21df5b2c4bfb968f163ed0051f6505518174a28b4f51e291393409a6950829b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigil_cli-1.0.0-py3-none-any.whl:

Publisher: publish.yml on kenzo-staelens/sigil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page