Jainish1808 commited on
Commit
9062d0b
·
1 Parent(s): 7caa1e8

Initial upload of ML music classifier app

Browse files
.gitattributes CHANGED
@@ -1,35 +1,2 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
  *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  *.pkl filter=lfs diff=lfs merge=lfs -text
2
+ models/* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Copy requirements and install dependencies
6
+ COPY requirements.txt .
7
+ RUN pip install --no-cache-dir -r requirements.txt
8
+
9
+ # Copy application code and models
10
+ COPY . .
11
+
12
+ # Expose port
13
+ EXPOSE 7860
14
+
15
+ # Run the application
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,12 +1,38 @@
1
  ---
2
- title: Ml Music Classifier Api
3
- emoji: 💻
4
- colorFrom: green
5
- colorTo: indigo
6
  sdk: docker
7
  pinned: false
8
  license: mit
9
- short_description: FastAPI service that predicts music
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: ML Music Classifier API
3
+ emoji: 🎵
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: docker
7
  pinned: false
8
  license: mit
9
+ app_port: 7860
10
  ---
11
 
12
+ # ML Music Classifier API
13
+
14
+ This API predicts whether a song will be "liked" or "not liked" based on audio features using 8 different machine learning models.
15
+
16
+ ## Models Available
17
+ - ANN (Artificial Neural Network)
18
+ - KNN (K-Nearest Neighbors)
19
+ - Logistic Regression
20
+ - Neural Network
21
+ - Naive Bayes
22
+ - Random Forest
23
+ - SVM (Support Vector Machine)
24
+ - XGBoost
25
+
26
+ ## API Endpoints
27
+ - `POST /predict/{model_name}` - Make predictions with specific model
28
+ - `GET /docs` - API documentation
29
+
30
+ ## Authentication
31
+ All endpoints require an API token in the `X-Token` header.
32
+
33
+ ## Usage
34
+ ```bash
35
+ curl -X POST "https://your-space-name.hf.space/predict/random_forest_model" \
36
+ -H "X-Token: your-token-here" \
37
+ -H "Content-Type: application/json" \
38
+ -d '{"danceability": 0.8, "energy": 0.7, ...}'
app.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import time
2
+ # import pickle
3
+ # import numpy as np
4
+ # from fastapi import FastAPI, Request, status, HTTPException, Depends
5
+ # from fastapi.security.api_key import APIKeyHeader
6
+ # from pydantic import BaseModel
7
+ # from typing import List
8
+ # import os
9
+ # import joblib
10
+
11
+ # app = FastAPI(
12
+ # title="ML Music Classifier API",
13
+ # description="Predict 'liked' or not from audio features using 8 ML models.",
14
+ # version="1.0.0"
15
+ # )
16
+
17
+ # DEFAULT_TOKEN = "a9b7c7e8b0e44157a99c9a8c5f6a172e10b77e2b44693506a32e5a6a0cd749d0"
18
+ # api_key_header = APIKeyHeader(name="X-Token", auto_error=False)
19
+
20
+ # @app.middleware("http")
21
+ # async def add_process_time_header(request: Request, call_next):
22
+ # start_time = time.perf_counter()
23
+ # response = await call_next(request)
24
+ # process_time = time.perf_counter() - start_time
25
+ # response.headers["X-Process-Time"] = str(process_time)
26
+ # return response
27
+
28
+ # def verify_token(x_token: str = Depends(api_key_header)):
29
+ # if x_token != DEFAULT_TOKEN:
30
+ # raise HTTPException(
31
+ # status_code=status.HTTP_401_UNAUTHORIZED,
32
+ # detail="Invalid or missing token. Use correct 'X-Token' in headers."
33
+ # )
34
+
35
+ # class SongFeatures(BaseModel):
36
+ # danceability: float
37
+ # energy: float
38
+ # key: int
39
+ # loudness: float
40
+ # mode: int
41
+ # speechiness: float
42
+ # acousticness: float
43
+ # instrumentalness: float
44
+ # liveness: float
45
+ # valence: float
46
+ # tempo: float
47
+ # duration_ms: int
48
+ # time_signature: int
49
+
50
+ # MODEL_DIR = "models"
51
+ # model_names = [
52
+ # "ANN_model", "knn_model", "logistic_regression_model",
53
+ # "neural_model", "Naive_Bayes_model",
54
+ # "random_forest_model", "svm_model", "XGBoost_model"
55
+ # ]
56
+ # models = {}
57
+
58
+
59
+ # for name in model_names:
60
+ # path = os.path.join(MODEL_DIR, f"{name}.pkl")
61
+ # try:
62
+ # models[name] = joblib.load(path)
63
+ # except Exception as e:
64
+ # print(f"Error loading {name}: {e}")
65
+
66
+
67
+ # @app.post("/predict/{model_name}", dependencies=[Depends(verify_token)])
68
+ # def predict(model_name: str, features: SongFeatures):
69
+ # if model_name not in models:
70
+ # raise HTTPException(status_code=404, detail="Model not found")
71
+
72
+ # model = models[model_name]
73
+ # input_array = np.array([[getattr(features, field) for field in features.model_fields]])
74
+
75
+ # try:
76
+ # prediction = model.predict(input_array)
77
+ # return {
78
+ # "model": model_name,
79
+ # "input": features,
80
+ # "prediction": int(prediction[0]),
81
+ # "prediction_label": "liked" if int(prediction[0]) == 1 else "not_liked"
82
+ # }
83
+ # except Exception as e:
84
+ # raise HTTPException(status_code=500, detail=f"Prediction error: {str(e)}")
85
+
86
+
87
+
88
+
89
+
90
+ import time
91
+ import pickle
92
+ import numpy as np
93
+ from fastapi import FastAPI, Request, status, HTTPException, Depends
94
+ from fastapi.security.api_key import APIKeyHeader
95
+ from pydantic import BaseModel
96
+ from typing import List
97
+ import os
98
+ import joblib
99
+
100
+ app = FastAPI(
101
+ title="ML Music Classifier API",
102
+ description="Predict 'liked' or not from audio features using 8 ML models.",
103
+ version="1.0.0"
104
+ )
105
+
106
+ DEFAULT_TOKEN = "a9b7c7e8b0e44157a99c9a8c5f6a172e10b77e2b44693506a32e5a6a0cd749d0"
107
+ api_key_header = APIKeyHeader(name="X-Token", auto_error=False)
108
+
109
+ @app.middleware("http")
110
+ async def add_process_time_header(request: Request, call_next):
111
+ start_time = time.perf_counter()
112
+ response = await call_next(request)
113
+ process_time = time.perf_counter() - start_time
114
+ response.headers["X-Process-Time"] = str(process_time)
115
+ return response
116
+
117
+ def verify_token(x_token: str = Depends(api_key_header)):
118
+ if x_token != DEFAULT_TOKEN:
119
+ raise HTTPException(
120
+ status_code=status.HTTP_401_UNAUTHORIZED,
121
+ detail="Invalid or missing token. Use correct 'X-Token' in headers."
122
+ )
123
+
124
+ class SongFeatures(BaseModel):
125
+ danceability: float
126
+ energy: float
127
+ key: int
128
+ loudness: float
129
+ mode: int
130
+ speechiness: float
131
+ acousticness: float
132
+ instrumentalness: float
133
+ liveness: float
134
+ valence: float
135
+ tempo: float
136
+ duration_ms: int
137
+ time_signature: int
138
+
139
+ MODEL_DIR = "models"
140
+ model_names = [
141
+ "ANN_model", "knn_model", "logistic_regression_model",
142
+ "neural_model", "Naive_Bayes_model",
143
+ "random_forest_model", "svm_model", "XGBoost_model"
144
+ ]
145
+ models = {}
146
+
147
+ for name in model_names:
148
+ path = os.path.join(MODEL_DIR, f"{name}.pkl")
149
+ try:
150
+ models[name] = joblib.load(path)
151
+ print(f"✅ Successfully loaded {name}")
152
+ except Exception as e:
153
+ print(f"❌ Error loading {name}: {e}")
154
+
155
+ @app.get("/")
156
+ def root():
157
+ return {
158
+ "message": "ML Music Classifier API is running!",
159
+ "loaded_models": len(models),
160
+ "available_models": list(models.keys()),
161
+ "endpoints": {
162
+ "predict": "/predict/{model_name}",
163
+ "docs": "/docs",
164
+ "health": "/health"
165
+ }
166
+ }
167
+
168
+ @app.get("/health")
169
+ def health_check():
170
+ return {
171
+ "status": "healthy",
172
+ "loaded_models": len(models),
173
+ "available_models": list(models.keys())
174
+ }
175
+
176
+ @app.post("/predict/{model_name}", dependencies=[Depends(verify_token)])
177
+ def predict(model_name: str, features: SongFeatures):
178
+ if model_name not in models:
179
+ raise HTTPException(status_code=404, detail="Model not found")
180
+
181
+ model = models[model_name]
182
+ input_array = np.array([[getattr(features, field) for field in features.model_fields]])
183
+
184
+ try:
185
+ prediction = model.predict(input_array)
186
+ return {
187
+ "model": model_name,
188
+ "input": features.dict(),
189
+ "prediction": int(prediction[0]),
190
+ "prediction_label": "liked" if int(prediction[0]) == 1 else "not_liked"
191
+ }
192
+ except Exception as e:
193
+ raise HTTPException(status_code=500, detail=f"Prediction error: {str(e)}")
194
+
195
+ if __name__ == "__main__":
196
+ import uvicorn
197
+ uvicorn.run(app, host="0.0.0.0", port=7860)
models/ANN_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a7ef761063244c4e594f8385de5071070315eb2633c062941911f35886cd93dc
3
+ size 105157
models/Naive_Bayes_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:97a0eecb4d7b963d384e23382fc0e3996f8c5877401f2d33e559d379512f828b
3
+ size 1607
models/XGBoost_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f5cc70c51e966e57f80c83788af6b0141d33442e66445d7d6a10cc2cca5ac1d2
3
+ size 90157
models/knn_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4cabf72390dfd02a2551fdcd048e1835f3339c5ee5ac1a1a8ebcce94dc0ccc01
3
+ size 38438
models/logistic_regression_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e468bd4e8d866af23ea1230069c59562f0a2bd9407b240c5de70518211445486
3
+ size 1391
models/neural_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7cd18acad4cc67fd56bab88c6d6973129ca7cba5faaf506f56b64ca900b7d585
3
+ size 61675
models/random_forest_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:507f7f1805fca68c21b4d82fa30818bcb3aecf5b883df6c2744133b974cb0f67
3
+ size 294793
models/svm_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d89a2b751168db26ed3efefea936e8b03945a02e5513ee696ffadedec12d8f42
3
+ size 15483
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ numpy==1.24.3
4
+ scikit-learn==1.3.0
5
+ joblib==1.3.2
6
+ pydantic==2.4.2
7
+ python-multipart==0.0.6
8
+ pandas==2.1.4
9
+ keras==2.12.0
10
+ tensorflow==2.12.0
11
+ xgboost==2.0.3