# PunimTag Web

**Modern Photo Management and Facial Recognition System**

A fast, simple, and modern web application for organizing and tagging photos using state-of-the-art DeepFace AI with ArcFace recognition model.

---

## 🎯 Features

- **🌐 Web-Based**: Modern React frontend with FastAPI backend
- **🔥 DeepFace AI**: State-of-the-art face detection with RetinaFace and ArcFace models
- **🎯 Superior Accuracy**: 512-dimensional embeddings (4x more detailed than face_recognition)
- **⚙️ Multiple Detectors**: Choose from RetinaFace, MTCNN, OpenCV, or SSD detectors
- **🎨 Flexible Models**: Select ArcFace, Facenet, Facenet512, or VGG-Face recognition models
- **👤 Person Identification**: Identify and tag people across your photo collection
- **🤖 Smart Auto-Matching**: Intelligent face matching with quality scoring and cosine similarity
- **📊 Confidence Calibration**: Empirical-based confidence scores for realistic match probabilities
- **🔍 Advanced Search**: Search by people, dates, tags, and folders
- **🏷️ Tag Management**: Organize photos with hierarchical tags
- **⚡ Batch Processing**: Process thousands of photos efficiently
- **🎯 Unique Faces Filter**: Hide duplicate faces to focus on unique individuals
- **🔄 Real-time Updates**: Live progress tracking and job status updates
- **🔒 Privacy-First**: All data stored locally, no cloud dependencies

---

## 🚀 Quick Start

### Prerequisites

- Python 3.12 or higher
- Node.js 18+ and npm
- Virtual environment (recommended)

### Installation

```bash
# Clone the repository
git clone <repository-url>
cd punimtag

# Create and activate virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install Python dependencies
pip install -r requirements.txt

# Install frontend dependencies
cd frontend
npm install
cd ..
```

### Database Setup

**PostgreSQL (Default - Network Database):**
The application is configured to use PostgreSQL by default. The database connection is configured via the `.env` file.

**Install PostgreSQL (if not installed):**
```bash
# On Ubuntu/Debian:
sudo apt update && sudo apt install -y postgresql postgresql-contrib
sudo systemctl start postgresql
sudo systemctl enable postgresql

# Or use the automated setup script:
./scripts/setup_postgresql.sh
```

**Create Database and User:**
```bash
sudo -u postgres psql -c "CREATE USER punimtag WITH PASSWORD 'punimtag_password';"
sudo -u postgres psql -c "CREATE DATABASE punimtag OWNER punimtag;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE punimtag TO punimtag;"
```

**Configuration:**
The `.env` file contains the database connection string:
```bash
DATABASE_URL=postgresql+psycopg2://punimtag:punimtag_password@localhost:5432/punimtag
```

**Automatic Initialization:**
The database and all tables are automatically created on first startup. No manual migration is needed!

The web application will:
- Connect to PostgreSQL using the `.env` configuration
- Create all required tables with the correct schema on startup
- Match the desktop version schema exactly for compatibility

**Manual Setup (Optional):**
If you need to reset the database or create it manually:
```bash
source venv/bin/activate
export PYTHONPATH=/home/ladmin/Code/punimtag
# Recreate all tables from models
python scripts/recreate_tables_web.py
```

**SQLite (Alternative - Local Database):**
To use SQLite instead of PostgreSQL, comment out or remove the `DATABASE_URL` line in `.env`, or set it to:
```bash
DATABASE_URL=sqlite:///data/punimtag.db
```

**Database Schema:**
The web version uses the **exact same schema** as the desktop version for full compatibility:
- `photos` - Photo metadata (path, filename, date_taken, processed)
- `people` - Person records (first_name, last_name, middle_name, maiden_name, date_of_birth)
- `faces` - Face detections (encoding, location, quality_score, face_confidence, exif_orientation)
- `person_encodings` - Person face encodings for matching
- `tags` - Tag definitions
- `phototaglinkage` - Photo-tag relationships (with linkage_type)

### Running the Application

