1+ # =========================
2+ # Predictive Maintenance API
3+ # =========================
4+
5+ IMAGE_NAME ?= pm-api
6+ CONTAINER_NAME ?= pm-api
7+ PORT ?= 8000
8+
9+ API_URL ?= http://127.0.0.1:$(PORT )
10+
11+
12+ help :
13+ @echo " Available commands:"
14+ @echo " make build Build Docker image ($( IMAGE_NAME) )"
15+ @echo " make run Run container on port $( PORT) "
16+ @echo " make run-d Run container in background (detached)"
17+ @echo " make stop Stop & remove container ($( CONTAINER_NAME) )"
18+ @echo " make rebuild Stop + build + run"
19+ @echo " make clean Remove image + prune build cache"
20+ @echo " make health Call GET /health"
21+ @echo " make predict Call POST /predict (single record)"
22+ @echo " make explain Call POST /explain (top contributors)"
23+ @echo " make explain-plot Call POST /explain/plot -> saves shap.png"
24+ @echo " make test Run all tests (local)"
25+ @echo " make test-cov Run tests with coverage"
26+ @echo " make test-unit Run unit tests only"
27+ @echo " make test-integration Run integration tests only"
28+ @echo " make test-docker Run tests inside Docker"
29+ @echo " "
30+ @echo " Vars:"
31+ @echo " IMAGE_NAME=pm-api PORT=8000 CONTAINER_NAME=pm-api"
32+
33+ # Build Docker image
34+ build :
35+ docker build -t $(IMAGE_NAME ) .
36+
37+ # Run container (foreground)
38+ run : stop
39+ docker run --rm \
40+ --name $(CONTAINER_NAME ) \
41+ -p $(PORT ) :8000 \
42+ $(IMAGE_NAME )
43+
44+ # Run container (detached)
45+ run-d : stop
46+ docker run -d \
47+ --name $(CONTAINER_NAME ) \
48+ -p $(PORT ) :8000 \
49+ $(IMAGE_NAME )
50+ @echo " Running: $( CONTAINER_NAME) on $( API_URL) "
51+
52+
53+
54+ # Stop & remove container by name (safe if not running)
55+ stop :
56+ @docker rm -f $(CONTAINER_NAME ) > /dev/null 2>&1 || true
57+ @echo " Container $( CONTAINER_NAME) stopped/removed (if existed)."
58+
59+ # Rebuild (stop + build + run-d)
60+ rebuild : stop build run-d
61+
62+ # Healthcheck
63+ health :
64+ curl -s $(API_URL ) /health | python3 -m json.tool
65+
66+ # Test /predict
67+ predict :
68+ curl -s -X POST $(API_URL ) /predict \
69+ -H " Content-Type: application/json" \
70+ -d ' {"Air temperature [K]":300,"Process temperature [K]":310,"Rotational speed [rpm]":1500,"Torque [Nm]":40,"Tool wear [min]":100,"Type":"M"}' \
71+ | python3 -m json.tool
72+
73+ # Test /explain
74+ explain :
75+ curl -s -X POST " $( API_URL) /explain?top_k=8" \
76+ -H " Content-Type: application/json" \
77+ -d ' {"Air temperature [K]":300,"Process temperature [K]":310,"Rotational speed [rpm]":1500,"Torque [Nm]":40,"Tool wear [min]":100,"Type":"M"}' \
78+ | python3 -m json.tool
79+
80+ # Test /explain/plot (saves PNG)
81+ explain-plot :
82+ curl -s -X POST $(API_URL ) /explain/plot \
83+ -H " Content-Type: application/json" \
84+ -d ' {"Air temperature [K]":300,"Process temperature [K]":310,"Rotational speed [rpm]":1500,"Torque [Nm]":40,"Tool wear [min]":100,"Type":"M"}' \
85+ -o shap.png
86+ @echo " Saved SHAP plot to ./shap.png"
87+
88+
89+ # Clean image + build cache
90+ clean : stop
91+ @docker image rm -f $(IMAGE_NAME ) > /dev/null 2>&1 || true
92+ @docker builder prune -f > /dev/null 2>&1 || true
93+ @echo " 🧹 Cleanup done."
94+
95+ # Run tests inside Docker container
96+ test-docker : build
97+ docker run --rm \
98+ $(IMAGE_NAME ) \
99+ pytest -v
100+
101+ test-docker-cov : build
102+ docker run --rm \
103+ $(IMAGE_NAME ) \
104+ pytest -v --cov=src --cov=api --cov-report=term-missing
0 commit comments