""" NLP Insight Engine — REST API FastAPI backend exposing the NLP pipeline as a JSON API. Run: uvicorn api.main:app --reload """ from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field from utils.pipeline import NLPPipeline app = FastAPI( title="NLP Insight Engine API", description=( "A free, open-source NLP analysis API. " "Supports sentiment analysis, named entity recognition, " "keyword extraction, and extractive summarisation." ), version="1.0.0", docs_url="/api/docs", ) # Lazy-load pipeline on first request _pipeline = None def get_pipeline() -> NLPPipeline: global _pipeline if _pipeline is None: _pipeline = NLPPipeline() return _pipeline # ── Request / Response schemas ─────────────────────────────────────────────── class AnalyseRequest(BaseModel): text: str = Field(..., min_length=20, max_length=5000, description="Text to analyse") sentiment: bool = Field(True, description="Run sentiment analysis") ner: bool = Field(True, description="Run named entity recognition") keywords: bool = Field(True, description="Run keyword extraction") summary: bool = Field(True, description="Run extractive summarisation") class AnalyseResponse(BaseModel): word_count: int sentiment: dict | None = None entities: list | None = None keywords: list | None = None summary: str | None = None # ── Endpoints ──────────────────────────────────────────────────────────────── @app.get("/") def root(): return { "service": "NLP Insight Engine", "version": "1.0.0", "docs": "/api/docs", } @app.get("/health") def health(): return {"status": "ok"} @app.post("/api/analyse", response_model=AnalyseResponse) def analyse(req: AnalyseRequest): """Run NLP analysis on the provided text.""" pipe = get_pipeline() text = req.text.strip() result = AnalyseResponse(word_count=len(text.split())) try: if req.sentiment: result.sentiment = pipe.analyse_sentiment(text) if req.ner: result.entities = pipe.extract_entities(text) if req.keywords: result.keywords = pipe.extract_keywords(text) if req.summary: result.summary = pipe.summarise(text) except Exception as e: raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}") return result