Spaces:
Sleeping
Sleeping
Update app/sentiment.py
Browse files- app/sentiment.py +21 -22
app/sentiment.py
CHANGED
|
@@ -1,32 +1,21 @@
|
|
| 1 |
"""
|
| 2 |
-
|
| 3 |
"""
|
| 4 |
-
|
| 5 |
import os
|
| 6 |
import hashlib
|
| 7 |
import logging
|
| 8 |
from functools import lru_cache
|
|
|
|
| 9 |
|
| 10 |
-
#
|
| 11 |
-
os.
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
from transformers import pipeline
|
| 15 |
|
|
|
|
| 16 |
class SentimentCache:
|
| 17 |
latest_id: int = 0
|
| 18 |
latest_result: dict = {}
|
| 19 |
-
_pipeline = None # Lazy init
|
| 20 |
-
|
| 21 |
-
@classmethod
|
| 22 |
-
def _get_pipeline(cls):
|
| 23 |
-
if cls._pipeline is None:
|
| 24 |
-
logging.info("🔄 Loading sentiment model…")
|
| 25 |
-
cls._pipeline = pipeline(
|
| 26 |
-
"sentiment-analysis",
|
| 27 |
-
model="distilbert-base-uncased-finetuned-sst-2-english"
|
| 28 |
-
)
|
| 29 |
-
return cls._pipeline
|
| 30 |
|
| 31 |
@classmethod
|
| 32 |
def _hash(cls, text: str) -> str:
|
|
@@ -35,16 +24,26 @@ class SentimentCache:
|
|
| 35 |
@classmethod
|
| 36 |
@lru_cache(maxsize=128)
|
| 37 |
def _analyze(cls, text: str):
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
@classmethod
|
| 42 |
def compute(cls, text: str):
|
|
|
|
| 43 |
res = cls._analyze(text)
|
| 44 |
cls.latest_id += 1
|
| 45 |
cls.latest_result = {
|
| 46 |
"text": text,
|
| 47 |
-
"label": res
|
| 48 |
-
"score": round(res
|
| 49 |
}
|
| 50 |
logging.info("✅ Sentiment computed: %s", cls.latest_result)
|
|
|
|
| 1 |
"""
|
| 2 |
+
Sentiment analysis module using Hugging Face Inference API to avoid local model downloads.
|
| 3 |
"""
|
|
|
|
| 4 |
import os
|
| 5 |
import hashlib
|
| 6 |
import logging
|
| 7 |
from functools import lru_cache
|
| 8 |
+
import httpx
|
| 9 |
|
| 10 |
+
# Environment variables (set HF_API_TOKEN in your Space's Settings)
|
| 11 |
+
HF_API_TOKEN = os.getenv("HF_API_TOKEN", "")
|
| 12 |
+
API_URL = "https://api-inference.huggingface.co/models/distilbert-base-uncased-finetuned-sst-2-english"
|
| 13 |
+
HEADERS = {"Authorization": f"Bearer {HF_API_TOKEN}"}
|
|
|
|
| 14 |
|
| 15 |
+
# In-memory cache for latest sentiment
|
| 16 |
class SentimentCache:
|
| 17 |
latest_id: int = 0
|
| 18 |
latest_result: dict = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
@classmethod
|
| 21 |
def _hash(cls, text: str) -> str:
|
|
|
|
| 24 |
@classmethod
|
| 25 |
@lru_cache(maxsize=128)
|
| 26 |
def _analyze(cls, text: str):
|
| 27 |
+
try:
|
| 28 |
+
response = httpx.post(API_URL, headers=HEADERS, json={"inputs": text}, timeout=20)
|
| 29 |
+
response.raise_for_status()
|
| 30 |
+
data = response.json()
|
| 31 |
+
# Expecting list of {label, score}
|
| 32 |
+
if isinstance(data, list) and data:
|
| 33 |
+
return data[0]
|
| 34 |
+
raise ValueError("Unexpected response format: %s" % data)
|
| 35 |
+
except Exception as e:
|
| 36 |
+
logging.error("❌ Sentiment API error: %s", e)
|
| 37 |
+
return {"label": "ERROR", "score": 0.0}
|
| 38 |
|
| 39 |
@classmethod
|
| 40 |
def compute(cls, text: str):
|
| 41 |
+
"""Trigger sentiment inference via API and update latest result."""
|
| 42 |
res = cls._analyze(text)
|
| 43 |
cls.latest_id += 1
|
| 44 |
cls.latest_result = {
|
| 45 |
"text": text,
|
| 46 |
+
"label": res.get("label"),
|
| 47 |
+
"score": round(res.get("score", 0.0), 4)
|
| 48 |
}
|
| 49 |
logging.info("✅ Sentiment computed: %s", cls.latest_result)
|