faizan20 commited on
Commit
c46e765
·
verified ·
1 Parent(s): 4172c34

Upload 8 files

Browse files
Files changed (8) hide show
  1. __init__.py +0 -0
  2. gradio_app.py +60 -0
  3. main.py +43 -0
  4. model_loader.py +32 -0
  5. predict.py +46 -0
  6. requirements.txt +10 -0
  7. routes.py +13 -0
  8. schemas.py +10 -0
__init__.py ADDED
File without changes
gradio_app.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+
4
+ API_URL = "http://127.0.0.1:8000/api/predict"
5
+
6
+ def analyze_text(text):
7
+ try:
8
+ response = requests.post(API_URL, json={"text": text})
9
+ if response.status_code == 200:
10
+ result = response.json()
11
+ sentiment = result.get("sentiment", "")
12
+ emotion = result.get("emotion", "")
13
+ return f"➡️ **Sentiment:** {sentiment}\n\n ➡️ **Emotion:** {emotion}"
14
+ else:
15
+ return f"API Error: {response.status_code}"
16
+ except Exception as e:
17
+ return f"Error connecting to API: {str(e)}"
18
+
19
+ custom_css = """
20
+ .gradio-container {
21
+ background: linear-gradient(135deg, #e9f1fc 0%, #fefefe 100%);
22
+ font-family: 'Segoe UI', Roboto, sans-serif;
23
+ }
24
+ h1 {
25
+ text-align: center !important;
26
+ font-size: 2.2rem !important;
27
+ color: #1f2937 !important;
28
+ font-weight: 600 !important;
29
+ }
30
+ textarea, .output_text {
31
+ font-size: 1.1rem !important;
32
+ line-height: 1.6 !important;
33
+ }
34
+ .output_text {
35
+ background: #f9fafb !important;
36
+ border-radius: 12px !important;
37
+ padding: 16px !important;
38
+ border: 1px solid #e5e7eb !important;
39
+ }
40
+ """
41
+
42
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
43
+ gr.Markdown("# 💬 Emotion & Sentiment Analyzer")
44
+ gr.Markdown("### Type your text below to discover its emotional tone and sentiment ✨")
45
+
46
+ with gr.Row():
47
+ text_input = gr.Textbox(
48
+ label="Enter text here",
49
+ placeholder="e.g. I'm so excited to work on this project!",
50
+ lines=4,
51
+ scale=2
52
+ )
53
+ with gr.Row():
54
+ output_box = gr.Markdown(label="Results", elem_classes="output_text")
55
+
56
+ analyze_button = gr.Button("🔍 Analyze", variant="primary")
57
+
58
+ analyze_button.click(fn=analyze_text, inputs=text_input, outputs=output_box)
59
+
60
+ demo.launch()
main.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from app.routes import router as emotion_router
4
+ import os
5
+
6
+ app = FastAPI(
7
+ title="NLP Emotion Analyzer",
8
+ description="Emotion & Sentiment Analyzer using HuggingFace models",
9
+ version="1.0.0"
10
+ )
11
+
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
+ app.include_router(emotion_router, tags=["Emotion Analyzer"])
21
+
22
+ @app.get("/")
23
+ def root():
24
+ return {"message": "Welcome to NLP Emotion Analyzer API", "status": "running", "endpoints": ["/api/predict", "/api/explain"]}
25
+
26
+ # Warm up models on startup to avoid long first request
27
+ @app.on_event("startup")
28
+ def startup_event():
29
+ try:
30
+ from app.model_loader import model_registry
31
+ model_registry.initialize()
32
+ try:
33
+ from app.predict import text_predictor
34
+ _ = text_predictor.predict("warm up", task="sentiment")
35
+ except Exception:
36
+ pass
37
+ print("Models initialized.")
38
+ except Exception as e:
39
+ print("Models not initialized:", e)
40
+
41
+ if __name__ == "__main__":
42
+ import uvicorn
43
+ uvicorn.run("app.main:app", host="127.0.0.1", port=8000, reload=True)
model_loader.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+ from transformers import pipeline
3
+ import os
4
+
5
+ load_dotenv()
6
+
7
+ class Config:
8
+ EMOTION_MODEL_NAME = os.getenv("EMOTION_MODEL_NAME", "j-hartmann/emotion-english-distilroberta-base")
9
+ SENTIMENT_MODEL_NAME = os.getenv("SENTIMENT_MODEL_NAME", "distilbert-base-uncased-finetuned-sst-2-english")
10
+ DEVICE = int(os.getenv("MODEL_DEVICE", "-1"))
11
+
12
+ class ModelRegistry:
13
+ def __init__(self):
14
+ self.models = {
15
+ "emotion": None,
16
+ "sentiment": None
17
+ }
18
+
19
+ def load_models(self):
20
+ print("Loading pretrained Hugging Face models...")
21
+ self.models["emotion"] = pipeline("text-classification", model=Config.EMOTION_MODEL_NAME, device=Config.DEVICE)
22
+ self.models["sentiment"] = pipeline("sentiment-analysis", model=Config.SENTIMENT_MODEL_NAME, device=Config.DEVICE)
23
+ print("Models loaded successfully and ready for inference.")
24
+
25
+ def initialize(self):
26
+ if not all(self.models.values()):
27
+ self.load_models()
28
+
29
+ def get(self, name: str):
30
+ return self.models.get(name)
31
+
32
+ model_registry = ModelRegistry()
predict.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from app.model_loader import model_registry
2
+
3
+ class TextPredictor:
4
+
5
+ def __init__(self):
6
+ model_registry.initialize()
7
+ self.sentiment_model = model_registry.get("sentiment")
8
+ self.emotion_model = model_registry.get("emotion")
9
+
10
+
11
+ self.emotion_emojis = {
12
+ "joy": "😊",
13
+ "anger": "😠",
14
+ "sadness": "😞",
15
+ "fear": "😨",
16
+ "love": "❤️",
17
+ "surprise": "😲",
18
+ "disgust": "🤢",
19
+ "neutral": "😐"
20
+ }
21
+
22
+ def predict(self, text: str):
23
+
24
+ if not text or not isinstance(text, str):
25
+ raise ValueError("Input text must be a non-empty string.")
26
+
27
+
28
+ cleaned_text = text.strip()
29
+
30
+ sentiment_result = self.sentiment_model(cleaned_text)[0]
31
+ sentiment_label = sentiment_result["label"].capitalize()
32
+
33
+ emotion_result = self.emotion_model(cleaned_text)[0]
34
+ emotion_label = emotion_result["label"].lower()
35
+ emotion_with_emoji = f"{emotion_label} {self.emotion_emojis.get(emotion_label, '')}"
36
+
37
+ result = {
38
+ "input_text": text,
39
+ "cleaned_text": cleaned_text,
40
+ "sentiment": sentiment_label,
41
+ "emotion": emotion_with_emoji
42
+ }
43
+
44
+ return result
45
+
46
+ text_predictor = TextPredictor()
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ transformers
4
+ torch
5
+ lime
6
+ numpy
7
+ pandas
8
+ joblib
9
+ python-dotenv
10
+ ftfy
routes.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException
2
+ from app.predict import text_predictor
3
+ from app.schemas import TextRequest, PredictionResponse
4
+
5
+ router = APIRouter()
6
+
7
+ @router.post("/api/predict", response_model=PredictionResponse)
8
+ def predict_text(request: TextRequest):
9
+ try:
10
+ result = text_predictor.predict(request.text)
11
+ return result
12
+ except Exception as e:
13
+ raise HTTPException(status_code=500, detail=str(e))
schemas.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+ class TextRequest(BaseModel):
4
+ text: str
5
+
6
+ class PredictionResponse(BaseModel):
7
+ input_text: str
8
+ cleaned_text: str
9
+ sentiment: str
10
+ emotion: str