Python Packaging Comprehensive guide to creating, structuring, and distributing Python packages using modern packaging tools, pyproject.toml, and publishing to PyPI. When to Use This Skill - Creating Python libraries for distribution - Building command-line tools with entry points - Publishing packages to PyPI or private repositories - Setting up Python project structure - Creating installable packages with dependencies - Building wheels and source distributions - Versioning and releasing Python packages - Creating namespace packages - Implementing package metadata and classifiers Core Concep…

\n\n# Ruff configuration\n[tool.ruff]\nline-length = 100\ntarget-version = \"py38\"\n\n[tool.ruff.lint]\nselect = [\"E\", \"F\", \"I\", \"N\", \"W\", \"UP\"]\n\n# MyPy configuration\n[tool.mypy]\npython_version = \"3.8\"\nwarn_return_any = true\nwarn_unused_configs = true\ndisallow_untyped_defs = true\n\n# Pytest configuration\n[tool.pytest.ini_options]\ntestpaths = [\"tests\"]\npython_files = [\"test_*.py\"]\naddopts = \"-v --cov=my_package --cov-report=term-missing\"\n\n# Coverage configuration\n[tool.coverage.run]\nsource = [\"src\"]\nomit = [\"*/tests/*\"]\n\n[tool.coverage.report]\nexclude_lines = [\n \"pragma: no cover\",\n \"def __repr__\",\n \"raise AssertionError\",\n \"raise NotImplementedError\",\n]\n```\n\n### Pattern 5: Dynamic Versioning\n\n```toml\n[build-system]\nrequires = [\"setuptools>=61.0\", \"setuptools-scm>=8.0\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"my-package\"\ndynamic = [\"version\"]\ndescription = \"Package with dynamic version\"\n\n[tool.setuptools.dynamic]\nversion = {attr = \"my_package.__version__\"}\n\n# Or use setuptools-scm for git-based versioning\n[tool.setuptools_scm]\nwrite_to = \"src/my_package/_version.py\"\n```\n\n**In **init**.py:**\n\n```python\n# src/my_package/__init__.py\n__version__ = \"1.0.0\"\n\n# Or with setuptools-scm\nfrom importlib.metadata import version\n__version__ = version(\"my-package\")\n```\n\n## Command-Line Interface (CLI) Patterns\n\n### Pattern 6: CLI with Click\n\n```python\n# src/my_package/cli.py\nimport click\n\[email protected]()\[email protected]_option()\ndef cli():\n \"\"\"My awesome CLI tool.\"\"\"\n pass\n\[email protected]()\[email protected](\"name\")\[email protected](\"--greeting\", default=\"Hello\", help=\"Greeting to use\")\ndef greet(name: str, greeting: str):\n \"\"\"Greet someone.\"\"\"\n click.echo(f\"{greeting}, {name}!\")\n\[email protected]()\[email protected](\"--count\", default=1, help=\"Number of times to repeat\")\ndef repeat(count: int):\n \"\"\"Repeat a message.\"\"\"\n for i in range(count):\n click.echo(f\"Message {i + 1}\")\n\ndef main():\n \"\"\"Entry point for CLI.\"\"\"\n cli()\n\nif __name__ == \"__main__\":\n main()\n```\n\n**Register in pyproject.toml:**\n\n```toml\n[project.scripts]\nmy-tool = \"my_package.cli:main\"\n```\n\n**Usage:**\n\n```bash\npip install -e .\nmy-tool greet World\nmy-tool greet Alice --greeting=\"Hi\"\nmy-tool repeat --count=3\n```\n\n### Pattern 7: CLI with argparse\n\n```python\n# src/my_package/cli.py\nimport argparse\nimport sys\n\ndef main():\n \"\"\"Main CLI entry point.\"\"\"\n parser = argparse.ArgumentParser(\n description=\"My awesome tool\",\n prog=\"my-tool\"\n )\n\n parser.add_argument(\n \"--version\",\n action=\"version\",\n version=\"%(prog)s 1.0.0\"\n )\n\n subparsers = parser.add_subparsers(dest=\"command\", help=\"Commands\")\n\n # Add subcommand\n process_parser = subparsers.add_parser(\"process\", help=\"Process data\")\n process_parser.add_argument(\"input_file\", help=\"Input file path\")\n process_parser.add_argument(\n \"--output\", \"-o\",\n default=\"output.txt\",\n help=\"Output file path\"\n )\n\n args = parser.parse_args()\n\n if args.command == \"process\":\n process_data(args.input_file, args.output)\n else:\n parser.print_help()\n sys.exit(1)\n\ndef process_data(input_file: str, output_file: str):\n \"\"\"Process data from input to output.\"\"\"\n print(f\"Processing {input_file} -> {output_file}\")\n\nif __name__ == \"__main__\":\n main()\n```\n\n## Building and Publishing\n\n### Pattern 8: Build Package Locally\n\n```bash\n# Install build tools\npip install build twine\n\n# Build distribution\npython -m build\n\n# This creates:\n# dist/\n# my-package-1.0.0.tar.gz (source distribution)\n# my_package-1.0.0-py3-none-any.whl (wheel)\n\n# Check the distribution\ntwine check dist/*\n```\n\n### Pattern 9: Publishing to PyPI\n\n```bash\n# Install publishing tools\npip install twine\n\n# Test on TestPyPI first\ntwine upload --repository testpypi dist/*\n\n# Install from TestPyPI to test\npip install --index-url https://test.pypi.org/simple/ my-package\n\n# If all good, publish to PyPI\ntwine upload dist/*\n```\n\n**Using API tokens (recommended):**\n\n```bash\n# Create ~/.pypirc\n[distutils]\nindex-servers =\n pypi\n testpypi\n\n[pypi]\nusername = __token__\npassword = pypi-...your-token...\n\n[testpypi]\nusername = __token__\npassword = pypi-...your-test-token...\n```\n\n### Pattern 10: Automated Publishing with GitHub Actions\n\n```yaml\n# .github/workflows/publish.yml\nname: Publish to PyPI\n\non:\n release:\n types: [created]\n\njobs:\n publish:\n runs-on: ubuntu-latest\n\n steps:\n - uses: actions/checkout@v3\n\n - name: Set up Python\n uses: actions/setup-python@v4\n with:\n python-version: \"3.11\"\n\n - name: Install dependencies\n run: |\n pip install build twine\n\n - name: Build package\n run: python -m build\n\n - name: Check package\n run: twine check dist/*\n\n - name: Publish to PyPI\n env:\n TWINE_USERNAME: __token__\n TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}\n run: twine upload dist/*\n```\n\nFor advanced patterns including data files, namespace packages, C extensions, version management, testing installation, documentation templates, and distribution workflows, see [references/advanced-patterns.md](./advanced-patterns.md)\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":7474,"content_sha256":"4bf009076d1e89cd2bf9bfffeea645095f10cd88f8fcc8b03c137303ebef27dc"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Python Packaging","type":"text"}]},{"type":"paragraph","content":[{"text":"Comprehensive guide to creating, structuring, and distributing Python packages using modern packaging tools, pyproject.toml, and publishing to PyPI.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use This Skill","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Creating Python libraries for distribution","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Building command-line tools with entry points","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Publishing packages to PyPI or private repositories","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Setting up Python project structure","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Creating installable packages with dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Building wheels and source distributions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Versioning and releasing Python packages","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Creating namespace packages","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implementing package metadata and classifiers","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Concepts","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Package Structure","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Source layout","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"src/package_name/","type":"text","marks":[{"type":"code_inline"}]},{"text":" (recommended)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Flat layout","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"package_name/","type":"text","marks":[{"type":"code_inline"}]},{"text":" (simpler but less flexible)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Package metadata","type":"text","marks":[{"type":"strong"}]},{"text":": pyproject.toml, setup.py, or setup.cfg","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Distribution formats","type":"text","marks":[{"type":"strong"}]},{"text":": wheel (.whl) and source distribution (.tar.gz)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. Modern Packaging Standards","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PEP 517/518","type":"text","marks":[{"type":"strong"}]},{"text":": Build system requirements","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PEP 621","type":"text","marks":[{"type":"strong"}]},{"text":": Metadata in pyproject.toml","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PEP 660","type":"text","marks":[{"type":"strong"}]},{"text":": Editable installs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"pyproject.toml","type":"text","marks":[{"type":"strong"}]},{"text":": Single source of configuration","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Build Backends","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"setuptools","type":"text","marks":[{"type":"strong"}]},{"text":": Traditional, widely used","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"hatchling","type":"text","marks":[{"type":"strong"}]},{"text":": Modern, opinionated","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"flit","type":"text","marks":[{"type":"strong"}]},{"text":": Lightweight, for pure Python","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"poetry","type":"text","marks":[{"type":"strong"}]},{"text":": Dependency management + packaging","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. Distribution","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PyPI","type":"text","marks":[{"type":"strong"}]},{"text":": Python Package Index (public)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"TestPyPI","type":"text","marks":[{"type":"strong"}]},{"text":": Testing before production","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Private repositories","type":"text","marks":[{"type":"strong"}]},{"text":": JFrog, AWS CodeArtifact, etc.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Minimal Package Structure","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"my-package/\n├── pyproject.toml\n├── README.md\n├── LICENSE\n├── src/\n│ └── my_package/\n│ ├── __init__.py\n│ └── module.py\n└── tests/\n └── test_module.py","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Minimal pyproject.toml","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"toml"},"content":[{"text":"[build-system]\nrequires = [\"setuptools>=61.0\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"my-package\"\nversion = \"0.1.0\"\ndescription = \"A short description\"\nauthors = [{name = \"Your Name\", email = \"[email protected]\"}]\nreadme = \"README.md\"\nrequires-python = \">=3.8\"\ndependencies = [\n \"requests>=2.28.0\",\n]\n\n[project.optional-dependencies]\ndev = [\n \"pytest>=7.0\",\n \"black>=22.0\",\n]","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Package Structure Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 1: Source Layout (Recommended)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"my-package/\n├── pyproject.toml\n├── README.md\n├── LICENSE\n├── .gitignore\n├── src/\n│ └── my_package/\n│ ├── __init__.py\n│ ├── core.py\n│ ├── utils.py\n│ └── py.typed # For type hints\n├── tests/\n│ ├── __init__.py\n│ ├── test_core.py\n│ └── test_utils.py\n└── docs/\n └── index.md","type":"text"}]},{"type":"paragraph","content":[{"text":"Advantages:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Prevents accidentally importing from source","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cleaner test imports","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Better isolation","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"pyproject.toml for source layout:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"toml"},"content":[{"text":"[tool.setuptools.packages.find]\nwhere = [\"src\"]","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 2: Flat Layout","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"my-package/\n├── pyproject.toml\n├── README.md\n├── my_package/\n│ ├── __init__.py\n│ └── module.py\n└── tests/\n └── test_module.py","type":"text"}]},{"type":"paragraph","content":[{"text":"Simpler but:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Can import package without installing","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Less professional for libraries","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Pattern 3: Multi-Package Project","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"project/\n├── pyproject.toml\n├── packages/\n│ ├── package-a/\n│ │ └── src/\n│ │ └── package_a/\n│ └── package-b/\n│ └── src/\n│ └── package_b/\n└── tests/","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Detailed patterns and worked examples","type":"text"}]},{"type":"paragraph","content":[{"text":"Detailed pattern documentation lives in ","type":"text"},{"text":"references/details.md","type":"text","marks":[{"type":"code_inline"}]},{"text":". Read that file when the navigation tier above is insufficient.","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"python-packaging","author":"@skillopedia","source":{"stars":42106,"repo_name":"agents","origin_url":"https://github.com/wshobson/agents/blob/HEAD/plugins/python-development/skills/python-packaging/SKILL.md","repo_owner":"wshobson","body_sha256":"744653d7bca3b0cfcb50155a3bb9ef56c7aba7eb4923091d07e75171261e5b49","cluster_key":"7dec6646cb1efb3ce8ee1db9dadc77a3845a5352f7fae7cfa5faa14048a8bb9c","clean_bundle":{"format":"clean-skill-bundle-v1","source":"wshobson/agents/plugins/python-development/skills/python-packaging/SKILL.md","text_bytes":14579,"source_commit":"7e2fb559cf4b824b27f1fec49fe88f7511066d26","skills_sh_rank":1906,"attachment_count":2,"text_attachments":2,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"plugins/python-development/skills/python-packaging/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"software-engineering","category_label":"Engineering"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"software-engineering","import_tag":"skills-sh-top20k-2026-11","description":"Create distributable Python packages with proper project structure, setup.py/pyproject.toml, and publishing to PyPI. Use when packaging Python libraries, creating CLI tools, or distributing Python code."}},"renderedAt":1793661278729}

Python Packaging Comprehensive guide to creating, structuring, and distributing Python packages using modern packaging tools, pyproject.toml, and publishing to PyPI. When to Use This Skill - Creating Python libraries for distribution - Building command-line tools with entry points - Publishing packages to PyPI or private repositories - Setting up Python project structure - Creating installable packages with dependencies - Building wheels and source distributions - Versioning and releasing Python packages - Creating namespace packages - Implementing package metadata and classifiers Core Concep…