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

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. Dockerfile +10 -7
  2. app.py +68 -75
  3. requirements.txt +2 -155
Dockerfile CHANGED
@@ -1,13 +1,16 @@
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"]
 
 
 
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
app.py CHANGED
@@ -1,89 +1,82 @@
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)
 
 
 
 
 
 
 
 
 
 
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")
requirements.txt CHANGED
@@ -1,155 +1,2 @@
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-json-logger==4.1.0
111
- pytz==2026.2
112
- pywavelets==1.9.0
113
- pyyaml==6.0.3
114
- pyzmq==27.1.0
115
- referencing==0.37.0
116
- requests==2.33.1
117
- rfc3339-validator==0.1.4
118
- rfc3986-validator==0.1.1
119
- rfc3987-syntax==1.1.0
120
- rich==15.0.0
121
- rpds-py==0.30.0
122
- scikit-learn==1.8.0
123
- scipy==1.16.3
124
- seaborn==0.13.2
125
- send2trash==2.1.0
126
- setuptools==75.8.0
127
- shellingham==1.5.4
128
- six==1.17.0
129
- soupsieve==2.8.3
130
- stack-data==0.6.3
131
- statsmodels==0.14.6
132
- terminado==0.18.1
133
- threadpoolctl==3.6.0
134
- tinycss2==1.4.0
135
- tornado==6.5.5
136
- tqdm==4.67.3
137
- traitlets==5.15.0
138
- typeguard==4.5.1
139
- typer==0.25.1
140
- typing-extensions==4.15.0
141
- typing-inspection==0.4.2
142
- tzdata==2026.2
143
- uri-template==1.3.0
144
- urllib3==2.7.0
145
- visions==0.8.1
146
- wcwidth==0.7.0
147
- webcolors==25.10.0
148
- webencodings==0.5.1
149
- websocket-client==1.9.0
150
- werkzeug==3.1.8
151
- wheel==0.47.0
152
- widgetsnbextension==4.0.15
153
- wordcloud==1.9.6
154
- xgboost==3.2.0
155
- gunicorn==21.2.0
 
1
+ requests==2.32.3
2
+ streamlit==1.45.0