⚡ Token Efficiency Note: This file contains complete operational instructions (~2,500 tokens).
Auto-loaded: NO (load explicitly with#file:AGENTS.mdwhen you need detailed procedures)
When to load: Complex workflows, troubleshooting, CI/CD setup, detailed architecture questions
Related files: See#file:.github/copilot-instructions.mdfor quick context (auto-loaded, ~500 tokens)
# Install all dependencies
pip install -r requirements.txt
pip install -r requirements-lint.txt
pip install -r requirements-test.txt
# Start development server
uvicorn main:app --reload --port 9000
# View API documentation
# Open http://localhost:9000/docs in browserThis project requires Python 3.13.3 (specified in .python-version).
If using pyenv, asdf, or mise, the correct version activates automatically. Otherwise, ensure Python 3.13.3 is installed before running any commands.
# Run all tests with verbose output
pytest -v
# Run tests with coverage report (matches CI)
pytest --cov=./ --cov-report=xml --cov-report=term
# Run specific test file
pytest tests/test_main.py -v
# Run specific test function
pytest tests/test_main.py::test_health_check -vCoverage requirement: Tests must maintain coverage. The CI pipeline enforces this with .coveragerc configuration.
# Lint code (must pass before committing)
flake8 .
# Check code formatting (must pass before committing)
black --check .
# Auto-format code
black .Pre-commit checklist:
- Run
flake8 .- must pass with no errors - Run
black --check .- must pass with no formatting changes needed (or runblack .to auto-fix) - Run
pytest --cov=./ --cov-report=term- all tests must pass
Style rules (enforced by Black + Flake8):
- Line length: 88 characters
- Target: Python 3.13
- Black configuration in
pyproject.toml - Flake8 configuration in
.flake8
# Database auto-initializes on first app startup via lifespan handler in main.py
# Pre-seeded database ships in storage/players.db
# To reset database to seed state (local development)
rm storage/players.db
# Next app startup will recreate from seed data
# Docker: Reset database by removing volume
docker compose down -v
# Next startup will reinitialize from built-in seedImportant: The database is SQLite stored in storage/players.db. It auto-seeds with football player data on first run.
# Build container image
docker compose build
# Start application in container
docker compose up
# Start in detached mode (background)
docker compose up -d
# View logs
docker compose logs -f
# Stop application
docker compose down
# Stop and remove database volume (full reset)
docker compose down -v
# Health check (when running)
curl http://localhost:9000/healthFirst run behavior: Container copies pre-seeded SQLite database into persistent volume. Subsequent runs reuse that volume to preserve data.
Trigger: Push to master or PR to master
Jobs:
- Lint: Commit messages (commitlint) → Flake8 → Black check
- Test: pytest with verbose output → coverage report generation
- Coverage: Upload to Codecov and Codacy (requires secrets)
Local validation (run this before pushing):
# Matches CI exactly
flake8 . && \
black --check . && \
pytest -v && \
pytest --cov=./ --cov-report=xml --cov-report=termTrigger: Version tags in format v{MAJOR}.{MINOR}.{PATCH}-{COACH}
Example:
git tag -a v1.0.0-ancelotti -m "Release 1.0.0 - Ancelotti"
git push origin v1.0.0-ancelottiPipeline automatically:
- Runs full test suite with coverage
- Builds multi-stage Docker image
- Pushes to GHCR with multiple tags (version, coach name, latest)
- Generates changelog from commits
- Creates GitHub Release with auto-generated notes
Coach naming convention: Famous football coaches A-Z (see README.md for full list)
Structure: Layered architecture (Routes → Services → Database)
routes/ # FastAPI endpoints with caching
├── player_route.py # CRUD endpoints
└── health_route.py # Health check
services/ # Business logic layer
└── player_service.py # Async database operations
databases/ # Database setup
└── player_database.py # SQLAlchemy engine, session, Base
schemas/ # ORM models
└── player_schema.py # Player table definition
models/ # API models
└── player_model.py # Pydantic validation (camelCase)
tests/ # Test suite
├── conftest.py # Fixtures (TestClient)
├── test_main.py # Endpoint tests
└── player_stub.py # Test data
Key patterns:
- Dependency injection:
AsyncSessionviaDepends(generate_async_session) - Async everywhere: SQLAlchemy async, aiocache, FastAPI async endpoints
- Pydantic validation: Request/response with camelCase aliasing
- In-memory caching: aiocache on GET endpoints
- Lifespan handler: DB initialization on app startup
# Kill process on port 9000
lsof -ti:9000 | xargs kill -9# Ensure all dependencies installed
pip install -r requirements.txt -r requirements-lint.txt -r requirements-test.txt
# Verify Python version
python --version # Should be 3.13.3# Stop all running instances
pkill -f uvicorn
# Reset database
rm storage/players.db# Clean slate
docker compose down -v
docker compose build --no-cache
docker compose upOpen http://localhost:9000/docs - Interactive Swagger UI with "Try it out" buttons
Pre-configured collection available in postman_collections/
# Health check
curl http://localhost:9000/health
# Get all players
curl http://localhost:9000/players
# Get player by ID
curl http://localhost:9000/players/1
# Create player
curl -X POST http://localhost:9000/players \
-H "Content-Type: application/json" \
-d '{"firstName":"Pele","lastName":"Nascimento","club":"Santos","nationality":"Brazil","dateOfBirth":"1940-10-23"}'
# Update player
curl -X PUT http://localhost:9000/players/1 \
-H "Content-Type: application/json" \
-d '{"firstName":"Diego","lastName":"Maradona","club":"Napoli","nationality":"Argentina","dateOfBirth":"1960-10-30"}'
# Delete player
curl -X DELETE http://localhost:9000/players/1- Never commit secrets: No API keys, tokens, or credentials in code
- Test coverage: Maintain existing coverage levels (currently high)
- Commit messages: Follow conventional commits (enforced by commitlint)
- Python version: Must use 3.13.3 for consistency with CI/CD
- Dependencies: Keep requirements files in sync with actual usage
- Database: SQLite is for demo/development only - not production-ready