Jakaria commited on
Commit
34e5a0f
·
1 Parent(s): 298ba53

Add Bangla model API

Browse files
Files changed (1) hide show
  1. app.py +13 -209
app.py CHANGED
@@ -1,218 +1,22 @@
1
- from fastapi import FastAPI, HTTPException
2
- from pydantic import BaseModel
3
  import joblib
4
- import os
5
- import logging
6
- import numpy as np
7
- import traceback
8
-
9
- logging.basicConfig(level=logging.INFO)
10
- logger = logging.getLogger(__name__)
11
 
12
  app = FastAPI()
13
 
14
- class PredictRequest(BaseModel):
15
- text: str
16
-
17
- # Global model variables
18
- model = None
19
- vectorizer = None
20
- label_encoder = None
21
- models_loaded = False
22
-
23
- def load_model_safe(filename):
24
- """Safely load model with multiple methods"""
25
- if not os.path.exists(filename):
26
- raise FileNotFoundError(f"{filename} not found")
27
-
28
- try:
29
- return joblib.load(filename)
30
- except Exception as e1:
31
- logger.warning(f"Joblib failed for {filename}: {e1}")
32
-
33
- try:
34
- with open(filename, 'rb') as f:
35
- return pickle.load(f)
36
- except Exception as e2:
37
- logger.error(f"Pickle also failed for {filename}: {e2}")
38
- raise e1
39
-
40
- @app.on_event("startup")
41
- async def startup_event():
42
- global model, vectorizer, label_encoder, models_loaded
43
-
44
- try:
45
- logger.info("Loading models...")
46
- model = load_model_safe("bangla_model.pkl")
47
- vectorizer = load_model_safe("bangla_vectorizer.pkl")
48
- label_encoder = load_model_safe("bangla_label_encoder.pkl")
49
-
50
- # Test pipeline
51
- test_vect = vectorizer.transform(["test"])
52
- test_pred = model.predict(test_vect)
53
- test_label = label_encoder.inverse_transform(test_pred)
54
-
55
- models_loaded = True
56
- logger.info("All models loaded successfully!")
57
-
58
- except Exception as e:
59
- logger.error(f"Failed to load models: {str(e)}")
60
- models_loaded = False
61
 
 
62
  @app.get("/")
63
  def root():
64
- return {
65
- "message": "Bangla model API is running!",
66
- "models_loaded": models_loaded,
67
- "status": "healthy" if models_loaded else "models_not_loaded"
68
- }
69
-
70
- @app.get("/status")
71
- def status():
72
- return {
73
- "models_loaded": models_loaded,
74
- "model_available": model is not None,
75
- "vectorizer_available": vectorizer is not None,
76
- "label_encoder_available": label_encoder is not None,
77
- "current_directory": os.getcwd(),
78
- "available_files": [f for f in os.listdir('.') if f.endswith('.pkl')]
79
- }
80
-
81
- @app.post("/debug-predict")
82
- def debug_predict(request: PredictRequest):
83
- """Debug version of predict with detailed logging"""
84
- if not models_loaded:
85
- raise HTTPException(status_code=503, detail="Models not loaded")
86
-
87
- debug_info = {"steps": []}
88
-
89
- try:
90
- # Step 1: Input validation
91
- debug_info["steps"].append("1. Input validation")
92
- if not request.text or not request.text.strip():
93
- raise HTTPException(status_code=400, detail="Text cannot be empty")
94
-
95
- debug_info["input_text"] = request.text
96
- debug_info["input_length"] = len(request.text)
97
-
98
- # Step 2: Text preprocessing
99
- debug_info["steps"].append("2. Text preprocessing")
100
- text_to_process = request.text.strip()
101
- debug_info["processed_text_length"] = len(text_to_process)
102
-
103
- # Step 3: Vectorization
104
- debug_info["steps"].append("3. Vectorization")
105
- try:
106
- vect = vectorizer.transform([text_to_process])
107
- debug_info["vectorized_shape"] = vect.shape
108
- debug_info["vectorized_nnz"] = vect.nnz
109
- debug_info["vectorized_dtype"] = str(vect.dtype)
110
- except Exception as e:
111
- debug_info["vectorization_error"] = str(e)
112
- raise HTTPException(status_code=500, detail=f"Vectorization failed: {str(e)}")
113
-
114
- # Step 4: Model prediction
115
- debug_info["steps"].append("4. Model prediction")
116
- try:
117
- pred = model.predict(vect)
118
- debug_info["raw_prediction"] = pred.tolist() if hasattr(pred, 'tolist') else str(pred)
119
- debug_info["prediction_type"] = str(type(pred))
120
- debug_info["prediction_shape"] = pred.shape if hasattr(pred, 'shape') else "no shape"
121
- except Exception as e:
122
- debug_info["prediction_error"] = str(e)
123
- raise HTTPException(status_code=500, detail=f"Model prediction failed: {str(e)}")
124
-
125
- # Step 5: Label transformation
126
- debug_info["steps"].append("5. Label transformation")
127
- try:
128
- # Check if prediction is in valid range
129
- if hasattr(label_encoder, 'classes_'):
130
- debug_info["available_classes"] = label_encoder.classes_.tolist()
131
- debug_info["num_classes"] = len(label_encoder.classes_)
132
-
133
- label = label_encoder.inverse_transform(pred)
134
- debug_info["final_label"] = label[0] if len(label) > 0 else "no label"
135
- debug_info["label_type"] = str(type(label[0])) if len(label) > 0 else "no label"
136
- except Exception as e:
137
- debug_info["label_transform_error"] = str(e)
138
- raise HTTPException(status_code=500, detail=f"Label transformation failed: {str(e)}")
139
-
140
- debug_info["steps"].append("6. Success!")
141
- debug_info["final_prediction"] = label[0]
142
-
143
- return debug_info
144
-
145
- except HTTPException:
146
- raise
147
- except Exception as e:
148
- debug_info["unexpected_error"] = str(e)
149
- debug_info["traceback"] = traceback.format_exc()
150
- raise HTTPException(status_code=500, detail=f"Unexpected error: {str(e)}")
151
 
 
152
  @app.post("/predict")
