“Transcendental-Programmer”
commited on
Commit
·
3d82292
1
Parent(s):
f56e71d
new
Browse files
routes.py
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
from models.multilingual_translation.model import MultilingualTranslationModel
|
2 |
from models.sentiment_analysis.model import SentimentAnalysisModel
|
3 |
from models.intelligent_routing.model import IntelligentRoutingModel
|
@@ -7,28 +8,233 @@ from datetime import datetime
|
|
7 |
|
8 |
logger = logging.getLogger(__name__)
|
9 |
|
10 |
-
|
11 |
-
translation_model = None
|
12 |
-
sentiment_model = None
|
13 |
-
routing_model = None
|
14 |
-
job_model = None
|
15 |
|
16 |
-
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Blueprint, request, jsonify
|
2 |
from models.multilingual_translation.model import MultilingualTranslationModel
|
3 |
from models.sentiment_analysis.model import SentimentAnalysisModel
|
4 |
from models.intelligent_routing.model import IntelligentRoutingModel
|
|
|
8 |
|
9 |
logger = logging.getLogger(__name__)
|
10 |
|
11 |
+
api_bp = Blueprint('api', __name__)
|
|
|
|
|
|
|
|
|
12 |
|
13 |
+
# Initialize models with proper paths
|
14 |
+
translation_model = MultilingualTranslationModel()
|
15 |
+
sentiment_model = SentimentAnalysisModel()
|
16 |
+
routing_model = IntelligentRoutingModel()
|
17 |
+
job_model = JobRecommendationModel()
|
18 |
+
|
19 |
+
# Load pre-trained models
|
20 |
+
try:
|
21 |
+
routing_model.load_model('models/intelligent_routing/saved_model/model.keras')
|
22 |
+
job_model.load_model('models/job_recommendation/saved_model/model.keras')
|
23 |
+
except Exception as e:
|
24 |
+
logger.error(f"Error loading models: {str(e)}")
|
25 |
+
|
26 |
+
@api_bp.route('/translate', methods=['POST'])
|
27 |
+
def translate():
|
28 |
+
try:
|
29 |
+
data = request.get_json()
|
30 |
+
|
31 |
+
if not data or 'user_message' not in data:
|
32 |
+
return jsonify({
|
33 |
+
'error': 'Missing required fields',
|
34 |
+
'required': ['user_message', 'target_language']
|
35 |
+
}), 400
|
36 |
+
|
37 |
+
result = translation_model.process_message(data)
|
38 |
+
|
39 |
+
if result.get('error'):
|
40 |
+
return jsonify({
|
41 |
+
'error': result['error']
|
42 |
+
}), 400
|
43 |
+
|
44 |
+
return jsonify(result), 200
|
45 |
+
|
46 |
+
except Exception as e:
|
47 |
+
logger.error(f"Translation error: {str(e)}")
|
48 |
+
return jsonify({
|
49 |
+
'error': 'Internal server error'
|
50 |
+
}), 500
|
51 |
+
|
52 |
+
@api_bp.route('/analyze-sentiment', methods=['POST'])
|
53 |
+
def analyze_sentiment():
|
54 |
+
try:
|
55 |
+
data = request.get_json()
|
56 |
+
|
57 |
+
if not data or 'grievance_id' not in data or 'text' not in data:
|
58 |
+
return jsonify({
|
59 |
+
'error': 'Missing required fields',
|
60 |
+
'required': ['grievance_id', 'text']
|
61 |
+
}), 400
|
62 |
+
|
63 |
+
result = sentiment_model.process_grievance(data)
|
64 |
+
|
65 |
+
if result.get('error'):
|
66 |
+
return jsonify({
|
67 |
+
'error': result['error']
|
68 |
+
}), 400
|
69 |
+
|
70 |
+
return jsonify({
|
71 |
+
'grievance_id': data['grievance_id'],
|
72 |
+
'emotional_label': result['emotional_label'],
|
73 |
+
'confidence': result['confidence'],
|
74 |
+
'timestamp': datetime.utcnow().isoformat()
|
75 |
+
}), 200
|
76 |
+
|
77 |
+
except Exception as e:
|
78 |
+
logger.error(f"Sentiment analysis error: {str(e)}")
|
79 |
+
return jsonify({
|
80 |
+
'error': 'Internal server error',
|
81 |
+
'details': str(e)
|
82 |
+
}), 500
|
83 |
+
|
84 |
+
@api_bp.route('/route-grievance', methods=['POST'])
|
85 |
+
def route_grievance():
|
86 |
+
try:
|
87 |
+
data = request.get_json()
|
88 |
+
|
89 |
+
required_fields = [
|
90 |
+
'grievance_id', 'category', 'student_room_no',
|
91 |
+
'hostel_name', 'floor_number', 'current_staff_status'
|
92 |
+
]
|
93 |
+
|
94 |
+
if not data or not all(field in data for field in required_fields):
|
95 |
+
return jsonify({
|
96 |
+
'error': 'Missing required fields',
|
97 |
+
'required': required_fields
|
98 |
+
}), 400
|
99 |
+
|
100 |
+
# Format timestamp to match expected format
|
101 |
+
if 'submission_timestamp' in data:
|
102 |
+
try:
|
103 |
+
# Convert to proper format
|
104 |
+
timestamp = datetime.fromisoformat(data['submission_timestamp'].replace('Z', '+00:00'))
|
105 |
+
data['submission_timestamp'] = timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
|
106 |
+
except Exception as e:
|
107 |
+
logger.warning(f"Error formatting timestamp: {str(e)}")
|
108 |
+
data['submission_timestamp'] = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
|
109 |
+
|
110 |
+
result = routing_model.predict(data)
|
111 |
+
|
112 |
+
if not result:
|
113 |
+
return jsonify({
|
114 |
+
'error': 'No suitable staff found'
|
115 |
+
}), 404
|
116 |
+
|
117 |
+
return jsonify({
|
118 |
+
'grievance_id': data['grievance_id'],
|
119 |
+
'assigned_staff_id': result['assigned_staff_id'],
|
120 |
+
'assignment_timestamp': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
|
121 |
+
'confidence_score': result.get('confidence_score', 0.0),
|
122 |
+
'estimated_resolution_time': result.get('estimated_resolution_time')
|
123 |
+
}), 200
|
124 |
+
|
125 |
+
except Exception as e:
|
126 |
+
logger.error(f"Routing error: {str(e)}")
|
127 |
+
return jsonify({
|
128 |
+
'error': 'Internal server error',
|
129 |
+
'details': str(e)
|
130 |
+
}), 500
|
131 |
+
|
132 |
+
@api_bp.route('/recommend-job', methods=['POST'])
|
133 |
+
def recommend_job():
|
134 |
+
try:
|
135 |
+
data = request.get_json()
|
136 |
+
|
137 |
+
required_fields = [
|
138 |
+
'job_id', 'type', 'description', 'urgency_level',
|
139 |
+
'location', 'workers'
|
140 |
+
]
|
141 |
+
|
142 |
+
if not data or not all(field in data for field in required_fields):
|
143 |
+
return jsonify({
|
144 |
+
'error': 'Missing required fields',
|
145 |
+
'required': required_fields
|
146 |
+
}), 400
|
147 |
+
|
148 |
+
# Filter available workers of matching department
|
149 |
+
available_workers = [
|
150 |
+
w for w in data['workers']
|
151 |
+
if w['department'].lower() == data['type'].lower()
|
152 |
+
and w['availability_status'] == 'Available'
|
153 |
+
]
|
154 |
+
|
155 |
+
if not available_workers:
|
156 |
+
return jsonify({
|
157 |
+
'error': 'No suitable workers found',
|
158 |
+
'details': 'No available workers matching the job type'
|
159 |
+
}), 404
|
160 |
+
|
161 |
+
# Sort workers by workload and success rate
|
162 |
+
sorted_workers = sorted(
|
163 |
+
available_workers,
|
164 |
+
key=lambda w: (-w['job_success_rate'], w['current_workload'])
|
165 |
+
)
|
166 |
+
|
167 |
+
# Get best worker and alternatives
|
168 |
+
best_worker = sorted_workers[0]
|
169 |
+
alternative_workers = sorted_workers[1:3] if len(sorted_workers) > 1 else []
|
170 |
+
|
171 |
+
return jsonify({
|
172 |
+
'job_id': data['job_id'],
|
173 |
+
'recommended_worker_id': best_worker['worker_id'],
|
174 |
+
'recommendation_timestamp': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
|
175 |
+
'predicted_completion_time': calculate_completion_time(best_worker, data['urgency_level']),
|
176 |
+
'confidence_score': best_worker['job_success_rate'],
|
177 |
+
'alternative_workers': [
|
178 |
+
{
|
179 |
+
'worker_id': w['worker_id'],
|
180 |
+
'confidence_score': w['job_success_rate'],
|
181 |
+
'current_workload': w['current_workload']
|
182 |
+
} for w in alternative_workers
|
183 |
+
]
|
184 |
+
}), 200
|
185 |
+
|
186 |
+
except Exception as e:
|
187 |
+
logger.error(f"Job recommendation error: {str(e)}")
|
188 |
+
return jsonify({
|
189 |
+
'error': 'Internal server error',
|
190 |
+
'details': str(e)
|
191 |
+
}), 500
|
192 |
+
|
193 |
+
def calculate_completion_time(worker, urgency):
|
194 |
+
"""Calculate estimated completion time based on worker load and urgency"""
|
195 |
+
base_hours = {
|
196 |
+
'High': 2,
|
197 |
+
'Medium': 4,
|
198 |
+
'Low': 8
|
199 |
+
}
|
200 |
|
201 |
+
# Adjust based on workload
|
202 |
+
workload_factor = 1 + (worker['current_workload'] * 0.2) # 20% increase per existing job
|
203 |
+
estimated_hours = base_hours.get(urgency, 4) * workload_factor
|
204 |
+
|
205 |
+
completion_time = datetime.utcnow()
|
206 |
+
completion_time = completion_time.replace(
|
207 |
+
hour=completion_time.hour + int(estimated_hours),
|
208 |
+
minute=int((estimated_hours % 1) * 60)
|
209 |
+
)
|
210 |
+
|
211 |
+
return completion_time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
212 |
+
|
213 |
+
# Health check endpoint
|
214 |
+
@api_bp.route('/health', methods=['GET'])
|
215 |
+
def health_check():
|
216 |
+
return jsonify({
|
217 |
+
'status': 'healthy',
|
218 |
+
'timestamp': datetime.utcnow().isoformat(),
|
219 |
+
'services': {
|
220 |
+
'translation': 'up',
|
221 |
+
'sentiment_analysis': 'up',
|
222 |
+
'intelligent_routing': 'up',
|
223 |
+
'job_recommendation': 'up'
|
224 |
+
}
|
225 |
+
}), 200
|
226 |
+
|
227 |
+
# Error handlers
|
228 |
+
@api_bp.errorhandler(404)
|
229 |
+
def not_found(error):
|
230 |
+
return jsonify({
|
231 |
+
'error': 'Not found',
|
232 |
+
'timestamp': datetime.utcnow().isoformat()
|
233 |
+
}), 404
|
234 |
+
|
235 |
+
@api_bp.errorhandler(500)
|
236 |
+
def server_error(error):
|
237 |
+
return jsonify({
|
238 |
+
'error': 'Internal server error',
|
239 |
+
'timestamp': datetime.utcnow().isoformat()
|
240 |
+
}), 500
|