A containerized FastAPI application for managing members and yearly memberships, built with modern Python tooling and an automated GitHub Actions–backed CI pipeline.
- Purpose: CRUD‑style API to create, query, update, and delete members and their yearly memberships.
- Goals:
- Practice backend development with FastAPI, SQLAlchemy, and Pydantic
- Enforce consistent development and testing environments via Docker Compose
- Automate linting, testing, and coverage reporting in CI
- Generate PDF welcome letters for new or existing members
- Python 3.11
- FastAPI – RESTful API framework
- SQLAlchemy + Alembic – ORM and schema migrations
- Pydantic – Data validation and configuration management
- PostgreSQL 16 – Relational database
- pgAdmin – GUI for PostgreSQL administration
- WeasyPrint – HTML/CSS to PDF rendering engine
- Jinja2 – Templating for personalized letters
- Docker & Docker Compose – Containerized services
- Make – Task automation and local developer tooling
- Pytest – Unit and integration testing
- GitHub Actions – CI pipeline (linting, tests, coverage)
- Ruff + Black – Linting and formatting
- Prometheus – Metrics collection
- Grafana – Dashboarding and visualization
- Loki + Promtail – Centralized structured logging
- cAdvisor – Container-level resource monitoring
- Alertmanager – Rule-based alerting
-
Clone & enter
git clone https://github.com/liocle/membership-manager.git cd membership-manager -
Set up Python
python -m venv .venv source .venv/bin/activate pip install -r app/requirements.txt -
Configure environment
- Copy
.env.exampleto.envand fill in values - Ensure
.env.testcontains test DB settings
- Copy
-
Start services
make
- API docs: http://localhost:8000/docs
- PDF letters are saved to output/letters/ by default
- Workflow file:
.github/workflows/ci.yml - Triggers:
pull_requestand manual viaworkflow_dispatch - Jobs:
- Lint & Format Check (
ruff,black --check) - Python Tests & Coverage (
pytest --cov=app, uploadscoverage.xml)
- Lint & Format Check (
Branch protection on main requires:
- Passing Python Tests & Coverage status check
- Lint check executed but do not fail PRs
- PDF Generation Tests
Run tests locally with coverage:
make pytest_localThis will:
- Spin up Postgres via Docker Compose
- Recreate the test database
- Execute
pytestwith:--cov=app--cov-report=term-missing--cov-report=xml--cov-report=html
Artifacts:
coverage.xml(CI artifact)htmlcov/index.html(open in browser)
membership-manager/
├─ .github/workflows/ci.yml
├─ docker-compose.yml
├─ Makefile
├─ .env, .env.test
├─ app/
│ ├─ api/ # route modules
│ ├─ models.py # SQLAlchemy models
│ ├─ schemas.py # Pydantic schemas
│ ├─ config.py # settings loader
│ ├─ create_tables.py
│ ├─ database.py
│ └─ pdf/ # PDF generation scripts & templates
│ ├─ generate_welcome_letter.py
│ └─ templates/
│ └─ welcome_letter.html.jinja2
├─ monitoring/
│ ├─ alertmanager/config.yml
│ ├─ Container_Host_Monitoring_cAdvisor.jpeg
│ ├─ grafana/
│ │ ├─ dashboards/
│ │ │ └─ docker_metrics_grafana_cadvisor.json
│ │ └─ provisioning/
│ │ ├─ dashboards/dashboards.yml
│ │ └─ datasources/datasource.yml
│ ├─ loki/loki-local-config.yml
│ ├─ monitoring_README.md
│ ├─ PostgreSQL.jpeg
│ ├─ Prometheus.jpeg
│ ├─ Prom_FastAPI.jpeg
│ ├─ prometheus/prometheus.yml
│ ├─ prometheus/rules/container_alerts.yml
│ └─ promtail-config.yml
├─ output/
│ └─ letters/ # Generated PDF files (gitignored)
├─ tests/ # pytest suite
│ └─ test_generate_welcome_letter_route.py
├─ coverage.xml # coverage artifact
├─ htmlcov/ # HTML coverage report
└─ requirements.txt
make– start Postgres, API & pgAdminmake pytest_local– run tests with coverage reportsmake create_db– run DB init scriptmake seed_db– seed sample datamake help– display full command list
This project provisions a complete observability stack with a single command:
make up_allAll services (Prometheus, Grafana, Loki, cAdvisor, etc.) are orchestrated via Docker Compose and automatically configured. On launch, Grafana loads a prebuilt dashboard to display real-time container metrics such as:
- CPU, memory, and network usage
- Disk I/O and container health
📁 For screenshots and config details, see monitoring/ and monitoring_README.md.
MIT © 2025 Lionel Clerc
