""" Gemini AI Service Handles resume text extraction and HTML generation """ import google.generativeai as genai from typing import Optional import base64 from app.core.config import settings class AIService: """Service for interacting with Google Gemini AI""" def __init__(self): """Initialize Gemini AI with API key""" if not settings.GEMINI_API_KEY: raise ValueError("GEMINI_API_KEY not configured") genai.configure(api_key=settings.GEMINI_API_KEY) self.model = genai.GenerativeModel('gemini-2.0-flash-exp') async def extract_text_from_resume( self, file_content: bytes, mime_type: str ) -> Optional[str]: """ Extract text from resume file using Gemini Vision Args: file_content: File content as bytes mime_type: MIME type of the file (application/pdf or application/vnd.openxmlformats-officedocument.wordprocessingml.document) Returns: Extracted text or None if failed """ try: # Convert bytes to base64 base64_data = base64.b64encode(file_content).decode('utf-8') prompt = """Extract all text from this resume document. Preserve the original structure, including sections, headings, bullet points, and line breaks, as plain text. Focus on maintaining the hierarchical structure of the content.""" response = self.model.generate_content([ { 'mime_type': mime_type, 'data': base64_data }, prompt ]) return response.text except Exception as e: print(f"Error extracting text from resume: {e}") return None async def generate_html_from_template( self, resume_text: str, template_html: str ) -> Optional[str]: """ Generate formatted HTML by merging resume content with template Args: resume_text: Extracted resume text template_html: HTML template content Returns: Generated HTML or None if failed """ try: prompt = self._build_generation_prompt(resume_text, template_html) response = self.model.generate_content(prompt) # Clean up the response (remove code blocks if present) html_content = response.text.strip() if html_content.startswith('```html'): html_content = html_content[7:] # Remove ```html if html_content.endswith('```'): html_content = html_content[:-3] # Remove ``` return html_content.strip() except Exception as e: print(f"Error generating HTML: {e}") return None def _build_generation_prompt(self, resume_text: str, template_html: str) -> str: """Build the prompt for HTML generation""" instructions = """### 🎯 EXACT TEMPLATE PRESERVATION INSTRUCTIONS: **🚨 RULE #1: COPY TEMPLATE EXACTLY - NO STRUCTURAL CHANGES! 🚨** **🚨 RULE #2: ONLY REPLACE PLACEHOLDER TEXT - NOTHING ELSE! 🚨** **YOU ARE A FIND-AND-REPLACE TOOL - NOT A DESIGNER!** **SIMPLE 3-STEP PROCESS:** 1. **COPY**: Take the entire HTML template (every character from ). 2. **FIND**: Locate placeholder text in the template (like "{{name}}", "John Doe", "Software Engineer", "2020-2023", etc.). 3. **REPLACE**: Replace ONLY that placeholder text with the user's corresponding information. **WHAT TO REPLACE:** - Names, contact info - Job titles, companies, dates, descriptions - Education details - Skills lists **WHAT TO NEVER CHANGE:** - HTML tags (div, p, h1, etc.), CSS classes, IDs, or any inline styles. - The overall HTML structure, layout, nesting, alignment, spacing, colors, and fonts. **FOR EXTRA USER CONTENT:** If the user's resume has sections not present in the template (e.g., 'Projects', 'Certifications'): - Find a similar section in the template (e.g., 'Experience'). - Copy that section's HTML structure. - Add it at a logical place (usually at the end) with the user's content. - Reuse the same CSS classes and styling patterns to maintain consistency. **CRITICAL:** Ensure ALL information from the user's resume is included in the final HTML. Do not omit any details. """ return f"""You are an expert HTML resume generator. Your task is to take the user's resume content and perfectly merge it into the provided company HTML template by acting as a precise find-and-replace tool. **User's Resume Content:** --- {resume_text} --- **Company HTML Template:** --- {template_html} --- {instructions} Now, generate the final, complete HTML file. Your entire output must be only the HTML code, starting with `` and ending with ``. Do not include any explanations or surrounding text.""" # Singleton instance ai_service = AIService()