Skip to content

Commit aa328da

Browse files
abpaiclaude
andcommitted
feat: transform template to generic Python boilerplate v0.3.0
Major refactoring to create a clean, OpenAI-agnostic Python project template: Dependencies: - Upgrade to Python 3.13 - Remove openai-agents dependency entirely - Update all packages to Oct 2025 versions (pydantic 2.11.10, structlog 25.4.0, ruff 0.13.3, etc.) Code: - Simplify src/main.py to basic Hello World with structlog - Remove OpenAI-specific settings (openai_api_key, default_model) - Update tests to validate LOG_LEVEL and LOG_FORMAT Tooling: - Upgrade pre-commit ruff to v0.13.3, add linting hook - Remove pyrightconfig.strict.json, consolidate config to pyproject.toml - Improve Makefile clean command to remove more cache directories - Delete .cursor/rules/general.mdc (superseded by AGENTS.md) Documentation: - Create comprehensive AGENTS.md with architecture principles and code style guide - Update README.md to reflect generic Python boilerplate usage - Update .env.example to remove OpenAI variables, fix typo All tests pass, linting clean, type checking passes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ac88415 commit aa328da

13 files changed

Lines changed: 279 additions & 831 deletions

.cursor/rules/general.mdc

Lines changed: 0 additions & 18 deletions
This file was deleted.

.env.example

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
# Copy this file to .env and uncomment/modify values as needed
22

33
# =============================================================================
4-
# Enviroment Variables
4+
# Environment Variables
55
# =============================================================================
66

7-
# Required: Your OpenAI API key for the Agents SDK to function.
8-
OPENAI_API_KEY=sk-...
9-
DEFAULT_MODEL=gpt-5-nano
10-
117
# Optional: The logging level for the application.
128
# Options: DEBUG, INFO, WARNING, ERROR
139
# Default: INFO

.pre-commit-config.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ repos:
1212
- id: check-docstring-first
1313

1414
- repo: https://github.com/astral-sh/ruff-pre-commit
15-
rev: v0.12.11
15+
rev: v0.13.3
1616
hooks:
17+
- id: ruff
18+
args: [--fix]
1719
- id: ruff-format
1820

1921
- repo: local

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.12
1+
3.13

AGENTS.md

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,64 @@
1-
# General Rules
1+
# AI Agent Code Guidelines
2+
3+
This document provides coding guidelines for AI agents working on this Python project.
24

35
## Environment and Dependencies
4-
- **Tooling**: Use `uv` for all package management.
6+
7+
- **Tooling**: Use `uv` for all package management
8+
- **Python Version**: 3.13+
9+
- **Package Manager**: uv (fast, modern dependency management)
510

611
## Code Style
712

8-
**Format**: 2-space indent, single quotes, `snake_case` vars/functions, `PascalCase` classes, `is_/has_/should_` booleans
13+
**Format**: 2-space indentation, single quotes, 88-character lines, `snake_case` variables/functions, `PascalCase` classes, boolean flags prefixed with `is_/has_/should_`. Pre-commit hooks ensure code quality on commit.
14+
15+
**Docstrings**:
16+
- Use simple one-line docstrings for most functions - be concise and descriptive
17+
- Type hints replace Args/Returns documentation - don't duplicate what's in the signature
18+
- No Examples section - type hints + function name should be self-explanatory
19+
- Exception: Top-level user-facing APIs may include brief usage notes if necessary
20+
- Rationale: Modern Python with PEP 484 type hints makes verbose docstrings redundant
21+
22+
## Architecture Principles
23+
24+
**Classes for state and lifecycle**, pure functions for transformations. Use classes when managing resources, coordinating operations, or defining interfaces.
25+
26+
**Protocols over inheritance**: Define interfaces with `typing.Protocol` for flexible, duck-typed implementations.
27+
28+
**Immutable configs**: Frozen dataclasses with `__post_init__` validation and factory classmethods (`from_uri()`, `from_dict()`).
29+
30+
**Factory functions**: Standalone functions (`get_backend()`, `resolve_config()`) that map configurations to implementations.
31+
32+
**Resource management**:
33+
- Reference counting for expensive resources (connections, clients) with acquire/release semantics
34+
- Context managers (`__enter__`/`__exit__`) for automatic cleanup
35+
- Track ownership with boolean flags to avoid closing borrowed resources
36+
37+
**Streaming over bulk**: Use `Iterator[T]` to yield chunks for large datasets. Implement retry logic within generators for resilience.
38+
39+
**Separation by lifecycle**: Split read and write operations into distinct classes, even when working with the same backend (e.g., `SessionStoreReader`, `SessionStoreWriter`).
40+
41+
**Domain exceptions**: Create specific exception types rather than generic `RuntimeError`.
42+
43+
**Performance**: Use `@dataclass(slots=True)` for frequently-instantiated objects and `TypeVar` for type-safe generic protocols.
44+
45+
**Resilience**: Exponential backoff for network operations, graceful empty returns over exceptions, debug logging for key metrics.
46+
47+
## Best Practices
948

