aloshy-ai Claude commited on
Commit
c348077
Β·
1 Parent(s): a1c0f97

feat: replace Gradio with Streamlit for better UI presentation

Browse files

- Convert app.py to use Streamlit with clean, minimal design
- Add score interpretation with visual feedback (emojis and colors)
- Update README.md configuration for Streamlit SDK
- Update requirements.txt for Streamlit dependencies
- Use

@st
.cache_resource for efficient model loading

πŸ€– Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (3) hide show
  1. README.md +3 -3
  2. app.py +50 -42
  3. requirements.txt +1 -1
README.md CHANGED
@@ -3,8 +3,8 @@ title: Resume Job Matcher
3
  emoji: πŸ“„
4
  colorFrom: blue
5
  colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.39.0
8
  app_file: app.py
9
  pinned: false
10
  license: mit
@@ -19,7 +19,7 @@ An AI-powered tool that calculates how well a resume matches a job description u
19
  - Upload resume files (.txt format)
20
  - Paste job descriptions
21
  - Get similarity scores between resumes and job postings
22
- - Built with Gradio for easy web interface
23
  - Uses BAAI/bge-large-en-v1.5 model with LoRA fine-tuning
24
 
25
  ## Usage
 
3
  emoji: πŸ“„
4
  colorFrom: blue
5
  colorTo: purple
6
+ sdk: streamlit
7
+ sdk_version: 1.28.1
8
  app_file: app.py
9
  pinned: false
10
  license: mit
 
19
  - Upload resume files (.txt format)
20
  - Paste job descriptions
21
  - Get similarity scores between resumes and job postings
22
+ - Built with Streamlit for clean web interface
23
  - Uses BAAI/bge-large-en-v1.5 model with LoRA fine-tuning
24
 
25
  ## Usage
app.py CHANGED
@@ -3,7 +3,7 @@ from transformers import AutoModel, AutoTokenizer
3
  from peft import PeftModel
4
  import torch
5
  import torch.nn.functional as F
6
- import gradio as gr
7
 
8
  # --- Configuration ---
9
  logging.basicConfig(level=logging.INFO)
@@ -49,47 +49,55 @@ def calculate_match_score(resume_text: str, job_text: str) -> float:
49
  return match_score
50
 
51
  # --- Initialize Models on Startup ---
52
- load_model_artifacts()
 
 
 
 
53
 
54
- # --- Gradio Interface ---
55
- def gradio_interface_fn(resume_file, job_description):
56
- """The function that powers the Gradio UI."""
57
- if resume_file is None:
58
- return "Please upload a resume file."
59
- try:
60
- # Handle file path from Gradio
61
- if hasattr(resume_file, 'name'):
62
- # resume_file is a file path string
63
- with open(resume_file.name, 'r', encoding='utf-8') as f:
64
- resume_text = f.read()
65
- elif isinstance(resume_file, str):
66
- # resume_file is a file path string
67
- with open(resume_file, 'r', encoding='utf-8') as f:
68
- resume_text = f.read()
69
- else:
70
- # Try to decode if it's bytes
71
- resume_text = resume_file.decode("utf-8")
72
-
73
- score = calculate_match_score(resume_text, job_description)
74
- return f"Match Score: {score:.4f}"
75
- except ValueError as e:
76
- return f"Error: {e}"
77
- except Exception as e:
78
- logger.error(f"Gradio Error: {e}")
79
- return "An unexpected error occurred. Please check the logs."
80
 
81
- gradio_ui = gr.Interface(
82
- fn=gradio_interface_fn,
83
- inputs=[
84
- gr.File(label="Upload Resume (.txt)"),
85
- gr.Textbox(lines=10, label="Job Description", placeholder="Paste the job description here...")
86
- ],
87
- outputs=gr.Textbox(label="Result"),
88
- title="πŸ“„ Resume to Job Matcher",
89
- description="Find out how well a resume matches a job description. Upload a resume file and paste the job details below.",
90
- allow_flagging="never"
91
- )
92
 
93
- # --- Launch Gradio Interface ---
94
- if __name__ == "__main__":
95
- gradio_ui.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  from peft import PeftModel
4
  import torch
5
  import torch.nn.functional as F
6
+ import streamlit as st
7
 
8
  # --- Configuration ---
9
  logging.basicConfig(level=logging.INFO)
 
49
  return match_score
50
 
51
  # --- Initialize Models on Startup ---
52
+ @st.cache_resource
53
+ def load_models():
54
+ """Load models with Streamlit caching."""
55
+ load_model_artifacts()
56
+ return models
57
 
58
+ # Load models
59
+ models_cache = load_models()
60
+
61
+ # --- Streamlit App ---
62
+ st.title("πŸ“„ Resume to Job Matcher")
63
+ st.write("Find out how well a resume matches a job description. Upload a resume file and paste the job details below.")
64
+
65
+ # File upload
66
+ uploaded_file = st.file_uploader("Upload Resume (.txt)", type=['txt'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
+ # Job description input
69
+ job_description = st.text_area("Job Description", placeholder="Paste the job description here...", height=200)
 
 
 
 
 
 
 
 
 
70
 
71
+ # Submit button
72
+ if st.button("Submit"):
73
+ if uploaded_file is not None and job_description.strip():
74
+ try:
75
+ # Read the uploaded file
76
+ resume_text = str(uploaded_file.read(), "utf-8")
77
+
78
+ # Calculate match score
79
+ score = calculate_match_score(resume_text, job_description)
80
+
81
+ # Display result
82
+ st.success(f"Match Score: {score:.4f}")
83
+
84
+ # Show interpretation
85
+ if score >= 0.7:
86
+ st.info("🎯 Excellent match! Your resume aligns very well with this job.")
87
+ elif score >= 0.5:
88
+ st.info("βœ… Good match! There's solid compatibility between your resume and this job.")
89
+ elif score >= 0.3:
90
+ st.warning("⚠️ Moderate match. Consider highlighting relevant skills more prominently.")
91
+ else:
92
+ st.error("❌ Poor match. This job may not align well with your current profile.")
93
+
94
+ except ValueError as e:
95
+ st.error(f"Error: {e}")
96
+ except Exception as e:
97
+ logger.error(f"Streamlit Error: {e}")
98
+ st.error("An unexpected error occurred. Please check your inputs and try again.")
99
+ else:
100
+ if uploaded_file is None:
101
+ st.error("Please upload a resume file.")
102
+ if not job_description.strip():
103
+ st.error("Please enter a job description.")
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
  transformers>=4.21.0
2
  peft>=0.4.0
3
  torch>=1.12.0
4
- gradio>=5.39.0
 
1
  transformers>=4.21.0
2
  peft>=0.4.0
3
  torch>=1.12.0
4
+ streamlit>=1.28.1