Skip to content

Commit 8dc85ac

Browse files
committed
docs: optimize AI agent instructions for token efficiency
- Reduce copilot-instructions.md to thin pointer file (~500 tokens) - Add AGENTS.md with operational procedures (on-demand loading) - Implement tiered loading to minimize auto-loaded token cost - Add token efficiency headers explaining load strategy Instructions now use thin pointer architecture: essential context auto-loads, detailed procedures load on-demand via #file reference.
1 parent bce5022 commit 8dc85ac

File tree

2 files changed

+334
-40
lines changed

2 files changed

+334
-40
lines changed

.github/copilot-instructions.md

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,81 @@
1-
# Copilot Instructions for python-samples-fastapi-restful
1+
# GitHub Copilot Instructions
22

3-
## Project Overview
3+
> **⚡ Token Efficiency Note**: This is a minimal pointer file (~500 tokens, auto-loaded by Copilot).
4+
> For complete operational details, reference: `#file:AGENTS.md` (~2,500 tokens, loaded on-demand)
5+
> For specialized knowledge, use: `#file:SKILLS/<skill-name>/SKILL.md` (loaded on-demand when needed)
46
5-
This is a RESTful API proof of concept built with **Python 3.13** and **FastAPI**. The application manages football player data with full CRUD operations, featuring async SQLAlchemy ORM, in-memory caching, and SQLite database storage.
7+
## 🎯 Quick Context
68

7-
## Tech Stack
9+
**Project**: FastAPI REST API demonstrating modern Python async patterns
10+
**Stack**: Python 3.13 • FastAPI • SQLAlchemy (async) • SQLite • Docker • pytest
11+
**Pattern**: Routes → Services → Database (layered architecture)
12+
**Philosophy**: Learning-focused PoC emphasizing async/await and type safety
813

9-
- **Framework**: FastAPI 0.123.0 with standard dependencies
10-
- **Database**: SQLite with async support (`aiosqlite 0.21.0`)
11-
- **ORM**: SQLAlchemy 2.0.44 (async)
12-
- **Caching**: aiocache 0.12.3 (SimpleMemoryCache)
13-
- **Testing**: pytest 9.0.1, pytest-cov 7.0.0, pytest-sugar 1.1.1, gevent 25.9.1
14-
- **Linting**: flake8 7.3.0, black 25.11.0
15-
- **Python Version**: 3.13.3 (see `.python-version`)
16-
- **Server**: uvicorn (included in FastAPI standard dependencies)
17-
- **Container**: Docker with multi-stage builds, Docker Compose
14+
## 📐 Core Conventions
1815

19-
## Project Structure
16+
- **Naming**: snake_case for functions/variables, PascalCase for classes
17+
- **Type Hints**: Mandatory throughout (enforced by mypy if enabled)
18+
- **Async**: All I/O operations use `async`/`await`
19+
- **Testing**: pytest with fixtures and async support
20+
- **Formatting**: black (opinionated), flake8 (linting)
2021

