Skip to content

Project Structure

MrBeanDev edited this page Aug 23, 2026 · 1 revision

Project Structure

Face-Gallery/
├── part1.py                          Standalone face extraction
├── part2.py                          Standalone photo sorting
├── requirements.txt                  Dependencies for the standalone scripts
│
├── .github/workflows/release.yml     Builds the executables on a v* tag
│
└── face-detection-webapp/
    ├── backend/
    │   ├── main.py                   FastAPI app, CORS, thumbnails, settings
    │   ├── launcher.py               Executable entry point
    │   ├── paths.py                  Resolves the writable data directory
    │   ├── database.py               SQLAlchemy models and migrations
    │   ├── processing.py             The two-pass pipeline, in a background thread
    │   ├── schemas.py                Pydantic response models
    │   ├── requirements.txt          Runtime dependencies
    │   ├── requirements-build.txt    CI dependencies, using the prebuilt dlib wheel
    │   ├── build-executable.spec     PyInstaller spec
    │   └── routers/
    │       ├── jobs.py               REST endpoints
    │       └── ws.py                 WebSocket progress bridge
    │
    └── frontend/
        ├── public/
        ├── src/
        │   ├── App.tsx               Router and layout wrapper
        │   ├── main.tsx              Entry point; handles ?backend=
        │   ├── api/client.ts         Axios client with a dynamic base URL
        │   ├── components/
        │   │   ├── BackendSetup.tsx  Backend URL dialog
        │   │   ├── EffectsDialog.tsx Visual effect toggles
        │   │   ├── Layout.tsx        Sidebar, header, resizable panels
        │   │   └── SettingsPopover.tsx  Crop padding and tolerance
        │   ├── hooks/useJobWS.ts     WebSocket hook
        │   ├── pages/
        │   │   ├── Upload.tsx        Upload and settings
        │   │   ├── Processing.tsx    Live progress
        │   │   └── Results.tsx       List and graph views, face management
        │   ├── store/
        │   │   ├── jobStore.ts       Processing state
        │   │   └── settingsStore.ts  Backend URL and effects
        │   └── types.ts              WebSocket event types
        ├── package.json
        ├── vite.config.ts
        └── tailwind.config.js

Where the work happens

processing.py is the core. FaceProcessor runs the two passes on a background thread and pushes progress events onto a queue that routers/ws.py drains to the WebSocket. It owns the detection downscaling and the closest-match logic.

routers/jobs.py is the largest file in the backend and holds every REST endpoint: uploads and their limits, job lifecycle, the face grouping model, and manual assignment.

paths.py decides where data lives. From source it is the current directory; frozen it is a per-user application directory. Everything else asks this module rather than hardcoding a path.

Results.tsx is by far the largest frontend file. It holds the list view, the graph view, the graph layout algorithm, and the face-management dialogs. Splitting it up is on the list.

Data model

Five tables, in database.py.

  • Job — one processing session, with status and progress counters
  • Image — an uploaded photo belonging to a job
  • UniqueFace — a distinct person, with a pickled 128-float encoding, an optional name, a disabled flag, and a group_id
  • FaceMatch — links a UniqueFace to an Image, with the bounding box
  • Notification — a message raised during processing

group_id carries the whole grouping model in one column. NULL means the face stands alone, a value equal to the row's own id means it is the primary of a group, and any other value means it is a member of that group. Because members keep their own rows and matches, a merge can always be undone.

Clone this wiki locally