Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
docs/_build
scratch
scratch
.idea/
224 changes: 224 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

This is a **fork** of [py-pkgs/py-pkgs-cookiecutter](https://github.com/py-pkgs/py-pkgs-cookiecutter), a cookiecutter template for generating Python packages. This fork extends the original with:

- Clean Architecture / DDD patterns (domain, application, infrastructure layers)
- FastAPI REST API with versioned endpoints
- Docker and docker-compose support
- Automatic setup and dependency installation via cookiecutter hooks
- Makefile with common development commands
- Semantic Release for automated versioning
- Pre-commit hooks for code quality
- CI workflows (GitHub Actions)

## Repository Structure

- **Root level**: The cookiecutter template configuration
- **`{{ cookiecutter.__package_slug }}/`**: The template directory that gets rendered when creating a new project
- **`tests/`**: Tests for the cookiecutter template itself (not the generated package)
- **`docs/`**: Documentation for the cookiecutter template (Sphinx-based)
- **`hooks/`**: Pre- and post-generation hooks for template initialization

## Development Commands

### Setting Up the Cookiecutter Development Environment

```bash
# Install template dependencies
pip install -r requirements.txt

# This installs: cookiecutter >= 2.0.0, pytest
```

### Testing the Cookiecutter Template

```bash
# Run all template tests (parametrized across license/CI combinations)
pytest tests/

# Run a specific test
pytest tests/test_cookiecutter.py::test_cookiecutter_default_options -v

# Generate a test package with default options
cookiecutter . --no-input --output-dir /tmp/test

# Generate a test package with specific options
cookiecutter . --no-input --output-dir /tmp/test \
package_name="test_pkg" \
open_source_license="MIT" \
include_github_actions="ci"
```

### Building Documentation

```bash
cd docs
make html
# Generated docs will be in docs/_build/html
```

## Template Configuration

The template options are defined in `cookiecutter.json`:
- `author_name`: Author name and email
- `package_name`: Name of the generated package
- `package_short_description`: Package description
- `package_version`: Initial version (default: 0.1.0)
- `python_version`: Python version to target (default: 3.12.8)
- `open_source_license`: License choice (MIT, Apache, GPL, BSD, CC0, Proprietary, None)
- `include_github_actions`: CI/CD options (no, ci)

## Generated Package Architecture

The template generates a package following clean architecture/DDD patterns:

```
src/<package>/
├── domain/ # Business logic layer
│ ├── entities/ # Domain entities (Task, TaskList)
│ ├── repositories/ # Repository interfaces
│ └── services/ # Domain services
├── application/ # Use cases/application services
└── infrastructure/ # External concerns
├── persistence/ # Database models and repository implementations
│ ├── models/ # SQLAlchemy models
│ └── repositories/ # RDS repository implementations
└── web/ # FastAPI web layer
├── api/v1/ # REST API endpoints
└── ui/ # UI routes
```

### Generated Package Makefile Targets

The generated package includes a Makefile with these commands:

**Development Setup:**
- `make setup` - Setup Python environment (pyenv, Python, virtualenv, Poetry)
- `make deps` - Install dependencies from pyproject.toml
- `make install` - Install package in development mode

**Testing:**
- `make test` - Run unit tests with pytest
- `make test-cov` - Run tests with coverage report

**Running the Application:**
- `make start` - Start FastAPI app (localhost only)
- `make dev-server` - Start FastAPI app (network accessible)
- `make prod-server` - Start FastAPI app in production mode

**Docker:**
- `make docker-build` - Build Docker image
- `make docker-up` - Build and start Docker compose stack
- `make docker-down` - Stop Docker compose stack
- `make docker-logs` - Tail Docker logs

**Utilities:**
- `make clean` - Clean build artifacts
- `make help` - Show available commands

## Cookiecutter Hooks

### Pre-Generation Hook (`hooks/pre_gen_project.py`)

Validates that cookiecutter >= 2.0.0 is installed. Exits with error message if requirement not met.

### Post-Generation Hook (`hooks/post_gen_project.py`)

Runs after template generation to:
1. **Setup Environment**: Runs `make setup` to initialize Python environment (pyenv, virtualenv, Poetry)
2. **Initialize Git**: Creates git repository and makes initial commit with all generated files
3. **Install Dependencies** (Optional): Prompts user to select dependency groups (core, test, linting) and installs them with `poetry add`
4. **Open in VS Code** (Optional): If VS Code is installed, offers to open the project in the editor
5. **Ready to Code**: Displays next steps and available commands

The hook automatically configures git with the author information from the template.

**Interactive Prompts:**
- Dependency groups selection (core, test, linting) - defaults to Yes, can skip with no
- VS Code opening - defaults to Yes, can skip with no
- Only shows in interactive mode (terminals, not CI/CD)

## Generated Package Features

Each generated project includes:

**Clean Architecture Structure:**
- Domain layer (entities, repositories, services)
- Application layer (use cases)
- Infrastructure layer (persistence, web, DI)

**FastAPI REST API:**
- Versioned endpoints (v1)
- Pydantic schemas for validation
- Dependency injection with dependency-injector
- OpenAPI/Swagger documentation at `/docs`

**Database Support:**
- SQLAlchemy ORM
- Alembic migrations
- Support for SQLite (default) and PostgreSQL

**Testing:**
- pytest with fixtures (conftest.py)
- CRUD flow tests
- API integration tests
- Repository tests

**Development Tools:**
- Makefile with 20+ commands
- Pre-commit hooks (ruff, black, mypy, bandit)
- Docker and docker-compose support
- Semantic Release for versioning

## Dependency Groups

The post-generation hook prompts users to optionally install dependency groups:

**Core Dependencies** - Production dependencies:
- FastAPI, SQLAlchemy, Pydantic, Click, Python-dotenv
- Database support: Alembic, databases, aiosqlite, psycopg
- Development tools: pre-commit, semantic-release, ipython, ipdb, twine

**Test Dependencies** - Testing and QA:
- pytest, pytest-cov, pytest-asyncio, coverage, pytest-html, tox, httpx

**Linting Dependencies** - Code quality:
- ruff, black

Users can select any combination of these groups during project generation, and they will be automatically installed using `poetry add`.

## VS Code Configuration

The generated project includes VS Code settings for optimal development experience:

- **Python Interpreter**: Automatically detected from pyenv environment
- **Terminal Integration**: Shells configured to activate the pyenv environment with login shell (`-l` flag)
- **Pytest Integration**: Configured for running tests directly from VS Code
- **Type Checking**: Set to "basic" mode for Python analysis

The `.vscode/settings.json` file includes:
- `python.venvPath`: Points to `~/.pyenv/versions/{python_version}/envs` where pyenv creates virtual environments
- `python.terminal.activateEnvironment`: Disabled (pyenv handles activation via `.python-version`)
- Task automation: Set to manual/on-demand execution

**How VS Code detects the Python environment:**
1. `.python-version` file tells pyenv which environment to activate (e.g., "myproject")
2. `python.venvPath` tells VS Code where to look for venvs (pyenv's envs folder)
3. VS Code matches the project name with the venv name to detect the correct interpreter
4. Terminal automatically uses login shell which activates pyenv

## Key Files

- `cookiecutter.json`: Template variables and available options
- `tests/test_cookiecutter.py`: Parametrized tests covering all license/CI combinations
- `hooks/post_gen_project.py`: Post-generation hook for setup, git init, and optional dependency installation
- `{{ cookiecutter.__package_slug }}/pyproject.toml`: Poetry configuration with semantic-release setup
- `{{ cookiecutter.__package_slug }}/Makefile`: Generated package's development commands
- `{{ cookiecutter.__package_slug }}/scripts/setup_env.sh`: Environment setup script (pyenv, Python, virtualenv, Poetry)
- `{{ cookiecutter.__package_slug }}/.python-version`: Python version specification for pyenv
- `{{ cookiecutter.__package_slug }}/.pre-commit-config.yaml`: Pre-commit hooks configuration
- `{{ cookiecutter.__package_slug }}/.vscode/settings.json`: VS Code configuration for Python development
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Py-Pkgs-Cookiecutter: A cookiecutter template for Python packages

[![Documentation Status](https://readthedocs.org/projects/py-pkgs-cookiecutter/badge/?version=latest)](https://py-pkgs-cookiecutter.readthedocs.io/en/latest/)
![tests](https://github.com/py-pkgs/py-pkgs-cookiecutter/workflows/test/badge.svg)
[![release](https://img.shields.io/github/release/py-pkgs/py-pkgs-cookiecutter.svg)](https://github.com/py-pkgs/py-pkgs-cookiecutter/releases)
![tests](https://github.com/dctx-ztocker/py-pkgs-cookiecutter/workflows/test/badge.svg)
[![release](https://img.shields.io/github/release/dctx-ztocker/py-pkgs-cookiecutter.svg)](https://github.com/dctx-ztocker/py-pkgs-cookiecutter/releases)
[![python](https://img.shields.io/badge/python-%5E3.8-blue)]()
[![os](https://img.shields.io/badge/OS-Ubuntu%2C%20Mac%2C%20Windows-purple)]()

Expand All @@ -24,10 +23,10 @@ Please see the [documentation](https://py-pkgs-cookiecutter.readthedocs.io/en/la
pip install cookiecutter
```

2. Generate a Python package structure using [`py-pkgs-cookiecutter`](https://github.com/py-pkgs/py-pkgs-cookiecutter):
2. Generate a Python package structure using [`py-pkgs-cookiecutter`](https://github.com/dctx-ztocker/py-pkgs-cookiecutter):

```bash
cookiecutter https://github.com/py-pkgs/py-pkgs-cookiecutter.git
cookiecutter https://github.com/dctx-ztocker/py-pkgs-cookiecutter.git
```

3. After responding to the prompts you should have a directory structure similar to that shown below. To learn more about the contents of this directory structure, please see the `py-pkgs-cookiecutter` [documentation](https://py-pkgs-cookiecutter.readthedocs.io/en/latest/).
Expand Down
9 changes: 4 additions & 5 deletions cookiecutter.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"author_name": "Monty Python",
"author_name": "Jose Miguel <josemiguel@ztocker.com>",
"package_name": "mypkg",
"__package_slug": "{{ cookiecutter.package_name|lower|replace(' ', '_')|replace('-', '_') }}",
"package_short_description": "A package for doing great things!",
"package_version": "0.1.0",
"python_version": "3.12",
"python_version": "3.12.8",
"open_source_license": [
"MIT",
"Apache License 2.0",
Expand All @@ -16,7 +16,6 @@
],
"include_github_actions": [
"no",
"ci",
"ci+cd"
"ci"
]
}
}
Loading