**Prerequisites:**
- **PostgreSQL** must be installed and running (see Database Setup section above)
- **Redis** must be installed and running (for background jobs)
  
  **Install Redis (if not installed):**
  ```bash
  # On Ubuntu/Debian:
  sudo apt update && sudo apt install -y redis-server
  sudo systemctl start redis-server
  sudo systemctl enable redis-server  # Auto-start on boot
  
  # On macOS with Homebrew:
  brew install redis
  brew services start redis
  
  # Verify Redis is running:
  redis-cli ping  # Should respond with "PONG"
  ```
  
  **Start Redis (if installed but not running):**
  ```bash
  # On Linux:
  sudo systemctl start redis-server
  
  # Or run directly:
  redis-server
  ```

#### Option 1: Manual Start (Recommended for Development)

**Terminal 1 - Backend API:**
```bash
cd /home/ladmin/Code/punimtag
source venv/bin/activate
export PYTHONPATH=/home/ladmin/Code/punimtag
uvicorn src.web.app:app --host 127.0.0.1 --port 8000
```

You should see:
```
✅ Database already initialized (7 tables exist)
✅ RQ worker started in background subprocess (PID: ...)
INFO:     Started server process
INFO:     Uvicorn running on http://127.0.0.1:8000
```

**Terminal 2 - Frontend:**
```bash
cd /home/ladmin/Code/punimtag/frontend
npm run dev
```

You should see:
```
VITE v5.4.21  ready in 811 ms
➜  Local:   http://localhost:3000/
```

#### Option 2: Using Helper Script (Backend + Worker)

**Terminal 1 - Backend API + Worker:**
```bash
cd /home/ladmin/Code/punimtag
./run_api_with_worker.sh
```

This script will:
- Check if Redis is running (start it if needed)
- Start the RQ worker in the background
- Start the FastAPI server
- Handle cleanup on Ctrl+C

**Terminal 2 - Frontend:**
```bash
cd /home/ladmin/Code/punimtag/frontend
npm run dev
```

#### Access the Application

1. Open your browser to **http://localhost:3000**
2. Login with default credentials:
   - Username: `admin`
   - Password: `admin`
3. API documentation available at **http://127.0.0.1:8000/docs**

#### Troubleshooting

**Port 8000 already in use:**
```bash
# Find and kill the process using port 8000
lsof -i :8000
kill <PID>

# Or use pkill
pkill -f "uvicorn.*app"
```

**Port 3000 already in use:**
```bash
# Find and kill the process using port 3000
lsof -i :3000
kill <PID>

# Or change the port in frontend/vite.config.ts
```

**Redis not running:**
```bash
# Start Redis
sudo systemctl start redis-server
# Or
redis-server
```

**Database issues:**
```bash
# Recreate all tables (WARNING: This will delete all data!)
cd /home/ladmin/Code/punimtag
source venv/bin/activate
export PYTHONPATH=/home/ladmin/Code/punimtag
python scripts/recreate_tables_web.py
```

#### Important Notes

- The database and tables are **automatically created on first startup** - no manual setup needed!
- The RQ worker starts automatically in a background subprocess when the API server starts
- Make sure Redis is running first, or the worker won't start
- Worker names are unique to avoid conflicts when restarting
- Photo uploads are stored in `data/uploads` (configurable via `PHOTO_STORAGE_DIR` env var)
- **DeepFace models download automatically on first use** (can take 5-10 minutes, ~100MB)
- First run is slower due to model downloads (subsequent runs are faster)

---

## 📖 Documentation

- **[Architecture](docs/ARCHITECTURE.md)**: System design and technical details


*

## 🏗️ Project Structure

```
punimtag/
├── src/                    # Source code
│   ├── web/               # Web backend
│   │   ├── api/           # API routers
│   │   ├── db/            # Database models and session
│   │   ├── schemas/       # Pydantic models
│   │   └── services/      # Business logic services
│   └── core/              # Legacy desktop business logic
├── frontend/               # React frontend
│   ├── src/
│   │   ├── api/           # API client
│   │   ├── components/    # React components
│   │   ├── context/       # React contexts (Auth)
│   │   ├── hooks/         # Custom hooks
│   │   └── pages/         # Page components
│   └── package.json
├── tests/                  # Test suite
├── docs/                   # Documentation
├── data/                   # Application data (database, images)
├── alembic/                # Database migrations
└── deploy/                 # Docker deployment configs
```