22+
## 🏗️ Architecture at a Glance
23+
24+
```
25+
Route → Service → Database
26+
↓ ↓
27+
Cache Session
2128
```
22-
├── main.py # FastAPI app entry point, lifespan handler, router registration
23-
├── databases/
24-
│ └── player_database.py # Async engine, sessionmaker, Base, session generator
25-
├── models/
26-
│ └── player_model.py # Pydantic models for API request/response validation
27-
├── schemas/
28-
│ └── player_schema.py # SQLAlchemy ORM table schema definitions
29-
├── routes/
30-
│ ├── player_route.py # Player CRUD endpoints with caching
31-
│ └── health_route.py # Health check endpoint
32-
├── services/
33-
│ └── player_service.py # Async database CRUD operations
34-
├── tests/
35-
│ ├── conftest.py # pytest fixtures (TestClient)
36-
│ ├── test_main.py # Test suite for all endpoints
37-
│ └── player_stub.py # Test data stubs
38-
├── storage/ # SQLite database file (seeded)
39-
├── scripts/
40-
│ ├── entrypoint.sh # Docker entrypoint for DB initialization
41-
│ └── healthcheck.sh # Docker health check script
42-
└── postman_collections/ # Postman collection for API testing
29+
30+
- **Routes**: FastAPI endpoints with dependency injection
31+
- **Services**: Async database operations via SQLAlchemy
32+
- **Database**: SQLite with async support (`aiosqlite`)
33+
- **Models**: Pydantic for validation, SQLAlchemy for ORM
34+
- **Cache**: aiocache SimpleMemoryCache (10min/1hr TTL)
35+
36+
## ✅ Copilot Should
37+
38+
- Generate idiomatic async FastAPI code with proper type hints
39+
- Use SQLAlchemy async APIs (`select()`, `scalars()`, `session.commit()`)
40+
- Follow dependency injection pattern with `Depends()`
41+
- Write tests with pytest async fixtures
42+
- Apply Pydantic models for request/response validation
43+
- Use structured logging (avoid print statements)
44+
- Implement proper HTTP status codes and responses
45+
46+
## 🚫 Copilot Should Avoid
47+
48+
- Synchronous database operations
49+
- Mixing sync and async code
50+
- Missing type hints on functions
51+
- Using `print()` instead of logging
52+
- Creating routes without caching consideration
53+
- Ignoring Pydantic validation
54+
55+
## ⚡ Quick Commands
56+
57+
```bash
58+
# Run with hot reload
59+
uvicorn main:app --reload --host 0.0.0.0 --port 8000
60+
61+
# Test with coverage
62+
pytest --cov=. --cov-report=term-missing
63+
64+
# Docker
65+
docker compose up
66+
67+
# Swagger: http://localhost:8000/docs
4368
```
4469

45-
## Key Architectural Patterns
70+
## 📚 Need More Detail?
71+
72+
**For operational procedures**: Load `#file:AGENTS.md`
73+
**For Docker expertise**: *(Planned)* `#file:SKILLS/docker-containerization/SKILL.md`
74+
**For testing patterns**: *(Planned)* `#file:SKILLS/testing-patterns/SKILL.md`
75+
76+
---
4677

47-
1. **Layered Architecture**: Routes → Services → Database
48-
2. **Dependency Injection**: `AsyncSession` via `Depends(generate_async_session)`
49-
3. **Pydantic for Validation**: `PlayerModel` with camelCase aliasing (`to_camel`)
50-
4. **SQLAlchemy ORM**: `Player` schema mapped to `players` table
78+
💡 **Why this structure?** Copilot auto-loads this file on every chat (~500 tokens). Loading `AGENTS.md` or `SKILLS/` explicitly gives you deep context only when needed, saving 80% of your token budget!
5179
5. **Caching**: In-memory cache (10 min TTL) with `X-Cache` headers (HIT/MISS)
5280
6. **Async/Await**: All database operations are async
5381

