Powered by FastAPI, Celery, PostgreSQL pgvector, and ONNX Runtime
Eventsnap is a distributed, horizontally scalable microservice architecture designed to process hundreds of event photos simultaneously. It uses complex math to turn human faces into 512-dimension vectors, and stores them in a highly optimized vector database for instant facial matching.
It is split into two main components (each with their own dedicated README files):
A FastAPI server that acts as the entry point. It accepts requests, authenticates them, saves face embeddings to Postgres, and dumps background encoding tasks into RabbitMQ for Celery workers to pick up.
A strictly mathematical, stateless ONNX Runtime container. It receives Base64 encoded photos, runs the powerful insightface SCRFD and ArcFace models on the NVIDIA GPU, and returns precise bounding boxes and 512-dimension glintr100 embeddings.
- API Framework: FastAPI (Python 3.14, Native AsyncIO)
- Architecture Pattern: Hexagonal Architecture (Ports and Adapters) with Dependency Injection
- Package Manager: uv (Ultra-fast Python package installer)
- Background Tasks: Celery + RabbitMQ (Broker) + PostgreSQL (Result Backend)
- Database: PostgreSQL +
pgvectorextension (Cosine Similarity matching) - Object Storage: Storage Bucket (S3 Compatible)
- Machine Learning: ONNX runtime (CUDA 11.8), InsightFace
- Containerization: Docker & Docker Compose
Eventsnap is completely Dockerized for rapid development and testing.
Because the Python environment for facial recognition (CUDA, ONNX, OpenCV) is massive, we build the images independently to cache the layers effectively before orchestrating them.
# Build the stateless inference API (requires Nvidia Container Toolkit)
docker build -t inference_api:dev ./inference_api
# Build the FastAPI orchestrator and Celery worker
docker build -t main_api:dev ./main_apiBring up all the containers (Postgres DB, RabbitMQ, Storage Bucket, Inference API, Main API, and Celery Worker). The orchestrated services will automatically wait for their database dependencies to become healthy before starting.
docker compose up -d- Main API Orchestrator: http://localhost:8000/docs
- Inference Model API: http://localhost:5000/docs
(For detailed sequence diagrams of the complete asynchronous system, see workflows.md)
- A user uploads a ZIP of an event directly via the Next.js frontend, which extracts and pushes the images into Storage Bucket.
- The frontend hits the Main API
/encode-event/endpoint, passing theevent_codein the JSON payload. - The Main API creates a Celery Task and immediately returns a
task_idso the user isn't stuck waiting. - The background Celery Worker picks up the task, pre-fetches images from Storage Bucket using an aggressive 64-connection pool, beams them (Base64) to the Inference API, and bulk-inserts the generated 512D vectors directly into PostgreSQL.
- An attendee hits the Main API
/sort-attendee/endpoint with their selfies and theevent_code. The orchestrator gets the embeddings for those selfies, averages them, and executes a sub-millisecond<=>cosine similarity search inpgvectorto find all photos they appear in!