Spaces:
Running
Running
File size: 6,576 Bytes
e280c8a 5053036 e280c8a 5053036 e280c8a 5053036 57d0c46 5053036 7b67b3d 5053036 7b67b3d 57d0c46 5053036 7b67b3d 5053036 7b67b3d 5053036 57d0c46 5053036 57d0c46 5053036 57d0c46 7b67b3d 5053036 e280c8a 5053036 e280c8a |
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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
from fastapi import FastAPI, Request, Header, HTTPException, UploadFile, File
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.openapi.utils import get_openapi
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from transformers import pipeline
from io import StringIO
import os, csv, logging
from model import summarize_review, smart_summarize
from typing import Optional
app = FastAPI(
title="🧠 NeuroPulse AI",
description="Multilingual GenAI for smarter feedback — summarization, sentiment, emotion, aspects, Q&A and tags.",
version="2025.1.0",
openapi_url="/openapi.json",
docs_url=None,
redoc_url="/redoc"
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title="🧠 Swagger UI - NeuroPulse AI",
swagger_favicon_url="https://cdn-icons-png.flaticon.com/512/3794/3794616.png",
swagger_js_url="https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui-bundle.js",
swagger_css_url="https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui.css",
)
@app.get("/", response_class=HTMLResponse)
def root():
return open("app/static/index.html").read()
class ReviewInput(BaseModel):
text: str
model: str = "distilbert-base-uncased-finetuned-sst-2-english"
industry: Optional[str] = None
aspects: bool = False
follow_up: Optional[str] = None
product_category: Optional[str] = None
device: Optional[str] = None
intelligence: Optional[bool] = False
verbosity: Optional[str] = "detailed"
explain: Optional[bool] = False
class BulkReviewInput(BaseModel):
reviews: list[str]
model: str = "distilbert-base-uncased-finetuned-sst-2-english"
industry: Optional[list[str]] = None
aspects: bool = False
product_category: Optional[list[str]] = None
device: Optional[list[str]] = None
VALID_API_KEY = "my-secret-key"
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
summarizer = pipeline("summarization", model="sshleifer/distilbart-cnn-12-6")
emotion_model = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", top_k=1)
sentiment_pipelines = {
"distilbert-base-uncased-finetuned-sst-2-english": pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english"),
"nlptown/bert-base-multilingual-uncased-sentiment": pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")
}
def auto_fill(value: Optional[str], default: str = "Generic") -> str:
if not value or value.strip().lower() == "auto-detect":
return default
return value
@app.post("/bulk/")
async def bulk(data: BulkReviewInput, x_api_key: str = Header(None)):
if x_api_key != VALID_API_KEY:
raise HTTPException(status_code=401, detail="Invalid or missing API key")
sentiment_pipeline = sentiment_pipelines[data.model]
summaries = summarizer(data.reviews, max_length=80, min_length=20, truncation=True)
sentiments = sentiment_pipeline(data.reviews)
emotions = emotion_model(data.reviews)
results = []
for i, review in enumerate(data.reviews):
label = sentiments[i]["label"]
if "star" in label:
stars = int(label[0])
label = "NEGATIVE" if stars <= 2 else "NEUTRAL" if stars == 3 else "POSITIVE"
result = {
"review": review,
"summary": summaries[i]["summary_text"],
"sentiment": label,
"emotion": emotions[i][0]["label"],
"aspects": [],
"product_category": auto_fill(data.product_category[i]) if data.product_category else None,
"device": auto_fill(data.device[i], "Web") if data.device else None,
"industry": auto_fill(data.industry[i]) if data.industry else None,
}
results.append(result)
return {"results": results}
@app.post("/analyze/")
async def analyze(request: Request, data: ReviewInput, x_api_key: str = Header(None)):
if x_api_key != VALID_API_KEY:
raise HTTPException(status_code=401, detail="Invalid or missing API key")
sentiment_pipeline = sentiment_pipelines.get(data.model)
summary = smart_summarize(data.text) if request.query_params.get("smart") == "1" else summarize_review(data.text)
sentiment = sentiment_pipeline(data.text)[0]
label = sentiment["label"]
if "star" in label:
stars = int(label[0])
label = "NEGATIVE" if stars <= 2 else "NEUTRAL" if stars == 3 else "POSITIVE"
emotion = emotion_model(data.text)[0][0]["label"]
aspects_list = []
if data.aspects:
for asp in ["battery", "price", "camera"]:
if asp in data.text.lower():
asp_result = sentiment_pipeline(asp + " " + data.text)[0]
aspects_list.append({
"aspect": asp,
"sentiment": asp_result["label"],
"score": asp_result["score"]
})
follow_up_response = None
if data.follow_up and data.intelligence:
follow_up_response = f"[Mocked Detailed Answer in {data.verbosity} mode]"
explanation = "This summary was generated using transformer-based sequence modeling and contextual keyword expansion." if data.explain else None
return {
"summary": summary,
"sentiment": {"label": label, "score": sentiment["score"]},
"emotion": emotion,
"aspects": aspects_list,
"follow_up": follow_up_response,
"explanation": explanation,
"product_category": auto_fill(data.product_category),
"device": auto_fill(data.device, "Web"),
"industry": auto_fill(data.industry)
}
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title=app.title,
version=app.version,
description="""
<b><span style='color:#4f46e5'>NeuroPulse AI</span></b> · Smart GenAI Feedback Engine<br>
Summarize reviews, detect sentiment/emotion, extract aspects, tag metadata, and ask GPT follow-ups.
""",
routes=app.routes
)
openapi_schema["openapi"] = "3.0.0"
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
|