Skip to content

SatyaJaiss/VisioMark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VisioMark

AI-Powered Biometric Attendance for Classrooms

FastAPI Flutter PostgreSQL Celery Redis Qdrant ONNX Runtime Azure Blob License: MIT

Replace manual roll calls with a 10-second video. VisioMark identifies every face, marks attendance, and notifies the teacher — all before the class settles down.

Features · Architecture · Tech Stack · Getting Started · Configuration · Contributing · License


What is VisioMark?

VisioMark is a production-grade EdTech attendance platform. A class representative takes a picture or records a 10-second video of the room; the system extracts faces, generates 512-dimensional embeddings via ArcFace, matches them against enrolled students in a Qdrant vector database, and pushes live results back to the teacher's app via SSE — all asynchronously, without blocking the API.

It is designed for institutions that need a tamper-resistant, mobile-first attendance workflow at scale.


✨ Features

  • Asynchronous AI pipeline — Large media (up to 50 MB) is uploaded directly to cloud storage via SAS/presigned URLs, keeping FastAPI stateless throughout.
  • ONNX inference — InsightFace models (RetinaFace detector + ArcFace ResNet50 embedder) run via ONNX Runtime for stable, dependency-light 512D embedding generation.
  • Vector identity matching — Qdrant cosine similarity search at threshold 0.65 resolves identities against pre-enrolled student embeddings in milliseconds.
  • Real-time updates — SSE pushes session completion events to the Flutter app; optimistic UI keeps interactions instant without polling.
  • Dispute engine — 8-hour dispute SLA with extended media retention, in-app evidence review, and teacher-side override workflows.

🏗 Architecture

Click to Expand
Class Rep records 10s video (back camera enforced)
         │
         ▼
  VisioMark Mobile App
         │  presigned URL upload
         ▼
  Cloud Storage (Azure Blob / S3-compatible / MinIO)
         │  storage event
         ▼
  FastAPI  ──►  Redis Queue
                    │
                    ▼
             Celery GPU Worker
               ├── Extract frames (video_utils)
               ├── RetinaFace  (face detection)
               ├── ArcFace ResNet50 ONNX  (512D embeddings)
               └── Qdrant cosine match (threshold 0.45)
                         │
                         ▼
                  PostgreSQL (bulk insert attendance records)
                         │
                         ▼
                  SSE webhook  ──►  Teacher App UI

🛠 Tech Stack

Layer Technology
Mobile app Flutter, Riverpod, fl_chart, GoRouter
API gateway FastAPI, Pydantic v2, SQLAlchemy 2.0
Async workers Celery, Redis
Transactional DB PostgreSQL
Vector search Qdrant Cloud
Object storage MinIO (local), Azure Blob / S3-compatible (cloud)
ML inference ONNX Runtime — RetinaFace + ArcFace ResNet50
Auth Bcrypt + pepper hashing, OTP (email & SMS)

📂 Project Structure

VisioMark/
├── backend_services/
│   ├── api/
│   │   ├── main.py               # FastAPI app entry point
│   │   ├── dependencies.py       # Shared DI (DB sessions, auth)
│   │   ├── routers/              # auth, attendance, classroom,
│   │   │                         #   enrollment, analytics, webhooks
│   │   └── schemas/              # Pydantic request/response models
│   ├── core/
│   │   ├── config.py             # Settings (pydantic-settings)
│   │   ├── azure_blob_handler.py # SAS URL generation
│   │   └── logger.py
│   ├── db/
│   │   ├── models.py             # SQLAlchemy ORM models
│   │   ├── postgres_client.py    # Async engine + session factory
│   │   └── qdrant_client.py      # Qdrant collection helpers
│   ├── worker/
│   │   ├── celery_app.py         # Celery broker/backend config
│   │   ├── tasks.py              # process_session task
│   │   ├── video_utils.py        # Frame extraction (OpenCV)
│   │   ├── ai_pipeline/
│   │   │   ├── insight_engine.py # RetinaFace + ArcFace wrapper
│   │   │   └── tracker.py        # Multi-face dedup across frames
│   │   └── weights/
│   │       └── check_weights.py  # Auto-download ONNX artifacts
│   ├── requirements.txt          # API dependencies
│   ├── requirements-worker.txt   # Worker dependencies (includes ONNX RT)
│   ├── docker-compose.yml
│   ├── Dockerfile.api
│   ├── Dockerfile.worker
│   └── .env.example
└── mobile_app/
    ├── lib/
    │   ├── core/                 # API client, router, theme
    │   ├── providers/            # Riverpod state providers
    │   └── screens/              # auth, attendance, classroom, main
    ├── pubspec.yaml
    └── test/

