A enterprise-grade, high-performance RESTful API built with Flask (App Factory Pattern) and SQLAlchemy ORM mapped to the industry-standard Pagila (PostgreSQL DVD rental benchmark) dataset of over 40,000+ records.
This architecture features dynamic Read/Write DB Splitting using PostgreSQL Primary/Replica Physical Streaming Replication, containerized with Docker Compose, optimized with custom B-tree indexing, and verified via Pytest.
flowchart TD
Client["π± Client / HTTP Request"]
subgraph AppContainer ["π³ Flask API Container"]
FlaskFactory["Flask Application Factory (create_app)"]
Blueprints["Blueprints (films, customers, rentals, payments)"]
DBRouter{"π Database Router (db_router.py)"}
end
subgraph PrimaryDB ["π’ Postgres Primary (Port 5432)"]
WriteEngine["WriteSession Engine (pool_size=5)"]
PrimaryData[("Primary Database: appdb")]
end
subgraph ReplicaDB ["π΅ Postgres Read-Replica (Port 5433)"]
ReadEngine["ReadSession Engine (pool_size=5)"]
ReplicaData[("Replica Database: appdb")]
end
Client -->|"HTTP GET / POST / PUT / DELETE"| FlaskFactory
FlaskFactory --> Blueprints
Blueprints --> DBRouter
DBRouter -->|"Write Operations: POST, PUT, DELETE"| WriteEngine
WriteEngine --> PrimaryData
DBRouter -->|"Read Operations: GET"| ReadEngine
ReadEngine --> ReplicaData
PrimaryData -->|"β‘ Streaming Replication (WAL / pg_basebackup)"| ReplicaData
- ποΈ Flask Application Factory Pattern: Modular Blueprint architecture (
films,customers,rentals,payments,health). - π Smart Database Read/Write Splitting:
- Write Queries (POST / PUT / DELETE): Dispatched directly to the Primary PostgreSQL instance.
- Read Queries (GET): Distributed to the Read-Replica PostgreSQL node to maximize throughput and prevent lock contention.
- ποΈ Comprehensive Pagila ORM Mapping: 15+ fully defined SQLAlchemy models including complex many-to-many relationships (Films, Actors, Categories, Rentals, Payments, Customers, Inventory).
- π³ Complete Containerization: Docker Compose stack orchestrating Flask API, Primary Postgres DB, and Replica Postgres DB.
- β‘ Database Optimization: Custom indexing (
idx_api_rental_customer_id) yielding sub-3ms query execution times on high-frequency lookups. - π©Ί Health & Readiness Endpoints: Enterprise
/healthz(liveness) and/readyz(readiness with active DB ping) routes. - π§ͺ Automated Testing Suite: 100% suite pass rate with Pytest for endpoint validation and database routing integrity.
Project - Flask/
βββ 1__pagila-schema.sql # Pagila database schema definition
βββ 2__pagila-insert-data.sql # Pagila dataset insert script (40,000+ records)
βββ README.md # Project documentation
βββ flask-app/
βββ app/
β βββ __init__.py # Flask App Factory initialization & blueprint setup
β βββ config.py # Environment-driven configuration loader
β βββ models/
β β βββ db.py # SQLAlchemy database models & schemas
β βββ routes/ # Modular API Blueprints
β β βββ health.py # Health & readiness checks (/healthz, /readyz)
β β βββ films.py # Film catalog endpoints (/api/films)
β β βββ customers.py # Customer management endpoints (/api/customers)
β β βββ rentals.py # Rental transaction routes (/api/rentals)
β β βββ payments.py # Payment transaction routes (/api/payments)
β βββ services/
β βββ db_router.py # ReadSession & WriteSession connection router
βββ scripts/
β βββ setup_replication.sh # Physical replication setup & streaming script
βββ tests/
β βββ test_routes.py # Pytest integration & endpoint test suite
βββ Dockerfile # Container spec for Flask API app
βββ docker-compose.yml # Multi-container service orchestration
βββ requirements.txt # Python package dependencies
βββ wsgi.py # WSGI application entry point
Ensure you have the following installed on your machine:
- π³ Docker Desktop (running)
- π Bash Environment (WSL2 / Git Bash on Windows, Terminal on Linux/macOS)
From the root directory, navigate into flask-app and launch the Docker stack:
cd flask-app
docker compose up -d --buildThis spins up the Flask API container alongside empty PostgreSQL Primary and Replica services.
Return to the repository root and run the replication setup script:
cd ..
bash flask-app/scripts/setup_replication.sh- Creates the
replicatordatabase role with replication permissions on the Primary node. - Injects Pagila schema (
1__pagila-schema.sql) and sample data (2__pagila-insert-data.sql). - Executes
pg_basebackupto clone the Primary database state onto the Replica node. - Synchronizes replication streams and verifies row counts across both instances.
| Method | Endpoint | Description | Targeted DB |
|---|---|---|---|
GET |
/healthz |
Web application liveness check | None (N/A) |
GET |
/readyz |
Database connectivity readiness probe | Read Replica |
| Method | Endpoint | Query / Body Params | Description | Target DB |
|---|---|---|---|---|
GET |
/api/films/ |
?category=Action |
List top 50 films (optional category filter) | Read Replica |
GET |
/api/films/<id> |
β | Get film details with actors & categories | Read Replica |
POST |
/api/films/ |
{ "title": "..." } |
Create a new film entry | Primary DB |
PUT |
/api/films/<id> |
{ "rental_rate": 3.99 } |
Update film details | Primary DB |
DELETE |
/api/films/<id> |
β | Delete a film record | Primary DB |
{
"film_id": 1,
"title": "ACADEMY ADAPTATION",
"description": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies",
"categories": ["Documentary"],
"actors": [
{ "first_name": "PENELOPE", "last_name": "GUINESS" },
{ "first_name": "CHRISTIAN", "last_name": "GABLE" }
]
}| Method | Endpoint | Description | Target DB |
|---|---|---|---|
GET |
/api/customers/ |
List active customers | Read Replica |
GET |
/api/customers/<id> |
Get customer profile & address | Read Replica |
POST |
/api/customers/ |
Register a new customer | Primary DB |
PUT |
/api/customers/<id> |
Update customer email/status | Primary DB |
| Method | Endpoint | Description | Target DB |
|---|---|---|---|
GET |
/api/rentals/ |
List rentals (?customer_id=1) |
Read Replica |
POST |
/api/rentals/ |
Create new film rental record | Primary DB |
PUT |
/api/rentals/<id>/return |
Mark rental as returned | Primary DB |
GET |
/api/payments/ |
List payments (?customer_id=1) |
Read Replica |
POST |
/api/payments/ |
Record customer payment | Primary DB |
To ensure optimal execution under heavy workloads, key indexes were created on high-frequency query targets like rental(customer_id).
EXPLAIN ANALYZE SELECT * FROM rental WHERE customer_id = 1;Bitmap Heap Scan on rental (cost=4.53..82.68 rows=32 width=36) (actual time=1.099..1.347 rows=32 loops=1)
Recheck Cond: (customer_id = 1)
Heap Blocks: exact=28
-> Bitmap Index Scan on idx_api_rental_customer_id (cost=0.00..4.53 rows=32 width=0) (actual time=1.039..1.066 rows=32 loops=1)
Index Cond: (customer_id = 1)
Planning Time: 6.116 ms
Execution Time: 2.834 ms
β‘ Execution Time: ~2.83 ms via
Bitmap Index Scanonidx_api_rental_customer_id.
You can connect directly to both database nodes using any GUI client (DBeaver, pgAdmin 4, TablePlus):
| Setting | Primary Database Node | Read-Replica Node |
|---|---|---|
| Host | localhost |
localhost |
| Port | 5432 |
5433 |
| Database | appdb |
appdb |
| Username | postgres |
postgres |
| Password | studentpass |
studentpass |
Run the full integration test suite inside the container environment:
docker exec -it flask-app pytest -v============================= test session starts ==============================
platform linux -- Python 3.11.15, pytest-9.1.0
collected 8 items
tests/test_routes.py::test_healthz_returns_ok PASSED [ 12%]
tests/test_routes.py::test_get_films_returns_200 PASSED [ 25%]
tests/test_routes.py::test_create_film_returns_201 PASSED [ 37%]
tests/test_routes.py::test_get_film_not_found_returns_404 PASSED [ 50%]
tests/test_routes.py::test_get_customers_returns_200 PASSED [ 62%]
tests/test_routes.py::test_create_customer_returns_201 PASSED [ 75%]
tests/test_routes.py::test_create_rental_returns_201 PASSED [ 87%]
tests/test_routes.py::test_return_rental_updates_return_date PASSED [100%]
============================== 8 passed in 1.77s ===============================
This project is open-source and available under the MIT License.