---

## 📊 Current Status

###  Foundations 

**Backend:**
- ✅ FastAPI application with CORS middleware
- ✅ Health, version, and metrics endpoints
- ✅ JWT authentication (login, refresh, user info)
- ✅ Job management endpoints (RQ/Redis integration)
- ✅ SQLAlchemy models for all entities
- ✅ Alembic migrations configured and applied
- ✅ Database initialized (SQLite default, PostgreSQL supported)
- ✅ RQ worker auto-start (starts automatically with API server)

**Frontend:**
- ✅ React + Vite + TypeScript setup
- ✅ Tailwind CSS configured
- ✅ Authentication flow with login page
- ✅ Protected routes with auth context
- ✅ Navigation layout (left sidebar + top bar)
- ✅ All page routes (Dashboard, Scan, Process, Search, Identify, Auto-Match, Tags, Settings)

**Database:**
- ✅ All tables created automatically on startup: `photos`, `faces`, `people`, `person_encodings`, `tags`, `phototaglinkage`
- ✅ Schema matches desktop version exactly for full compatibility
- ✅ Indices configured for performance
- ✅ SQLite database at `data/punimtag.db` (auto-created if missing)

###  Image Ingestion & Processing 

**Backend:**
- ✅ Photo import service with checksum computation
- ✅ EXIF date extraction and image metadata
- ✅ Folder scanning with recursive option
- ✅ File upload support
- ✅ Background job processing with RQ
- ✅ Real-time job progress via SSE (Server-Sent Events)
- ✅ Duplicate detection (by path and checksum)
- ✅ Photo storage configuration (`PHOTO_STORAGE_DIR`)
- ✅ **DeepFace pipeline integration**
- ✅ **Face detection (RetinaFace, MTCNN, OpenCV, SSD)**
- ✅ **Face embeddings computation (ArcFace, Facenet, Facenet512, VGG-Face)**
- ✅ **Face processing service with configurable detectors/models**
- ✅ **EXIF orientation handling**
- ✅ **Face quality scoring and validation**
- ✅ **Batch processing with progress tracking**
- ✅ **Job cancellation support**

**Frontend:**
- ✅ Scan tab UI with folder selection
- ✅ Drag-and-drop file upload
- ✅ Recursive scan toggle
- ✅ Real-time job progress with progress bar
- ✅ Job status monitoring (SSE integration)
- ✅ Results display (added/existing counts)
- ✅ Error handling and user feedback
- ✅ **Process tab UI with configuration controls**
- ✅ **Detector/model selection dropdowns**
- ✅ **Batch size configuration**
- ✅ **Start/Stop processing controls**
- ✅ **Processing progress display with photo count**
- ✅ **Results summary (faces detected, faces stored)**
- ✅ **Job cancellation support**

**Worker:**
- ✅ RQ worker auto-starts with API server
- ✅ Unique worker names to avoid conflicts
- ✅ Graceful shutdown handling
- ✅ **String-based function paths for reliable serialization**

### Identify Workflow & Auto-Match 

**Backend:**
- ✅ Identify face endpoints with person creation
- ✅ Auto-match engine with similarity thresholds
- ✅ Unidentified faces management and filtering
- ✅ Person creation and linking
- ✅ Batch identification support
- ✅ Similar faces search with cosine similarity
- ✅ Confidence calibration system (empirical-based)
- ✅ Face unmatch/removal functionality
- ✅ Batch similarity calculations

**Frontend:**
- ✅ Identify page UI with face navigation
- ✅ Person creation and editing
- ✅ Similar faces panel with confidence display
- ✅ Auto-Match page with person-centric view
- ✅ Checkbox selection for batch identification
- ✅ Confidence percentages with color coding
- ✅ Unique faces filter (hide duplicates)
- ✅ Date filtering for faces
- ✅ Real-time face matching and display

### PSearch & Tags 

**Backend:**
- ✅ Search endpoints with filters (people, dates, tags, folders)
- ✅ Tag management endpoints (create, update, delete)
- ✅ Photo-tag linkage system
- ✅ Advanced filtering and querying
- ✅ Photo grid endpoints with pagination

