# Python Project Scaffold

> Python Project Scaffold

- Skill: `lucadominguez/python-project-scaffold` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lucadominguez/python-project-scaffold`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lucadominguez/python-project-scaffold/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: lucadominguez (https://skillmd.com/u/lucadominguez)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lucadominguez/python-project-scaffold

---

# Python Project Scaffold

Standardized Python project initialization — the pattern used for CLI tools, data pipelines, and libraries. Produces a working `pip install -e .` project in under a minute.

## Directory Structure

```
project-name/
├── README.md
├── pyproject.toml
├── src/
│   └── package_name/
│       ├── __init__.py
│       ├── cli.py          # rich-based CLI
│       └── core_module.py
├── tests/
│   ├── __init__.py
│   └── test_core.py
└── data/                   # optional static data
```

## pyproject.toml Template

```toml
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "package-name"
version = "0.1.0"
description = "Short description"
readme = "README.md"
license = {text = "MIT"}
requires-python = ">=3.10"
authors = [{name = "Your Name"}]
keywords = ["keyword1", "keyword2"]

dependencies = [
    "rich>=13.0.0",
    "pydantic>=2.0.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0.0",
    "pytest-cov>=4.0.0",
    "ruff>=0.1.0",
]

[project.scripts]
cli-name = "package_name.cli:main"

[tool.ruff]
line-length = 100
target-version = "py310"

[tool.pytest.ini_options]
testpaths = ["tests"]
```

## CLI Template (rich-based)

```python
"""Package description."""

import argparse
from rich.console import Console
from rich.table import Table
from rich.panel import Panel

console = Console()

def create_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(prog="cli-name")
    subparsers = parser.add_subparsers(dest="command")
    
    cmd = subparsers.add_parser("action", help="Do something")
    cmd.add_argument("input", help="Input value")
    cmd.add_argument("--flag", action="store_true", help="Optional flag")
    
    return parser

def main():
    parser = create_parser()
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        return
    
    if args.command == "action":
        console.print(f"[green]Processing:[/green] {args.input}")
```

## Installation

```bash
cd project-name
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

On systems with PEP 668 restrictions (Ubuntu 24.04+, Debian 12+), the venv is required — `--break-system-packages` works but is not recommended.

## Pitfalls

- **pip install timeout**: Large packages (rdkit, numpy) may take 2-5 minutes. Use `terminal(background=True, notify_on_complete=True)` with a 600s timeout for the install step.
- **src layout imports**: Package is importable as `package_name` (not `src.package_name`). The `pip install -e .` creates the editable link.
- **Script entry points**: Defined in `[project.scripts]`, become available on PATH only after `pip install`.

## Verification

```bash
source .venv/bin/activate
python -c "import package_name; print(package_name.__version__)"
pytest tests/ -v
```