AGENTS.md

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
# AGENTS.md
2+
3+
> **⚡ Token Efficiency Note**: This file contains complete operational instructions (~2,500 tokens).
4+
> **Auto-loaded**: NO (load explicitly with `#file:AGENTS.md` when you need detailed procedures)
5+
> **When to load**: Complex workflows, troubleshooting, CI/CD setup, detailed architecture questions
6+
> **Related files**: See `#file:.github/copilot-instructions.md` for quick context (auto-loaded, ~500 tokens)
7+
8+
---
9+
10+
## Quick Start
11+
12+
```bash
13+
# Install all dependencies
14+
pip install -r requirements.txt
15+
pip install -r requirements-lint.txt
16+
pip install -r requirements-test.txt
17+
18+
# Start development server
19+
uvicorn main:app --reload --port 9000
20+
21+
# View API documentation
22+
# Open http://localhost:9000/docs in browser
23+
```
24+
25+
## Python Version
26+
27+
This project requires **Python 3.13.3** (specified in `.python-version`).
28+
29+
If using pyenv, asdf, or mise, the correct version activates automatically. Otherwise, ensure Python 3.13.3 is installed before running any commands.
30+
31+
## Development Workflow
32+
33+
### Running Tests
34+
35+
```bash
36+
# Run all tests with verbose output
37+
pytest -v
38+
39+
# Run tests with coverage report (matches CI)
40+
pytest --cov=./ --cov-report=xml --cov-report=term
41+
42+
# Run specific test file
43+
pytest tests/test_main.py -v
44+
45+
# Run specific test function
46+
pytest tests/test_main.py::test_health_check -v
47+
```
48+
49+
**Coverage requirement**: Tests must maintain coverage. The CI pipeline enforces this with `.coveragerc` configuration.
50+
51+
### Code Quality
52+
53+
```bash
54+
# Lint code (must pass before committing)
55+
flake8 .
56+
57+
# Check code formatting (must pass before committing)
58+
black --check .
59+
60+
# Auto-format code
61+
black .
62+
```
63+
64+
**Pre-commit checklist**:
65+
1. Run `flake8 .` - must pass with no errors
66+
2. Run `black --check .` - must pass with no formatting changes needed (or run `black .` to auto-fix)
67+
3. Run `pytest --cov=./ --cov-report=term` - all tests must pass
68+
69+
**Style rules** (enforced by Black + Flake8):
70+
- Line length: 88 characters
71+
- Target: Python 3.13
72+
- Black configuration in `pyproject.toml`
73+
- Flake8 configuration in `.flake8`
74+
75+
### Database Management
76+
77+
```bash
78+
# Database auto-initializes on first app startup via lifespan handler in main.py
79+
# Pre-seeded database ships in storage/players.db
80+
81+
# To reset database to seed state (local development)
82+
rm storage/players.db
83+
# Next app startup will recreate from seed data
84+
85+
# Docker: Reset database by removing volume
86+
docker compose down -v
87+
# Next startup will reinitialize from built-in seed
88+
```
89+
90+
**Important**: The database is SQLite stored in `storage/players.db`. It auto-seeds with football player data on first run.
91+
92+
## Docker Workflow
93+
94+
```bash
95+
# Build container image
96+
docker compose build
97+
98+
# Start application in container
99+
docker compose up
100+
101+
# Start in detached mode (background)
102+
docker compose up -d
103+
104+
# View logs
105+
docker compose logs -f
106+
107+
# Stop application
108+
docker compose down
109+
110+
# Stop and remove database volume (full reset)
111+
docker compose down -v
112+
113+
# Health check (when running)
114+
curl http://localhost:9000/health
115+
```
116+
117+
**First run behavior**: Container copies pre-seeded SQLite database into persistent volume. Subsequent runs reuse that volume to preserve data.
118+
119+
## CI/CD Pipeline
120+
121+
### Continuous Integration (python-ci.yml)
122+
123+
**Trigger**: Push to `master` or PR to `master`
124+
125+
**Jobs**:
126+
1. **Lint**: Commit messages (commitlint) → Flake8 → Black check
127+
2. **Test**: pytest with verbose output → coverage report generation
128+
3. **Coverage**: Upload to Codecov and Codacy (requires secrets)
129+
130+
**Local validation** (run this before pushing):
131+
```bash
132+
# Matches CI exactly
133+
flake8 . && \
134+
black --check . && \
135+
pytest -v && \
136+
pytest --cov=./ --cov-report=xml --cov-report=term
137+
```
138+
139+
### Continuous Deployment (python-cd.yml)
140+
141+
**Trigger**: Version tags in format `v{MAJOR}.{MINOR}.{PATCH}-{COACH}`
142+
143+
Example:
144+
```bash
145+
git tag -a v1.0.0-ancelotti -m "Release 1.0.0 - Ancelotti"
146+
git push origin v1.0.0-ancelotti
147+
```
148+
149+
**Pipeline automatically**:
150+
- Runs full test suite with coverage
151+
- Builds multi-stage Docker image
152+
- Pushes to GHCR with multiple tags (version, coach name, latest)
153+
- Generates changelog from commits
154+
- Creates GitHub Release with auto-generated notes
155+
156+
**Coach naming convention**: Famous football coaches A-Z (see README.md for full list)
157+
158+
## Project Architecture
159+
160+
**Structure**: Layered architecture (Routes → Services → Database)
161+
162+
```
163+
routes/ # FastAPI endpoints with caching
164+
├── player_route.py # CRUD endpoints
165+
└── health_route.py # Health check
166+
167+
services/ # Business logic layer
168+
└── player_service.py # Async database operations
169+
170+
databases/ # Database setup
171+
└── player_database.py # SQLAlchemy engine, session, Base
172+
173+
schemas/ # ORM models
174+
└── player_schema.py # Player table definition
175+
176+
models/ # API models
177+
└── player_model.py # Pydantic validation (camelCase)
178+
179+
tests/ # Test suite
180+
├── conftest.py # Fixtures (TestClient)
181+
├── test_main.py # Endpoint tests
182+
└── player_stub.py # Test data
183+
```
184+
185+
**Key patterns**:
186+
- Dependency injection: `AsyncSession` via `Depends(generate_async_session)`
187+
- Async everywhere: SQLAlchemy async, aiocache, FastAPI async endpoints
188+
- Pydantic validation: Request/response with camelCase aliasing
189+
- In-memory caching: aiocache on GET endpoints
190+
- Lifespan handler: DB initialization on app startup
191+
192+
## Troubleshooting
193+
194+
### Port already in use
195+
```bash
196+
# Kill process on port 9000
197+
lsof -ti:9000 | xargs kill -9
198+
```
199+
200+
### Module import errors
201+
```bash
202+
# Ensure all dependencies installed
203+
pip install -r requirements.txt -r requirements-lint.txt -r requirements-test.txt
204+
205+
# Verify Python version
206+
python --version # Should be 3.13.3
207+
```
208+
209+
### Database locked errors
210+
```bash
211+
# Stop all running instances
212+
pkill -f uvicorn
213+
214+
# Reset database
215+
rm storage/players.db
216+
```
217+
218+
### Docker issues
219+
```bash
220+
# Clean slate
221+
docker compose down -v
222+
docker compose build --no-cache
223+
docker compose up
224+
```
225+
226+
## Testing the API
227+
228+
### Using FastAPI Docs (Recommended)
229+
Open http://localhost:9000/docs - Interactive Swagger UI with "Try it out" buttons
230+
231+
### Using Postman
232+
Pre-configured collection available in `postman_collections/`
233+
234+
### Using curl
235+
```bash
236+
# Health check
237+
curl http://localhost:9000/health
238+
239+
# Get all players
240+
curl http://localhost:9000/players
241+
242+
# Get player by ID
243+
curl http://localhost:9000/players/1
244+
245+
# Create player
246+
curl -X POST http://localhost:9000/players \
247+
-H "Content-Type: application/json" \
248+
-d '{"firstName":"Pele","lastName":"Nascimento","club":"Santos","nationality":"Brazil","dateOfBirth":"1940-10-23"}'
249+
250+
# Update player
251+
curl -X PUT http://localhost:9000/players/1 \
252+
-H "Content-Type: application/json" \
253+
-d '{"firstName":"Diego","lastName":"Maradona","club":"Napoli","nationality":"Argentina","dateOfBirth":"1960-10-30"}'
254+
255+
# Delete player
256+
curl -X DELETE http://localhost:9000/players/1
257+
```
258+
259+
## Important Notes
260+
261+
- **Never commit secrets**: No API keys, tokens, or credentials in code
262+
- **Test coverage**: Maintain existing coverage levels (currently high)
263+
- **Commit messages**: Follow conventional commits (enforced by commitlint)
264+
- **Python version**: Must use 3.13.3 for consistency with CI/CD
265+
- **Dependencies**: Keep requirements files in sync with actual usage
266+
- **Database**: SQLite is for demo/development only - not production-ready

0 commit comments

Comments
 (0)