Files
gh-jmazzahacks-byteforge-cl…/skills/python-pypi-setup/SKILL.md
2025-11-30 08:27:45 +08:00

443 lines
9.3 KiB
Markdown

---
name: python-pypi-setup
description: Set up Python project for PyPI publishing with pyproject.toml, src layout, and build scripts
---
# Python PyPI Project Setup Pattern
This skill helps you set up a Python project for PyPI publishing following modern best practices with pyproject.toml, src layout, and standardized build/publish scripts.
## When to Use This Skill
Use this skill when:
- Starting a new Python package for PyPI distribution
- You want to use modern pyproject.toml-based configuration
- You need a standardized src/ layout with explicit package discovery
- You want automated build and publish scripts
## What This Skill Creates
1. **`pyproject.toml`** - Modern Python project configuration
2. **`src/{package_name}/`** - Source layout with package structure
3. **`.gitignore`** - Comprehensive Python gitignore
4. **`dev-requirements.txt`** - Development dependencies (build, twine, testing tools)
5. **`build-publish.sh`** - Automated build and publish script
6. **`README.md`** - Basic project documentation
## Step 1: Gather Project Information
**IMPORTANT**: Before creating files, ask the user these questions:
1. **"What is your project name?"** (e.g., "pg-podcast-toolkit", "mypackage")
- Use this to derive:
- PyPI package name: `{project-name}` (with hyphens, e.g., `pg-podcast-toolkit`)
- Python package name: `{package_name}` (with underscores, e.g., `pg_podcast_toolkit`)
- Module directory: `src/{package_name}/`
2. **"What is the project description?"** (brief one-line description for PyPI)
3. **"What is your name?"** (for author field)
4. **"What is your email?"** (for author field)
5. **"What is your GitHub username?"** (for project URLs)
6. **"What license do you want to use?"** (options: MIT, Apache-2.0, GPL-3.0, BSD-3-Clause)
7. **"What Python version should be the minimum requirement?"** (default: 3.8)
8. **"What are your initial dependencies?"** (optional - comma-separated list, can be empty)
9. **"What keywords describe your project?"** (optional - for PyPI searchability)
## Step 2: Create Directory Structure
Create these directories if they don't exist:
```
{project_root}/
├── src/
│ └── {package_name}/
└── (other files at root)
```
## Step 3: Create pyproject.toml
Create `pyproject.toml` with the following structure, **substituting project-specific values**:
```toml
[project]
name = "{project-name}"
version = "0.0.1"
authors = [
{ name="{author_name}", email="{author_email}" },
]
description = "{project_description}"
keywords = [{keywords_list}]
readme = "README.md"
requires-python = ">={python_version}"
license = {text = "{license_name} License"}
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: {license_classifier}",
"Operating System :: OS Independent",
]
dependencies = [
{dependencies_list}
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/{package_name}"]
[project.urls]
Homepage = "https://github.com/{github_username}/{project-name}"
Issues = "https://github.com/{github_username}/{project-name}/issues"
```
**CRITICAL Substitutions**:
- `{project-name}` → project name with hyphens (e.g., `pg-podcast-toolkit`)
- `{package_name}` → package name with underscores (e.g., `pg_podcast_toolkit`)
- `{author_name}` → author's name
- `{author_email}` → author's email
- `{project_description}` → one-line description
- `{keywords_list}` → comma-separated quoted keywords (e.g., `"podcasting", "rss", "parser"`) or empty
- `{python_version}` → minimum Python version (e.g., `3.8`)
- `{license_name}` → license name (e.g., `MIT`, `Apache-2.0`)
- `{license_classifier}` → OSI classifier (e.g., `MIT License`, `Apache Software License`)
- `{dependencies_list}` → comma-separated quoted dependencies (e.g., `'requests', 'beautifulsoup4'`) or empty
- `{github_username}` → GitHub username
**License Classifiers Mapping**:
- MIT → `MIT License`
- Apache-2.0 → `Apache Software License`
- GPL-3.0 → `GNU General Public License v3 (GPLv3)`
- BSD-3-Clause → `BSD License`
## Step 4: Create Comprehensive .gitignore
Create `.gitignore` with comprehensive Python patterns:
```gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
*.manifest
*.spec
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
Pipfile.lock
# PEP 582
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
bin/
include/
pyvenv.cfg
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
```
## Step 5: Create dev-requirements.txt
Create `dev-requirements.txt` with development dependencies:
```
build
twine
pytest
black
mypy
```
These are the tools needed to build, publish, and develop the package. Add other dev tools as needed (isort, pytest-cov, etc.).
## Step 6: Create build-publish.sh
Create `build-publish.sh` with venv activation and build/publish commands:
```bash
#!/bin/bash
# Build and publish package to PyPI
# Activates virtual environment before running
# Activate virtual environment
source bin/activate
# Clean previous builds
rm -rf dist/*
# Build package
python -m build
# Upload to PyPI
python -m twine upload dist/*
```
**Note**: This script follows the convention that the virtual environment is in `bin/` at the project root.
## Step 7: Create Package Structure
Create the basic package structure:
1. **`src/{package_name}/__init__.py`** - Package initialization file:
```python
"""
{project_description}
"""
__version__ = "0.0.1"
```
2. **If this is a library package**, you can add:
```python
# Export main classes/functions here for easier imports
# from .module import ClassName, function_name
# __all__ = ['ClassName', 'function_name']
```
## Step 8: Create README.md
Create `README.md` with basic project documentation:
```markdown
# {project-name}
{project_description}
## Installation
```bash
pip install {project-name}
```
## Usage
```python
import {package_name}
# Add usage examples here
```
## Development
### Setup
```bash
# Create virtual environment
python -m venv .
# Activate virtual environment
source bin/activate # On Windows: bin\Scripts\activate
# Install dependencies
pip install -r dev-requirements.txt
pip install -e .
```
### Building and Publishing
```bash
# Make sure you have PyPI credentials configured
# Build and publish to PyPI
./build-publish.sh
```
## License
{license_name}
## Author
{author_name} ({author_email})
```
## Step 9: Make Script Executable
Run:
```bash
chmod +x build-publish.sh
```
## Step 10: Create Initial Git Repository (if needed)
If not already a git repository:
```bash
git init
git add .
git commit -m "Initial project structure for PyPI package"
```
## Step 11: Document Next Steps
Inform the user of the next steps:
1. **Install development dependencies**:
```bash
source bin/activate
pip install -r dev-requirements.txt
```
2. **Install package in development mode**:
```bash
pip install -e .
```
3. **Write your code** in `src/{package_name}/`
4. **Update version** in `pyproject.toml` before publishing
5. **Configure PyPI credentials** (one-time setup):
```bash
# Create ~/.pypirc with your PyPI token
```
6. **Build and publish**:
```bash
./build-publish.sh
```
## Design Principles
This pattern follows these principles:
1. **Modern pyproject.toml** - No setup.py needed, all config in pyproject.toml
2. **Src Layout** - Source code in `src/` directory for better separation
3. **Explicit Package Discovery** - Using hatchling with explicit package paths
4. **Comprehensive .gitignore** - Covers all common Python artifacts
5. **Virtual Environment Convention** - Uses `bin/` at project root
6. **Automated Publishing** - Simple script for build and publish
7. **Best Practices** - Follows PEP 517/518 and modern Python packaging standards
## Example Usage in Claude Code
User: "Set up a Python package for PyPI"
Claude: "What is your project name?"
User: "awesome-lib"
Claude: [Asks remaining questions]
Claude:
1. Creates src/awesome_lib/ directory structure
2. Creates pyproject.toml with project metadata
3. Creates comprehensive .gitignore
4. Creates dev-requirements.txt with build tools and dev dependencies
5. Creates build-publish.sh script
6. Creates src/awesome_lib/__init__.py
7. Creates README.md with instructions
8. Makes script executable
9. Documents next steps for the user