Skip to content

Commit be90430

Browse files
committed
Add FastAPI app with Docker, CI/CD, and linter
1 parent 17e9ca0 commit be90430

File tree

8 files changed

+21
-18
lines changed

8 files changed

+21
-18
lines changed

register.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
from pathlib import Path
2+
13
import mlflow
24
from mlflow.tracking import MlflowClient
3-
from pathlib import Path
45

56
# Set tracking URI
67
mlruns_path = Path(

src/PreProcessing.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import pandas as pd
2-
from sklearn.pipeline import Pipeline
3-
from sklearn.preprocessing import (
4-
StandardScaler,
5-
RobustScaler,
6-
OneHotEncoder
7-
)
82
from sklearn.compose import ColumnTransformer
93
from sklearn.impute import SimpleImputer
4+
from sklearn.pipeline import Pipeline
5+
from sklearn.preprocessing import OneHotEncoder, RobustScaler
106

117

128
def process_data(file_path):

src/RFMmetrics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pandas as pd
2-
from sklearn.preprocessing import StandardScaler
32
from sklearn.cluster import KMeans
3+
from sklearn.preprocessing import StandardScaler
44

55

66
def load_data(filepath):

src/api/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import mlflow
2-
from fastapi import FastAPI
32
import pandas as pd
3+
from fastapi import FastAPI
4+
45
from .pydantic_models import CustomerData, PredictionResponse
56

67
app = FastAPI()

src/api/pydantic_models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from pydantic import BaseModel
22

3+
34
class CustomerData(BaseModel):
45
Recency: int
56
Frequency: int

src/load.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import pandas as pd
1+
import matplotlib.pyplot as plt
22
import numpy as np
3+
import pandas as pd
34
import seaborn as sns
4-
import matplotlib.pyplot as plt
55
from scipy.stats import chi2_contingency
66

77

src/visualization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import matplotlib.pyplot as plt
12
import pandas as pd
23
import seaborn as sns
3-
import matplotlib.pyplot as plt
44

55

66
def plot_feature_distributions(data):

test/test_api.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import sys
21
import os
3-
from unittest.mock import patch, MagicMock
2+
import sys
3+
from unittest.mock import MagicMock, patch
4+
45

56
# Add src to sys.path for imports
6-
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src')))
7+
sys.path.insert(0, os.path.abspath(os.path.join(
8+
os.path.dirname(__file__), '..', 'src')))
9+
710

811
# Mock mlflow.sklearn.load_model before importing your app
912
mock_model = MagicMock()
@@ -12,12 +15,12 @@
1215
patcher = patch('mlflow.sklearn.load_model', return_value=mock_model)
1316
patcher.start()
1417

15-
from api.main import app # import AFTER patching
16-
1718
from fastapi.testclient import TestClient
19+
from api.main import app # import AFTER patching
1820

1921
client = TestClient(app)
2022

23+
2124
def test_predict():
2225
sample_data = {
2326
"Recency": 1,
@@ -45,12 +48,13 @@ def test_predict():
4548
"ProductCategory_ticket": False,
4649
"ProductCategory_transport": False,
4750
"ProductCategory_tv": False,
48-
"ProductCategory_utility_bill": False
51+
"ProductCategory_utility_bill": False,
4952
}
5053

5154
response = client.post("/predict", json=sample_data)
5255
assert response.status_code == 200
5356
assert "risk_probability" in response.json()
5457
assert abs(response.json()["risk_probability"] - 0.7) < 1e-6
5558

59+
5660
patcher.stop()

0 commit comments

Comments
 (0)