Skip to main content

Overview

This guide walks you through installing Interview Simulator, configuring your AI provider, and running your first mock interview session.
You’ll need Python 3.11+ and an API key from Google Gemini or OpenRouter to use the interview features.

Installation

1

Clone the repository

Get the source code from GitHub:
git clone https://github.com/DanielPopoola/interview-simulator.git
cd interview-simulator
2

Create virtual environment

Set up an isolated Python environment:
python -m venv .venv
source .venv/bin/activate
3

Install dependencies

Install all required packages:
pip install -r requirements.txt
Key dependencies include:
  • flask==3.1.2 - Web framework
  • google-genai==1.49.0 - Gemini AI integration
  • pdfplumber==0.11.8 - PDF document parsing
  • python-docx==1.2.0 - Word document support
  • tenacity==9.1.2 - Retry logic for API calls
4

Configure environment

Copy the example environment file and add your credentials:
cp .env.example .env
Edit .env and add your API keys:
.env
# Google Gemini API key (get from https://ai.google.dev/)
GEMINI_API_KEY=your_gemini_api_key_here

# Optional: OpenRouter API key
OPENROUTER_API_KEY=your_openrouter_api_key_here

# Flask secret for session management
SECRET_KEY=your_random_secret_key_change_this

# Database configuration
DATABASE_URL=sqlite:///instance/app.db

# Active AI providers (comma-separated)
ACTIVE_PROVIDERS=openrouter,gemini
Keep your .env file secure and never commit it to version control. The .gitignore file excludes it by default.

Run the application

Start the Flask development server:
flask run
You should see output like:
 * Serving Flask app 'app'
 * Debug mode: on
 * Running on http://127.0.0.1:5000
Open your browser to http://127.0.0.1:5000 to access the application.

Your first interview

1

Create a session

On the homepage, enter the details for your target role:
  • Job title: e.g., “Senior Software Engineer”
  • Company name: e.g., “TechCorp”
Click Start Interview to create your session.
2

Upload documents

You’ll be redirected to the upload page:Upload your CV: Choose a PDF, DOCX, or TXT file containing your resume.
# Behind the scenes, the DocumentParser extracts text
from utils.document_parser import DocumentParser

cv_text = DocumentParser.extract_text(file_path)
# Supports .pdf, .docx, .txt with automatic format detection
Paste job description: Copy the full job posting into the text area.Click Continue when both documents are uploaded.
3

Start the interview

The AI generates your first question based on your CV and the job description:
# The interview service coordinates the flow
from app.services.interview_service import InterviewService

first_question = interview_service.start_interview(session_id)
# Returns a contextual question tailored to your background
You’ll see a conversational interface with:
  • The AI’s question
  • A text area for your response
  • Progress indicator (e.g., “Question 1 of 8”)
4

Answer questions

Type your response and click Submit. The AI generates follow-up questions based on:
  • Your previous answers
  • Your CV content
  • The job requirements
# Each answer triggers adaptive questioning
result = interview_service.submit_answer(
    session_id=session_id,
    answer=user_response
)
# Returns next_question, is_complete, question_count
The interview continues for up to 8 questions, adapting to your responses.
5

Review feedback

After the final question, click Complete Interview to generate your feedback report.You’ll receive:Performance score: Numerical rating from 1-10Strengths: Positive aspects of your interview performanceAreas to improve: Specific suggestions with examplesCV optimization: Recommendations to tailor your resume for this role
All feedback is stored in the database, so you can review past sessions anytime.

Understanding the interview flow

The interview uses a maximum of 8 questions defined in the InterviewService:
class InterviewService:
    MAX_QUESTIONS = 8

    def submit_answer(self, session_id: int, answer: str) -> dict:
        # Store the user's answer
        self.message_repo.create_message(session_id, "user", answer)

        # Check if interview is complete
        question_count = self.message_repo.count_messages(
            session_id, role="assistant"
        )

        if question_count >= self.MAX_QUESTIONS:
            return {
                "next_question": None,
                "is_complete": True,
                "question_count": question_count,
            }

        # Generate next question if not complete
        next_question = self.ai_client.generate_followup_question(
            convo_history=convo_history,
            cv_text=session.cv_text,
            job_desc=session.job_description_text,
            question_count=question_count,
            max_questions=self.MAX_QUESTIONS,
        )

        return {
            "next_question": next_question,
            "is_complete": False,
            "question_count": question_count + 1,
        }

Resume incomplete sessions

All interview data persists in the SQLite database. If you close the browser mid-interview:
  1. Return to the homepage
  2. Find your session in the recent sessions list
  3. Click Continue to resume where you left off
The conversation history is preserved:
# Messages are stored with timestamps
class Message(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    session_id = db.Column(db.Integer, db.ForeignKey('session.id'))
    role = db.Column(db.String(20))  # 'assistant' or 'user'
    content = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)

Next steps

Installation guide

Learn about Docker deployment and production configuration

Architecture

Understand the service layer and AI provider pattern

API reference

Explore the REST endpoints and data models

Contributing

Help improve Interview Simulator

Troubleshooting

API key errors

If you see “AI provider not configured” errors:
  1. Verify your .env file contains valid API keys
  2. Check that ACTIVE_PROVIDERS includes your configured provider
  3. Restart the Flask server after editing .env

Database errors

If you encounter database initialization issues:
# Delete the database and recreate
rm -rf instance/
flask run
# Database is automatically created on startup

Document parsing errors

If CV upload fails:
  • Ensure the file is a valid PDF, DOCX, or TXT
  • Check file size is under 16MB (default limit)
  • Try re-saving the document to fix corruption
# The parser handles multiple formats gracefully
class DocumentParser:
    SUPPORTED_EXTENSIONS = {'.pdf', '.docx', '.txt'}

    @classmethod
    def extract_text(cls, file_path: str) -> str:
        extension = Path(file_path).suffix.lower()
        if extension not in cls.SUPPORTED_EXTENSIONS:
            raise DocumentParsingError(
                f"Unsupported file type: {extension}"
            )
        # ... format-specific extraction

Build docs developers (and LLMs) love