Skip to content
Skills Library
Programming · Building & coding

python-package-cli

/python-package-cli

Create or extend an installable Python tool: src layout, pyproject.toml (entry point, package data, black/ruff/pytest config, optional dev deps), __version__ and --version, argparse subcommands with one cmd_<name> function each, --dry-run, plan/verify commands, conda env file. Use for stand-alone tools like dataset builders or CLIs, not for single workflow scripts.

Licence
MIT
Last repository change
11.11.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 11.11.2026, without references to retired models or APIs.

Licence

MIT, open: use and modify while retaining author attribution.

What it does and when to use it

Create or extend an installable Python tool: src layout, pyproject.toml (entry point, package data, black/ruff/pytest config, optional dev deps), __version__ and --version, argparse subcommands with one cmd_<name> function each, --dry-run, plan/verify commands, conda env file. Use for stand-alone tools like dataset builders or CLIs, not for single workflow scripts.

Original author description

Create or extend an installable Python tool: src layout, pyproject.toml (entry point, package data, black/ruff/pytest config, optional dev deps), __version__ and --version, argparse subcommands with one cmd_<name> function each, --dry-run, plan/verify commands, conda env file. Use for stand-alone tools like dataset builders or CLIs, not for single workflow scripts.

How it works

  1. When to use / not to use
  2. Steps
  3. Checks before finishing
  4. Pitfalls
Original SKILL.md headings · 68 lines, 465 words
SKILL.md preview
---
name: python-package-cli
description: 'Create or extend an installable Python tool: src layout, pyproject.toml (entry point, package data, black/ruff/pytest config, optional dev deps), __version__ and --version, argparse subcommands with one cmd_<name> function each, --dry-run, plan/verify commands, conda env file. Use for stand-alone tools like dataset builders or CLIs, not for single workflow scripts.'
---

# Installable package with a CLI

Purpose: a reusable tool (e.g. seqc2-toolkit) with subcommands, defaults that are safe, and a
layout that tests and conda can install.

## When to use / not to use

Use when the tool has several commands, shipped data files, or is used outside one workflow. For one
workflow helper use `python-bin-script`. Use typer/click only if the app already does;
new tools use argparse.

## Steps

1. **Layout.**
   ```
   <repo>/pyproject.toml  README.md  CHANGELOG.md  LICENSE
   <repo>/envs/<name>.yaml
   <repo>/src/<pkg>/__init__.py   (__version__ = "0.1.0-dev")
   <repo>/src/<pkg>/cli.py  <topic modules>.py  data/*.yaml
   <repo>/tests/test_<module>.py
   ```
   Repository name follows CUBI rules (`workflow-...`, `project-...`); a pure tool may use a plain short name.
2. **pyproject.toml** (adapt):
   ```toml
   [project]
   name = "<pkg>"
   version = "0.1.0-dev"
   requires-python = ">=3.10"
   dependencies = ["pyyaml"]
   [project.optional-dependencies]
   dev = ["pytest", "black", "ruff"]
   [project.scripts]
   <tool> = "<pkg>.cli:main"
   [tool.setuptools.packages.find]
   where = ["src"]
   [tool.setuptools.package-data]
   <pkg> = ["*.yaml"]
   [tool.black]
   line-length = 100
   [tool.ruff]
   line-length = 100
   [tool.ruff.lint]
   select = ["E", "F", "W", "I", "B", "UP"]
   [tool.pytest.ini_options]
   testpaths = ["tests"]
   pythonpath = ["src"]
   ```
   Version is a semver string with `-dev` on the dev branch; a manual bump is its own commit.
3. **cli.py.** Module docstring lists the commands plus an Examples block. One function `cmd_<name>(args)` per subcommand with a docstring; `build_parser()` uses `add_subparsers(dest="command", required=True)`; global `--verbose`, `--version`. `main(argv=None)` configures logging, calls `args.func(args)`, catches the tool's error class, prints `ERROR: <msg>` to stderr, exits 1.
4. **Command set that works well:** `plan` (what would happen, sizes, what is cached), `fetch`/`build` (do only what is missing), `run` with `--dry-run` (print the final command prefixed with `$ `), `verify` (recompute checksums, exit 1 if any changed), `list`/`catalog` (read-only). Mutating commands support `--dry-run`; never `--force` by default.
5. **Config vs flags.** Defaults in a YAML file shipped as package data; user config (YAML, `n/a` for unset) overrides; CLI flags override config. Cache/data dirs from an env var, else a user dir. Document the order in `--help`.
6. **Environment file** `envs/<name>.yaml`: conda-forge + bioconda, `python=3.12`, tools with exact pins, comment headers per group, `pip: [-e .]` for the package, dev tools at the end. No `.venv`.
7. **Tests**: parser smoke test (`--help`, `--version`), one test per command on tiny synthetic input, failure tests for bad config.
8. Run `black`, `ruff check`, `pytest`; update README (usage per command) and CHANGELOG.

## Checks before finishing

- `pip install -e .` in the conda env, then `<tool> --help` and `<tool> --version` work.
- Package data is found after install (not only from the source tree).
- `--dry-run` writes and downloads nothing (check with `git status` or a temp dir).

## Pitfalls

- Forgetting package-data: works in the repo, fails when installed.
- Type hints are expected in packages; add them to every public function.
- Do not parse secrets from flags; read them from env or a config outside the repo.

Versions

The database has no other skills named python-package-cli.

Database snapshot: 13.11.2026 · package version f2b5c49026c7 (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100python-packaging
    Python project structure patterns — pyproject.toml for services and internal tools, source vs flat layout, CLI entry points with Click/argparse, dynamic versioning, and editable installs. Use when structuring a new Python project or building internal CLI tools.
  • 90python-packaging
    Package a Python project with a single pyproject.toml, a src layout, and a clean build/publish path to PyPI including entry points. Use when turning a script or library into an installable, distributable package.
  • 87python-app-conventions
    Application and library conventions for plain Python projects (no web framework): src/ package layout, CLI tooling (argparse/click/typer), configuration management (pydantic-settings), logging setup, module design, entry points, and packaging conventions. Activated automatically…
  • 100build-python-library
    Implements pip-installable Python libraries from scratch using src layout, pyproject.toml, and pytest. Use when the user asks to build, create, implement, or scaffold a Python library, package, pip package, middleware, SDK, or wrapper. Covers project scaffolding, proxy/wrapper…
  • 100python-conventions
    Enforce Python tooling conventions for uv, ty, Ruff, pytest, and pyproject.toml. Use when working on .py files or Python project config. NOT for JS/TS, shell scripts, CI design, profiling, or test architecture.
  • 100cli-architecture
    This skill should be used when the user is adding a CLI to a Python package, choosing between Click, Typer, and argparse, structuring cli.py or a cli/ directory, creating a __main__.py for python -m support, defining console script entry points, handling exit codes, or…

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.