Spaces:
Sleeping
Sleeping
File size: 4,726 Bytes
7701077 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, field_validator
from typing import Optional
import time, os
from src.database import init_db, log_request
from src.multilingual import load_all_models, run_inference_multilingual
from src.enrichment import enrich
MODEL_DIR = os.getenv("MODEL_DIR", "models/finbert-finetuned")
MAX_LENGTH = int(os.getenv("MAX_LENGTH", "128"))
app = FastAPI(
title="Financial Sentiment Analysis API",
description="Türkçe ve İngilizce finansal metinleri analiz eder.",
version="3.0.0",
)
@app.on_event("startup")
async def startup():
init_db()
load_all_models()
class SentimentRequest(BaseModel):
text: str
@field_validator("text")
@classmethod
def validate(cls, v):
v = v.strip()
if not v:
raise ValueError("text boş olamaz")
if len(v) > 2000:
raise ValueError("text 2000 karakteri aşamaz")
return v
class SentimentScore(BaseModel):
negative: float
neutral: float
positive: float
class SentimentResponse(BaseModel):
text: str
translated_text: Optional[str] = None
sentiment: str
confidence: float
language: str
scores: SentimentScore
keywords: list[str] # ← YENİ
risk_score: float # ← YENİ
risk_level: str # ← YENİ: LOW / MEDIUM / HIGH
latency_ms: float
class BatchRequest(BaseModel):
texts: list[str]
@field_validator("texts")
@classmethod
def validate_batch(cls, v):
if not v:
raise ValueError("texts boş olamaz")
if len(v) > 32:
raise ValueError("max 32 metin")
return v
class BatchResponse(BaseModel):
results: list[SentimentResponse]
latency_ms: float
@app.get("/", tags=["Health"])
def root():
return {"status": "ok", "version": "3.0.0"}
@app.get("/health", tags=["Health"])
def health():
return {"status": "ok", "model_dir": MODEL_DIR}
@app.get("/monitoring/stats", tags=["Monitoring"])
def monitoring_stats():
from src.database import get_stats
return get_stats()
@app.post("/predict", response_model=SentimentResponse, tags=["Inference"])
def predict(req: SentimentRequest):
t0 = time.perf_counter()
result = run_inference_multilingual([req.text])[0]
# Enrichment — İngilizce metin üzerinde çalışır
analysis_text = result.get("translated_text") or result["text"]
enriched = enrich(analysis_text, result["sentiment"], result["confidence"])
latency = round((time.perf_counter() - t0) * 1000, 2)
log_request(
text = req.text,
sentiment = result["sentiment"],
confidence= result["confidence"],
latency_ms= latency,
endpoint = "/predict",
)
return SentimentResponse(
text = result["text"],
translated_text = result.get("translated_text"),
sentiment = result["sentiment"],
confidence = result["confidence"],
language = result["language"],
scores = SentimentScore(**result["scores"]),
keywords = enriched["keywords"],
risk_score = enriched["risk_score"],
risk_level = enriched["risk_level"],
latency_ms = latency,
)
@app.post("/predict/batch", response_model=BatchResponse, tags=["Inference"])
def predict_batch(req: BatchRequest):
t0 = time.perf_counter()
results = run_inference_multilingual(req.texts)
latency = round((time.perf_counter() - t0) * 1000, 2)
responses = []
for r in results:
analysis_text = r.get("translated_text") or r["text"]
enriched = enrich(analysis_text, r["sentiment"], r["confidence"])
log_request(
text = r["text"],
sentiment = r["sentiment"],
confidence= r["confidence"],
latency_ms= latency / len(results),
endpoint = "/predict/batch",
batch_size= len(req.texts),
)
responses.append(SentimentResponse(
text = r["text"],
translated_text = r.get("translated_text"),
sentiment = r["sentiment"],
confidence = r["confidence"],
language = r["language"],
scores = SentimentScore(**r["scores"]),
keywords = enriched["keywords"],
risk_score = enriched["risk_score"],
risk_level = enriched["risk_level"],
latency_ms = latency,
))
return BatchResponse(results=responses, latency_ms=latency)
|