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