---

🚀 Getting Started

Prerequisites

Requirement Minimum version Notes
Docker 24.0 With Docker Compose v2 (docker compose)
Docker BuildKit enabled Set DOCKER_BUILDKIT=1
Flutter SDK 3.19 For mobile app only
GPU (optional) CUDA 11.8 CPU inference works; GPU recommended for production

No local Python install required. All backend services run inside Docker containers.

1. Clone & configure

git clone https://github.com/<your-org>/visiomark.git
cd visiomark/backend_services

cp .env.example .env
# Edit .env — see Configuration section below

2. Start all services

docker compose up -d --build

This starts: api, worker, postgres, redis, qdrant, and minio.

First boot takes ~3 minutes as the worker downloads ONNX model weights (~350 MB).

# Follow logs
docker compose logs -f api worker

# Check all containers are healthy
docker compose ps

3. Verify

Service URL
API (Swagger UI) http://localhost:8000/docs
MinIO Console http://localhost:9001
Qdrant Dashboard http://localhost:6333/dashboard

4. Run the mobile app

cd ../mobile_app
flutter pub get

# Update lib/core/config.dart with your local API IP
# e.g. const apiBase = 'http://192.168.1.x:8000';

flutter run

⚙️ Configuration

Copy .env.example to .env and fill in each variable. All required variables must be set before docker compose up.

Variable Required Description
DATABASE_URL PostgreSQL connection string (Use asyncpg format)
REDIS_URL Redis broker URL
QDRANT_URL Qdrant Cloud HTTPS endpoint
QDRANT_API_KEY Secret API Key for Qdrant Cloud
QDRANT_COLLECTION Collection name for vector embeddings
AZURE_STORAGE_CONNECTION_STRING Connection string for Azure Blob Storage
AZURE_CONTAINER_NAME Container name inside Azure Blob
JWT_SECRET Secret key for JWT signing (min 32 chars)
JWT_ALGORITHM Algorithm used for JWT encoding
JWT_EXPIRE_MINUTES Lifespan of an access token
PASSWORD_PEPPER Global bcrypt pepper for password hashing
WORKER_CALLBACK_SECRET Secret to authenticate internal Celery webhooks
API_INTERNAL_URL Internal URL for Celery to reach FastAPI

🔐 Security

  • Passwords hashed with bcrypt (per-user salt) plus a global pepper stored outside the database.
  • All endpoints are JWT-protected; tokens are short-lived to minimize exposure windows.
  • Media upload uses presigned/SAS URLs — the API never proxies binary data.

🤝 Contributing

Contributions are welcome! Please read the guidelines before opening a PR.

  1. Fork the repository and create a feature branch: git checkout -b feat/your-feature
  2. Follow the existing code style (ruff for Python, flutter format for Dart).
  3. Write or update tests for any changed behaviour.
  4. Open a pull request against main with a clear description of the change.

For large changes, open an issue first to discuss the approach.

Reporting bugs: Use the GitHub Issues tracker. Include your OS, Docker version, and the full stack trace.


📄 License

This project is licensed under the MIT License.


Built with ❤️ for classrooms that deserve better than paper roll calls.

About

AI-Powered Biometric Attendance System

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors