Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import firebase_admin | |
| from firebase_admin import credentials, firestore | |
| from flask import Flask, request, jsonify | |
| from transformers import pipeline | |
| app = Flask(__name__) | |
| # ====== CONFIGURAÇÃO FIREBASE ====== | |
| try: | |
| firebase_key = os.getenv("FIREBASE_KEY") | |
| if firebase_key: | |
| cred_dict = json.loads(firebase_key) | |
| cred = credentials.Certificate(cred_dict) | |
| firebase_admin.initialize_app(cred) | |
| db = firestore.client() | |
| print("✅ Firebase conectado com sucesso.") | |
| else: | |
| print("⚠️ FIREBASE_KEY não encontrada nos secrets do Space.") | |
| except Exception as e: | |
| print(f"❌ Erro ao inicializar Firebase: {e}") | |
| # ====== MODELO ====== | |
| try: | |
| model_pipeline = pipeline("text-classification", model="pysentimiento/robertuito-emotion-analysis") | |
| print("✅ Modelo carregado com sucesso!") | |
| except Exception as e: | |
| print(f"❌ Erro ao carregar modelo: {e}") | |
| model_pipeline = None | |
| # ====== MAPEAMENTO DE EMOÇÕES ====== | |
| emotion_labels = { | |
| "sadness": "tristeza", | |
| "joy": "alegria", | |
| "anger": "raiva", | |
| "fear": "ansiedade", | |
| "disgust": "insegurança", | |
| "surprise": "alegria", | |
| "others": "neutro" | |
| } | |
| # ====== SUGESTÕES ====== | |
| def gerar_sugestao(emotion_pt): | |
| sugestoes = { | |
| "tristeza": "Procure fazer algo que te acalme e traga conforto emocional.", | |
| "depressão": "Você não está sozinho. Considere conversar com alguém de confiança ou buscar apoio profissional.", | |
| "alegria": "Continue aproveitando esse momento positivo e compartilhe boas energias!", | |
| "raiva": "Afaste-se da situação e respire antes de reagir. Canalize essa energia em algo produtivo.", | |
| "ansiedade": "Tente identificar o que está te causando ansiedade e dê pequenos passos para enfrentá-la.", | |
| "insegurança": "Analise os pontos que causam insegurança e busque soluções práticas.", | |
| "neutro": "Mantenha o equilíbrio emocional e cuide de si mesmo.", | |
| "desconhecido": "Emoção não identificada com precisão." | |
| } | |
| return sugestoes.get(emotion_pt, "Mantenha o equilíbrio emocional e cuide de você mesmo.") | |
| # ====== FALLBACK APRIMORADO COM PALAVRAS-CHAVE ====== | |
| EMOTION_KEYWORDS = { | |
| "tristeza": ["triste","desanimado","melancólico","chateado","solitário","deprimido","abatido","infeliz","desmotivado"], | |
| "ansiedade": ["ansioso","preocupado","nervoso","tenso","inquieto","aflito","alarmado","sobrecarregado","inseguro","apreensivo"], | |
| "insegurança": ["inseguro","incerto","receoso","hesitante","duvidoso","apreensivo","desconfiado"], | |
| "raiva": ["irritado","zangado","raiva","furioso","ódio","revoltado","frustrado","indignado","hostil","bravo","enfurecido","irado"], | |
| "alegria": ["feliz","animado","contente","alegre","satisfeito","entusiasmado","radiante","orgulhoso","euforia"], | |
| "depressão": ["sem esperança","vazio","desesperado","sem vontade","cansado da vida","desamparado"], | |
| "neutro": ["ok","normal","tranquilo","indiferente","equilibrado","estável"] | |
| } | |
| def fallback_emotion(text): | |
| text_lower = text.lower() | |
| match_counts = {k: sum(1 for w in v if w in text_lower) for k, v in EMOTION_KEYWORDS.items()} | |
| emotion = max(match_counts, key=match_counts.get) | |
| if match_counts[emotion] == 0: | |
| emotion = "neutro" | |
| return { | |
| "status": "fallback", | |
| "emotion": emotion, | |
| "emode": [emotion], | |
| "confidence": 0.6 if match_counts[emotion] > 0 else 0.0, | |
| "suggestion": gerar_sugestao(emotion), | |
| "debug": "Fallback ativado" | |
| } | |
| # ====== AJUSTE HÍBRIDO ====== | |
| def hybrid_emotion(text, result): | |
| text_lower = text.lower() | |
| detected = result.get("emotion", "neutro") | |
| max_matches = 0 | |
| for emo, keywords in EMOTION_KEYWORDS.items(): | |
| matches = sum(2 for w in keywords if w in text_lower) | |
| if matches > max_matches: | |
| max_matches = matches | |
| if emo != detected: | |
| detected = emo | |
| confidence = result.get("confidence", 0.0) | |
| if detected != result.get("emotion"): | |
| confidence = 0.7 + max_matches * 0.05 | |
| confidence = min(confidence, 1.0) | |
| return { | |
| "status": "ok", | |
| "emotion": detected, | |
| "emode": [detected], | |
| "confidence": round(confidence, 2), | |
| "probabilities": result.get("probabilities", {detected: 1.0}), | |
| "suggestion": result.get("suggestion", gerar_sugestao(detected)), | |
| "debug": result.get("debug", "Híbrido aplicado") | |
| } | |
| # ====== ROTA DE ANÁLISE ====== | |
| def analyze(): | |
| try: | |
| data = request.get_json() | |
| if not data or "text" not in data: | |
| return jsonify({"error": "Campo 'text' é obrigatório."}), 400 | |
| text = data["text"] | |
| if not model_pipeline: | |
| return jsonify(fallback_emotion(text)) | |
| result = model_pipeline(text, return_all_scores=True) | |
| if not result or len(result) == 0: | |
| return jsonify(fallback_emotion(text)) | |
| scores = {r["label"]: r["score"] for r in result[0]} | |
| top_label = max(scores, key=scores.get) | |
| confidence = round(scores[top_label], 2) | |
| emotion_pt = emotion_labels.get(top_label, "desconhecido") | |
| # Ajuste especial para "tristeza" muito forte | |
| if emotion_pt == "tristeza" and confidence >= 0.9: | |
| emotion_pt = "depressão" | |
| base_result = { | |
| "status": "ok", | |
| "emotion": emotion_pt, | |
| "emode": [emotion_pt], | |
| "confidence": confidence, | |
| "probabilities": {emotion_labels.get(k, k): round(v,3) for k,v in scores.items()}, | |
| "suggestion": gerar_sugestao(emotion_pt) | |
| } | |
| # Aplica lógica híbrida com fallback de palavras-chave | |
| final_result = hybrid_emotion(text, base_result) | |
| return jsonify(final_result) | |
| except Exception as e: | |
| return jsonify({"error": str(e)}), 500 | |
| if __name__ == "__main__": | |
| app.run(host="0.0.0.0", port=7860) | |