Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import requests | |
| import os | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| # Configuration | |
| # Defaults to localhost for dev, but can be overridden in production (e.g., Docker) | |
| BACKEND_URL = os.getenv("BACKEND_URL", "http://127.0.0.1:8000/process-resume") | |
| st.set_page_config(page_title="AI Resume Analyzer", page_icon="π", layout="centered") | |
| st.title("π Intelligent Resume Parser") | |
| st.markdown("---") | |
| st.write("Upload a professional resume in PDF format to extract key insights using AI.") | |
| # Sidebar for status | |
| with st.sidebar: | |
| st.info(f"Connected to Backend: `{BACKEND_URL}`") | |
| uploaded_file = st.file_uploader("Upload PDF Resume", type="pdf") | |
| if uploaded_file: | |
| # Basic Frontend Validation | |
| if uploaded_file.size > 5 * 1024 * 1024: | |
| st.error("File is too large! Please upload a file smaller than 5MB.") | |
| else: | |
| if st.button("Analyze Resume", type="primary"): | |
| with st.spinner("Processing with AI..."): | |
| try: | |
| files = { | |
| "file": (uploaded_file.name, uploaded_file.getvalue(), "application/pdf") | |
| } | |
| # Set a timeout to prevent hanging | |
| response = requests.post(BACKEND_URL, files=files, timeout=30) | |
| if response.status_code == 200: | |
| data = response.json() | |
| # Handle case where AI returns an error key | |
| if "error" in data: | |
| st.error(data["error"]) | |
| else: | |
| st.success("Extraction Complete!") | |
| # Summary Section | |
| st.markdown("### π Professional Summary") | |
| st.info(data.get('summary', 'No summary available.')) | |
| # Contact Info | |
| st.markdown("### π Contact Details") | |
| c1, c2, c3 = st.columns(3) | |
| c1.metric("Name", data.get('name', 'N/A')) | |
| c2.metric("Email", data.get('email', 'N/A')) | |
| c3.metric("Phone", data.get('phone', 'N/A')) | |
| # Skills Section | |
| st.markdown("### π Technical Skills") | |
| skills = data.get('skills', []) | |
| if skills and isinstance(skills, list): | |
| # CSS styling for tags | |
| st.markdown( | |
| f""" | |
| <div style="display: flex; flex-wrap: wrap; gap: 10px;"> | |
| {''.join([f'<span style="background-color: #e0f2f1; color: #00695c; padding: 5px 10px; border-radius: 15px; font-size: 14px;">{skill}</span>' for skill in skills])} | |
| </div> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| else: | |
| st.write("No specific skills detected.") | |
| with st.expander("View Raw JSON Data"): | |
| st.json(data) | |
| elif response.status_code == 413: | |
| st.error("The file is too large for the server to process.") | |
| else: | |
| st.error(f"Server Error: {response.status_code} - {response.text}") | |
| except requests.exceptions.ConnectionError: | |
| st.error("π¨ Connection Failed: Could not reach the backend server.") | |
| except requests.exceptions.Timeout: | |
| st.error("π¨ Request Timed Out: The AI took too long to respond.") | |
| except Exception as e: | |
| st.error(f"An unexpected error occurred: {e}") |