Amitgupta2982 commited on
Commit
a09aa5e
·
verified ·
1 Parent(s): 4a5ed6e

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. Dockerfile +10 -3
  2. app.py +10 -18
  3. requirements.txt +0 -1
Dockerfile CHANGED
@@ -1,14 +1,14 @@
1
- # Dockerfile — FastAPI backend for HF Spaces (Docker SDK)
2
  FROM python:3.10-slim
3
 
4
- # (Optional) system deps helpful for pandas/numpy wheels
5
  RUN apt-get update && apt-get install -y --no-install-recommends \
6
  build-essential gcc g++ && \
7
  rm -rf /var/lib/apt/lists/*
8
 
9
  WORKDIR /app
10
 
11
- # Install Python dependencies first (better layer caching)
12
  COPY requirements.txt /app/requirements.txt
13
  RUN pip install --no-cache-dir --upgrade pip && \
14
  pip install --no-cache-dir -r requirements.txt
@@ -16,3 +16,10 @@ RUN pip install --no-cache-dir --upgrade pip && \
16
  # Copy app + model
17
  COPY app.py /app/app.py
18
  COPY SuperKart_prediction_model_v1_0.joblib /app/SuperKart_prediction_model_v1_0.joblib
 
 
 
 
 
 
 
 
1
+ # FastAPI backend for HF Spaces
2
  FROM python:3.10-slim
3
 
4
+ # Optional build deps for numpy/pandas
5
  RUN apt-get update && apt-get install -y --no-install-recommends \
6
  build-essential gcc g++ && \
7
  rm -rf /var/lib/apt/lists/*
8
 
9
  WORKDIR /app
10
 
11
+ # Install Python dependencies
12
  COPY requirements.txt /app/requirements.txt
13
  RUN pip install --no-cache-dir --upgrade pip && \
14
  pip install --no-cache-dir -r requirements.txt
 
16
  # Copy app + model
17
  COPY app.py /app/app.py
18
  COPY SuperKart_prediction_model_v1_0.joblib /app/SuperKart_prediction_model_v1_0.joblib
19
+
20
+ # Hugging Face Spaces expects PORT
21
+ ENV PORT=7860
22
+ EXPOSE 7860
23
+
24
+ # Start with uvicorn
25
+ CMD ["bash", "-lc", "uvicorn app:app --host 0.0.0.0 --port ${PORT}"]
app.py CHANGED
@@ -6,14 +6,13 @@ from fastapi import FastAPI, File, UploadFile, HTTPException
6
  from fastapi.middleware.cors import CORSMiddleware
7
  from pydantic import BaseModel
8
 
9
- MODEL_PATH = "SuperKart_prediction_model_v1_0.joblib" # <-- update if your filename differs
10
 
11
- # Expected feature order/names (must match training)
12
  EXPECTED_COLS = [
13
  "Product_Weight",
14
  "Product_Allocated_Area",
15
  "Product_MRP",
16
- "Store_Age", # change to Store_Age_Years or Store_Establishment_Year if that's what you trained on
17
  "Product_Sugar_Content",
18
  "Product_Type",
19
  "Store_Type",
@@ -21,45 +20,40 @@ EXPECTED_COLS = [
21
  "Store_Location_City_Type",
22
  ]
23
 
24
- # ---------- App ----------
25
  app = FastAPI(title="SuperKart Backend", version="1.0")
26
 
27
- # CORS (allow any frontend, incl. your Streamlit Space)
28
  app.add_middleware(
29
  CORSMiddleware,
30
- allow_origins=["*"], # tighten for prod
31
  allow_credentials=True,
32
  allow_methods=["*"],
33
  allow_headers=["*"],
34
  )
35
 
36
- # ---------- Load model at startup ----------
37
  model = None
 
38
  @app.on_event("startup")
39
  def load_model():
40
  global model
41
  model = joblib.load(MODEL_PATH)
42
 
43
- # ---------- Schemas ----------
44
  class Payload(BaseModel):
45
  Product_Weight: float
46
  Product_Allocated_Area: float
47
  Product_MRP: float
48
- Store_Age: int # adjust type/name if needed
49
  Product_Sugar_Content: str
50
  Product_Type: str
51
  Store_Type: str
52
- Store_Size: int # or str, if you trained as categorical strings
53
- Store_Location_City_Type: int # or str, adjust to your training
54
 
55
- # ---------- Helpers ----------
56
  def validate_and_order(df: pd.DataFrame) -> pd.DataFrame:
57
  missing = [c for c in EXPECTED_COLS if c not in df.columns]
58
  if missing:
59
  raise HTTPException(status_code=422, detail=f"Missing columns: {missing}")
60
  return df[EXPECTED_COLS].copy()
61
 
62
- # ---------- Endpoints ----------
63
  @app.get("/health")
64
  def health():
65
  return {"status": "ok"}
@@ -77,16 +71,14 @@ def predict_single(payload: Payload):
77
  @app.post("/v1/salespricebatch")
78
  def predict_batch(file: UploadFile = File(...)):
79
  try:
80
- # read CSV into DataFrame
81
  content = file.file.read()
82
  df = pd.read_csv(io.BytesIO(content))
83
  X = validate_and_order(df)
84
  y = model.predict(X)
85
- out = df.copy()
86
- out["Predicted Price"] = y
87
- # return as records (JSON)
88
- return json.loads(out.to_json(orient="records"))
89
  except HTTPException:
90
  raise
91
  except Exception as e:
92
  raise HTTPException(status_code=500, detail=str(e))
 
 
6
  from fastapi.middleware.cors import CORSMiddleware
7
  from pydantic import BaseModel
8
 
9
+ MODEL_PATH = "SuperKart_prediction_model_v1_0.joblib"
10
 
 
11
  EXPECTED_COLS = [
12
  "Product_Weight",
13
  "Product_Allocated_Area",
14
  "Product_MRP",
15
+ "Store_Age",
16
  "Product_Sugar_Content",
17
  "Product_Type",
18
  "Store_Type",
 
20
  "Store_Location_City_Type",
21
  ]
22
 
 
23
  app = FastAPI(title="SuperKart Backend", version="1.0")
24
 
 
25
  app.add_middleware(
26
  CORSMiddleware,
27
+ allow_origins=["*"],
28
  allow_credentials=True,
29
  allow_methods=["*"],
30
  allow_headers=["*"],
31
  )
32
 
 
33
  model = None
34
+
35
  @app.on_event("startup")
36
  def load_model():
37
  global model
38
  model = joblib.load(MODEL_PATH)
39
 
 
40
  class Payload(BaseModel):
41
  Product_Weight: float
42
  Product_Allocated_Area: float
43
  Product_MRP: float
44
+ Store_Age: int
45
  Product_Sugar_Content: str
46
  Product_Type: str
47
  Store_Type: str
48
+ Store_Size: int
49
+ Store_Location_City_Type: int
50
 
 
51
  def validate_and_order(df: pd.DataFrame) -> pd.DataFrame:
52
  missing = [c for c in EXPECTED_COLS if c not in df.columns]
53
  if missing:
54
  raise HTTPException(status_code=422, detail=f"Missing columns: {missing}")
55
  return df[EXPECTED_COLS].copy()
56
 
 
57
  @app.get("/health")
58
  def health():
59
  return {"status": "ok"}
 
71
  @app.post("/v1/salespricebatch")
72
  def predict_batch(file: UploadFile = File(...)):
73
  try:
 
74
  content = file.file.read()
75
  df = pd.read_csv(io.BytesIO(content))
76
  X = validate_and_order(df)
77
  y = model.predict(X)
78
+ df["Predicted Price"] = y
79
+ return json.loads(df.to_json(orient="records"))
 
 
80
  except HTTPException:
81
  raise
82
  except Exception as e:
83
  raise HTTPException(status_code=500, detail=str(e))
84
+
requirements.txt CHANGED
@@ -5,4 +5,3 @@ numpy==2.0.2
5
  scikit-learn==1.6.1
6
  xgboost==2.1.4
7
  joblib==1.4.2
8
- python-multipart==0.0.9
 
5
  scikit-learn==1.6.1
6
  xgboost==2.1.4
7
  joblib==1.4.2