Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI | |
| from pydantic import BaseModel | |
| import requests | |
| import os | |
| app = FastAPI(title="Forex Sentiment API", version="2.0") | |
| # =============================== | |
| # Konfigurasi | |
| # =============================== | |
| HF_ROUTER_URL = "https://router.huggingface.co/hf-inference/models" | |
| HF_API_KEY = os.getenv("HF_API_KEY") | |
| FINBERT_MODEL = "ProsusAI/finbert" | |
| LONGFORMER_MODEL = "Miruzen/LongFormer_Skripsi" | |
| # =============================== | |
| # Input Schema | |
| # =============================== | |
| class InputData(BaseModel): | |
| title: str | None = None | |
| content: str | None = None | |
| # =============================== | |
| # Helper Functions | |
| # =============================== | |
| def call_hf_model(model_name: str, text: str): | |
| """Kirim teks ke model Hugging Face menggunakan router API baru""" | |
| headers = { | |
| "Authorization": f"Bearer {HF_API_KEY}", | |
| "Content-Type": "application/json", | |
| } | |
| payload = { | |
| "inputs": text, | |
| "options": {"wait_for_model": True} | |
| } | |
| url = f"{HF_ROUTER_URL}/{model_name}" | |
| response = requests.post(url, headers=headers, json=payload) | |
| if response.status_code != 200: | |
| raise Exception( | |
| f"HF API error ({response.status_code}): {response.text}" | |
| ) | |
| return response.json() | |
| def extract_scores(predictions): | |
| """Convert HF model output into {positive, neutral, negative} dict.""" | |
| scores = {"positive": 0.0, "neutral": 0.0, "negative": 0.0} | |
| # Router API sometimes returns either list of lists or single list | |
| data = predictions[0] if isinstance(predictions, list) else predictions | |
| if isinstance(data, list) and len(data) > 0 and isinstance(data[0], dict): | |
| for item in data: | |
| label = item.get("label", "").lower() | |
| if "pos" in label: | |
| scores["positive"] = item["score"] | |
| elif "neg" in label: | |
| scores["negative"] = item["score"] | |
| elif "neu" in label: | |
| scores["neutral"] = item["score"] | |
| dominant = max(scores, key=scores.get) | |
| return {"label": dominant, "scores": scores} | |
| # =============================== | |
| # Main Endpoint | |
| # =============================== | |
| def analyze(data: InputData): | |
| print("π Incoming request:", data) | |
| print("π‘ Using router endpoint:", HF_ROUTER_URL) | |
| print("π Using key starts with:", HF_API_KEY[:10]) | |
| result = {} | |
| errors = [] | |
| if data.title: | |
| try: | |
| finbert_out = call_hf_model(FINBERT_MODEL, data.title) | |
| result["title"] = extract_scores(finbert_out) | |
| except Exception as e: | |
| errors.append(f"Title analysis error: {e}") | |
| if data.content: | |
| try: | |
| longformer_out = call_hf_model(LONGFORMER_MODEL, data.content) | |
| result["content"] = extract_scores(longformer_out) | |
| except Exception as e: | |
| errors.append(f"Content analysis error: {e}") | |
| mood_score = ( | |
| result.get("title", {}).get("scores", {}).get("positive", 0) | |
| + result.get("content", {}).get("scores", {}).get("positive", 0) | |
| - result.get("title", {}).get("scores", {}).get("negative", 0) | |
| - result.get("content", {}).get("scores", {}).get("negative", 0) | |
| ) | |
| return { | |
| "mood_score": mood_score, | |
| "details": result, | |
| "errors": errors, | |
| "status": "ok" if not errors else "partial" | |
| } | |
| def root(): | |
| return {"message": "Forex Sentiment API active via router.huggingface.co!"} | |