An AI-driven web application that detects whether news articles are real or fake using a fine-tuned DistilBERT model and Groq API for verification.
- 🤖 AI-Powered Detection: Fine-tuned DistilBERT model for accurate news classification
- 📄 Multi-Format Input: Accept text, PDF files, or URLs for analysis
- ✅ Auto-Verification: Low-confidence predictions automatically verified via Groq LLM API
- 💬 Interactive Q&A: Ask follow-up questions about articles or general queries
- 🎨 Modern UI: Beautiful React frontend with TailwindCSS and Framer Motion animations
- 🌓 Dark Mode: Full light/dark theme support
- 📱 Responsive Design: Works seamlessly on desktop, tablet, and mobile devices
Sanity_V1/
├── backend/ # Flask backend
│ ├── app.py # Main Flask application
│ ├── scripts/ # Utility scripts
│ │ ├── preprocess_data.py # Data preprocessing
│ │ ├── train_model.py # Model training
│ │ ├── evaluate_model.py # Model evaluation
│ │ ├── check_groq_models.py # Groq model checker
│ │ └── auto_update_model.py # Auto-update Groq model
│ ├── utils/ # Utility modules
│ │ ├── llm_handler.py # Groq API integration
│ │ ├── prompts.py # LLM prompt templates
│ │ ├── pdf_extractor.py # PDF text extraction
│ │ ├── webpage_extractor.py # URL scraping
│ │ ├── text_cleaner.py # Text cleaning utilities
│ │ └── logger.py # Logging utilities
│ ├── data/ # Datasets
│ │ ├── raw/ # Raw datasets
│ │ └── processed/ # Processed datasets
│ ├── model/ # Trained models
│ │ └── distilbert/ # DistilBERT model files
│ ├── tests/ # Unit tests
│ ├── docs/ # Backend documentation
│ └── logs/ # Application logs
├── frontend/ # React frontend
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── store/ # Zustand state management
│ │ ├── lib/ # API utilities
│ │ └── hooks/ # Custom React hooks
│ └── package.json
├── docs/ # Project documentation
├── .env # Environment variables (create this)
├── requirements.txt # Python dependencies
└── README.md # This file
- Python 3.9+ (for backend)
- Node.js 18+ and npm (for frontend)
- Groq API Key (Get one here)
git clone https://github.com/nameadarsh/Sanity.git
cd Sanity# Create virtual environment (recommended)
python -m venv venv
# Activate virtual environment
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# Install Python dependencies
pip install -r backend/requirements.txt
# Download NLTK data (required for preprocessing)
python -c "import nltk; nltk.download('punkt'); nltk.download('punkt_tab'); nltk.download('wordnet'); nltk.download('stopwords')"Note: Large files (model files >100MB and dataset CSV files >50MB) are excluded from the repository due to GitHub file size limits. You'll need to:
- Download the DistilBERT model or train your own (see Training section)
- Add your own datasets to
backend/data/raw/for training
cd frontend
npm install
cd ..Create a .env file in the project root:
# Groq API Configuration
GROQ_API_KEY=your_groq_api_key_here
# Flask Configuration
FLASK_ENV=development
FLASK_PORT=5000
# Model Configuration
MODEL_DIR=backend/model/distilbert
FINE_TUNED_MODEL_PATH=backend/model/sanity_model.bin
PROCESSED_DATA_DIR=backend/data/processed
RAW_DATA_DIR=backend/data/raw
CONFIDENCE_THRESHOLD=0.70
# Frontend API URL
VITE_API_URL=http://localhost:5000If you want to train your own model:
# Preprocess data
python backend/scripts/preprocess_data.py
# Train model
python backend/scripts/train_model.py --epochs 3 --batch-size 8
# Evaluate model
python backend/scripts/evaluate_model.pycd backend
python app.pyThe backend will be available at http://localhost:5000
cd frontend
npm run devThe frontend will be available at http://localhost:3000
GET /healthReturns server status and model readiness.
POST /predict
Content-Type: application/json
{
"input_type": "text", // "text", "pdf", or "url"
"text": "Your news article text here...",
// OR for PDF:
"input_type": "pdf",
"pdf_path": "/path/to/file.pdf",
// OR for URL:
"input_type": "url",
"url": "https://example.com/news-article"
}Response:
{
"label": "Real",
"confidence": 0.85,
"probabilities": {
"real": 0.85,
"fake": 0.15
},
"needs_verification": false,
"context_id": "uuid-here",
"auto_verification": {
"prediction": "Real",
"reasoning": "Verified reasoning..."
}
}POST /verify
Content-Type: application/json
{
"article_text": "Article content here..."
}POST /ask
Content-Type: application/json
{
"question": "Is this article reliable?",
"context_id": "uuid-from-prediction" // Optional: for follow-up questions
}- Setup Guide - Detailed setup instructions
- Input Handling - How to handle different input types
- LLM Prompt Flows - LLM integration details
- Development Plan - Original development plan
pytest backend/tests/- Start both backend and frontend servers
- Navigate to
http://localhost:3000 - Try different input types (text, PDF, URL)
- Test the chat interface for Q&A
- Input Processing: User submits news via text, PDF, or URL
- Text Extraction: System extracts text from the input format using specialized libraries
- Text Cleaning: Extracted text is cleaned and normalized before processing
- Model Prediction: Fine-tuned DistilBERT classifies as Real/Fake with confidence
- Auto-Verification: If confidence < 70%, Groq LLM verifies the prediction
- Result Display: User sees final prediction (LLM if verified, model otherwise)
- Interactive Q&A: Users can ask follow-up questions about the article
- Flask (≥3.0.0): Lightweight Python web framework for building REST APIs
- Flask-CORS (≥4.0.0): Cross-Origin Resource Sharing support for frontend-backend communication
- python-dotenv (≥1.0.0): Environment variable management from
.envfiles - uvicorn (≥0.24.0): ASGI server for production deployment
- gunicorn (≥21.2.0): WSGI HTTP server for production
- PyTorch (≥2.1.0): Deep learning framework for model inference
- Transformers (≥4.35.0): Hugging Face library for DistilBERT model loading and tokenization
- accelerate (≥0.25.0): Accelerated training and inference utilities
- scikit-learn (≥1.3.0): Machine learning utilities for data preprocessing and evaluation
- numpy (≥1.24.0): Numerical computing for array operations
- pandas (≥2.1.0): Data manipulation and analysis for dataset processing
- NLTK (≥3.8.1): Natural Language Toolkit for text preprocessing
- punkt: Sentence tokenization
- punkt_tab: Updated tokenizer data
- wordnet: Lexical database for lemmatization
- stopwords: Common stop words removal
- omw-1.4: Open Multilingual Wordnet
The application uses a multi-library fallback approach for robust PDF text extraction:
-
pdfplumber (≥0.10.0) - Primary Method
- High-quality text extraction with layout preservation
- Handles complex PDF structures and tables
- Extracts text from both file paths and byte streams
- Best for most PDF formats
-
PyPDF2 (≥3.0.0) - Fallback Method 1
- Lightweight PDF manipulation library
- Good for simple PDF documents
- Works with both file paths and byte streams
- Used when pdfplumber fails
-
PyMuPDF (≥1.23.1) - Fallback Method 2 (Optional)
- Fast PDF rendering and text extraction
- Excellent for scanned PDFs and complex layouts
- Only works with file paths (not byte streams)
- Used as final fallback if other methods fail
Extraction Flow:
PDF Input → pdfplumber (try) → PyPDF2 (try) → PyMuPDF (try) → Error
Implementation Location: backend/utils/pdf_extractor.py
The application uses a dual-library approach for extracting article content from URLs:
-
newspaper3k (≥0.2.8) - Primary Method
- Specialized library for article extraction from news websites
- Automatically identifies and extracts main article content
- Removes ads, navigation, and other non-article elements
- Handles article metadata (title, author, publish date)
- Best for news websites and blogs
-
BeautifulSoup4 (≥4.12.0) + requests (≥2.31.0) - Fallback Method
- requests: HTTP library for fetching web pages
- BeautifulSoup: HTML parsing library for extracting text
- Extracts all paragraph (
<p>) tags from HTML - More generic approach, works with any website
- Used when newspaper3k fails or is unavailable
Extraction Flow:
URL Input → newspaper3k (try) → BeautifulSoup + requests (try) → Error
Implementation Location: backend/utils/webpage_extractor.py
- text_cleaner.py: Custom utility module for cleaning text before LLM processing
- Removes excessive whitespace
- Normalizes line breaks
- Truncates text to maximum length (default: 8000 chars)
- Word-boundary aware truncation
- Groq API: Fast inference API for LLM interactions
- Default Model:
llama-3.3-70b-versatile(70B parameter model) - API Endpoint:
https://api.groq.com/openai/v1/chat/completions - Three Prompt Flows:
- Direct questions (general queries)
- Follow-up questions (context-aware)
- Low-confidence verification (auto-verification)
- Default Model:
- requests (≥2.31.0): HTTP client for API calls
- loguru (≥0.7.0): Advanced logging library with structured logging
- Custom logger utilities in
backend/utils/logger.py
- pytest (≥8.0.0): Testing framework for backend unit tests
- tqdm (≥4.66.0): Progress bars for long-running operations
- React (^18.2.0): JavaScript library for building user interfaces
- React DOM (^18.2.0): React renderer for web browsers
- Vite (^5.0.8): Fast build tool and development server
- React Router DOM (^6.20.0): Declarative routing for React applications
- Zustand (^4.4.7): Lightweight state management library
usePredictionStore: Manages prediction results, chat history, loading statesuseThemeStore: Manages light/dark theme with localStorage persistence
- Axios (^1.6.2): Promise-based HTTP client for API requests
- Wrapper in
frontend/src/lib/api.jsfor backend communication - Automatic error handling and request/response interceptors
- Wrapper in
- TailwindCSS (^3.3.6): Utility-first CSS framework
- Dark mode support via class strategy
- Custom theme extensions (colors, animations, transitions)
- Fully responsive design system
- PostCSS (^8.4.32): CSS transformation tool
- Autoprefixer (^10.4.16): Automatic vendor prefixing
- Framer Motion (^10.16.16): Production-ready motion library for React
- Page transitions
- Component animations (fade, slide, scale)
- Stagger effects for lists
- Smooth hover interactions
- @headlessui/react (^1.7.17): Unstyled, accessible UI components
- @heroicons/react (^2.1.1): Beautiful hand-crafted SVG icons
- lucide-react (^0.294.0): Additional icon library
- ESLint (^8.55.0): JavaScript linter
- eslint-plugin-react (^7.33.2): React-specific linting rules
- eslint-plugin-react-hooks (^4.6.0): React Hooks linting rules
- @vitejs/plugin-react (^4.2.1): Vite plugin for React support
- Load Datasets: Merges real and fake news CSV files
- Text Cleaning:
- Lowercase conversion
- Special character removal
- URL and email removal
- Whitespace normalization
- Tokenization: NLTK word tokenization
- Stopword Removal: Removes common stop words
- Lemmatization: Reduces words to their root forms
- Dataset Splitting: Train/validation/test split (80/10/10)
- Base Model:
distilbert-base-uncasedfrom Hugging Face - Fine-tuning: Custom training on news classification dataset
- Framework: Hugging Face Trainer API
- Output: Fine-tuned model saved to
backend/model/distilbert/
- Tokenization: DistilBERT tokenizer with max length 512
- Inference: PyTorch model forward pass
- Post-processing: Softmax for probability distribution
- Confidence Calculation: Maximum probability as confidence score
-
PROMPT_DIRECT_QUESTION: For general user queries
- System prompt: Expert AI assistant with fact-checking emphasis
- Output format: Bullet points, no hallucinations
-
PROMPT_FOLLOWUP_NEWS: For context-aware follow-up questions
- Includes: Article text, model prediction, verification summary
- System prompt: Answer based strictly on provided context
-
PROMPT_LOW_CONFIDENCE_VERIFY: For auto-verification
- System prompt: Fact-checking model with strict verification
- Output format: "Prediction: Real/Fake\nReasoning: <2-3 sentences>"
- GroqClient: Wrapper class for Groq API interactions
- Methods:
call_llm(): Generic LLM call with prompt templateverify_article(): Auto-verification for low-confidence predictionsanswer_question(): Q&A with context routing
- Error Handling: Robust error handling with fallbacks
- Response Parsing: Extracts prediction and reasoning from LLM output
Adjust the confidence threshold in .env:
CONFIDENCE_THRESHOLD=0.70 # Auto-verify if confidence < 0.70The default model is llama-3.3-70b-versatile. To check available models:
python backend/scripts/check_groq_models.pyTo auto-update the model:
python backend/scripts/auto_update_model.pyThe PDF extraction system automatically tries multiple libraries in order:
- pdfplumber (recommended for best results)
- PyPDF2 (fallback for simple PDFs)
- PyMuPDF (fallback for complex/scanned PDFs)
All three libraries are included in backend/requirements.txt. If you want to disable PyMuPDF (optional dependency), you can remove it from requirements, and the system will use the first two methods.
The URL extraction system uses:
- newspaper3k (primary - best for news sites)
- BeautifulSoup + requests (fallback - works with any website)
Both are included in backend/requirements.txt. The system automatically falls back if newspaper3k fails.
Note: Some websites may block automated scraping. If you encounter issues:
- Check if the website requires authentication
- Verify the URL is publicly accessible
- Consider adding custom headers or delays for rate limiting
- Model not loading: Ensure
MODEL_DIRin.envpoints to the correct model directory - Groq API errors: Check your API key and model availability
- Port already in use: Change
FLASK_PORTin.env - PDF extraction fails:
- Ensure all PDF libraries are installed:
pip install pdfplumber PyPDF2 PyMuPDF - Check if the PDF is password-protected or corrupted
- Verify file permissions
- Ensure all PDF libraries are installed:
- URL scraping fails:
- Check if the website is accessible and not blocking bots
- Verify the URL is a valid news article link
- Some sites may require custom headers (modify
webpage_extractor.py)
- NLTK data missing: Run the NLTK download command in the installation section
- API connection errors: Verify
VITE_API_URLin.envmatches backend URL - Build errors: Run
npm installagain in the frontend directory - Theme not persisting: Check browser localStorage permissions
- Animations not working: Ensure Framer Motion is properly installed
ISC
Contributions are welcome! Please feel free to submit a Pull Request.
nameadarsh
- GitHub: @nameadarsh
- Hugging Face Transformers - Pre-trained models and tokenizers
- Groq API - Fast LLM inference
- PyTorch - Deep learning framework
- Flask - Web framework
- React - UI library
- TailwindCSS - CSS framework
- Framer Motion - Animation library
- Zustand - State management
- Vite - Build tool
- NLTK - Natural language processing
- pandas - Data manipulation
- scikit-learn - Machine learning utilities
- pdfplumber - PDF text extraction
- PyPDF2 - PDF manipulation
- PyMuPDF - Fast PDF processing
- newspaper3k - Article extraction
- BeautifulSoup - HTML parsing
- requests - HTTP library
Made with ❤️ for truth and accuracy in news