153
- def predict(request: PredictRequest):
154
- """Production predict endpoint with better error handling"""
155
- if not models_loaded:
156
- raise HTTPException(status_code=503, detail="Models not loaded")
157
-
158
- try:
159
- # Input validation
160
- if not request.text or not request.text.strip():
161
- raise HTTPException(status_code=400, detail="Text cannot be empty")
162
-
163
- text_to_process = request.text.strip()
164
- logger.info(f"Processing text of length: {len(text_to_process)}")
165
-
166
- # Vectorization with error handling
167
- try:
168
- vect = vectorizer.transform([text_to_process])
169
- logger.info(f"Vectorization successful: shape={vect.shape}, nnz={vect.nnz}")
170
- except Exception as e:
171
- logger.error(f"Vectorization error: {str(e)}")
172
- raise HTTPException(status_code=500, detail="Text vectorization failed")
173
-
174
- # Prediction with error handling
175
- try:
176
- pred = model.predict(vect)
177
- logger.info(f"Prediction successful: {pred}")
178
- except Exception as e:
179
- logger.error(f"Model prediction error: {str(e)}")
180
- raise HTTPException(status_code=500, detail="Model prediction failed")
181
-
182
- # Label transformation with error handling
183
- try:
184
- # Validate prediction is in expected range
185
- if hasattr(label_encoder, 'classes_'):
186
- max_class = len(label_encoder.classes_) - 1
187
- if np.any(pred < 0) or np.any(pred > max_class):
188
- logger.error(f"Prediction {pred} out of range [0, {max_class}]")
189
- raise ValueError(f"Prediction out of range")
190
-
191
- label = label_encoder.inverse_transform(pred)
192
- logger.info(f"Label transformation successful: {label[0]}")
193
- except Exception as e:
194
- logger.error(f"Label transformation error: {str(e)}")
195
- raise HTTPException(status_code=500, detail="Label transformation failed")
196
-
197
- return {"prediction": label[0]}
198
-
199
- except HTTPException:
200
- raise
201
- except Exception as e:
202
- logger.error(f"Unexpected error in predict: {str(e)}")
203
- logger.error(traceback.format_exc())
204
- raise HTTPException(status_code=500, detail="Internal server error")
205
-
206
- @app.post("/reload-models")
207
- def reload_models():
208
- global model, vectorizer, label_encoder, models_loaded
209
-
210
- try:
211
- model = load_model_safe("bangla_model.pkl")
212
- vectorizer = load_model_safe("bangla_vectorizer.pkl")
213
- label_encoder = load_model_safe("bangla_label_encoder.pkl")
214
- models_loaded = True
215
- return {"message": "Models reloaded successfully"}
216
- except Exception as e:
217
- models_loaded = False
218
- raise HTTPException(status_code=500, detail=f"Failed to reload models: {str(e)}")
 
1
+ from fastapi import FastAPI
 
2
  import joblib
 
 
 
 
 
 
 
3
 
4
  app = FastAPI()
5
 
6
+ # Load your model, vectorizer, label encoder
7
+ model = joblib.load("bangla_model.pkl")
8
+ vectorizer = joblib.load("bangla_vectorizer.pkl")
9
+ label_encoder = joblib.load("bangla_label_encoder.pkl")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ # Root route to avoid 404
12
  @app.get("/")
13
  def root():
14
+ return {"message": "Bangla model API is running!"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ # Example predict endpoint
17
  @app.post("/predict")
18
+ def predict(text: str):
19
+ vect = vectorizer.transform([text])
20
+ pred = model.predict(vect)
21
+ label = label_encoder.inverse_transform(pred)
22
+ return {"prediction": label[0]}