Humanize README and entry docs for clearer tone
Replace marketing feature walls with a plain install/config README and short entry guides per project-template docs/writing-docs.md.
This commit is contained in:
@@ -1,898 +1,111 @@
|
||||
# PunimTag Web
|
||||
# PunimTag
|
||||
|
||||
**Modern Photo Management and Facial Recognition System**
|
||||
Local photo library with face recognition (DeepFace / ArcFace). One monorepo
|
||||
holds the FastAPI backend, React admin UI, and Next.js viewer. Data stays on
|
||||
your machines; there is no cloud dependency for core photo or face storage.
|
||||
|
||||
A fast, simple, and modern web application for organizing and tagging photos using state-of-the-art DeepFace AI with ArcFace recognition model.
|
||||
Status: active.
|
||||
|
||||
**Monorepo Structure:** This project contains both the admin interface (React) and viewer interface (Next.js) in a unified repository for easier maintenance and setup.
|
||||
## Requirements
|
||||
|
||||
---
|
||||
- Python 3.12+
|
||||
- Node.js 18+ (20+ recommended for the viewer)
|
||||
- PostgreSQL (two databases: app + auth)
|
||||
- Redis (RQ background jobs)
|
||||
- Python tkinter (native folder picker in admin Scan)
|
||||
|
||||
## 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
|
||||
- **Network Path Support**: Browse and scan folders on network shares (UNC paths on Windows, mounted shares on Linux)
|
||||
- **Native Folder Picker**: Browse button uses native OS folder picker with full absolute path support
|
||||
- **Privacy-First**: All data stored locally, no cloud dependencies
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Python 3.12 or higher** (with pip)
|
||||
- **Node.js 18+ and npm**
|
||||
- **PostgreSQL** (required for both development and production)
|
||||
- **Redis** (for background job processing)
|
||||
- **Python tkinter** (for native folder picker in Scan tab)
|
||||
|
||||
**Note:** The automated installation script (`./install.sh`) will install PostgreSQL, Redis, and Python tkinter automatically on Ubuntu/Debian systems.
|
||||
|
||||
### Installation
|
||||
|
||||
#### Option 1: Automated Installation (Recommended for Linux/Ubuntu/Debian)
|
||||
|
||||
The automated installation script will install all system dependencies, Python packages, frontend dependencies, and set up databases:
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repository-url>
|
||||
cd punimtag
|
||||
|
||||
# Run the installation script
|
||||
./install.sh
|
||||
./install.sh # Ubuntu/Debian: deps, venv, DBs; elsewhere install Postgres/Redis yourself
|
||||
cp .env.example .env # set DATABASE_URL, DATABASE_URL_AUTH, SECRET_KEY, ADMIN_*
|
||||
```
|
||||
|
||||
The script will:
|
||||
- Check prerequisites (Python 3.12+, Node.js 18+)
|
||||
- Install system dependencies (PostgreSQL, Redis, Python tkinter) on Ubuntu/Debian
|
||||
- Set up PostgreSQL databases (main + auth)
|
||||
- Create Python virtual environment
|
||||
- Install all Python dependencies
|
||||
- Install all frontend dependencies (admin-frontend and viewer-frontend)
|
||||
- Create `.env` configuration files
|
||||
- Create necessary data directories
|
||||
|
||||
**Note:** After installation, you'll need to generate Prisma clients for the viewer-frontend:
|
||||
```bash
|
||||
cd viewer-frontend
|
||||
npx prisma generate
|
||||
```
|
||||
|
||||
**Note:** On macOS or other systems, the script will skip system dependency installation. You'll need to install PostgreSQL, Redis, and Python tkinter manually.
|
||||
|
||||
**Installing tkinter manually:**
|
||||
- **Ubuntu/Debian:** `sudo apt install python3-tk`
|
||||
- **RHEL/CentOS:** `sudo yum install python3-tkinter`
|
||||
- **macOS:** Usually included with Python, but if missing: `brew install python-tk` (if using Homebrew Python)
|
||||
- **Windows:** Usually included with Python installation
|
||||
|
||||
#### Option 2: Manual Installation
|
||||
After install on the viewer:
|
||||
|
||||
```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 admin-frontend
|
||||
npm install
|
||||
cd ../viewer-frontend
|
||||
npm install
|
||||
# Generate Prisma clients for viewer-frontend (after setting up .env)
|
||||
npx prisma generate
|
||||
cd ..
|
||||
cd viewer-frontend && npx prisma generate && cd ..
|
||||
```
|
||||
|
||||
### Database Setup
|
||||
|
||||
**Database Configuration:**
|
||||
The application uses **two separate PostgreSQL databases**:
|
||||
1. **Main database** (`punimtag`) - Stores photos, faces, people, tags, and backend user accounts
|
||||
- **Required: PostgreSQL**
|
||||
2. **Auth database** (`punimtag_auth`) - Stores frontend website user accounts and moderation data
|
||||
- **Required: PostgreSQL**
|
||||
|
||||
Both database connections are configured via the `.env` file.
|
||||
|
||||
#### Development Database
|
||||
|
||||
For development, you can use the shared development PostgreSQL server:
|
||||
|
||||
**Dev PostgreSQL Server:**
|
||||
- **Host**: `<db-host>`
|
||||
- **Port**: 5432
|
||||
- **User**: `<db-user>`
|
||||
- **Password**: [Contact administrator for password]
|
||||
|
||||
**Development Server:**
|
||||
- **Host**: `<backend-host>`
|
||||
- **User**: appuser
|
||||
- **Password**: [Contact administrator for password]
|
||||
|
||||
Configure your `.env` file for development:
|
||||
```bash
|
||||
# Main database (dev)
|
||||
DATABASE_URL=postgresql+psycopg2://<db-user>:[PASSWORD]@<db-host>:5432/punimtag
|
||||
|
||||
# Auth database (dev)
|
||||
DATABASE_URL_AUTH=postgresql+psycopg2://<db-user>:[PASSWORD]@<db-host>:5432/punimtag_auth
|
||||
```
|
||||
|
||||
**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 Main Database and User:**
|
||||
```bash
|
||||
sudo -u postgres psql -c "CREATE USER punimtag WITH PASSWORD '<choose-a-password>';"
|
||||
sudo -u postgres psql -c "CREATE DATABASE punimtag OWNER punimtag;"
|
||||
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE punimtag TO punimtag;"
|
||||
```
|
||||
|
||||
**Create Auth Database (for frontend website user accounts):**
|
||||
```bash
|
||||
sudo -u postgres psql -c "CREATE DATABASE punimtag_auth OWNER punimtag;"
|
||||
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE punimtag_auth TO punimtag;"
|
||||
```
|
||||
|
||||
**Note:** The auth database (`punimtag_auth`) stores user accounts for the frontend website, separate from the main application database. Both databases are required for full functionality.
|
||||
|
||||
**Grant DELETE Permissions on Auth Database Tables:**
|
||||
If you encounter permission errors when trying to delete records from the auth database (e.g., when using "Clear database" in the admin panel), grant DELETE permissions:
|
||||
Run three processes:
|
||||
|
||||
```bash
|
||||
# Grant DELETE permission on all auth database tables
|
||||
sudo -u postgres psql -d punimtag_auth << 'EOF'
|
||||
GRANT DELETE ON TABLE pending_photos TO punimtag;
|
||||
GRANT DELETE ON TABLE users TO punimtag;
|
||||
GRANT DELETE ON TABLE pending_identifications TO punimtag;
|
||||
GRANT DELETE ON TABLE inappropriate_photo_reports TO punimtag;
|
||||
EOF
|
||||
|
||||
# Or grant on a single table:
|
||||
sudo -u postgres psql -d punimtag_auth -c "GRANT DELETE ON TABLE pending_photos TO punimtag;"
|
||||
./run_api_with_worker.sh # API http://127.0.0.1:8000 + RQ worker
|
||||
cd admin-frontend && npm run dev # http://localhost:3000
|
||||
cd viewer-frontend && npm run dev # http://localhost:3001
|
||||
```
|
||||
|
||||
Alternatively, use the automated script (requires sudo password):
|
||||
```bash
|
||||
./scripts/grant_auth_db_delete_permission.sh
|
||||
```
|
||||
API docs: http://127.0.0.1:8000/docs
|
||||
|
||||
**Configuration:**
|
||||
The `.env` file in the project root contains database connection strings:
|
||||
Or use root npm scripts: `npm run dev:admin`, `npm run dev:viewer`, `npm run ci:local`.
|
||||
|
||||
**Local Development:**
|
||||
```bash
|
||||
# Main application database (PostgreSQL - required)
|
||||
DATABASE_URL=postgresql+psycopg2://punimtag:<choose-a-password>@localhost:5432/punimtag
|
||||
## Config
|
||||
|
||||
# Auth database (PostgreSQL - required for frontend website users)
|
||||
DATABASE_URL_AUTH=postgresql+psycopg2://punimtag:<choose-a-password>@localhost:5432/punimtag_auth
|
||||
```
|
||||
Root `.env` (see `.env.example`):
|
||||
|
||||
**Development Server:**
|
||||
```bash
|
||||
# Main database (dev PostgreSQL server)
|
||||
DATABASE_URL=postgresql+psycopg2://<db-user>:[PASSWORD]@<db-host>:5432/punimtag
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `DATABASE_URL` | Main app DB (photos, faces, people, tags) |
|
||||
| `DATABASE_URL_AUTH` | Viewer auth / moderation DB |
|
||||
| `SECRET_KEY` | JWT signing |
|
||||
| `ADMIN_USERNAME` / `ADMIN_PASSWORD` | Bootstrap admin |
|
||||
| `REDIS_URL` | RQ jobs |
|
||||
| `PHOTO_STORAGE_DIR` | Uploaded media (default `data/uploads`) |
|
||||
|
||||
# Auth database (dev PostgreSQL server)
|
||||
DATABASE_URL_AUTH=postgresql+psycopg2://<db-user>:[PASSWORD]@<db-host>:5432/punimtag_auth
|
||||
```
|
||||
Viewer and admin each have their own `.env.example` under those folders.
|
||||
Secrets for deployed instances belong in Infisical (`/apps/punimtag`), not in git.
|
||||
|
||||
**Automatic Initialization:**
|
||||
The database and all tables are automatically created on first startup. No manual migration is needed!
|
||||
## What it does
|
||||
|
||||
The web application will:
|
||||
- Connect to the database using the `.env` configuration
|
||||
- Create all required tables with the correct schema on startup
|
||||
- Match the desktop version schema exactly for compatibility
|
||||
- Detect and match faces (RetinaFace + ArcFace by default; other detectors/models configurable)
|
||||
- Identify people across a library; auto-match with quality scoring
|
||||
- Search by person, date, tag, folder
|
||||
- Admin UI for scan/process/identify; viewer UI for browsing
|
||||
- Hierarchical tags, batch jobs via Redis/RQ
|
||||
- Network path browsing (UNC on Windows, mounted shares on Linux)
|
||||
|
||||
**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, media_type)
|
||||
- `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, excluded)
|
||||
- `person_encodings` - Person face encodings for matching
|
||||
- `tags` - Tag definitions
|
||||
- `phototaglinkage` - Photo-tag relationships (with linkage_type)
|
||||
- `users` - Backend user accounts (with password hashing, roles, permissions)
|
||||
- `photo_person_linkage` - Direct photo-person associations (for videos)
|
||||
- `role_permissions` - Role-based permission matrix
|
||||
|
||||
**Auth Database Schema:**
|
||||
The separate auth database (`punimtag_auth`) stores frontend website user accounts:
|
||||
- `users` - Frontend website user accounts (email, password_hash, is_active)
|
||||
- `pending_photos` - Photos pending moderation
|
||||
- `pending_identifications` - Face identifications pending approval
|
||||
- `inappropriate_photo_reports` - Reported photos for review
|
||||
|
||||
### 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: Using Helper Scripts (Recommended)
|
||||
|
||||
**Terminal 1 - Backend API + Worker:**
|
||||
```bash
|
||||
cd punimtag
|
||||
./run_api_with_worker.sh
|
||||
```
|
||||
|
||||
This script will:
|
||||
- Check if Redis is running (start it if needed)
|
||||
- Ensure database schema is up to date
|
||||
- Start the RQ worker in the background
|
||||
- Start the FastAPI server
|
||||
- Handle cleanup on Ctrl+C
|
||||
|
||||
You should see:
|
||||
```
|
||||
✅ Database schema ready
|
||||
🚀 Starting RQ worker...
|
||||
🚀 Starting FastAPI server...
|
||||
✅ Server running on http://127.0.0.1:8000
|
||||
✅ Worker running (PID: ...)
|
||||
✅ API running (PID: ...)
|
||||
```
|
||||
|
||||
**Alternative: Start backend only (without worker):**
|
||||
```bash
|
||||
cd punimtag
|
||||
./start_backend.sh
|
||||
```
|
||||
|
||||
**Stop the backend:**
|
||||
```bash
|
||||
cd punimtag
|
||||
./stop_backend.sh
|
||||
```
|
||||
|
||||
**Terminal 2 - Admin Frontend:**
|
||||
```bash
|
||||
cd punimtag/admin-frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
VITE v5.4.21 ready in 811 ms
|
||||
➜ Local: http://localhost:3000/
|
||||
```
|
||||
|
||||
**Terminal 3 - Viewer Frontend (Optional):**
|
||||
```bash
|
||||
cd punimtag/viewer-frontend
|
||||
# Generate Prisma clients (only needed once or after schema changes)
|
||||
npx prisma generate
|
||||
npm run dev
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
▲ Next.js 16.1.1 (Turbopack)
|
||||
- Local: http://localhost:3001/
|
||||
```
|
||||
|
||||
#### Option 2: Manual Start
|
||||
|
||||
**Terminal 1 - Backend API:**
|
||||
```bash
|
||||
cd punimtag
|
||||
source venv/bin/activate
|
||||
export PYTHONPATH="$(pwd)"
|
||||
python3 -m uvicorn backend.app:app --host 127.0.0.1 --port 8000 --reload
|
||||
```
|
||||
|
||||
**Note:** If you encounter warnings about "Electron/Chromium" when running `uvicorn`, use `python3 -m uvicorn` instead, or use the helper scripts above.
|
||||
|
||||
**Terminal 2 - Admin Frontend:**
|
||||
```bash
|
||||
cd punimtag/admin-frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
**Terminal 3 - Viewer Frontend (Optional):**
|
||||
```bash
|
||||
cd punimtag/viewer-frontend
|
||||
npx prisma generate # Only needed once or after schema changes
|
||||
npm run dev
|
||||
```
|
||||
|
||||
#### Access the Applications
|
||||
|
||||
1. **Admin Interface**: Open your browser to **http://localhost:3000**
|
||||
- Log in with the credentials configured in your `.env` (`ADMIN_USERNAME` / `ADMIN_PASSWORD`)
|
||||
2. **Viewer Interface** (Optional): Open your browser to **http://localhost:3001**
|
||||
- Public photo viewing interface
|
||||
- Separate authentication system
|
||||
3. **API Documentation**: Available at **http://127.0.0.1:8000/docs**
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
**Port 8000 already in use:**
|
||||
```bash
|
||||
# Use the stop script
|
||||
cd punimtag
|
||||
./stop_backend.sh
|
||||
|
||||
# Or manually find and kill the process
|
||||
lsof -i :8000
|
||||
kill <PID>
|
||||
|
||||
# Or use pkill
|
||||
pkill -f "uvicorn.*backend.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 admin-frontend/vite.config.ts
|
||||
```
|
||||
|
||||
**Redis not running:**
|
||||
```bash
|
||||
# Start Redis
|
||||
sudo systemctl start redis-server
|
||||
# Or
|
||||
redis-server
|
||||
|
||||
# Verify Redis is running
|
||||
redis-cli ping # Should respond with "PONG"
|
||||
```
|
||||
|
||||
**Worker module not found error:**
|
||||
If you see `ModuleNotFoundError: No module named 'backend'`:
|
||||
- Make sure you're using the helper scripts (`./run_api_with_worker.sh` or `./start_backend.sh`)
|
||||
- These scripts set PYTHONPATH correctly
|
||||
- If running manually, ensure `export PYTHONPATH="$(pwd)"` is set
|
||||
|
||||
**Python/Cursor interception warnings:**
|
||||
If you see warnings about "Electron/Chromium" when running `uvicorn`:
|
||||
- Use `python3 -m uvicorn` instead of just `uvicorn`
|
||||
- Or use the helper scripts which handle this automatically
|
||||
|
||||
**Database issues:**
|
||||
```bash
|
||||
# The database is automatically created on first startup
|
||||
# If you need to reset it, delete the database file:
|
||||
rm data/punimtag.db
|
||||
|
||||
# The schema will be recreated on next startup
|
||||
```
|
||||
|
||||
**Browse button returns 503 error or doesn't show folder picker:**
|
||||
This indicates that Python tkinter is not available. Install it:
|
||||
```bash
|
||||
# Ubuntu/Debian:
|
||||
sudo apt install python3-tk
|
||||
|
||||
# RHEL/CentOS:
|
||||
sudo yum install python3-tkinter
|
||||
|
||||
# Verify installation:
|
||||
python3 -c "import tkinter; print('tkinter available')"
|
||||
```
|
||||
|
||||
**Note:** If running on a remote server without a display, you may need to set the DISPLAY environment variable or use X11 forwarding:
|
||||
```bash
|
||||
export DISPLAY=:0
|
||||
# Or for X11 forwarding:
|
||||
export DISPLAY=localhost:10.0
|
||||
```
|
||||
|
||||
**Viewer frontend shows 0 photos:**
|
||||
- Make sure the database has photos (import them via admin frontend)
|
||||
- Verify `DATABASE_URL` in `viewer-frontend/.env` points to the correct database
|
||||
- Ensure Prisma client is generated: `cd viewer-frontend && npx prisma generate`
|
||||
- Check that photos are marked as `processed: true` in the database
|
||||
|
||||
#### 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
|
||||
## Layout
|
||||
|
||||
```
|
||||
punimtag/
|
||||
├── backend/ # FastAPI backend
|
||||
│ ├── api/ # API routers
|
||||
│ ├── db/ # Database models and session
|
||||
│ ├── schemas/ # Pydantic models
|
||||
│ ├── services/ # Business logic services
|
||||
│ ├── constants/ # Constants and configuration
|
||||
│ ├── utils/ # Utility functions
|
||||
│ ├── app.py # FastAPI application
|
||||
│ └── worker.py # RQ worker for background jobs
|
||||
├── admin-frontend/ # React admin interface
|
||||
│ ├── src/
|
||||
│ │ ├── api/ # API client
|
||||
│ │ ├── components/ # React components
|
||||
│ │ ├── context/ # React contexts (Auth)
|
||||
│ │ ├── hooks/ # Custom hooks
|
||||
│ │ └── pages/ # Page components
|
||||
│ └── package.json
|
||||
├── viewer-frontend/ # Next.js viewer interface
|
||||
│ ├── app/ # Next.js app router
|
||||
│ ├── components/ # React components
|
||||
│ ├── lib/ # Utilities and database
|
||||
│ ├── prisma/ # Prisma schemas
|
||||
│ └── package.json
|
||||
├── src/ # Legacy desktop code
|
||||
│ └── core/ # Legacy desktop business logic
|
||||
├── tests/ # Test suite
|
||||
├── docs/ # Documentation
|
||||
├── data/ # Application data (database, images)
|
||||
├── scripts/ # Utility scripts
|
||||
├── deploy/ # Docker deployment configs
|
||||
└── package.json # Root package.json for monorepo
|
||||
├── backend/ # FastAPI + SQLAlchemy
|
||||
├── admin-frontend/ # React + Vite (port 3000)
|
||||
├── viewer-frontend/ # Next.js (port 3001)
|
||||
├── e2e/ # Playwright (@levkin/playkit)
|
||||
├── scripts/ # Install / DB helpers
|
||||
├── docs/ # Guides and reference
|
||||
└── install.sh
|
||||
```
|
||||
|
||||
---
|
||||
## Docs
|
||||
|
||||
## Current Status
|
||||
| Doc | Purpose |
|
||||
|-----|---------|
|
||||
| [docs/README.md](docs/README.md) | Doc index |
|
||||
| [docs/QUICK_START.md](docs/QUICK_START.md) | Day-to-day run commands |
|
||||
| [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) | Deploy overview |
|
||||
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | System design |
|
||||
| [docs/USER_GUIDE.md](docs/USER_GUIDE.md) | Product walkthrough |
|
||||
| [CONTRIBUTING.md](CONTRIBUTING.md) | Dev workflow |
|
||||
| [e2e/README.md](e2e/README.md) | End-to-end tests |
|
||||
|
||||
### Foundations
|
||||
Homelab deploy runbooks (hosts, Caddy, monitoring) live in the private
|
||||
`ansible` repo, not here.
|
||||
|
||||
**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 (PostgreSQL required)
|
||||
- RQ worker auto-start (starts automatically with API server)
|
||||
- Pending linkage moderation API for user tag suggestions
|
||||
## Security notes
|
||||
|
||||
**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)
|
||||
- User Tagged Photos moderation tab for approving/denying pending tag linkages
|
||||
Set strong `ADMIN_*` and `SECRET_KEY` before any shared deploy. Older commits
|
||||
may still show LAN examples; treat matching real passwords as compromised and
|
||||
rotate. Prefer placeholders in public docs.
|
||||
|
||||
**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
|
||||
- PostgreSQL database (required for both development and production)
|
||||
- Separate auth database (PostgreSQL) for frontend user accounts
|
||||
## Known limits
|
||||
|
||||
### 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
|
||||
- **Native folder picker (Browse button)** - Uses tkinter for native OS folder selection
|
||||
- **Network path support** - Handles UNC paths (Windows: `\\server\share\folder`) and mounted network shares (Linux: `/mnt/nfs-share/photos`)
|
||||
- **Full absolute path handling** - Automatically normalizes and validates paths
|
||||
- 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 (Required):**
|
||||
Both databases use PostgreSQL. Configure via the `.env` file:
|
||||
```bash
|
||||
# Main application database (PostgreSQL - required)
|
||||
DATABASE_URL=postgresql+psycopg2://punimtag:<choose-a-password>@localhost:5432/punimtag
|
||||
|
||||
# Auth database (PostgreSQL - required for frontend website users)
|
||||
DATABASE_URL_AUTH=postgresql+psycopg2://punimtag:<choose-a-password>@localhost:5432/punimtag_auth
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Configuration is managed via the `.env` file in the project root. A `.env.example` template is provided.
|
||||
|
||||
**Required Configuration:**
|
||||
```bash
|
||||
# Main Database (PostgreSQL - required)
|
||||
DATABASE_URL=postgresql+psycopg2://punimtag:<choose-a-password>@localhost:5432/punimtag
|
||||
|
||||
# Auth Database (PostgreSQL - required for frontend website user accounts)
|
||||
DATABASE_URL_AUTH=postgresql+psycopg2://punimtag:<choose-a-password>@localhost:5432/punimtag_auth
|
||||
|
||||
# JWT Secrets (change in production!)
|
||||
SECRET_KEY=dev-secret-key-change-in-production
|
||||
|
||||
# Single-user credentials (set your own values!)
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=<choose-a-password>
|
||||
|
||||
# Photo storage directory (default: data/uploads)
|
||||
PHOTO_STORAGE_DIR=data/uploads
|
||||
```
|
||||
|
||||
**Admin Frontend Configuration:**
|
||||
Create a `.env` file in the `admin-frontend/` directory:
|
||||
```bash
|
||||
# Backend API URL (must be accessible from browsers)
|
||||
VITE_API_URL=http://127.0.0.1:8000
|
||||
```
|
||||
|
||||
**Viewer Frontend Configuration:**
|
||||
Create a `.env` file in the `viewer-frontend/` directory:
|
||||
```bash
|
||||
# Main database connection (PostgreSQL - required)
|
||||
DATABASE_URL=postgresql://punimtag:<choose-a-password>@localhost:5432/punimtag
|
||||
|
||||
# Auth database connection (PostgreSQL - required)
|
||||
DATABASE_URL_AUTH=postgresql://punimtag:<choose-a-password>@localhost:5432/punimtag_auth
|
||||
|
||||
# Write-capable database connection (optional, falls back to DATABASE_URL if not set)
|
||||
DATABASE_URL_WRITE=postgresql://punimtag:<choose-a-password>@localhost:5432/punimtag
|
||||
|
||||
# NextAuth configuration
|
||||
NEXTAUTH_URL=http://localhost:3001
|
||||
NEXTAUTH_SECRET=dev-secret-key-change-in-production
|
||||
```
|
||||
|
||||
**Generate Prisma Clients:**
|
||||
After setting up the `.env` file, generate the Prisma clients:
|
||||
```bash
|
||||
cd viewer-frontend
|
||||
npx prisma generate
|
||||
```
|
||||
|
||||
**Important:** The viewer frontend uses **PostgreSQL** for the main database (matching the backend). The Prisma schema is configured for PostgreSQL.
|
||||
|
||||
**Note:** The viewer frontend uses the same database as the backend by default. For production deployments, you may want to create separate read-only and write users for better security.
|
||||
|
||||
**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 (required)
|
||||
- **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`
|
||||
- `psycopg2-binary==2.9.9` (PostgreSQL driver)
|
||||
- `python-multipart==0.0.9` (file uploads)
|
||||
- `python-dotenv==1.0.0` (environment variables)
|
||||
- `bcrypt==4.1.2` (password hashing)
|
||||
- `deepface>=0.0.79`
|
||||
- `tensorflow>=2.13.0`
|
||||
- `opencv-python>=4.8.0`
|
||||
- `retina-face>=0.0.13`
|
||||
- `numpy>=1.21.0`
|
||||
- `pillow>=8.0.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 with bcrypt
|
||||
- CORS configured for development (restrict in production)
|
||||
- SQL injection prevention via SQLAlchemy ORM
|
||||
- Input validation via Pydantic schemas
|
||||
- Separate auth database for frontend website user accounts
|
||||
|
||||
**Note**: Set strong values for `ADMIN_USERNAME`, `ADMIN_PASSWORD`, and `SECRET_KEY` before deploying.
|
||||
|
||||
**History:** Older commits may still contain LAN IPs or example passwords in docs. Treat those as compromised for any real credentials that matched; rotate DB/admin passwords if they were ever used outside localhost. Prefer placeholders (`<db-host>`, `<choose-a-password>`) in all public docs.
|
||||
|
||||
---
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- Multi-user support with role-based permissions (single-user mode deprecated)
|
||||
- PostgreSQL for both development and 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)
|
||||
|
||||
---
|
||||
- Face pipeline is CPU-only for now; first DeepFace model download is large and slow
|
||||
- Libraries over ~50k photos may need tuning
|
||||
- Multi-user RBAC is the supported mode (single-user path deprecated)
|
||||
|
||||
## 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
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
### Development Server Deployment
|
||||
|
||||
The project includes scripts for deploying to the development server.
|
||||
|
||||
**Development Server:**
|
||||
- **Host**: `<backend-host>`
|
||||
- **User**: appuser
|
||||
- **Password**: [Contact administrator for password]
|
||||
|
||||
**Development Database:**
|
||||
- **Host**: `<db-host>`
|
||||
- **Port**: 5432
|
||||
- **User**: `<db-user>`
|
||||
- **Password**: [Contact administrator for password]
|
||||
|
||||
#### Build and Deploy to Dev
|
||||
|
||||
```bash
|
||||
# Build all frontends and prepare for deployment
|
||||
npm run deploy:dev
|
||||
|
||||
# Or build individually
|
||||
npm run build:admin
|
||||
npm run build:viewer
|
||||
```
|
||||
|
||||
The deployment script will:
|
||||
1. Build admin-frontend for production
|
||||
2. Build viewer-frontend for production
|
||||
3. Prepare deployment package
|
||||
4. Copy files to deployment directory (ready for manual transfer)
|
||||
|
||||
#### Manual Deployment Steps
|
||||
|
||||
1. **Build the applications:**
|
||||
```bash
|
||||
npm run deploy:dev
|
||||
```
|
||||
|
||||
2. **Transfer files to server:**
|
||||
```bash
|
||||
# Transfer backend and built frontends
|
||||
scp -r backend admin-frontend/dist viewer-frontend/.next appuser@<backend-host>:/path/to/deployment
|
||||
```
|
||||
|
||||
3. **Set up environment on server:**
|
||||
- Create `.env` file with dev database credentials
|
||||
- Install Python dependencies: `pip install -r requirements.txt`
|
||||
- Set up systemd services or PM2 for process management
|
||||
|
||||
4. **Start services:**
|
||||
- Backend API (FastAPI)
|
||||
- RQ Worker
|
||||
- Frontend servers (nginx or similar)
|
||||
|
||||
See `docs/DEPLOYMENT.md` for detailed deployment instructions.
|
||||
|
||||
### Production Deployment
|
||||
|
||||
For production deployment:
|
||||
1. Update environment variables with production credentials
|
||||
2. Configure PostgreSQL connection strings
|
||||
3. Set up Redis for background jobs
|
||||
4. Configure reverse proxy (nginx)
|
||||
5. Set up SSL certificates
|
||||
6. Configure firewall rules
|
||||
7. Set up monitoring and logging
|
||||
|
||||
See `docs/DEPLOYMENT.md` for complete production deployment guide.
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For questions or issues:
|
||||
1. Check documentation in `docs/`
|
||||
2. Review `docs/DEPLOYMENT.md` for deployment questions
|
||||
3. Check `docs/ARCHITECTURE.md` for technical details
|
||||
|
||||
---
|
||||
|
||||
**Made for photo enthusiasts**
|
||||
|
||||
|
||||
MIT. See [LICENSE](LICENSE).
|
||||
|
||||
Reference in New Issue
Block a user