# Modern Python Project Structure

## Learning Objectives

- Understand modern Python project layouts
- Learn about `pyproject.toml` and `pixi.toml` configuration files
- Set up proper directory structure for CLI applications
- Implement version control best practices

## Project Layout Options

There are two main approaches to organizing Python projects:

### Flat Layout

```
my-cli/
├── my_cli/
│   ├── __init__.py
│   ├── cli.py
│   └── utils.py
├── tests/
├── pyproject.toml
└── README.md
```

### Src Layout (Recommended)

```
my-cli/
├── src/
│   └── my_cli/
│       ├── __init__.py
│       ├── cli.py
│       └── utils.py
├── tests/
├── pyproject.toml
├── pixi.toml
└── README.md
```

**Why src layout?**
- Prevents accidental imports from development directory
- Clearer separation between source and other files
- Better for testing and packaging

## Essential Configuration Files

### pyproject.toml

The modern standard for Python project metadata:

```toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-cli-tool"
version = "0.1.0"
description = "An AI-powered CLI tool"
authors = [{name = "Your Name", email = "you@example.com"}]
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
    "typer>=0.9",
    "rich>=13.0",
]

[project.scripts]
my-cli = "my_cli.cli:app"

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

[tool.mypy]
python_version = "3.11"
strict = true
```

### pixi.toml

Pixi-specific configuration for environment management:

```toml
[project]
name = "my-cli-tool"
version = "0.1.0"
description = "An AI-powered CLI tool"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-64", "win-64"]

[dependencies]
python = ">=3.11"
typer = ">=0.9"
rich = ">=13.0"

[feature.dev.dependencies]
pytest = "*"
ruff = "*"
mypy = "*"
black = "*"

[environments]
default = []
dev = ["dev"]

[tasks]
start = "python -m my_cli.cli"
test = "pytest tests/"
lint = "ruff check src/"
format = "black src/ tests/"
```

## Complete Project Structure

Here's a complete, production-ready project structure:

```
my-cli-tool/
├── .git/                      # Git repository
├── .gitignore                 # Git ignore rules
├── .vscode/                   # VS Code settings
│   └── settings.json
├── src/
│   └── my_cli/
│       ├── __init__.py        # Package initialization
│       ├── cli.py             # Main CLI entry point
│       ├── commands/          # Command modules
│       │   ├── __init__.py
│       │   ├── organize.py
│       │   └── stats.py
│       ├── core/              # Core functionality
│       │   ├── __init__.py
│       │   └── processor.py
│       └── utils/             # Utility functions
│           ├── __init__.py
│           └── helpers.py
├── tests/
│   ├── __init__.py
│   ├── conftest.py            # Pytest configuration
│   ├── test_cli.py
│   └── test_core.py
├── docs/                      # Documentation
│   └── README.md
├── .gitignore
├── pyproject.toml             # Python project config
├── pixi.toml                  # Pixi environment config
├── pixi.lock                  # Locked dependencies
├── LICENSE                    # License file
└── README.md                  # Project documentation
```

## Creating the Structure

Use this script to create the structure:

```bash
#!/bin/bash
# create-project.sh

PROJECT_NAME="my-cli-tool"
PACKAGE_NAME="my_cli"

# Create directories
mkdir -p $PROJECT_NAME/{src/$PACKAGE_NAME/{commands,core,utils},tests,docs,.vscode}

# Create __init__.py files
touch $PROJECT_NAME/src/$PACKAGE_NAME/__init__.py
touch $PROJECT_NAME/src/$PACKAGE_NAME/commands/__init__.py
touch $PROJECT_NAME/src/$PACKAGE_NAME/core/__init__.py
touch $PROJECT_NAME/src/$PACKAGE_NAME/utils/__init__.py
touch $PROJECT_NAME/tests/__init__.py

# Create main files
touch $PROJECT_NAME/src/$PACKAGE_NAME/cli.py
touch $PROJECT_NAME/README.md
touch $PROJECT_NAME/LICENSE

echo "Project structure created!"
```

Or use pixi to create it:

```bash
# Initialize with pixi
pixi init my-cli-tool
cd my-cli-tool

# Add Python and dependencies
pixi add python typer rich

# Create src layout
mkdir -p src/my_cli/{commands,core,utils}
touch src/my_cli/__init__.py
touch src/my_cli/cli.py

# Create tests
mkdir tests
touch tests/__init__.py
```

## .gitignore

Essential patterns for Python projects:

```gitignore
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Virtual environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Pixi
.pixi/
pixi.lock

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~

# Testing
.pytest_cache/
.coverage
htmlcov/

# OS
.DS_Store
Thumbs.db
```

## Version Control Setup

Initialize Git and make your first commit:

```bash
# Initialize repository
git init

# Create .gitignore (use content above)
# Use Copilot: "Generate a comprehensive .gitignore for Python projects"

# Add files
git add .

# First commit
git commit -m "Initial project structure"

# Create GitHub repository (optional)
gh repo create my-cli-tool --public --source=. --remote=origin
git push -u origin main
```

## Package Initialization

### src/my_cli/__init__.py

```python
"""My CLI Tool - An AI-powered command-line application."""

__version__ = "0.1.0"
__author__ = "Your Name"
__email__ = "you@example.com"

# Export main components
from .cli import app

__all__ = ["app"]
```

## Best Practices

1. **Use src layout**: Prevents import issues and improves testing
2. **Lock dependencies**: Commit `pixi.lock` for reproducibility
3. **Separate concerns**: Use subdirectories for commands, core logic, and utilities
4. **Write tests early**: Create test files alongside implementation
5. **Document as you go**: Update README with each feature
6. **Use type hints**: Enable better IDE support and catch errors early

## Using Copilot for Project Setup

Ask Copilot to help with:

```python
# In your IDE, write comments like:
# "Create a pyproject.toml for a CLI tool with typer and rich dependencies"
# "Generate a comprehensive .gitignore for a Python project"
# "Create a README template for a CLI application"
```

## Next Steps

With your project structure in place, you're ready to start building your CLI application. In the next chapter, we'll use Typer to create powerful command-line interfaces.

## Resources

- [Python Packaging Guide](https://packaging.python.org/)
- [Pixi Project Configuration](https://pixi.sh/latest/reference/project_configuration/)
- [PEP 518 - pyproject.toml](https://peps.python.org/pep-0518/)
