| name | python-packaging |
| description | 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. |
| allowed-tools | Read, Write, Edit, Bash |
| metadata | {"triggers":"pyproject.toml, Python project structure, source layout, flat layout, CLI tool Python, Click entry point, argparse CLI, Python versioning, editable install, Python internal tool, Python script packaging","related-skills":"python-dev, uv-package-manager, api-design-principles","domain":"backend","role":"specialist","scope":"implementation","output-format":"code"} |
| last-reviewed | 2026-03-14 |
Iron Law
USE SOURCE LAYOUT (src/) FOR ALL SERVICES AND INSTALLABLE TOOLS — flat layout works for scripts but causes import confusion in larger projects and CI environments
Python Packaging
Project structure patterns for Python 3.14 services, internal tools, and CLI applications.
Scope
This skill covers the workspace-relevant subset of Python packaging:
pyproject.toml structure for FastAPI services and internal tools
- Source layout vs flat layout decision
- CLI entry points (Click, argparse) for internal tooling
- Dynamic versioning
- Editable installs for development
Out of scope for this workspace: PyPI publishing, wheels, namespace packages, C extensions, private package index. The workspace builds services and internal tools, not distributable libraries.
Layout Decision
New project?
│
├── FastAPI service / internal service
│ └── Source layout: src/<package>/ ← default for all services
│
├── Internal CLI tool (deployment scripts, data tools)
│ └── Source layout with [project.scripts] entry point
│
└── Quick one-off script
└── Flat layout (single .py file or simple directory)
Reference File
Load resources/implementation-playbook.md for:
- Source layout pattern (Pattern 1) — full directory structure with init.py placement
- Flat layout pattern (Pattern 2) — when appropriate
- Full pyproject.toml template (Pattern 4) — with all modern metadata fields
- Dynamic versioning with
setuptools-scm (Pattern 5)
- CLI with Click (Pattern 6) — entry points, commands, options
- CLI with argparse (Pattern 7) — subcommands, arguments
- Editable install (Pattern 16) —
uv pip install -e . for development
Key pyproject.toml Sections
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-service"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = [
"fastapi>=0.135.2",
"pydantic>=2.0.0",
]
[project.scripts]
my-cli = "my_package.cli:main"
[tool.hatch.build.targets.wheel]
packages = ["src/my_package"]
CLI Entry Point Pattern
import click
@click.group()
def main():
"""Internal deployment tool."""
pass
@main.command()
@click.argument("environment")
@click.option("--dry-run", is_flag=True)
def deploy(environment: str, dry_run: bool):
"""Deploy to environment."""
click.echo(f"Deploying to {environment} (dry_run={dry_run})")
if __name__ == "__main__":
main()
Install and run: uv pip install -e . then my-cli deploy staging --dry-run