Spaces:
Sleeping
Sleeping
| import io | |
| import pdfplumber | |
| import google.generativeai as genai | |
| import os | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| genai.configure(api_key=os.getenv("GEMINI_API_KEY")) | |
| model = genai.GenerativeModel("gemini-3.1-flash-lite") | |
| def extract_text_from_pdf(pdf_input): | |
| text = "" | |
| try: | |
| # Support both file path and bytes | |
| pdf_file = io.BytesIO(pdf_input) if isinstance(pdf_input, bytes) else pdf_input | |
| with pdfplumber.open(pdf_file) as pdf: | |
| for page in pdf.pages: | |
| text += page.extract_text() or "" | |
| except Exception as e: | |
| print(f"pdfplumber error: {e}") | |
| # Fallback to Gemini inline PDF parsing if pdfplumber fails or returns no content (scanned PDF) | |
| if len(text.strip()) < 50: | |
| try: | |
| print("pdfplumber returned insufficient text. Falling back to Gemini inline PDF parser...") | |
| if isinstance(pdf_input, bytes): | |
| pdf_bytes = pdf_input | |
| else: | |
| with open(pdf_input, "rb") as f: | |
| pdf_bytes = f.read() | |
| response = model.generate_content([ | |
| { | |
| "mime_type": "application/pdf", | |
| "data": pdf_bytes | |
| }, | |
| "Extract all text from this resume PDF. Maintain the exact structural layout, headings, and details. Do not explain anything, just output the clean text of the resume." | |
| ]) | |
| extracted_text = response.text.strip() | |
| if extracted_text: | |
| text = extracted_text | |
| except Exception as e: | |
| print(f"Gemini PDF extraction fallback error: {e}") | |
| return text | |
| def extract_skills(text, source="resume"): | |
| prompt = f"""You are an expert HR analyst. | |
| Extract all technical skills from this {source} text. | |
| Return ONLY a Python list like: ['Python', 'SQL', 'Docker'] | |
| No explanation. Just the list. | |
| Text: | |
| {text}""" | |
| response = model.generate_content(prompt) | |
| raw = response.text.strip() | |
| # Handle possible markdown formatting | |
| if raw.startswith("```"): | |
| raw = "\n".join(raw.split("\n")[1:-1]).strip() | |
| try: | |
| skills = eval(raw) | |
| except Exception: | |
| skills = [] | |
| return skills | |