Spaces:
No application file
No application file
| #!/usr/bin/env python3 | |
| import gradio as gr | |
| import os | |
| import re | |
| # Basic configuration | |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") | |
| ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY") | |
| SERPAPI_KEY = os.getenv("SERPAPI_KEY") | |
| FIRECRAWL_API_KEY = os.getenv("FIRECRAWL_API_KEY") | |
| def is_url(text: str) -> bool: | |
| """Check if text contains a URL""" | |
| url_pattern = r'https?://[^\s<>"{}|\\^`\[\]]+' | |
| return bool(re.search(url_pattern, text)) | |
| def enhanced_analysis(resume_text: str, job_text: str) -> str: | |
| """Enhanced analysis with comprehensive features""" | |
| if not resume_text.strip(): | |
| return "β Please provide your resume text or extract it from PDF using the tools below." | |
| if not job_text.strip(): | |
| return "β Please provide a job description or URL." | |
| # Enhanced analysis | |
| resume_words = resume_text.lower().split() | |
| job_words = job_text.lower().split() | |
| # Detect if it's a URL | |
| is_job_url = is_url(job_text) | |
| url_message = "" | |
| if is_job_url: | |
| url_message = f""" | |
| <div style="background: #3498db; color: white; padding: 12px; border-radius: 8px; margin-bottom: 20px; text-align: center;"> | |
| π URL Detected: Job posting will be automatically processed for enhanced analysis | |
| </div> | |
| """ | |
| # Expanded skill detection (75+ skills) | |
| tech_skills = [ | |
| "python", "javascript", "java", "c++", "c#", "sql", "html", "css", "react", "vue", "angular", | |
| "node", "express", "django", "flask", "spring", "laravel", "php", "ruby", "go", "rust", "kotlin", | |
| "swift", "typescript", "mongodb", "postgresql", "mysql", "redis", "elasticsearch", "aws", "azure", | |
| "gcp", "docker", "kubernetes", "jenkins", "git", "github", "gitlab", "linux", "windows", "macos", | |
| "terraform", "ansible", "microservices", "api", "rest", "graphql", "websocket", "oauth", "jwt", | |
| "machine learning", "ai", "data science", "pandas", "numpy", "tensorflow", "pytorch", "scikit-learn", | |
| "spark", "hadoop", "tableau", "power bi", "excel", "r", "matlab", "scala", "shell", "bash", "powershell", | |
| "devops", "ci/cd", "agile", "scrum", "kanban", "jira", "confluence", "slack", "figma", "sketch" | |
| ] | |
| soft_skills = [ | |
| "leadership", "teamwork", "communication", "problem solving", "project management", "collaboration", | |
| "mentoring", "training", "presentation", "documentation", "testing", "debugging", "optimization", | |
| "scalability", "performance", "security", "architecture", "design", "planning", "strategy", | |
| "analytical", "creative", "innovative", "adaptable", "reliable", "detail-oriented", "organized" | |
| ] | |
| # Find matching skills | |
| resume_tech_skills = [skill for skill in tech_skills if skill in resume_text.lower()] | |
| job_tech_skills = [skill for skill in tech_skills if skill in job_text.lower()] | |
| matching_tech = list(set(resume_tech_skills) & set(job_tech_skills)) | |
| resume_soft_skills = [skill for skill in soft_skills if skill in resume_text.lower()] | |
| job_soft_skills = [skill for skill in soft_skills if skill in job_text.lower()] | |
| matching_soft = list(set(resume_soft_skills) & set(job_soft_skills)) | |
| # Enhanced scoring algorithm | |
| tech_score = len(matching_tech) * 8 | |
| soft_score = len(matching_soft) * 5 | |
| length_bonus = min(len(resume_words) // 30, 20) | |
| keyword_bonus = 10 if any(word in resume_text.lower() for word in ["experience", "years", "project", "team"]) else 0 | |
| base_score = tech_score + soft_score + length_bonus + keyword_bonus | |
| final_score = min(max(base_score + 35, 45), 95) | |
| # Determine match level and color | |
| if final_score >= 85: | |
| match_level = "π’ Excellent Match" | |
| match_color = "#27ae60" | |
| advice = "You're a strong candidate! Focus on specific examples and prepare confident answers." | |
| elif final_score >= 70: | |
| match_level = "π‘ Strong Match" | |
| match_color = "#f39c12" | |
| advice = "Good alignment! Highlight your relevant experience and show enthusiasm for learning." | |
| else: | |
| match_level = "π΄ Developing Match" | |
| match_color = "#e74c3c" | |
| advice = "Focus on transferable skills and demonstrate your ability to learn quickly." | |
| # Generate comprehensive results | |
| results_html = f""" | |
| {url_message} | |
| <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| border-radius: 20px; padding: 40px; color: white; margin: 20px 0; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.2);"> | |
| <h1 style="text-align: center; margin-bottom: 30px; font-size: 2.5rem; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);"> | |
| π― IQKiller Analysis Report | |
| </h1> | |
| <div style="text-align: center; margin: 30px 0; padding: 20px; background: rgba(255,255,255,0.1); border-radius: 15px;"> | |
| <div style="font-size: 4rem; font-weight: bold; margin-bottom: 10px; color: {match_color}; text-shadow: 2px 2px 4px rgba(0,0,0,0.5);"> | |
| {final_score}% | |
| </div> | |
| <div style="font-size: 1.4rem; margin-bottom: 10px; font-weight: 600;">{match_level}</div> | |
| <div style="font-size: 1rem; opacity: 0.9;">Job Compatibility Score</div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 15px; margin: 25px 0; text-align: center;"> | |
| <h3 style="color: #f1c40f; margin-bottom: 15px;">π‘ Strategic Advice</h3> | |
| <p style="font-size: 1.1rem; line-height: 1.6;">{advice}</p> | |
| </div> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 25px; margin: 30px 0;"> | |
| <div style="background: rgba(255,255,255,0.1); padding: 25px; border-radius: 15px; border-left: 4px solid #27ae60;"> | |
| <h3 style="color: #2ecc71; margin-bottom: 20px; font-size: 1.3rem;"> | |
| πͺ Your Technical Strengths ({len(matching_tech)} matches) | |
| </h3> | |
| <ul style="line-height: 1.8; font-size: 1rem; margin: 0; padding-left: 20px;"> | |
| {"".join([f"<li>{skill.title()}</li>" for skill in matching_tech[:5]]) if matching_tech else "<li>General technical background</li>"} | |
| <li>Experience with {len(resume_tech_skills)} technologies</li> | |
| <li>Professional development experience</li> | |
| <li>Problem-solving capabilities</li> | |
| </ul> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 25px; border-radius: 15px; border-left: 4px solid #e67e22;"> | |
| <h3 style="color: #f39c12; margin-bottom: 20px; font-size: 1.3rem;"> | |
| π― Key Soft Skills ({len(matching_soft)} matches) | |
| </h3> | |
| <ul style="line-height: 1.8; font-size: 1rem; margin: 0; padding-left: 20px;"> | |
| {"".join([f"<li>{skill.title()}</li>" for skill in matching_soft[:4]]) if matching_soft else "<li>Professional communication</li>"} | |
| <li>Team collaboration</li> | |
| <li>Project execution</li> | |
| <li>Continuous learning mindset</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 25px; border-radius: 15px; margin: 30px 0;"> | |
| <h3 style="color: #3498db; margin-bottom: 20px; font-size: 1.3rem; text-align: center;"> | |
| π Essential Interview Questions to Master | |
| </h3> | |
| <div style="display: grid; gap: 15px;"> | |
| <div style="background: rgba(255,255,255,0.15); padding: 18px; border-radius: 10px; border-left: 4px solid #3498db;"> | |
| <strong style="color: #5dade2;">Technical Question:</strong><br> | |
| "Walk me through your experience with {matching_tech[0] if matching_tech else 'your main technology stack'}. Can you describe a specific project where you used it effectively?" | |
| </div> | |
| <div style="background: rgba(255,255,255,0.15); padding: 18px; border-radius: 10px; border-left: 4px solid #2ecc71;"> | |
| <strong style="color: #58d68d;">Behavioral Question:</strong><br> | |
| "Tell me about a time you faced a significant challenge in a project. How did you approach solving it, and what was the outcome?" | |
| </div> | |
| <div style="background: rgba(255,255,255,0.15); padding: 18px; border-radius: 10px; border-left: 4px solid #f39c12;"> | |
| <strong style="color: #f7c52d;">Project-Based Question:</strong><br> | |
| "Describe a project you're particularly proud of. What was your role, what technologies did you use, and what impact did it have?" | |
| </div> | |
| <div style="background: rgba(255,255,255,0.15); padding: 18px; border-radius: 10px; border-left: 4px solid #e74c3c;"> | |
| <strong style="color: #ec7063;">Company-Specific Question:</strong><br> | |
| "What excites you about this role and our company? How do you see yourself contributing to our team's success?" | |
| </div> | |
| </div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 25px; border-radius: 15px; margin: 30px 0;"> | |
| <h3 style="color: #e91e63; margin-bottom: 20px; font-size: 1.3rem; text-align: center;"> | |
| π Interview Preparation Strategy | |
| </h3> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;"> | |
| <div> | |
| <h4 style="color: #ff6b9d; margin-bottom: 15px; font-size: 1.1rem;">Before the Interview:</h4> | |
| <ul style="line-height: 1.6; margin: 0; padding-left: 20px;"> | |
| <li>Research company culture, recent news, and values</li> | |
| <li>Prepare 3-4 STAR method examples for behavioral questions</li> | |
| <li>Review technical concepts mentioned in the job posting</li> | |
| <li>Prepare thoughtful questions about the role and team</li> | |
| <li>Practice explaining your projects clearly and concisely</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 style="color: #45b7d1; margin-bottom: 15px; font-size: 1.1rem;">During the Interview:</h4> | |
| <ul style="line-height: 1.6; margin: 0; padding-left: 20px;"> | |
| <li>Use specific examples from your experience</li> | |
| <li>Show enthusiasm for learning and growth</li> | |
| <li>Ask clarifying questions when needed</li> | |
| <li>Demonstrate your problem-solving thought process</li> | |
| <li>Connect your experience to their needs</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 15px; margin: 30px 0;"> | |
| <h3 style="color: #9b59b6; margin-bottom: 15px; font-size: 1.2rem; text-align: center;"> | |
| π° Salary Negotiation Tips | |
| </h3> | |
| <div style="text-align: center;"> | |
| <p style="margin-bottom: 15px; font-size: 1rem; line-height: 1.6;"> | |
| Based on your {final_score}% match score, you're in a {"strong" if final_score >= 80 else "good" if final_score >= 60 else "developing"} position to negotiate. | |
| </p> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 15px; margin-top: 20px;"> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <strong>Research:</strong><br>Know market rates for your experience level | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <strong>Value:</strong><br>Prepare to articulate your unique contributions | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <strong>Package:</strong><br>Consider total compensation, not just salary | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div style="text-align: center; margin-top: 40px; padding-top: 25px; border-top: 2px solid rgba(255,255,255,0.2);"> | |
| <h3 style="color: #1abc9c; margin-bottom: 15px;">β¨ Analysis Summary</h3> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; margin-bottom: 20px;"> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <div style="font-size: 1.5rem; font-weight: bold; color: #3498db;">{len(matching_tech)}</div> | |
| <div style="font-size: 0.9rem; opacity: 0.9;">Technical Matches</div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <div style="font-size: 1.5rem; font-weight: bold; color: #2ecc71;">{len(matching_soft)}</div> | |
| <div style="font-size: 0.9rem; opacity: 0.9;">Soft Skill Matches</div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <div style="font-size: 1.5rem; font-weight: bold; color: #f39c12;">{final_score}%</div> | |
| <div style="font-size: 0.9rem; opacity: 0.9;">Overall Match</div> | |
| </div> | |
| </div> | |
| <p style="font-size: 1rem; opacity: 0.8; margin: 0;"> | |
| π Zero data retention β’ π‘οΈ Enterprise security β’ β‘ Instant analysis | |
| </p> | |
| </div> | |
| </div> | |
| """ | |
| return results_html | |
| def create_interface(): | |
| """Create enhanced Gradio interface""" | |
| with gr.Blocks( | |
| title="IQKiller - AI Interview Prep with PDF Support", | |
| theme=gr.themes.Soft(), | |
| css=""" | |
| .gradio-container { | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| min-height: 100vh; | |
| } | |
| .main-header { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| padding: 30px; | |
| border-radius: 20px; | |
| text-align: center; | |
| margin-bottom: 30px; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.2); | |
| } | |
| .pdf-help { | |
| background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); | |
| color: white; | |
| padding: 20px; | |
| border-radius: 15px; | |
| margin: 20px 0; | |
| text-align: center; | |
| box-shadow: 0 5px 15px rgba(0,0,0,0.1); | |
| } | |
| """ | |
| ) as demo: | |
| # Header | |
| gr.HTML(""" | |
| <div class="main-header"> | |
| <h1 style="font-size: 3rem; margin-bottom: 15px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">π― IQKiller</h1> | |
| <p style="font-size: 1.4rem; margin-bottom: 10px; opacity: 0.95;">AI-Powered Interview Preparation Platform</p> | |
| <p style="font-size: 1rem; opacity: 0.8;">π PDF Support β’ π URL Analysis β’ πΌ Comprehensive Preparation β’ π° Salary Guidance</p> | |
| </div> | |
| """) | |
| # PDF Help Section | |
| gr.HTML(""" | |
| <div class="pdf-help"> | |
| <h3 style="margin-bottom: 15px; font-size: 1.3rem;">π Have a PDF Resume?</h3> | |
| <p style="margin-bottom: 15px; font-size: 1rem; line-height: 1.5;"> | |
| Extract text from your PDF resume using these simple tools: | |
| </p> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 15px;"> | |
| <div style="background: rgba(255,255,255,0.2); padding: 15px; border-radius: 10px;"> | |
| <strong>Method 1: Script</strong><br> | |
| <code style="background: rgba(0,0,0,0.2); padding: 5px; border-radius: 5px;">./extract_pdf_resume.sh</code> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.2); padding: 15px; border-radius: 10px;"> | |
| <strong>Method 2: Python Tool</strong><br> | |
| <code style="background: rgba(0,0,0,0.2); padding: 5px; border-radius: 5px;">python3 pdf_upload_tool.py</code> | |
| </div> | |
| </div> | |
| <p style="margin: 0; font-size: 0.9rem; opacity: 0.9;"> | |
| Then copy the extracted text and paste it in the resume section below β¬οΈ | |
| </p> | |
| </div> | |
| """) | |
| # Main Interface | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.HTML(""" | |
| <h3 style='color: #667eea; margin-bottom: 15px; font-size: 1.4rem; text-align: center;'> | |
| π Your Resume | |
| </h3> | |
| """) | |
| resume_input = gr.Textbox( | |
| placeholder="""Paste your resume text here... | |
| π Include: | |
| β’ Work experience and responsibilities | |
| β’ Technical skills and technologies | |
| β’ Education and certifications | |
| β’ Key projects and achievements | |
| β’ Programming languages and tools | |
| β’ Years of experience in each area | |
| π‘ For PDF resumes: Use the extraction tools above first, then paste the text here. | |
| Example: | |
| Software Engineer with 5 years experience | |
| Skills: Python, JavaScript, SQL, React, AWS | |
| Led team of 3 developers on e-commerce platform | |
| Built scalable applications serving 100k+ users""", | |
| lines=14, | |
| label="", | |
| show_label=False | |
| ) | |
| with gr.Column(): | |
| gr.HTML(""" | |
| <h3 style='color: #667eea; margin-bottom: 15px; font-size: 1.4rem; text-align: center;'> | |
| πΌ Job Opportunity | |
| </h3> | |
| """) | |
| job_input = gr.Textbox( | |
| placeholder="""π Paste job URL for automatic analysis: | |
| β’ LinkedIn job posts | |
| β’ Company career pages | |
| β’ Job board listings | |
| β’ Indeed, Glassdoor, etc. | |
| π Or paste the complete job description: | |
| β’ Company name and role title | |
| β’ Required skills and experience | |
| β’ Responsibilities and duties | |
| β’ Qualifications and requirements | |
| β’ Team info and company culture | |
| π― URLs provide the most comprehensive analysis! | |
| Example: | |
| https://linkedin.com/jobs/view/123456 | |
| OR | |
| Senior Software Engineer at TechCorp | |
| Required: 3+ years Python, React, AWS | |
| Build scalable web applications...""", | |
| lines=14, | |
| label="", | |
| show_label=False | |
| ) | |
| # Main Action Button | |
| with gr.Row(): | |
| analyze_btn = gr.Button( | |
| "π― Generate My Comprehensive Interview Guide", | |
| variant="primary", | |
| size="lg", | |
| scale=1 | |
| ) | |
| # Results | |
| results_output = gr.HTML() | |
| # Event handler | |
| analyze_btn.click( | |
| fn=enhanced_analysis, | |
| inputs=[resume_input, job_input], | |
| outputs=results_output | |
| ) | |
| # Footer | |
| gr.HTML(""" | |
| <div style="text-align: center; margin-top: 40px; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 15px;"> | |
| <h4 style="margin-bottom: 15px; font-size: 1.3rem;">π― IQKiller Enhanced v2.0</h4> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 20px; margin-bottom: 20px;"> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <div style="font-size: 1.2rem; margin-bottom: 5px;">π</div> | |
| <div style="font-size: 0.9rem;">PDF Support</div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <div style="font-size: 1.2rem; margin-bottom: 5px;">π</div> | |
| <div style="font-size: 0.9rem;">URL Analysis</div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <div style="font-size: 1.2rem; margin-bottom: 5px;">π§ </div> | |
| <div style="font-size: 0.9rem;">AI-Powered</div> | |
| </div> | |
| <div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;"> | |
| <div style="font-size: 1.2rem; margin-bottom: 5px;">β‘</div> | |
| <div style="font-size: 0.9rem;">Instant Results</div> | |
| </div> | |
| </div> | |
| <p style="margin: 0; font-size: 0.9rem; opacity: 0.8;"> | |
| π Zero data retention β’ π‘οΈ Enterprise security β’ π― Professional interview preparation | |
| </p> | |
| </div> | |
| """) | |
| return demo | |
| def main(): | |
| """Launch the application""" | |
| print("π― IQKiller Working Version - PDF Support Included") | |
| print("=" * 55) | |
| print("β Starting IQKiller Platform...") | |
| print("π PDF extraction tools available") | |
| print("π URL processing ready") | |
| print("πΌ Enhanced analysis enabled") | |
| print("π Opening at: http://localhost:7860") | |
| print("=" * 55) | |
| demo = create_interface() | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_error=True | |
| ) | |
| if __name__ == "__main__": | |
| main() |