**Frontend:**
- ✅ Search page with advanced filters
- ✅ Tag management UI
- ✅ Photo grid with virtualized rendering
- ✅ Filter by people, dates, tags, and folders
- ✅ Search results display

---

## 🔧 Configuration

### Database

**PostgreSQL (Default - Network Database):**
The application uses PostgreSQL by default, configured via the `.env` file:
```bash
DATABASE_URL=postgresql+psycopg2://punimtag:punimtag_password@localhost:5432/punimtag
```

**SQLite (Alternative - Local Database):**
To use SQLite instead, comment out or remove the `DATABASE_URL` line in `.env`, or set:
```bash
DATABASE_URL=sqlite:///data/punimtag.db
```

### Environment Variables

Configuration is managed via the `.env` file in the project root. A `.env.example` template is provided.

**Required Configuration:**
```bash
# Database (PostgreSQL by default)
DATABASE_URL=postgresql+psycopg2://punimtag:punimtag_password@localhost:5432/punimtag

# JWT Secrets (change in production!)
SECRET_KEY=dev-secret-key-change-in-production

# Single-user credentials (change in production!)
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin

# Photo storage directory (default: data/uploads)
PHOTO_STORAGE_DIR=data/uploads
```

**Note:** The `.env` file is automatically loaded by the application using `python-dotenv`. Environment variables can also be set directly in your shell if preferred.

---


---

### 🔄 Phase 5: Polish & Release (In Progress)
- Performance optimization
- Accessibility improvements
- Production deployment
- Documentation updates

---

## 🏗️ Architecture

**Backend:**
- **Framework**: FastAPI (Python 3.12+)
- **Database**: PostgreSQL (default, network), SQLite (optional, local)
- **ORM**: SQLAlchemy 2.0
- **Configuration**: Environment variables via `.env` file (python-dotenv)
- **Jobs**: Redis + RQ
- **Auth**: JWT (python-jose)

**Frontend:**
- **Framework**: React 18 + TypeScript
- **Build Tool**: Vite
- **Styling**: Tailwind CSS
- **State**: React Query + Context API
- **Routing**: React Router

**Deployment:**
- Docker Compose for local development
- Containerized services for production

---

## 📦 Dependencies

**Backend:**
- `fastapi==0.115.0`
- `uvicorn[standard]==0.30.6`
- `pydantic==2.9.1`
- `SQLAlchemy==2.0.36`
- `alembic==1.13.2`
- `python-jose[cryptography]==3.3.0`
- `redis==5.0.8`
- `rq==1.16.2`
- `deepface>=0.0.79`
- `tensorflow>=2.13.0`

**Frontend:**
- `react==18.2.0`
- `react-router-dom==6.20.0`
- `@tanstack/react-query==5.8.4`
- `axios==1.6.2`
- `tailwindcss==3.3.5`

---

## 🔒 Security

- JWT-based authentication with refresh tokens
- Password hashing (to be implemented in production)
- CORS configured for development (restrict in production)
- SQL injection prevention via SQLAlchemy ORM
- Input validation via Pydantic schemas

**⚠️ Note**: Default credentials (`admin`/`admin`) are for development only. Change in production!

---

## 🐛 Known Limitations

- Single-user mode only (multi-user support planned)
- SQLite for development (PostgreSQL recommended for production)
- No password hashing yet (plain text comparison - fix before production)
- GPU acceleration not yet implemented (CPU-only for now)
- Large databases (>50K photos) may require optimization
- DeepFace model downloads on first use (can take 5-10 minutes, ~100MB)
- Face processing is CPU-intensive (~2-3x slower than face_recognition, but more accurate)
- First run is slower due to model downloads (subsequent runs are faster)

---

## 📝 License

[Add your license here]

---

## 👥 Authors

PunimTag Development Team

---



## 🙏 Acknowledgments

- **DeepFace** library by Sefik Ilkin Serengil - Modern face recognition framework
- **ArcFace** - Additive Angular Margin Loss for Deep Face Recognition
- **RetinaFace** - State-of-the-art face detection
- TensorFlow, React, FastAPI, and all open-source contributors

---

## 📧 Support

For questions or issues:
1. Check documentation in `docs/`


---

**Made with ❤️ for photo enthusiasts**


