Spaces:
Paused
Paused
Download sentiment.py from Therdpoom/line-webhook: direct link, hf CLI and curl.
- Browser
- Download file 3.39 kB
-
https://huggingface.co/spaces/Therdpoom/line-webhook/resolve/main/sentiment.py
- Command line
-
hf download hf://spaces/Therdpoom/line-webhook/sentiment.py
-
curl -L -o sentiment.py https://huggingface.co/spaces/Therdpoom/line-webhook/resolve/main/sentiment.py
3.39 kB
| """ | |
| HuggingFace Sentiment Analysis | |
| ───────────────────────────── | |
| เรียก HuggingFace Inference API เพื่อวิเคราะห์ความรู้สึกของข้อความภาษาไทย | |
| Model ที่แนะนำ: | |
| - airesearch/wangchanberta-base-att-spm-uncased (ภาษาไทย ทั่วไป) | |
| - pythainlp/thai-sentiment-analysis (ถ้ามี fine-tune) | |
| - อาจใช้ multilingual model: cardiffnlp/twitter-xlm-roberta-base-sentiment | |
| """ | |
| import httpx | |
| import logging | |
| from app.config import settings | |
| from app.models import SentimentResult | |
| logger = logging.getLogger(__name__) | |
| HF_API_URL = ( | |
| f"https://api-inference.huggingface.co/models/{settings.HF_MODEL_NAME}" | |
| ) | |
| # Label mapping จาก model output → ชื่อ standard | |
| LABEL_MAP = { | |
| # WangchanBERTa / Thai models | |
| "pos": "positive", | |
| "neu": "neutral", | |
| "neg": "negative", | |
| # cardiffnlp / XLM-RoBERTa | |
| "positive": "positive", | |
| "neutral": "neutral", | |
| "negative": "negative", | |
| # LABEL_0/1/2 fallback (ขึ้นกับ model) | |
| "LABEL_0": "negative", | |
| "LABEL_1": "neutral", | |
| "LABEL_2": "positive", | |
| } | |
| async def analyze_sentiment(text: str) -> SentimentResult: | |
| """ | |
| ส่งข้อความไปวิเคราะห์ที่ HuggingFace แล้วคืน SentimentResult | |
| HuggingFace Inference API คืนรูปแบบ: | |
| [[{"label": "pos", "score": 0.91}, {"label": "neg", "score": 0.05}, ...]] | |
| """ | |
| headers = {"Authorization": f"Bearer {settings.HF_API_TOKEN}"} | |
| payload = {"inputs": text, "options": {"wait_for_model": True}} | |
| try: | |
| async with httpx.AsyncClient(timeout=15.0) as client: | |
| response = await client.post(HF_API_URL, headers=headers, json=payload) | |
| response.raise_for_status() | |
| data = response.json() | |
| # Flatten nested list ที่ HF คืนมา | |
| scores = data[0] if isinstance(data[0], list) else data | |
| # แปลง label และสร้าง raw_scores dict | |
| raw_scores: dict[str, float] = {} | |
| for item in scores: | |
| normalized = LABEL_MAP.get(item["label"], item["label"].lower()) | |
| raw_scores[normalized] = round(item["score"], 4) | |
| # หา label ที่มี score สูงสุด | |
| best_label = max(raw_scores, key=raw_scores.get) | |
| return SentimentResult( | |
| label=best_label, | |
| score=raw_scores[best_label], | |
| raw_scores=raw_scores, | |
| ) | |
| except httpx.HTTPStatusError as e: | |
| logger.error(f"HuggingFace API error {e.response.status_code}: {e.response.text}") | |
| return _fallback_result() | |
| except httpx.TimeoutException: | |
| logger.error("HuggingFace API timeout") | |
| return _fallback_result() | |
| except Exception as e: | |
| logger.error(f"Unexpected error in sentiment analysis: {e}") | |
| return _fallback_result() | |
| def _fallback_result() -> SentimentResult: | |
| """คืน neutral เมื่อ API ล้มเหลว เพื่อไม่ให้ระบบหยุด""" | |
| return SentimentResult( | |
| label="neutral", | |
| score=0.0, | |
| raw_scores={"positive": 0.0, "neutral": 0.0, "negative": 0.0}, | |
| ) | |