A Flask + MySQL + Socket.IO web app for conducting live, proctored technical interviews with:
Dockerfile: Python 3.9)stun:stun.l.google.com:19302@vladmandic/face-api) + local JS logicapp.py # Flask app + Socket.IO events
config.py # Env-based configuration
extensions.py # sqlite helpers + socketio
routes/
auth.py # login/logout/setup-admin
main.py # dashboard/add-candidate/schedule/interview/resume endpoints
templates/ # Jinja templates (UI)
static/js/ # webrtc/editor/chat/face detection
schema.sql # Database schema
init_db.py # Initialize DB from schema.sql
update_db.py # Apply schema updates (adds missing columns/tables)
update_db_join_status.py# Adds join-status column (older DB support)
uploads/resumes/ # Stored candidate resumes (gitignored recommended)
interviews.meeting_link (UUID)interviews.code_content)chat_messagesinterviews.candidate_join_statuscheat-detected → interviewer receives cheat-alertThe schema is defined in schema.sql. Core tables:
users
role: admin or candidatephone, target_role, experience_levelresume_path, resume_original_nameinterviews
meeting_link: unique UUID used as the room idcode_content: last saved editor contentcandidate_join_status: pending/requested/approved/rejectedchat_messages
interview_idEnvironment variables are loaded via python-dotenv (.env) and read in config.py.
SECRET_KEY: Flask session secretDATABASE_PATH: Full path to SQLite database file. If not set, uses instance/interview_system.db in the project directory.INSTANCE_PATH: Directory for the DB file (used if DATABASE_PATH is not set).MAX_CONTENT_LENGTH: max request size in bytes (default: 10MB)docker compose up --build
http://127.0.0.1:5000The app uses SQLite by default; the database file is created on first run (python init_db.py or when the app starts with an existing schema).
python -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txt
.env (optional)Set SECRET_KEY. Optionally set DATABASE_PATH to a custom SQLite file path (default: instance/interview_system.db).
python init_db.py
If you already created the DB earlier and need new columns/tables:
python update_db.py
python update_db_join_status.py
python app.py
The server is configured to bind to 0.0.0.0:5000 (LAN/Docker friendly).
python --version)pip --version)cd c:\xampp1\htdocs\Ai-Powered-Interview-sysetm
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
.env (optional)Create/update .env in the project root. Example:
SECRET_KEY=dev
# Optional: custom SQLite path (default: instance/interview_system.db)
# DATABASE_PATH=./data/interview_system.db
MAX_CONTENT_LENGTH=10485760
python init_db.py
If you already had a DB and need to add the newer columns/tables:
python update_db.py
python update_db_join_status.py
python app.py
Open:
http://127.0.0.1:5000Note: the server binds to
0.0.0.0, so you can also access it from another device on your LAN using your PC’s IP (e.g.http://192.168.x.x:5000).
/setup-admin/login/add-candidateResumes are stored on disk under uploads/resumes/ and the path is stored in MySQL.
/schedule-interviewmeeting_link UUID is generated and stored in interviews.meeting_link/interview/<meeting_link>GET/POST /loginGET/POST /setup-adminGET /logoutGET /dashboardGET/POST /add-candidateGET/POST /schedule-interviewGET /interview/<meeting_link>POST /interview/<meeting_link>/completeGET /interview/<meeting_link>/resume (authorized users only)join { room, username }leave { room, username }request-join { room, username } (candidate)approve-join { room } (interviewer)reject-join { room } (interviewer)joineduser-joined, user-leftjoin-requestjoin-approvedjoin-rejectedcandidate-approvedoffer, answer, ice-candidatecode-change { room, code } (also persists to interviews.code_content)code-update { code }chat-message { room, message, username, timestamp } (also persists to chat_messages)cheat-detected { room, type, message, timestamp }cheat-alert { type, message, timestamp } (server broadcasts to interviewer)uploads/resumes/<uuid>_<originalname>users):
resume_pathresume_original_nameResume serving endpoint is scoped to the interview:
GET /interview/<meeting_link>/resume
python init_db.py to create the SQLite database and tables.DATABASE_PATH in .env to a writable path.users.resume_path not NULL)/interview/<meeting_link>/resumeuploads/ to .gitignore.Add a license if you plan to publish/distribute this project.