# 🚀 API & Architecture Documentation ## API Endpoints ### 1. Health Check ```http GET /health Content-Type: application/json ``` **Response (200 OK):** ```json { "status": "ok", "spacy_model": "en_core_web_sm", "whisper_model": "small", "whisper_device": "cpu" } ``` --- ### 2. Analyze Text/Audio (JSON Response) ```http POST /api/analyze Content-Type: multipart/form-data Parameters: file: File[Optional] - Audio file (.wav, .mp3, .m4a, .flac, .ogg, .aac, .webm) text: str[Optional] - Raw text or text file content language: str[Optional] - Language code (en, es, fr, de, zh, etc.) Default: "en" Note: Either 'file' or 'text' must be provided, but not both ``` **Response (200 OK):** ```json { "transcript": "string - normalized input text", "normalizedText": "string - same as transcript", "products": [ { "name": "camera", "sentiment": "positive|neutral|negative", "score": 0.87, "confidence": 0.82, "mentions": 1, "context": "The camera quality is absolutely stunning", "contexts": ["The camera quality is..."], "highlights": [ { "product": "camera", "text": "camera", "start": 4, "end": 10 } ] } ], "highlights": [ { "product": "camera", "text": "camera", "start": 4, "end": 10 } ], "summary": { "positive": 75, "negative": 25, "neutral": 0, "counts": { "positive": 3, "negative": 1, "neutral": 0 }, "dominant": "positive", "averageScore": 0.555, "totalProducts": 4 }, "pipeline": [ { "id": "uploading", "title": "Uploading", "status": "completed", "detail": "Accepted audio input from file.wav." }, { "id": "speech_to_text", "title": "Speech-to-text", "status": "completed", "detail": "Converted audio to text with Whisper." }, { "id": "nlp_extraction", "title": "NLP extraction", "status": "completed", "detail": "Extracted 4 aspect mentions with spaCy." }, { "id": "sentiment_analysis", "title": "Sentiment analysis", "status": "completed", "detail": "Scored each aspect context with VADER." } ], "metadata": { "sourceType": "audio|text", "sourceName": "filename or typed-text", "language": "en", "processingMs": 245, "transcriptionConfidence": 0.95, "whisperModel": "small", "wordCount": 58, "sentenceCount": 6, "createdAt": "2026-04-13T10:30:45.123Z" } } ``` **Error Responses:** ```json 400 Bad Request - Missing both text and file { "detail": "Provide either text input or a file upload." } ``` ```json 400 Bad Request - Invalid file type { "detail": "Unsupported file type '.xyz'. Upload audio or a text file." } ``` ```json 422 Unprocessable Entity - Empty transcription { "detail": "Whisper returned an empty transcript. Try a clearer or longer audio sample." } ``` ```json 500 Internal Server Error { "detail": "Aspect sentiment analysis failed: [error details]" } ``` --- ### 3. Analyze with Streaming (Server-Sent Events) ```http POST /api/analyze-stream Content-Type: multipart/form-data Parameters: (same as /api/analyze) ``` **Response (200 OK with text/event-stream):** The server streams JSONL (JSON Lines) events, one per line: ```jsonl {"type": "step", "step": {"id": "uploading", "title": "Uploading", "status": "completed", "detail": "Received input from file.wav."}} {"type": "step", "step": {"id": "speech_to_text", "title": "Speech-to-text", "status": "active", "detail": "Transcribing audio with Whisper."}} {"type": "step", "step": {"id": "speech_to_text", "title": "Speech-to-text", "status": "completed", "detail": "Audio successfully converted to text."}} {"type": "step", "step": {"id": "nlp_extraction", "title": "NLP extraction", "status": "active", "detail": "Extracting noun phrases and feature mentions with spaCy."}} {"type": "step", "step": {"id": "nlp_extraction", "title": "NLP extraction", "status": "completed", "detail": "Extracted 4 aspect mentions."}} {"type": "step", "step": {"id": "sentiment_analysis", "title": "Sentiment analysis", "status": "active", "detail": "Scoring aspect-specific context windows with VADER."}} {"type": "step", "step": {"id": "sentiment_analysis", "title": "Sentiment analysis", "status": "completed", "detail": "Calculated sentiment for 4 products/features."}} {"type": "result", "data": {...full analysis response...}} ``` **Step Status Values:** - `pending` - Not yet started - `active` - Currently processing - `completed` - Successfully finished - `skipped` - Skipped (e.g., no audio input) - `error` - Failed --- ## Architecture Overview ### System Components ``` ┌─────────────────────────────────────┐ │ Frontend (React + TypeScript) │ │ │ │ Components: │ │ - UploadSection │ │ - HeroSection │ │ - PipelineSection │ │ - SentimentSection │ │ - EntitySection │ │ - SummarySection │ │ - TranscriptSection │ │ │ │ Libraries: │ │ - React 18 │ │ - Framer Motion (animations) │ │ - Chart.js (visualizations) │ │ - Tailwind CSS (styling) │ └─────────────────────────────────────┘ ↑↓ HTTP/SSE Port 8000 ↔ Port 5173 ↓↑ ┌─────────────────────────────────────┐ │ Backend (FastAPI + Python) │ │ │ │ Endpoints: │ │ - GET /health │ │ - POST /api/analyze │ │ - POST /api/analyze-stream │ │ │ │ Core Modules: │ │ ┌─────────────────────────────┐ │ │ │ AspectSentimentEngine │ │ │ │ - Text normalization │ │ │ │ - spaCy parsing │ │ │ │ - Noun extraction │ │ │ │ - Context windowing │ │ │ │ - VADER sentiment scoring │ │ │ │ - Results aggregation │ │ │ └─────────────────────────────┘ │ │ │ │ ┌─────────────────────────────┐ │ │ │ WhisperTranscriber │ │ │ │ - Audio file handling │ │ │ │ - Format detection │ │ │ │ - Whisper integration │ │ │ │ - Confidence estimation │ │ │ └─────────────────────────────┘ │ │ │ │ ┌─────────────────────────────┐ │ │ │ Data Models (Pydantic) │ │ │ │ - AnalysisResponse │ │ │ │ - ProductSentiment │ │ │ │ - SentimentSummary │ │ │ │ - PipelineStage │ │ │ │ - AnalysisMetadata │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────┘ ↓↑ ┌─────────────────────────────────────┐ │ NLP Processing Pipeline │ │ │ │ 1. Text Normalization │ │ Input: " Hello WORLD " │ │ Output: "Hello WORLD" │ │ │ │ 2. Tokenization & POS Tagging │ │ spaCy NLP pipeline │ │ - Segmentation │ │ - Part-of-speech tagging │ │ - Dependency parsing │ │ │ │ 3. Noun Extraction │ │ Filter: pos_ in ["NOUN","PROPN"]│ │ Results: [camera, battery, ...]│ │ │ │ 4. Aspect Mention Detection │ │ - Span extraction │ │ - Name normalization │ │ - Duplicate filtering │ │ - Generic term removal │ │ │ │ 5. Context Window Selection │ │ - Sentence isolation │ │ - Clause boundary detection │ │ - Negation handling │ │ │ │ 6. Sentiment Scoring (VADER) │ │ For each context window: │ │ - Tokenization │ │ - Lexicon lookup │ │ - Valence computation │ │ - Score normalization │ │ │ │ 7. Results Aggregation │ │ - Unique products │ │ - Score averaging │ │ - Confidence calculation │ │ - Summary statistics │ └─────────────────────────────────────┘ ``` --- ## Data Flow ### Text Input Flow ``` User Input ↓ Frontend: Form submission ↓ HTTP POST /api/analyze-stream ↓ Backend: Parse FormData ↓ AspectSentimentEngine.analyze_text() ├─ normalize_text() ├─ parse() → spaCy Doc ├─ extract_mentions() → [AspectMention] ├─ score_products() → [ProductSentiment] ├─ summarize() → SentimentSummary └─ Return AnalysisResponse ↓ Stream Events (SSE) ├─ uploading: completed ├─ speech_to_text: skipped ├─ nlp_extraction: completed ├─ sentiment_analysis: completed └─ result: {...} ↓ Frontend: Display Results Dashboard ``` ### Audio Input Flow ``` User Uploads Audio ↓ Frontend: Read File ↓ HTTP POST /api/analyze-stream (multipart/form-data) ├─ file: [audio_data] └─ language: "en" ↓ Backend: Receive Upload ├─ Save to temp location └─ Stream: uploading: completed ↓ WhisperTranscriber.transcribe() ├─ Ensure ffmpeg on PATH ├─ Load model (if needed) ├─ Transcribe audio ├─ Extract language ├─ Estimate confidence └─ Clean up temp file ↓ Stream Events: └─ speech_to_text: completed → transcript ↓ AspectSentimentEngine.analyze_text() (same as text flow) ↓ Frontend: Display Results ``` --- ## Configuration ### Environment Variables ```bash # .env file or system environment variables # Whisper Settings WHISPER_MODEL_SIZE=small # small, base, medium, large WHISPER_DEVICE=cpu # cpu, cuda # API Settings LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR PORT=8000 # API port # Frontend VITE_API_BASE_URL=http://localhost:8000 ``` ### Whisper Model Sizes | Size | VRAM | Accuracy | Speed | Use Case | |------|------|----------|-------|----------| | tiny | 1GB | ~60% | Very Fast | Demo/Testing | | small | 2GB | ~75% | Fast | Development | | base | 2GB | ~80% | Moderate | Recommended | | medium | 5GB | ~88% | Slow | High Quality | | large | 10GB | ~95% | Very Slow | Maximum Accuracy | --- ## Performance Metrics ### Response Times (measured on test system) - Text analysis (50 words): ~100ms - Text analysis (500 words): ~200ms - Audio transcription (1 min): ~2-5s - Total end-to-end (audio): ~3-7s ### Resource Usage - Memory: ~2-3GB (with models loaded) - CPU: ~30-50% during processing - GPU: Optional (significant speedup if available) --- ## Error Handling ### Common Error Scenarios **1. Missing spaCy Model** ``` Error: OSError: [E050] Can't find model 'en_core_web_sm' Solution: python -m spacy download en_core_web_sm ``` **2. ffmpeg Not Found** ``` Error: FileNotFoundError: ffmpeg not found Solution: Already bundled, check PATH or install ffmpeg ``` **3. Invalid Audio File** ``` Error: [...] no matching input format found Solution: Convert to .wav or .mp3 format ``` **4. Out of Memory** ``` Error: RuntimeError: CUDA out of memory Solution: Use smaller whisper model or CPU device ``` **5. Empty Transcription** ``` Error: "Whisper returned an empty transcript" Solution: Try clearer audio or longer duration ``` --- ## Deployment ### Production Considerations 1. **Use Production ASGI Server** ```bash # Instead of: uvicorn src.api.server:app --reload gunicorn src.api.server:app -w 4 -b 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker ``` 2. **Enable HTTPS** ```python # Use nginx reverse proxy or certbot for SSL ``` 3. **Rate Limiting** ```python # Add rate limiting middleware to prevent abuse from slowapi import Limiter ``` 4. **Caching** ```python # Cache common requests using Redis ``` 5. **Monitoring** ```python # Add Prometheus metrics for monitoring ``` ### Docker Deployment ```dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt && \ python -m spacy download en_core_web_sm COPY . . CMD ["uvicorn", "src.api.server:app", "--host", "0.0.0.0", "--port", "8000"] ``` --- ## Testing ### API Testing ```bash # Health check curl http://localhost:8000/health # Text analysis curl -X POST "http://localhost:8000/api/analyze" \ -F "text=The camera is amazing but battery drains fast" # Audio analysis curl -X POST "http://localhost:8000/api/analyze" \ -F "file=@audio.wav" \ -F "language=en" # Streaming analysis curl -X POST "http://localhost:8000/api/analyze-stream" \ -F "text=Test text" \ -N # No buffering to see streaming events ``` ### Frontend Testing ```bash # Unit tests (if available) npm test # E2E tests npm run test:e2e # Build and preview npm run build npm run preview ``` --- ## API Documentation UIs When backend is running: - **Swagger UI**: http://localhost:8000/docs - **ReDoc**: http://localhost:8000/redoc --- ## Support & Troubleshooting 1. **Check API Status** ```bash curl http://localhost:8000/health ``` 2. **Review Test Results** ```bash python test_system.py ``` 3. **Check Logs** - Backend: Terminal output with `--reload` flag - Frontend: Browser console (F12) 4. **Verify Dependencies** ```bash .venv\Scripts\pip.exe list ``` --- **Last Updated:** April 2026 **Status:** Production Ready