Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import os | |
| import tempfile | |
| from pathlib import Path | |
| import time | |
| from typing import List, Dict | |
| import pandas as pd | |
| # Initialize Streamlit app | |
| st.set_page_config( | |
| page_title="IntraTalent Resume Processor", | |
| page_icon="π", | |
| layout="wide" | |
| ) | |
| def save_uploaded_file(uploaded_file) -> str: | |
| """Save uploaded file to temporary directory and return path.""" | |
| try: | |
| with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_file: | |
| tmp_file.write(uploaded_file.getvalue()) | |
| return tmp_file.name | |
| except Exception as e: | |
| st.error(f"Error saving file: {e}") | |
| return None | |
| def process_resumes(uploaded_files: List[st.UploadedFile]) -> Dict: | |
| """Process multiple resumes and return results.""" | |
| results = {} | |
| progress_bar = st.progress(0) | |
| for idx, file in enumerate(uploaded_files): | |
| if file.type != "application/pdf": | |
| st.warning(f"Skipping {file.name}: Not a PDF file") | |
| continue | |
| temp_path = save_uploaded_file(file) | |
| if temp_path: | |
| try: | |
| name, projects = parse_resume(temp_path) | |
| results[file.name] = { | |
| "name": name, | |
| "projects": projects | |
| } | |
| # Update progress | |
| progress_bar.progress((idx + 1) / len(uploaded_files)) | |
| except Exception as e: | |
| st.error(f"Error processing {file.name}: {e}") | |
| finally: | |
| # Clean up temporary file | |
| os.unlink(temp_path) | |
| return results | |
| def display_results(results: Dict): | |
| """Display processed resume results in an organized manner.""" | |
| if not results: | |
| return | |
| st.subheader("Processed Resumes") | |
| for filename, data in results.items(): | |
| with st.expander(f"π {data['name']} ({filename})"): | |
| if data['projects']: | |
| df = pd.DataFrame(data['projects']) | |
| st.dataframe( | |
| df, | |
| column_config={ | |
| "name": "Project Name", | |
| "description": "Description" | |
| }, | |
| hide_index=True | |
| ) | |
| else: | |
| st.info("No projects found in this resume") | |
| def main(): | |
| st.title("IntraTalent Resume Processor") | |
| # File uploader section | |
| st.header("Upload Resumes") | |
| uploaded_files = st.file_uploader( | |
| "Upload up to 10 resumes (PDF only)", | |
| type=['pdf'], | |
| accept_multiple_files=True, | |
| key="resume_uploader" | |
| ) | |
| # Validate number of files | |
| if len(uploaded_files) > 10: | |
| st.error("Maximum 10 files allowed. Please remove some files.") | |
| return | |
| # Process button | |
| if uploaded_files and st.button("Process Resumes"): | |
| with st.spinner("Processing resumes..."): | |
| results = process_resumes(uploaded_files) | |
| st.session_state['processed_results'] = results | |
| display_results(results) | |
| # Query section | |
| st.header("Search Projects") | |
| query = st.text_area( | |
| "Enter your project requirements", | |
| placeholder="Example: Looking for team members with experience in machine learning and computer vision...", | |
| height=100 | |
| ) | |
| if query and st.button("Search"): | |
| if 'processed_results' not in st.session_state: | |
| st.warning("Please process some resumes first!") | |
| return | |
| with st.spinner("Searching for matches..."): | |
| # Here you would implement the embedding and similarity search | |
| # Using the code from your original script | |
| st.success("Search completed!") | |
| # Display results in a nice format | |
| st.subheader("Top Matches") | |
| # Placeholder for search results | |
| st.info("Feature coming soon: Will display matching projects and candidates based on similarity search") | |
| if __name__ == "__main__": | |
| main() |