Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🎙️ Rehearsal — AI Mock Interview Platform

Practice HR, technical, and coding interviews against an AI interviewer that transcribes your spoken answers, watches your camera for engagement signals, scores your code, and gives you a full report at the end — clarity, technical correctness, confidence, and engagement, all tracked over time.

Python FastAPI React Whisper License

Architecture diagram

Features

  • Voice interview — record spoken answers in the browser, transcribed via OpenAI's Whisper (faster-whisper, runs locally/self-hosted — no audio ever leaves your server)
  • Camera analysis — periodic webcam frame capture during recording
  • Engagement heuristics — face detection, eye-contact estimation, and a lightweight smile/engagement signal, computed with OpenCV Haar cascades (see note below)
  • Resume-based questions — upload a resume (PDF/DOCX/TXT); Gemini tailors HR/technical questions to your actual experience
  • Coding interview — live Monaco code editor, sandboxed Python execution with timeout + memory limits, correctness scoring
  • HR & Technical interview modes — separate question pools and evaluation rubrics
  • AI feedback — Gemini scores each answer for clarity/relevance (and correctness for code), then writes a full closing summary with strengths and improvement areas
  • Interview report & score dashboard — per-session report plus a running trend chart across all your past sessions

Tech stack

Layer Technology
Speech-to-text Whisper via faster-whisper (self-hosted, no external API)
Camera analysis OpenCV (Haar cascades)
LLM Google Gemini (google-genai SDK) — optional, falls back to templates without a key
Backend FastAPI, SQLAlchemy, SQLite, JWT auth
Frontend React 18, Vite, Tailwind CSS, Monaco Editor, Recharts
Deployment Docker + docker-compose, nginx

Project structure

ai-mock-interview-platform/
├── backend/
│   ├── app/
│   │   ├── core/          # config, database, security, auth deps
│   │   ├── models/        # SQLAlchemy models
│   │   ├── schemas/       # Pydantic request/response schemas
│   │   ├── routers/       # auth, resume, interview, voice, vision, coding
│   │   ├── services/      # gemini_service, whisper_service, vision_service, scoring_service
│   │   ├── utils/          # resume_parser
│   │   └── main.py
│   ├── requirements.txt
│   ├── Dockerfile
│   └── .env.example
├── frontend/
│   ├── src/
│   │   ├── pages/          # Login, Register, Dashboard, InterviewRoom, Report
│   │   ├── components/     # Navbar, ConfidenceRing, ProtectedRoute
│   │   ├── context/         # AuthContext
│   │   └── services/        # api.js, interviewService.js
│   ├── Dockerfile
│   ├── nginx.conf
│   └── .env.example
├── docker-compose.yml
└── LICENSE

How an interview session works

Choose mode (HR / Technical / Coding) + optional resume
        │
        ▼
Gemini generates N tailored questions (falls back to a curated
question bank per mode if no API key is set)
        │
        ▼
Per question:
  HR/Technical → record voice (Whisper transcribes) + webcam frames
                 (OpenCV estimates eye contact / engagement)
  Coding       → write & run code in Monaco, sandboxed execution
        │
        ▼
Gemini scores the answer (clarity, relevance, correctness) and
gives short per-question feedback
        │
        ▼
After the last question: Gemini writes a closing summary,
scores are aggregated into Communication / Technical / Confidence /
Engagement / Overall — all shown on the report + dashboard trend chart

Getting started (local development)

1. Backend

cd backend
python3 -m venv venv && source venv/bin/activate   # optional but recommended
pip install -r requirements.txt

cp .env.example .env
# GEMINI_API_KEY is optional but recommended for real AI-generated
# questions/feedback instead of the offline template fallback.

uvicorn app.main:app --reload --port 8000

Backend runs at http://localhost:8000. Interactive API docs at http://localhost:8000/docs.

First run note: faster-whisper downloads its model weights the first time it's used (a one-time download, cached afterward). Set WHISPER_MODEL_SIZE=tiny in .env for the fastest/smallest option during development.

2. Frontend

cd frontend
npm install
cp .env.example .env
npm run dev

Frontend runs at http://localhost:5174 and proxies /api/* to the backend.

Getting started (Docker)

cp backend/.env.example backend/.env   # fill in GEMINI_API_KEY if you have one
docker compose up --build
  • Frontend: http://localhost
  • Backend API: http://localhost:8000

Configuration

Variable Required? Purpose
SECRET_KEY Yes JWT signing secret — generate a real random value for production
GEMINI_API_KEY No Enables AI-generated questions/feedback/reports; falls back to templates without it
WHISPER_MODEL_SIZE No tiny/base/small/medium/large-v3 — trade off speed vs. accuracy
DATABASE_URL No Defaults to local SQLite; point at Postgres for production

Testing

cd backend
pip install -r requirements.txt   # includes pytest
pytest tests/ -v

The suite covers auth, the full interview lifecycle (create → answer → complete → scored report), access control (you can't view someone else's interview), and the coding sandbox (correct output, error capture, and the 5-second timeout on infinite loops — that test genuinely waits out the timeout, so the suite takes a few seconds longer than you'd expect). CI runs this on every push via GitHub Actions (.github/workflows/ci.yml), alongside a frontend build check.

On the camera analysis approach

The engagement/emotion signal is built with OpenCV's bundled Haar cascade classifiers (face, eye, and smile detection) rather than a deep-learning emotion model. This was a deliberate trade-off: it ships fully working with zero external model downloads and no GPU requirement, which matters for a "clone and run" portfolio project — a Tasks-API/MediaPipe or FER2013-CNN approach would need model weight files fetched at runtime, adding a hard external dependency that can silently break in an offline or restricted-network deployment.

If you want to swap in a trained deep-learning emotion classifier for higher accuracy, app/services/vision_service.py is the only file you need to touch — analyze_frame() has a clear, self-contained contract (base64 image in, {face_detected, dominant_emotion, emotion_scores, eye_contact, head_pose} out).

Security note on the coding sandbox

app/routers/coding.py executes submitted Python in a subprocess with a CPU/wall-clock timeout and a memory limit — reasonable for a personal portfolio/demo project. If you deploy this publicly, replace it with a properly isolated per-request container (Docker-in-Docker, gVisor, Firecracker) or a managed code-execution service (Judge0, Piston) before allowing untrusted users to submit code.

Extending this project

  • More languages in the coding round: coding.py currently only runs Python; add language-specific Docker sandboxes for JS/Java/C++.
  • Live WebSocket streaming: replace the record→upload→transcribe flow with a streaming Whisper pipeline for real-time transcription as you speak.
  • Video review: save short clips per answer so candidates can watch themselves back alongside the transcript.
  • Team/interviewer mode: let a real interviewer review AI transcripts and override scores.

License

MIT — see LICENSE.

About

AI-powered mock interview platform with voice transcription (Whisper), camera-based engagement analysis (OpenCV), resume-tailored questions, and AI-scored feedback across HR, technical, and coding interview modes. FastAPI + React.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages