sentiment-api / app.py
Javeriakhalid15's picture
Upload 3 files
a0a882d verified
Raw
History Blame Contribute Delete
2.95 kB
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
from transformers import pipeline
from typing import Dict, List
from contextlib import asynccontextmanager
import torch, logging
from datetime import datetime, timezone
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("sentiment-api")
MODEL_ID = "Javeriakhalid15/my-sentiment-analyzer"
ml_models: Dict[str, object] = {}
@asynccontextmanager
async def lifespan(app: FastAPI):
logger.info(f"Loading model: {MODEL_ID}")
try:
ml_models["classifier"] = pipeline(
"sentiment-analysis", model=MODEL_ID,
device=0 if torch.cuda.is_available() else -1,
)
logger.info("Model loaded.")
except Exception as e:
logger.error(f"Failed: {e}")
ml_models["classifier"] = None
yield
ml_models.clear()
app = FastAPI(title="Sentiment Analysis API", version="1.0.0", lifespan=lifespan)
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
class TextRequest(BaseModel):
text: str = Field(..., min_length=1, max_length=5000)
class BatchRequest(BaseModel):
texts: List[str] = Field(..., min_length=1, max_length=50)
class SentimentResponse(BaseModel):
text: str
label: str
confidence: float
probabilities: Dict[str, float]
timestamp: str
@app.get("/")
async def root():
return {"message": "Sentiment Analysis API", "docs": "/docs", "health": "/health"}
@app.get("/health")
async def health():
loaded = ml_models.get("classifier") is not None
return {"status": "healthy" if loaded else "degraded", "model_loaded": loaded}
@app.post("/predict", response_model=SentimentResponse)
async def predict(request: TextRequest):
clf = ml_models.get("classifier")
if clf is None:
raise HTTPException(503, "Model not loaded.")
result = clf(request.text)[0]
other = "LABEL_0" if result["label"] == "LABEL_1" else "LABEL_1"
return SentimentResponse(
text=request.text[:200],
label=result["label"],
confidence=round(result["score"], 4),
probabilities={result["label"]: round(result["score"], 4), other: round(1 - result["score"], 4)},
timestamp=datetime.now(timezone.utc).isoformat(),
)
@app.post("/predict/batch")
async def predict_batch(request: BatchRequest):
clf = ml_models.get("classifier")
if clf is None:
raise HTTPException(503, "Model not loaded.")
results = clf(request.texts)
return {
"results": [{"text": t[:100], "label": r["label"], "confidence": round(r["score"], 4)}
for t, r in zip(request.texts, results)],
"total": len(results),
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)