Spaces:
No application file
No application file
| # app.py — HuggingFace Space (FastAPI) | |
| # FREE CPU tier hosting for CreatorPulse sentiment model | |
| # Space URL: https://ningaraddi-creatorpulse-api.hf.space | |
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel | |
| from typing import List | |
| from transformers import pipeline | |
| import os | |
| app = FastAPI(title="CreatorPulse Sentiment API") | |
| # ── CORS — allow calls from any origin (our React app) ───────────────────────── | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["POST", "GET"], | |
| allow_headers=["*"], | |
| ) | |
| # ── Load model once on startup ───────────────────────────────────────────────── | |
| MODEL_REPO = "ningaraddi/creatorpulse-sentiment" | |
| print(f"Loading model: {MODEL_REPO}") | |
| classifier = pipeline( | |
| "text-classification", | |
| model=MODEL_REPO, | |
| tokenizer=MODEL_REPO, | |
| truncation=True, | |
| max_length=128, | |
| device=-1, # CPU — free tier | |
| top_k=None, # Return all labels with scores | |
| ) | |
| print("Model loaded!") | |
| # ── Schemas ──────────────────────────────────────────────────────────────────── | |
| class ClassifyRequest(BaseModel): | |
| inputs: List[str] | |
| class Prediction(BaseModel): | |
| label: str | |
| confidence: float | |
| text: str | |
| class ClassifyResponse(BaseModel): | |
| predictions: List[Prediction] | |
| # ── Health check ─────────────────────────────────────────────────────────────── | |
| def health(): | |
| return {"status": "ok", "model": MODEL_REPO} | |
| # ── Classify endpoint ────────────────────────────────────────────────────────── | |
| def classify(request: ClassifyRequest): | |
| texts = request.inputs[:100] # Max 100 per call | |
| results = classifier(texts, batch_size=8) | |
| predictions = [] | |
| for text, label_list in zip(texts, results): | |
| top = max(label_list, key=lambda x: x["score"]) | |
| # Normalize label names | |
| label_map = {"LABEL_0": "NEGATIVE", "LABEL_1": "NEUTRAL", "LABEL_2": "POSITIVE"} | |
| label = label_map.get(top["label"], top["label"]) | |
| predictions.append(Prediction( | |
| text=text, | |
| label=label, | |
| confidence=round(top["score"], 4), | |
| )) | |
| return ClassifyResponse(predictions=predictions) | |