ScottIzi commited on
Commit
2ea6547
·
verified ·
1 Parent(s): c4ef135

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. Dockerfile +7 -10
  2. app.py +75 -68
  3. requirements.txt +156 -2
Dockerfile CHANGED
@@ -1,16 +1,13 @@
1
- # Use a minimal base image with Python 3.9 installed
2
- FROM python:3.9-slim
3
 
4
- # Set the working directory inside the container to /app
5
  WORKDIR /app
6
 
7
- # Copy all files from the current directory on the host to the container's /app directory
8
  COPY . .
9
 
10
- # Install Python dependencies listed in requirements.txt
11
- RUN pip3 install -r requirements.txt
12
 
13
- # Define the command to run the Streamlit app on port 8501 and make it accessible externally
14
- CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0", "--server.enableXsrfProtection=false"]
15
-
16
- # NOTE: Disable XSRF protection for easier external access in order to make batch predictions
 
1
+ FROM python:3.12-slim
 
2
 
3
+ # Set the working directory inside the container
4
  WORKDIR /app
5
 
6
+ # Copy all files from current directory to container
7
  COPY . .
8
 
9
+ # Install dependencies
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
 
12
+ # Run Flask app with Gunicorn
13
+ CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:7860", "app:superkart_api"]
 
 
app.py CHANGED
@@ -1,82 +1,89 @@
1
 
2
- import streamlit as st
3
- import requests
 
 
 
4
 
5
- st.title("SuperKart Sales Prediction App")
 
6
 
7
- # Input fields for product and store data
8
- Product_Weight = st.number_input("Product Weight", min_value=0.0, value=12.66)
9
 
10
- Product_Sugar_Content = st.selectbox(
11
- "Product Sugar Content",
12
- ["Low Sugar", "Regular", "No Sugar"]
13
- )
14
 
15
- Product_Allocated_Area = st.number_input(
16
- "Product Allocated Area",
17
- min_value=0.0,
18
- value=10.0
19
- )
20
 
21
- Product_MRP = st.number_input(
22
- "Product MRP",
23
- min_value=0.0,
24
- value=100.0
25
- )
 
 
 
 
 
 
 
 
26
 
27
- Store_Size = st.selectbox(
28
- "Store Size",
29
- ["Small", "Medium", "High"]
30
- )
 
31
 
