|
from flask import Blueprint, request, jsonify |
|
from models.multilingual_translation.model import MultilingualTranslationModel |
|
from models.sentiment_analysis.model import SentimentAnalysisModel |
|
from models.intelligent_routing.model import IntelligentRoutingModel |
|
from models.job_recommendation.model import JobRecommendationModel |
|
import logging |
|
from datetime import datetime |
|
import os |
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
logger.info(f"HUGGINGFACE_API_TOKEN present: {'HUGGINGFACE_API_TOKEN' in os.environ}") |
|
|
|
api_bp = Blueprint('api', __name__) |
|
|
|
|
|
try: |
|
logger.info("Initializing translation model...") |
|
translation_model = MultilingualTranslationModel() |
|
|
|
logger.info("Initializing sentiment model...") |
|
sentiment_model = SentimentAnalysisModel() |
|
|
|
logger.info("Initializing routing model...") |
|
routing_model = IntelligentRoutingModel() |
|
|
|
logger.info("Initializing job model...") |
|
job_model = JobRecommendationModel() |
|
except Exception as e: |
|
logger.error(f"Error initializing models: {str(e)}") |
|
|
|
|
|
try: |
|
routing_model.load_model('models/intelligent_routing/saved_model/model.keras') |
|
job_model.load_model('models/job_recommendation/saved_model/model.keras') |
|
except Exception as e: |
|
logger.error(f"Error loading models: {str(e)}") |
|
|
|
@api_bp.route('/translate', methods=['POST']) |
|
def translate(): |
|
try: |
|
data = request.get_json() |
|
|
|
if not data or 'user_message' not in data: |
|
return jsonify({ |
|
'error': 'Missing required fields', |
|
'required': ['user_message', 'target_language'] |
|
}), 400 |
|
|
|
result = translation_model.process_message(data) |
|
|
|
if result.get('error'): |
|
return jsonify({ |
|
'error': result['error'] |
|
}), 400 |
|
|
|
return jsonify(result), 200 |
|
|
|
except Exception as e: |
|
logger.error(f"Translation error: {str(e)}") |
|
return jsonify({ |
|
'error': 'Internal server error' |
|
}), 500 |
|
|
|
@api_bp.route('/analyze-sentiment', methods=['POST']) |
|
def analyze_sentiment(): |
|
try: |
|
data = request.get_json() |
|
logger.info(f"Received sentiment analysis request with data: {data}") |
|
|
|
if not data or 'grievance_id' not in data or 'text' not in data: |
|
logger.warning("Missing required fields in request") |
|
return jsonify({ |
|
'error': 'Missing required fields', |
|
'required': ['grievance_id', 'text'] |
|
}), 400 |
|
|
|
logger.info("Processing grievance with sentiment model...") |
|
result = sentiment_model.process_grievance(data) |
|
logger.info(f"Sentiment analysis result: {result}") |
|
|
|
if result.get('error'): |
|
logger.error(f"Error in sentiment model: {result['error']}") |
|
return jsonify({ |
|
'error': result['error'] |
|
}), 400 |
|
|
|
return jsonify({ |
|
'grievance_id': data['grievance_id'], |
|
'emotional_label': result['emotional_label'], |
|
'confidence': result['confidence'], |
|
'timestamp': datetime.utcnow().isoformat() |
|
}), 200 |
|
|
|
except Exception as e: |
|
logger.error(f"Sentiment analysis error: {str(e)}", exc_info=True) |
|
return jsonify({ |
|
'error': 'Internal server error', |
|
'details': str(e) |
|
}), 500 |
|
|
|
@api_bp.route('/route-grievance', methods=['POST']) |
|
def route_grievance(): |
|
try: |
|
data = request.get_json() |
|
|
|
required_fields = [ |
|
'grievance_id', 'category', 'student_room_no', |
|
'hostel_name', 'floor_number', 'current_staff_status' |
|
] |
|
|
|
if not data or not all(field in data for field in required_fields): |
|
return jsonify({ |
|
'error': 'Missing required fields', |
|
'required': required_fields |
|
}), 400 |
|
|
|
|
|
if 'submission_timestamp' in data: |
|
try: |
|
|
|
timestamp = datetime.fromisoformat(data['submission_timestamp'].replace('Z', '+00:00')) |
|
data['submission_timestamp'] = timestamp.strftime("%Y-%m-%dT%H:%M:%SZ") |
|
except Exception as e: |
|
logger.warning(f"Error formatting timestamp: {str(e)}") |
|
data['submission_timestamp'] = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") |
|
|
|
result = routing_model.predict(data) |
|
|
|
if not result: |
|
return jsonify({ |
|
'error': 'No suitable staff found' |
|
}), 404 |
|
|
|
return jsonify({ |
|
'grievance_id': data['grievance_id'], |
|
'assigned_staff_id': result['assigned_staff_id'], |
|
'assignment_timestamp': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"), |
|
'confidence_score': result.get('confidence_score', 0.0), |
|
'estimated_resolution_time': result.get('estimated_resolution_time') |
|
}), 200 |
|
|
|
except Exception as e: |
|
logger.error(f"Routing error: {str(e)}") |
|
return jsonify({ |
|
'error': 'Internal server error', |
|
'details': str(e) |
|
}), 500 |
|
|
|
@api_bp.route('/recommend-job', methods=['POST']) |
|
def recommend_job(): |
|
try: |
|
data = request.get_json() |
|
|
|
required_fields = [ |
|
'job_id', 'type', 'description', 'urgency_level', |
|
'location', 'workers' |
|
] |
|
|
|
if not data or not all(field in data for field in required_fields): |
|
return jsonify({ |
|
'error': 'Missing required fields', |
|
'required': required_fields |
|
}), 400 |
|
|
|
|
|
available_workers = [ |
|
w for w in data['workers'] |
|
if w['department'].lower() == data['type'].lower() |
|
and w['availability_status'] == 'Available' |
|
] |
|
|
|
if not available_workers: |
|
return jsonify({ |
|
'error': 'No suitable workers found', |
|
'details': 'No available workers matching the job type' |
|
}), 404 |
|
|
|
|
|
sorted_workers = sorted( |
|
available_workers, |
|
key=lambda w: (-w['job_success_rate'], w['current_workload']) |
|
) |
|
|
|
|
|
best_worker = sorted_workers[0] |
|
alternative_workers = sorted_workers[1:3] if len(sorted_workers) > 1 else [] |
|
|
|
return jsonify({ |
|
'job_id': data['job_id'], |
|
'recommended_worker_id': best_worker['worker_id'], |
|
'recommendation_timestamp': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"), |
|
'predicted_completion_time': calculate_completion_time(best_worker, data['urgency_level']), |
|
'confidence_score': best_worker['job_success_rate'], |
|
'alternative_workers': [ |
|
{ |
|
'worker_id': w['worker_id'], |
|
'confidence_score': w['job_success_rate'], |
|
'current_workload': w['current_workload'] |
|
} for w in alternative_workers |
|
] |
|
}), 200 |
|
|
|
except Exception as e: |
|
logger.error(f"Job recommendation error: {str(e)}") |
|
return jsonify({ |
|
'error': 'Internal server error', |
|
'details': str(e) |
|
}), 500 |
|
|
|
def calculate_completion_time(worker, urgency): |
|
"""Calculate estimated completion time based on worker load and urgency""" |
|
base_hours = { |
|
'High': 2, |
|
'Medium': 4, |
|
'Low': 8 |
|
} |
|
|
|
|
|
workload_factor = 1 + (worker['current_workload'] * 0.2) |
|
estimated_hours = base_hours.get(urgency, 4) * workload_factor |
|
|
|
completion_time = datetime.utcnow() |
|
completion_time = completion_time.replace( |
|
hour=completion_time.hour + int(estimated_hours), |
|
minute=int((estimated_hours % 1) * 60) |
|
) |
|
|
|
return completion_time.strftime("%Y-%m-%dT%H:%M:%SZ") |
|
|
|
|
|
@api_bp.route('/health', methods=['GET']) |
|
def health_check(): |
|
return jsonify({ |
|
'status': 'healthy', |
|
'timestamp': datetime.utcnow().isoformat(), |
|
'services': { |
|
'translation': 'up', |
|
'sentiment_analysis': 'up', |
|
'intelligent_routing': 'up', |
|
'job_recommendation': 'up' |
|
} |
|
}), 200 |
|
|
|
|
|
@api_bp.errorhandler(404) |
|
def not_found(error): |
|
return jsonify({ |
|
'error': 'Not found', |
|
'timestamp': datetime.utcnow().isoformat() |
|
}), 404 |
|
|
|
@api_bp.errorhandler(500) |
|
def server_error(error): |
|
return jsonify({ |
|
'error': 'Internal server error', |
|
'timestamp': datetime.utcnow().isoformat() |
|
}), 500 |