A production-ready fact-checking platform built with Django REST Framework backend and React frontend, featuring secure API endpoints and external model integration.
- Backend: Django 4.2 with Django REST Framework
- Frontend: React 18 with Bootstrap
- Database: PostgreSQL (production) / SQLite (development)
- Containerization: Docker & Docker Compose
factual/
βββ backend/ # Django backend application
β βββ API/ # API endpoints and views
β βββ accounts/ # User authentication
β βββ factualweb/ # Django project settings
β β βββ settings/ # Split settings (base, dev, prod)
β βββ bert/ # ML models and ETL
β βββ manage.py # Django management script
β βββ requirements.txt # Python dependencies
β βββ Dockerfile # Backend Docker configuration
βββ frontend/ # React frontend application
β βββ src/ # React source files
β βββ public/ # Static assets
β βββ package.json # Node dependencies
β βββ Dockerfile # Frontend Docker configuration
βββ docker-compose.yml # Multi-container setup
βββ .env.example # Environment variables template
βββ README.md # This file
- Python 3.10+
- Node.js 18+
- PostgreSQL (for production)
- Docker & Docker Compose (optional)
Use the provided setup script for quick installation:
git clone <repository-url>
cd factual
chmod +x scripts/setup.sh
./scripts/setup.shgit clone <repository-url>
cd factualcd backend
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Copy environment variables
cp ../.env.example .env
# Edit .env with your configuration
# Run migrations
python manage.py migrate
# Create superuser (optional)
python manage.py createsuperuser
# Run development server
python manage.py runserverThe backend will be available at http://localhost:8000
cd frontend
# Install dependencies
npm install
# Copy environment variables
cp .env.example .env.local
# Edit .env.local with your configuration
# Start development server
npm startThe frontend will be available at http://localhost:3000
# Copy the example environment file
cp .env.example .env
# Edit .env with your production values
nano .env# Build and start all services (DB, Backend, Frontend)
docker-compose up --build
# Or run in detached mode
docker-compose up -d --build
# View logs
docker-compose logs -f
# Stop services
docker-compose down
# Stop and remove volumes
docker-compose down -vServices will be available at:
- Frontend:
http://localhost:3000 - Backend API:
http://localhost:8000 - PostgreSQL:
localhost:5432
All sensitive configuration is managed through environment variables. See .env.example for required variables:
DJANGO_SECRET_KEY: Django secret key (required)DJANGO_DEBUG: Debug mode (True/False)DJANGO_ALLOWED_HOSTS: Comma-separated list of allowed hostsDJANGO_SETTINGS_MODULE: Settings module to use (dev/prod)
DB_ENGINE: Database engine (default: postgresql)DB_NAME: Database nameDB_USER: Database userDB_PASSWORD: Database passwordDB_HOST: Database hostDB_PORT: Database port
MODEL_API_URL: URL of the external finetuned binary word-level sentiment model APIMODEL_API_KEY: API key for the model endpoint (if required)
The model endpoint should accept POST requests with JSON body:
{
"text": "Text to analyze"
}FACTUAL_API_KEY: API key for Factual services
REACT_APP_API_URL: Backend API URL
POST /api/
Legacy endpoint for fact-checking queries.
Request Body:
{
"text/URL": "Text or URL to fact-check"
}POST /api/factual/<endpoint>/
Low-level proxy endpoint for direct Factual API access.
POST /api/analyze-and-match/
High-level endpoint that combines external sentiment model analysis with fact-checking.
Request Body:
{
"text": "Text to analyze and fact-check"
}Response:
{
"sentiment_analysis": { ... },
"fact_check_matches": [ ... ],
"text": "Original text"
}POST /account/register/ # User registration
POST /account/login/ # User login
POST /account/token/ # Get JWT token
POST /account/token/refresh/ # Refresh JWT token
GET /account/get_profile/ # Get user profile
PUT /account/update-profile/ # Update profile
PUT /account/update-email/ # Update email
PUT /account/change-password/ # Change password
- Split Django settings (base, dev, prod) with secure defaults
- All secrets loaded from environment variables
- No credentials committed to repository
- CORS protection with configurable origins
- JWT-based authentication
- HTTPS enforcement in production
- Secure cookie settings
- HSTS headers in production
- Content Security Policy headers
cd backend
python manage.py testcd frontend
npm test- β
Set strong
DJANGO_SECRET_KEY - β
Set
DJANGO_DEBUG=False - β
Configure
DJANGO_ALLOWED_HOSTSwith your domain - β Set up PostgreSQL database
- β
Configure
MODEL_API_URLwith your model endpoint - β Set all required API keys
- β
Enable SSL/TLS (set
SECURE_SSL_REDIRECT=True) - β Configure CORS origins properly
- β Set up static file serving (nginx/CDN)
- β Configure backup strategy for database
The application uses different settings modules:
- Development:
factualweb.settings.dev - Production:
factualweb.settings.prod
Set the appropriate module using the DJANGO_SETTINGS_MODULE environment variable.
- Create a feature branch
- Make your changes
- Run tests
- Submit a pull request
See LICENSE file for details.
For issues and questions:
- Check existing GitHub issues
- Create a new issue with detailed description
- Include error logs and environment details
This application requires an external sentiment analysis model API to be running and accessible. The model is NOT loaded in-process. You must:
- Deploy your finetuned binary word-level sentiment model as a separate API service
- Configure
MODEL_API_URLto point to your model endpoint - Ensure the model API accepts POST requests with JSON body containing a "text" field
- (Optional) Set
MODEL_API_KEYif your model API requires authentication
The /api/analyze-and-match/ endpoint will not function without a properly configured external model API.
When switching from SQLite to PostgreSQL:
# Export data from SQLite
python manage.py dumpdata > data.json
# Configure PostgreSQL in .env
# Run migrations
python manage.py migrate
# Import data
python manage.py loaddata data.json