10-
**Architecture**:
11-
- Pure functions preferred; classes for stateful operations (3+ shared params), data structures, framework requirements
1249
- RORO pattern: service functions receive/return single Pydantic objects
13-
- Single responsibility: break 150+ line functions into focused 15-25 line methods, early returns, no magic values, explicit dependencies
14-
- DRY principle: extract utility functions to eliminate code duplication when applicable
50+
- Single responsibility: break 150+ line functions into focused 15-25 line methods
51+
- Early returns, no magic values, explicit dependencies
52+
- DRY principle: extract utility functions to eliminate duplication
1553
- Pipeline pattern: chain transformations with clear inputs/outputs
1654
- No excessive error handling or low-value comments
1755

56+
## Pydantic Commitment
57+
58+
- All interface models use Pydantic `BaseModel` (not dataclasses)
59+
- Validation, `.model_dump()`, JSON serialization built-in
60+
- Reserve `@dataclass(slots=True)` only for inner performance-critical helpers (graph traversal caches, etc.)
61+
1862
## Codex Commands
1963

2064
Conventions:

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@ format:
3737
uv run ruff format .
3838

3939
typecheck:
40-
uv run pyright -p pyrightconfig.strict.json
40+
uv run pyright
4141

4242
test: ## Run Pytest
4343
uv run pytest
4444

4545
clean: ## Remove caches & pyc files
4646
find . -type f -name "*.pyc" -delete
47-
find . -type d -name "__pycache__" -exec rm -rf {} +
47+
find . -type d -name "pycache" -exec rm -rf {} +
48+
find . -type d -name ".pytest_cache" -exec rm -rf {} +
49+
find . -type d -name ".ruff_cache" -exec rm -rf {} +
50+
rm -rf .pytest_cache .ruff_cache .mypy_cache .coverage
4851

4952
lock-check: ## Ensure uv.lock is up-to-date
5053
uv sync --locked --extra dev

README.md

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This template is a **lean starting point** for Python projects that use:
66
- 🧪 Pytest – testing
77
- ⚙️ Pydantic Settings – typed environment configuration
88
- 📦 uv – fast dependency management / locking
9+
- 📝 structlog – structured logging
910

1011
---
1112

