DevResume-AI / app.py
EATosin's picture
Update app.py
46d0b96 verified
import streamlit as st
import google.generativeai as genai
from github import Github
from pypdf import PdfReader
import os
from dotenv import load_dotenv
# --- CONFIG ---
st.set_page_config(page_title="DevResume Pro", layout="wide", page_icon="⚑")
# Load Keys
api_key = os.getenv("GEMINI_API_KEY")
github_token = os.getenv("GITHUB_TOKEN")
if not api_key:
load_dotenv()
api_key = os.getenv("GEMINI_API_KEY")
github_token = os.getenv("GITHUB_TOKEN")
# --- FUNC 1: PDF PARSER ---
def extract_pdf_text(file):
try:
reader = PdfReader(file)
text = ""
for page in reader.pages:
text += page.extract_text()
return text
except:
return None
# --- FUNC 2: GITHUB CRAWLER ---
def fetch_github_data(username):
try:
g = Github(github_token) if github_token else Github()
user = g.get_user(username)
repos = sorted(user.get_repos(), key=lambda x: x.stargazers_count, reverse=True)[:4]
repo_data = ""
for repo in repos:
readme = "No README"
try:
if repo.get_readme().decoded_content:
readme = repo.get_readme().decoded_content.decode("utf-8")[:1000]
except: pass
repo_data += f"Project: {repo.name} ({repo.stargazers_count} Stars, {repo.language})\nDesc: {repo.description}\nContext: {readme}\n\n"
return repo_data
except Exception as e:
return f"Error fetching GitHub: {str(e)}"
# --- FUNC 3: THE RESUME ARCHITECT ---
def generate_full_resume(old_resume_text, github_data, target_role):
genai.configure(api_key=api_key)
try:
model = genai.GenerativeModel('gemini-2.5-flash')
except:
model = genai.GenerativeModel('gemini-1.5-flash')
prompt = f"""
You are an Elite Tech Resume Writer.
SOURCE MATERIAL:
1. OLD RESUME TEXT:
{old_resume_text[:4000]}
2. GITHUB PORTFOLIO ANALYSIS:
{github_data}
TARGET ROLE: {target_role}
TASK:
Write a complete, SOTA Resume (Markdown Format).
STRUCTURE:
1. **Header:** Name, Title (Target Role), Links (GitHub/LinkedIn).
2. **Professional Summary:** Synthesize the old resume + new GitHub achievements into a killer 3-line bio.
3. **Technical Skills:** Grouped by category (Languages, Frameworks, Tools).
4. **Featured Projects:** Use the GitHub Data. Write "XYZ Style" impact bullets.
5. **Experience:** Polish the old resume's experience section. Make it punchy.
6. **Education:** Keep it simple.
TONE: Senior, High-Impact, Quantified.
"""
try:
response = model.generate_content(prompt)
return response.text
except Exception as e:
return f"AI Error: {e}"
# --- UI ---
st.title("⚑ DevResume Pro: The Hybrid Architect")
st.markdown("Combines your **Old Resume** + **Real GitHub Code** to build the ultimate portfolio.")
col1, col2 = st.columns([1, 2])
with col1:
st.subheader("1. Your Inputs")
gh_user = st.text_input("GitHub Username", placeholder="eatosin")
role = st.text_input("Target Role", value="Senior AI Engineer")
uploaded_file = st.file_uploader("Upload Old Resume (PDF)", type="pdf")
if st.button("πŸš€ Build Resume", type="primary"):
if not gh_user or not uploaded_file:
st.error("Please provide both GitHub User and PDF Resume.")
else:
with st.spinner("πŸ•΅οΈβ€β™‚οΈ Reading PDF & Scraping GitHub..."):
# 1. Read PDF
pdf_text = extract_pdf_text(uploaded_file)
# 2. Scrape GitHub
gh_data = fetch_github_data(gh_user)
# 3. Generate
if pdf_text and gh_data:
st.session_state['resume'] = generate_full_resume(pdf_text, gh_data, role)
else:
st.error("Failed to read inputs.")
with col2:
if 'resume' in st.session_state:
st.subheader("πŸ“„ Your New Resume")
st.markdown(st.session_state['resume'])
st.download_button("πŸ“₯ Download Markdown", st.session_state['resume'], file_name="SOTA_Resume.md")