# ============================================================================= # engine/__init__.py — Resume Engine Package Initialiser # ============================================================================= # PURPOSE: # Makes engine/ a proper Python package. # Exposes all public functions from every module in one clean import. # # BENEFIT — instead of writing this in main.py: # from engine.parser import load_resumes_from_folder # from engine.database import init_db, insert_resume # from engine.extractor import build_resume_record # ... (7 separate import lines) # # You can write this: # from engine import load_resumes_from_folder, init_db, build_resume_record # # STATUS LEGEND (updated as each step is completed): # ✅ Built and tested # 🔲 Not built yet — imported conditionally so missing modules don't crash # # MODULES: # ✅ parser.py Step 3 — PDF/DOCX text extraction # ✅ database.py Step 2 — SQLite read/write operations # 🔲 extractor.py Step 4 — Structured field extraction (skills, exp, etc) # 🔲 jd_parser.py Step 5 — Job description parsing # 🔲 matcher.py Step 6 — Scoring engine # 🔲 explainer.py Step 7 — Summary + interview question generation # ============================================================================= # ── Standard library ────────────────────────────────────────────────────────── import os import sys # Ensure project root is always on the path so config.py is importable # regardless of where you run Python from _ENGINE_DIR = os.path.dirname(os.path.abspath(__file__)) _PROJECT_ROOT = os.path.dirname(_ENGINE_DIR) if _PROJECT_ROOT not in sys.path: sys.path.insert(0, _PROJECT_ROOT) # ============================================================================= # ✅ STEP 3 — parser.py # Text extraction from PDF and DOCX resume files # ============================================================================= try: from engine.parser import ( extract_text, # Route any file to the correct extractor extract_text_from_pdf, # PDF-specific extractor (pdfplumber) extract_text_from_docx, # DOCX-specific extractor (python-docx) load_resumes_from_folder, # Batch-load all resumes from a folder clean_text, # Internal text cleaner (useful for JD text too) ) _PARSER_OK = True except (ImportError, SyntaxError, Exception) as e: _PARSER_OK = False import warnings warnings.warn(f"[engine] parser.py not available: {e}", ImportWarning) # ============================================================================= # ✅ STEP 2 — database.py # All SQLite read/write operations # ============================================================================= try: from engine.database import ( init_db, # Create all tables (run once on startup) insert_resume, # Insert one parsed resume → returns resume_id insert_jd, # Insert one job description → returns jd_id insert_match_result, # Insert one scored match → returns match_id get_all_resumes, # Fetch all resumes as list of dicts get_resume_by_id, # Fetch one resume by resume_id get_all_jds, # Fetch all job descriptions get_matches_by_jd, # Fetch all matches for a JD, sorted by score export_matches_to_csv, # Save match results to a CSV file ) _DATABASE_OK = True except (ImportError, SyntaxError, Exception) as e: _DATABASE_OK = False import warnings warnings.warn(f"[engine] database.py not available: {e}", ImportWarning) # ============================================================================= # 🔲 STEP 4 — extractor.py # Structured field extraction from raw resume text # (Skills, experience, education, stability, recency etc.) # ============================================================================= try: from engine.extractor import ( build_resume_record, # Master function — returns complete DB-ready dict extract_candidate_name, extract_contact, extract_skills, extract_soft_skills, extract_experience, extract_education, extract_projects, extract_certifications, extract_recency, ) _EXTRACTOR_OK = True except (ImportError, SyntaxError, Exception): _EXTRACTOR_OK = False # Silently skip — not built yet # ============================================================================= # 🔲 STEP 5 — jd_parser.py # Job description parsing # ============================================================================= try: from engine.jd_parser import ( parse_jd_text, # Parse raw JD text → structured dict load_jd_from_file, # Load JD from .txt or .pdf file ) _JD_PARSER_OK = True except (ImportError, SyntaxError, Exception): _JD_PARSER_OK = False # ============================================================================= # 🔲 STEP 6 — matcher.py # Scoring engine — computes all 5 component scores + final weighted score # ============================================================================= try: from engine.matcher import ( match_resume_to_jd, # Master scorer — returns complete match dict score_skill_match, score_experience, score_stability, score_recency, score_education, compute_final_score, ) _MATCHER_OK = True except (ImportError, SyntaxError, Exception): _MATCHER_OK = False # ============================================================================= # 🔲 STEP 7 — explainer.py # Plain-language summaries + interview question generation # ============================================================================= try: from engine.explainer import ( generate_summary, # Build structured text explanation generate_interview_questions, # Call OpenAI to generate questions build_full_output, # Combine match result + summary + questions ) _EXPLAINER_OK = True except (ImportError, SyntaxError, Exception): _EXPLAINER_OK = False # ============================================================================= # PACKAGE STATUS — what is ready vs pending # ============================================================================= # Dictionary you can query programmatically: engine.STATUS STATUS = { "parser" : _PARSER_OK, "database" : _DATABASE_OK, "extractor" : _EXTRACTOR_OK, "jd_parser" : _JD_PARSER_OK, "matcher" : _MATCHER_OK, "explainer" : _EXPLAINER_OK, } # Convenience: list of modules that are fully ready READY_MODULES = [name for name, ok in STATUS.items() if ok] # ============================================================================= # SELF-TEST # Run this file directly to see which modules are loaded: # python engine/__init__.py # ============================================================================= if __name__ == "__main__": GREEN = "\033[92m" RED = "\033[91m" YELLOW = "\033[93m" BOLD = "\033[1m" RESET = "\033[0m" step_map = { "parser" : "Step 3", "database" : "Step 2", "extractor" : "Step 4", "jd_parser" : "Step 5", "matcher" : "Step 6", "explainer" : "Step 7", } print(f"\n{BOLD}{'='*55}{RESET}") print(f"{BOLD} RESUME ENGINE — MODULE STATUS{RESET}") print(f"{BOLD}{'='*55}{RESET}\n") all_built = ["parser", "database"] # steps confirmed built for module, ok in STATUS.items(): step = step_map[module] if ok: tag = f"{GREEN}✅ LOADED{RESET}" elif module in all_built: tag = f"{RED}✗ FAILED TO IMPORT — check for errors in {module}.py{RESET}" else: tag = f"{YELLOW}🔲 NOT BUILT YET{RESET}" print(f" {step:<8} {module:<12} {tag}") built_count = sum(STATUS.values()) total = len(STATUS) print(f"\n{BOLD} Progress: {built_count}/{total} modules loaded{RESET}") if STATUS["parser"] and STATUS["database"]: print(f"\n {GREEN}{BOLD}✓ Core modules ready — proceed to Step 4 (extractor.py){RESET}") else: print(f"\n {RED}Fix import errors above before proceeding.{RESET}") print(f"\n{'='*55}\n")