@@ -30,7 +31,7 @@ This template is a **lean starting point** for Python projects that use:
3031
make setup
3132
```
3233

33-
3. **Run the Quick-Start Agent Demo:**
34+
3. **Run the Application:**
3435

3536
```bash
3637
# This will use your activated environment
@@ -42,7 +43,7 @@ This template is a **lean starting point** for Python projects that use:
4243
make format && make lint && make test
4344
```
4445

45-
`src/main.py` is a minimal script that spins up an assistant. Modify it to explore the SDK.
46+
`src/main.py` is a minimal script with structured logging. Modify it to build your application.
4647

4748
---
4849

@@ -66,12 +67,10 @@ This template is a **lean starting point** for Python projects that use:
6667

6768
`utils/settings.py` reads variables from a `.env` file or the environment.
6869

69-
| Variable | Default | Description |
70-
| ---------------- | ------------ | ----------------------------------- |
71-
| `OPENAI_API_KEY` | (required) | Your OpenAI API key. |
72-
| `LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
73-
| `LOG_FORMAT` | `console` | `console` (colored) or `json`. |
74-
| `DEFAULT_MODEL` | `gpt-5-nano` | Default model for agents. |
70+
| Variable | Default | Description |
71+
| ------------ | --------- | ----------------------------------- |
72+
| `LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
73+
| `LOG_FORMAT` | `console` | `console` (colored) or `json`. |
7574

7675
See `.env.example` for a template.
7776

@@ -83,7 +82,7 @@ Only what you need, nothing more:
8382

8483
```
8584
├── src/
86-
│ └── main.py # Minimal OpenAI Agents example
85+
│ └── main.py # Main application entry point
8786
├── utils/
8887
│ └── settings.py # Pydantic Settings helper
8988
├── tests/
@@ -96,6 +95,19 @@ Only what you need, nothing more:
9695
9796
---
9897
98+
## Optional: ML Dependencies
99+
100+
This template includes an optional ML dependency group for data science and machine learning projects:
101+
102+
```bash
103+
# Install with ML dependencies
104+
uv sync --extra ml
105+
```
106+
107+
Includes: PyTorch, scikit-learn, MLflow, matplotlib, numpy, pandas, and seaborn.
108+
109+
---
110+
99111
## License
100112

101113
MIT

pyproject.toml

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,38 @@
11
[project]
22
name = "templates.python"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
description = "A boilerplate for Python projects."
55
readme = "README.md"
6-
requires-python = ">=3.12"
6+
requires-python = ">=3.13"
77
license = {text = "MIT"}
88
authors = [
99
{name = "Andy Pai", email = "andy@r2pi.co"},
1010
]
1111

1212
dependencies = [
13-
"openai-agents>=0.2.2",
14-
"pydantic>=2.11.7",
15-
"pydantic-settings>=2.10.1",
16-
"structlog>=24.0.0",
17-
"tqdm>=4.65.0",
13+
"pydantic>=2.11.10",
14+
"pydantic-settings>=2.11.0",
15+
"structlog>=25.4.0",
16+
"tqdm>=4.67.1",
1817
]
1918

2019
[project.optional-dependencies]
2120
dev = [
2221
"ipykernel>=6.30.1",
23-
"pre-commit>=4.2.0",
24-
"pyright>=1.1.405",
25-
"pytest>=8.4.1",
22+
"pre-commit>=4.3.0",
23+
"pyright>=1.1.406",
24+
"pytest>=8.4.2",
2625
"pytest-cov>=6.2.1",
27-
"ruff>=0.12.11",
26+
"ruff>=0.13.3",
2827
]
2928

3029
ml = [
3130
"torch>=2.7.1",
3231
"scikit-learn>=1.7.1",
3332
"mlflow>=3.1.1",
34-
"matplotlib>=3.10.3",
35-
"numpy>=2.3.1",
36-
"pandas>=2.3.1",
33+
"matplotlib>=3.10.6",
34+
"numpy>=2.3.3",
35+
"pandas>=2.3.3",
3736
"seaborn>=0.13.2",
3837
]
3938

@@ -63,7 +62,7 @@ line-ending = "auto"
6362

6463
[tool.pytest.ini_options]
6564
testpaths = ["tests"]
66-
python_files = ["test_*.py", "*_test.py"]
65+
python_files = ["test_*.py"]
6766
addopts = ["-ra"]
6867
pythonpath = ["."]
6968

@@ -75,5 +74,5 @@ typeCheckingMode = "off"
7574
reportMissingImports = true
7675
reportMissingTypeStubs = false
7776

78-
pythonVersion = "3.12"
77+
pythonVersion = "3.13"
7978
pythonPlatform = "All"

pyrightconfig.strict.json

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)