Faffio commited on
Commit
04a4266
·
1 Parent(s): 5f1ba91

Modello funzionante su chiamata API

Browse files
app/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (142 Bytes). View file
 
app/api/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (146 Bytes). View file
 
app/api/__pycache__/main.cpython-312.pyc ADDED
Binary file (2.07 kB). View file
 
app/api/main.py CHANGED
@@ -1,5 +1,7 @@
1
  from fastapi import FastAPI, HTTPException
2
  from pydantic import BaseModel
 
 
3
 
4
  # 1. Inizializziamo l'app
5
  app = FastAPI(
@@ -18,30 +20,28 @@ class SentimentResponse(BaseModel):
18
  sentiment: str
19
  confidence: float
20
 
21
- # 3. Endpoint di Health Check (fondamentale per MLOps e Docker)
 
 
 
 
 
22
  # Serve a capire se il container è vivo
23
  @app.get("/health")
24
  def health_check():
25
  return {"status": "ok", "message": "Service is running"}
26
 
27
- # 4. Endpoint di Previsione (Dummy per ora)
28
  @app.post("/predict", response_model=SentimentResponse)
29
  def predict_sentiment(request: SentimentRequest):
30
- """
31
- Riceve un testo e restituisce il sentiment (Positive, Neutral, Negative).
32
- """
33
- # TODO: Qui caricheremo il modello ML vero!
34
- # Per ora simuliamo una risposta logica
35
- print(f"Analyzing text: {request.text}")
36
-
37
- # Logica finta (Mock) per testare l'API
38
- mock_sentiment = "neutral"
39
- if "ottimo" in request.text.lower():
40
- mock_sentiment = "positive"
41
- elif "pessimo" in request.text.lower():
42
- mock_sentiment = "negative"
43
 
44
- return {
45
- "sentiment": mock_sentiment,
46
- "confidence": 0.95
47
- }
 
 
 
 
1
  from fastapi import FastAPI, HTTPException
2
  from pydantic import BaseModel
3
+ # Importiamo l'istanza del modello che abbiamo appena creato
4
+ from app.model.loader import model_instance
5
 
6
  # 1. Inizializziamo l'app
7
  app = FastAPI(
 
20
  sentiment: str
21
  confidence: float
22
 
23
+ # 3. Endpoint di default (la nostra Home che consiglia reindirizzamento a docs)
24
+ @app.get("/")
25
+ def home():
26
+ return {"message": "Reputation Monitor API is running. Go to /docs for Swagger UI."}
27
+
28
+ # 4. Endpoint di Health Check (fondamentale per MLOps e Docker)
29
  # Serve a capire se il container è vivo
30
  @app.get("/health")
31
  def health_check():
32
  return {"status": "ok", "message": "Service is running"}
33
 
34
+ # 5. Endpoint di Previsione (Dummy per ora)
35
  @app.post("/predict", response_model=SentimentResponse)
36
  def predict_sentiment(request: SentimentRequest):
37
+ try:
38
+ # Chiamiamo la funzione predict del nostro loader
39
+ sentiment, confidence = model_instance.predict(request.text)
 
 
 
 
 
 
 
 
 
 
40
 
41
+ return {
42
+ "sentiment": sentiment,
43
+ "confidence": confidence
44
+ }
45
+ except Exception as e:
46
+ # Se qualcosa va storto, restituiamo errore 500
47
+ raise HTTPException(status_code=500, detail=str(e))
app/model/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (148 Bytes). View file
 
app/model/__pycache__/loader.cpython-312.pyc ADDED
Binary file (2.05 kB). View file
 
app/model/loader.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, AutoConfig
2
+ import numpy as np
3
+ from scipy.special import softmax
4
+
5
+ # Questo è il modello specifico richiesto dall'esercizio
6
+ MODEL_NAME = "cardiffnlp/twitter-roberta-base-sentiment-latest"
7
+
8
+ class SentimentModel:
9
+ def __init__(self):
10
+ print(f"🔄 Loading model: {MODEL_NAME}...")
11
+ # Scarichiamo Tokenizer (trasforma testo in numeri) e Modello (Rete Neurale)
12
+ self.tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
13
+ self.config = AutoConfig.from_pretrained(MODEL_NAME)
14
+ self.model = AutoModelForSequenceClassification.from_pretrained(MODEL_NAME)
15
+ print("✅ Model loaded successfully!")
16
+
17
+ def predict(self, text: str):
18
+ # 1. Preprocessing
19
+ # Trasformiamo il testo in input per RoBERTa (truncation=True taglia i tweet troppo lunghi)
20
+ encoded_input = self.tokenizer(text, return_tensors='pt', truncation=True, max_length=512)
21
+
22
+ # 2. Inferenza (Il passaggio nella rete neurale)
23
+ output = self.model(**encoded_input)
24
+
25
+ # 3. Post-processing
26
+ # L'output sono "logits" (punteggi grezzi), usiamo Softmax per avere probabilità (0-1)
27
+ scores = output[0][0].detach().numpy()
28
+ scores = softmax(scores)
29
+
30
+ # 4. Mappatura Etichette
31
+ # Questo modello specifico usa l'ordine: 0 -> Negative, 1 -> Neutral, 2 -> Positive
32
+ labels = ["negative", "neutral", "positive"]
33
+
34
+ # Troviamo l'indice con il punteggio più alto
35
+ ranking = np.argsort(scores)
36
+ ranking = ranking[::-1] # Ordiniamo decrescente
37
+
38
+ top_label_id = ranking[0]
39
+ top_label = labels[top_label_id]
40
+ confidence = scores[top_label_id]
41
+
42
+ return top_label, float(confidence)
43
+
44
+ # Istanziamo il modello UNA VOLTA sola qui.
45
+ # Quando importiamo 'model_instance' negli altri file, sarà già caricato.
46
+ model_instance = SentimentModel()
requirements.txt CHANGED
@@ -9,6 +9,10 @@ pydantic==2.6.0
9
  pandas
10
  scikit-learn
11
  joblib
 
 
 
 
12
 
13
  # --- Testing ---
14
  pytest
 
9
  pandas
10
  scikit-learn
11
  joblib
12
+ torch
13
+ transformers
14
+ scipy
15
+ numpy
16
 
17
  # --- Testing ---
18
  pytest