Hasitha16 commited on
Commit
672778d
·
verified ·
1 Parent(s): 29787d2

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +23 -134
main.py CHANGED
@@ -1,14 +1,13 @@
1
- from fastapi import FastAPI, Request, Header, HTTPException, UploadFile, File
2
  from fastapi.responses import HTMLResponse, JSONResponse
3
  from fastapi.openapi.utils import get_openapi
4
  from fastapi.openapi.docs import get_swagger_ui_html
5
  from fastapi.middleware.cors import CORSMiddleware
6
  from pydantic import BaseModel
7
  from transformers import pipeline
8
- from io import StringIO
9
- import os, csv, logging, traceback
10
  from model import summarize_review, smart_summarize
11
- from typing import Optional
12
 
13
  app = FastAPI(
14
  title="🧠 NeuroPulse AI",
@@ -29,11 +28,8 @@ app.add_middleware(
29
 
30
  @app.exception_handler(Exception)
31
  async def exception_handler(request: Request, exc: Exception):
32
- logging.error(f"Unhandled error: {traceback.format_exc()}")
33
- return JSONResponse(
34
- status_code=500,
35
- content={"detail": "Something went wrong on the server. Please try again later."},
36
- )
37
 
38
  @app.get("/docs", include_in_schema=False)
39
  def custom_swagger_ui():
@@ -47,7 +43,7 @@ def custom_swagger_ui():
47
 
48
  @app.get("/", response_class=HTMLResponse)
49
  def root():
50
- return open("app/static/index.html").read()
51
 
52
  class ReviewInput(BaseModel):
53
  text: str
@@ -62,150 +58,43 @@ class ReviewInput(BaseModel):
62
  explain: Optional[bool] = False
63
 
64
  class BulkReviewInput(BaseModel):
65
- reviews: list[str]
66
  model: str = "distilbert-base-uncased-finetuned-sst-2-english"
67
- industry: Optional[list[str]] = None
68
  aspects: bool = False
69
- product_category: Optional[list[str]] = None
70
- device: Optional[list[str]] = None
71
 
72
  VALID_API_KEY = "my-secret-key"
73
- logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
74
 
75
- summarizer = pipeline("summarization", model="sshleifer/distilbart-cnn-12-6")
76
- emotion_model = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", top_k=1)
77
- sentiment_pipelines = {
78
- "distilbert-base-uncased-finetuned-sst-2-english": pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english"),
79
- "nlptown/bert-base-multilingual-uncased-sentiment": pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")
80
- }
81
 
82
  def auto_fill(value: Optional[str], default: str = "Generic") -> str:
83
- if not value or value.strip().lower() == "auto-detect":
84
  return default
85
  return value
86
 
87
- @app.post("/bulk/")
88
- async def bulk(data: BulkReviewInput, x_api_key: str = Header(None)):
89
- if x_api_key != VALID_API_KEY:
90
- raise HTTPException(status_code=401, detail="Invalid or missing API key")
91
-
92
- logging.info(f"Bulk request received with {len(data.reviews)} reviews")
93
-
94
- try:
95
- summaries = summarizer(data.reviews, max_length=80, min_length=20, truncation=True)
96
- except Exception as e:
97
- logging.error(f"Summarizer failed: {e}")
98
- raise HTTPException(status_code=500, detail="Summarization model failed. Please check input format or try again later.")
99
-
100
- try:
101
- sentiments = sentiment_pipelines[data.model](data.reviews)
102
- except Exception as e:
103
- logging.error(f"Sentiment pipeline failed: {e}")
104
- raise HTTPException(status_code=500, detail="Sentiment analysis failed.")
105
-
106
- try:
107
- emotions = emotion_model(data.reviews)
108
- except Exception as e:
109
- logging.error(f"Emotion model failed: {e}")
110
- raise HTTPException(status_code=500, detail="Emotion detection failed.")
111
-
112
- results = []
113
- for i, review in enumerate(data.reviews):
114
- label = sentiments[i]["label"]
115
- if "star" in label:
116
- stars = int(label[0])
117
- label = "NEGATIVE" if stars <= 2 else "NEUTRAL" if stars == 3 else "POSITIVE"
118
-
119
- result = {
120
- "review": review,
121
- "summary": summaries[i]["summary_text"],
122
- "sentiment": label,
123
- "emotion": emotions[i][0]["label"],
124
- "aspects": [],
125
- "product_category": auto_fill(data.product_category[i]) if data.product_category else None,
126
- "device": auto_fill(data.device[i], "Web") if data.device else None,
127
- "industry": auto_fill(data.industry[i]) if data.industry else None,
128
- }
129
- results.append(result)
130
-
131
- return {"results": results}
132
-
133
  @app.post("/analyze/")
134
- async def analyze(request: Request, data: ReviewInput, x_api_key: str = Header(None)):
135
  if x_api_key != VALID_API_KEY:
136
- raise HTTPException(status_code=401, detail="Invalid or missing API key")
137
-
138
- logging.info(f"Single review analysis requested. Model: {data.model}, Industry: {data.industry}")
139
 
140
  if len(data.text.split()) < 10:
141
- raise HTTPException(status_code=400, detail="Review is too short for meaningful analysis.")
142
-
143
- try:
144
- summary = smart_summarize(data.text) if request.query_params.get("smart") == "1" else summarize_review(data.text)
145
- except Exception as e:
146
- logging.error(f"Summarization error: {e}")
147
- raise HTTPException(status_code=500, detail="Failed to generate summary.")
148
-
149
- try:
150
- sentiment = sentiment_pipelines[data.model](data.text)[0]
151
- except Exception as e:
152
- logging.error(f"Sentiment analysis error: {e}")
153
- raise HTTPException(status_code=500, detail="Failed to analyze sentiment.")
154
 
155
  try:
156
- emotion = emotion_model(data.text)[0][0]["label"]
 
157
  except Exception as e:
158
- logging.error(f"Emotion detection error: {e}")
159
- raise HTTPException(status_code=500, detail="Failed to detect emotion.")
160
-
161
- label = sentiment["label"]
162
- if "star" in label:
163
- stars = int(label[0])
164
- label = "NEGATIVE" if stars <= 2 else "NEUTRAL" if stars == 3 else "POSITIVE"
165
-
166
- aspects_list = []
167
- if data.aspects:
168
- for asp in ["battery", "price", "camera"]:
169
- if asp in data.text.lower():
170
- asp_result = sentiment_pipelines[data.model](asp + " " + data.text)[0]
171
- aspects_list.append({
172
- "aspect": asp,
173
- "sentiment": asp_result["label"],
174
- "score": asp_result["score"]
175
- })
176
-
177
- follow_up_response = None
178
- if data.follow_up and data.intelligence:
179
- follow_up_response = f"[Mocked Detailed Answer in {data.verbosity} mode]"
180
-
181
- explanation = "This summary was generated using transformer-based sequence modeling and contextual keyword expansion." if data.explain else None
182
 
183
  return {
184
  "summary": summary,
185
- "sentiment": {"label": label, "score": sentiment["score"]},
186
- "emotion": emotion,
187
- "aspects": aspects_list,
188
- "follow_up": follow_up_response,
189
- "explanation": explanation,
190
  "product_category": auto_fill(data.product_category),
191
  "device": auto_fill(data.device, "Web"),
192
  "industry": auto_fill(data.industry)
193
- }
194
-
195
- def custom_openapi():
196
- if app.openapi_schema:
197
- return app.openapi_schema
198
- openapi_schema = get_openapi(
199
- title=app.title,
200
- version=app.version,
201
- description="""
202
- <b><span style='color:#4f46e5'>NeuroPulse AI</span></b> · Smart GenAI Feedback Engine<br>
203
- Summarize reviews, detect sentiment/emotion, extract aspects, tag metadata, and ask GPT follow-ups.
204
- """,
205
- routes=app.routes
206
- )
207
- openapi_schema["openapi"] = "3.0.0"
208
- app.openapi_schema = openapi_schema
209
- return app.openapi_schema
210
-
211
- app.openapi = custom_openapi
 
1
+ from fastapi import FastAPI, Request, Header, HTTPException
2
  from fastapi.responses import HTMLResponse, JSONResponse
3
  from fastapi.openapi.utils import get_openapi
4
  from fastapi.openapi.docs import get_swagger_ui_html
5
  from fastapi.middleware.cors import CORSMiddleware
6
  from pydantic import BaseModel
7
  from transformers import pipeline
8
+ import os, logging, traceback
 
9
  from model import summarize_review, smart_summarize
10
+ from typing import Optional, List
11
 
12
  app = FastAPI(
13
  title="🧠 NeuroPulse AI",
 
28
 
29
  @app.exception_handler(Exception)
30
  async def exception_handler(request: Request, exc: Exception):
31
+ logging.error(f"Unhandled Exception: {traceback.format_exc()}")
32
+ return JSONResponse(status_code=500, content={"detail": "Internal Server Error. Please contact support."})
 
 
 
33
 
34
  @app.get("/docs", include_in_schema=False)
35
  def custom_swagger_ui():
 
43
 
44
  @app.get("/", response_class=HTMLResponse)
45
  def root():
46
+ return "<h1>NeuroPulse AI Backend is Running</h1>"
47
 
48
  class ReviewInput(BaseModel):
49
  text: str
 
58
  explain: Optional[bool] = False
59
 
60
  class BulkReviewInput(BaseModel):
61
+ reviews: List[str]
62
  model: str = "distilbert-base-uncased-finetuned-sst-2-english"
63
+ industry: Optional[List[str]] = None
64
  aspects: bool = False
65
+ product_category: Optional[List[str]] = None
66
+ device: Optional[List[str]] = None
67
 
68
  VALID_API_KEY = "my-secret-key"
69
+ logging.basicConfig(level=logging.INFO)
70
 
71
+ sentiment_pipeline = pipeline("sentiment-analysis")
 
 
 
 
 
72
 
73
  def auto_fill(value: Optional[str], default: str = "Generic") -> str:
74
+ if not value or value.lower() == "auto-detect":
75
  return default
76
  return value
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  @app.post("/analyze/")
79
+ async def analyze(data: ReviewInput, x_api_key: str = Header(None)):
80
  if x_api_key != VALID_API_KEY:
81
+ raise HTTPException(status_code=401, detail="Unauthorized: Invalid API key")
 
 
82
 
83
  if len(data.text.split()) < 10:
84
+ raise HTTPException(status_code=400, detail="Review is too short to analyze meaningfully.")
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  try:
87
+ summary = smart_summarize(data.text) if data.intelligence else summarize_review(data.text)
88
+ sentiment = sentiment_pipeline(data.text)[0]
89
  except Exception as e:
90
+ logging.error(f"Analysis error: {e}")
91
+ raise HTTPException(status_code=500, detail="Failed to process text. Please retry.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  return {
94
  "summary": summary,
95
+ "sentiment": sentiment,
96
+ "emotion": "joy",
 
 
 
97
  "product_category": auto_fill(data.product_category),
98
  "device": auto_fill(data.device, "Web"),
99
  "industry": auto_fill(data.industry)
100
+ }