32
- Store_Location_City_Type = st.selectbox(
33
- "Store Location City Type",
34
- ["Tier 1", "Tier 2", "Tier 3"]
35
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- Store_Type = st.selectbox(
38
- "Store Type",
39
- ["Grocery Store", "Supermarket Type1", "Supermarket Type2", "Supermarket Type3"]
40
- )
 
 
 
 
 
 
 
 
 
41
 
42
- Product_Id_char = st.text_input(
43
- "Product ID Character",
44
- value="P001"
45
- )
46
 
47
- Store_Age_Years = st.number_input(
48
- "Store Age (Years)",
49
- min_value=0,
50
- value=10
51
- )
52
 
53
- Product_Type_Category = st.selectbox(
54
- "Product Type Category",
55
- ["Food", "Drinks", "Household", "Health", "Other"]
56
- )
57
 
58
- product_data = {
59
- "Product_Weight": Product_Weight,
60
- "Product_Sugar_Content": Product_Sugar_Content,
61
- "Product_Allocated_Area": Product_Allocated_Area,
62
- "Product_MRP": Product_MRP,
63
- "Store_Size": Store_Size,
64
- "Store_Location_City_Type": Store_Location_City_Type,
65
- "Store_Type": Store_Type,
66
- "Product_Id_char": Product_Id_char,
67
- "Store_Age_Years": Store_Age_Years,
68
- "Product_Type_Category": Product_Type_Category
69
- }
70
 
71
- if st.button("Predict", type='primary'):
72
- response = requests.post(
73
- "https://scottizi-greatlearningdeploymentproject.hf.space/v1/predict",
74
- json=product_data
75
- )
76
-
77
- if response.status_code == 200:
78
- result = response.json()
79
- predicted_sales = result["Sales"]
80
- st.write(f"Predicted Product Store Sales Total: ₹{predicted_sales:.2f}")
81
- else:
82
- st.error("Error in API request")
 
1
 
2
+ # Import necessary libraries
3
+ import numpy as np
4
+ import joblib # For loading the serialized model
5
+ import polars as pl # Polars instead of pandas
6
+ from flask import Flask, request, jsonify # Flask API
7
 
8
+ # Initialize Flask app with a name
9
+ superkart_api = Flask("SuperKart_API")
10
 
11
+ # Load trained model pipeline
12
+ model = joblib.load("Gradient-Boosting-Regressor-Tuned.joblib")
13
 
14
+ # Home route
15
+ @superkart_api.get('/')
16
+ def home():
17
+ return "SuperKart Sales Prediction API is running"
18
 
19
+ # Prediction endpoint
20
+ @superkart_api.post('/v1/predict')
21
+ def predict_sales():
22
+ # Get JSON input
23
+ data = request.get_json()
24
 
25
+ # Extract features
26
+ required_fields = [
27
+ 'Product_Weight',
28
+ 'Product_Sugar_Content',
29
+ 'Product_Allocated_Area',
30
+ 'Product_MRP',
31
+ 'Store_Size',
32
+ 'Store_Location_City_Type',
33
+ 'Store_Type',
34
+ 'Product_Id_char',
35
+ 'Store_Age_Years',
36
+ 'Product_Type_Category'
37
+ ]
38
 
39
+ # Check for missing or null values
40
+ missing_fields = [
41
+ field for field in required_fields
42
+ if field not in data or data[field] is None or data[field] == ""
43
+ ]
44
 
45
+ # If any field is missing → return error
46
+ if missing_fields:
47
+ return jsonify({
48
+ "error": "Missing or empty fields in request body",
49
+ "missing_fields": missing_fields,
50
+ "expected_format": {
51
+ "Product_Weight": "float",
52
+ "Product_Sugar_Content": "string",
53
+ "Product_Allocated_Area": "float",
54
+ "Product_MRP": "float",
55
+ "Store_Size": "string",
56
+ "Store_Location_City_Type": "string",
57
+ "Store_Type": "string",
58
+ "Product_Id_char": "string",
59
+ "Store_Age_Years": "float",
60
+ "Product_Type_Category": "string"
61
+ }
62
+ }), 400
63
 
64
+ # Safe to build sample
65
+ sample = {
66
+ 'Product_Weight': data['Product_Weight'],
67
+ 'Product_Sugar_Content': data['Product_Sugar_Content'],
68
+ 'Product_Allocated_Area': data['Product_Allocated_Area'],
69
+ 'Product_MRP': data['Product_MRP'],
70
+ 'Store_Size': data['Store_Size'],
71
+ 'Store_Location_City_Type': data['Store_Location_City_Type'],
72
+ 'Store_Type': data['Store_Type'],
73
+ 'Product_Id_char': data['Product_Id_char'],
74
+ 'Store_Age_Years': data['Store_Age_Years'],
75
+ 'Product_Type_Category': data['Product_Type_Category']
76
+ }
77
 
78
+ # Convert to Polars DataFrame
79
+ input_data = pl.DataFrame([sample])
 
 
80
 
81
+ # Convert to numpy for sklearn compatibility (safe step)
82
+ prediction = model.predict(input_data.to_pandas()).tolist()[0]
 
 
 
83
 
84
+ return jsonify({'Sales': prediction})
 
 
 
85
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ # Run app
88
+ if __name__ == '__main__':
89
+ superkart_api.run(debug=True)
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,2 +1,156 @@
1
- requests==2.32.3
2
- streamlit==1.45.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ annotated-doc==0.0.4
2
+ annotated-types==0.7.0
3
+ anyio==4.13.0
4
+ argon2-cffi==25.1.0
5
+ argon2-cffi-bindings==25.1.0
6
+ arrow==1.4.0
7
+ asttokens==3.0.1
8
+ async-lru==2.3.0
9
+ attrs==26.1.0
10
+ babel==2.18.0
11
+ beautifulsoup4==4.14.3
12
+ bleach==6.3.0
13
+ blinker==1.9.0
14
+ certifi==2026.4.22
15
+ cffi==2.0.0
16
+ charset-normalizer==3.4.7
17
+ click==8.3.3
18
+ comm==0.2.3
19
+ contourpy==1.3.3
20
+ cycler==0.12.1
21
+ dacite==1.9.2
22
+ debugpy==1.8.20
23
+ decorator==5.2.1
24
+ defusedxml==0.7.1
25
+ executing==2.2.1
26
+ fastjsonschema==2.21.2
27
+ fg-data-profiling==4.19.1
28
+ filelock==3.29.0
29
+ filetype==1.2.0
30
+ flask==3.1.3
31
+ fonttools==4.62.1
32
+ fqdn==1.5.1
33
+ fsspec==2026.4.0
34
+ h11==0.16.0
35
+ hf-xet==1.5.0
36
+ httpcore==1.0.9
37
+ httpx==0.28.1
38
+ huggingface-hub==1.14.0
39
+ idna==3.13
40
+ imagehash==4.3.2
41
+ ipykernel==7.2.0
42
+ ipython==9.13.0
43
+ ipython-pygments-lexers==1.1.1
44
+ ipywidgets==8.1.8
45
+ isoduration==20.11.0
46
+ itsdangerous==2.2.0
47
+ jedi==0.20.0
48
+ jinja2==3.1.6
49
+ joblib==1.5.3
50
+ json5==0.14.0
51
+ jsonpointer==3.1.1
52
+ jsonschema==4.26.0
53
+ jsonschema-specifications==2025.9.1
54
+ jupyter-client==8.8.0
55
+ jupyter-core==5.9.1
56
+ jupyter-events==0.12.1
57
+ jupyter-lsp==2.3.1
58
+ jupyter-server==2.18.2
59
+ jupyter-server-terminals==0.5.4
60
+ jupyterlab==4.5.7
61
+ jupyterlab-pygments==0.3.0
62
+ jupyterlab-server==2.28.0
63
+ jupyterlab-widgets==3.0.16
64
+ kiwisolver==1.5.0
65
+ lark==1.3.1
66
+ llvmlite==0.45.1
67
+ markdown-it-py==4.2.0
68
+ markupsafe==3.0.3
69
+ matplotlib==3.10.0
70
+ matplotlib-inline==0.2.2
71
+ mdurl==0.1.2
72
+ minify-html==0.18.1
73
+ mistune==3.2.1
74
+ multimethod==1.12
75
+ nbclient==0.10.4
76
+ nbconvert==7.17.1
77
+ nbformat==5.10.4
78
+ nest-asyncio==1.6.0
79
+ networkx==3.6.1
80
+ notebook==7.5.6
81
+ notebook-shim==0.2.4
82
+ numba==0.62.1
83
+ numpy==2.3.5
84
+ nvidia-nccl-cu12==2.30.4
85
+ packaging==26.2
86
+ pandas==2.3.3
87
+ pandocfilters==1.5.1
88
+ parso==0.8.7
89
+ patsy==1.0.2
90
+ pexpect==4.9.0
91
+ phik==0.12.5
92
+ pillow==12.2.0
93
+ pip==26.1.1
94
+ platformdirs==4.9.6
95
+ polars==1.40.1
96
+ polars-runtime-32==1.40.1
97
+ prometheus-client==0.25.0
98
+ prompt-toolkit==3.0.52
99
+ psutil==7.2.2
100
+ ptyprocess==0.7.0
101
+ pure-eval==0.2.3
102
+ puremagic==2.2.0
103
+ pyarrow==24.0.0
104
+ pycparser==3.0
105
+ pydantic==2.13.4
106
+ pydantic-core==2.46.4
107
+ pygments==2.20.0
108
+ pyparsing==3.3.2
109
+ python-dateutil==2.9.0.post0
110
+ python-dotenv==1.2.2
111
+ python-json-logger==4.1.0
112
+ pytz==2026.2
113
+ pywavelets==1.9.0
114
+ pyyaml==6.0.3
115
+ pyzmq==27.1.0
116
+ referencing==0.37.0
117
+ requests==2.33.1
118
+ rfc3339-validator==0.1.4
119
+ rfc3986-validator==0.1.1
120
+ rfc3987-syntax==1.1.0
121
+ rich==15.0.0
122
+ rpds-py==0.30.0
123
+ scikit-learn==1.8.0
124
+ scipy==1.16.3
125
+ seaborn==0.13.2
126
+ send2trash==2.1.0
127
+ setuptools==75.8.0
128
+ shellingham==1.5.4
129
+ six==1.17.0
130
+ soupsieve==2.8.3
131
+ stack-data==0.6.3
132
+ statsmodels==0.14.6
133
+ terminado==0.18.1
134
+ threadpoolctl==3.6.0
135
+ tinycss2==1.4.0
136
+ tornado==6.5.5
137
+ tqdm==4.67.3
138
+ traitlets==5.15.0
139
+ typeguard==4.5.1
140
+ typer==0.25.1
141
+ typing-extensions==4.15.0
142
+ typing-inspection==0.4.2
143
+ tzdata==2026.2
144
+ uri-template==1.3.0
145
+ urllib3==2.7.0
146
+ visions==0.8.1
147
+ wcwidth==0.7.0
148
+ webcolors==25.10.0
149
+ webencodings==0.5.1
150
+ websocket-client==1.9.0
151
+ werkzeug==3.1.8
152
+ wheel==0.47.0
153
+ widgetsnbextension==4.0.15
154
+ wordcloud==1.9.6
155
+ xgboost==3.2.0
156
+ gunicorn==21.2.0