ABAO77 commited on
Commit
faf2e55
Β·
1 Parent(s): e3fe7c5

Add application file

Browse files
Files changed (2) hide show
  1. UI.py +178 -0
  2. app.py +178 -0
UI.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ from PIL import Image
4
+ import io
5
+ import base64
6
+ import json
7
+
8
+ # Set the backend URL
9
+ BACKEND_URL = "https://abao77-cv-parsing.hf.space"
10
+
11
+ # Initialize session state
12
+ def init_session_state():
13
+ if "uploaded_image" not in st.session_state:
14
+ st.session_state["uploaded_image"] = None
15
+ if "processed_image" not in st.session_state:
16
+ st.session_state["processed_image"] = None
17
+ if "extracted_text" not in st.session_state:
18
+ st.session_state["extracted_text"] = None
19
+ if "reformatted_cv" not in st.session_state:
20
+ st.session_state["reformatted_cv"] = None
21
+ if "bounding_boxes" not in st.session_state:
22
+ st.session_state["bounding_boxes"] = None
23
+
24
+ def main():
25
+ st.set_page_config(page_title="Resume Analyzer", layout="wide")
26
+ init_session_state()
27
+
28
+ # Title and description
29
+ st.title("πŸ“„ Resume Analyzer & Job Matcher")
30
+ st.markdown("""
31
+ Upload your resume image, extract text, and match it with job descriptions.
32
+ """)
33
+
34
+ # Create tabs
35
+ tab1, tab2, tab3 = st.tabs(["πŸ“Έ Extract Text", "πŸ“ Format Resume", "🎯 Job Matching"])
36
+
37
+ # Tab 1: Extract Text
38
+ with tab1:
39
+ col1, col2 = st.columns([1, 1])
40
+
41
+ with col1:
42
+ st.subheader("Upload Resume")
43
+ uploaded_file = st.file_uploader("Choose an image file", type=["jpg", "jpeg", "png"])
44
+
45
+ if uploaded_file:
46
+ st.session_state["uploaded_image"] = uploaded_file
47
+ st.image(uploaded_file, caption="Uploaded Image", use_column_width=True)
48
+
49
+ if st.button("πŸ“· Extract Text", type="primary"):
50
+ if st.session_state["uploaded_image"]:
51
+ with st.spinner("Processing image..."):
52
+ image_bytes = st.session_state["uploaded_image"].read()
53
+ files = {
54
+ "image": (
55
+ st.session_state["uploaded_image"].name,
56
+ image_bytes,
57
+ st.session_state["uploaded_image"].type,
58
+ )
59
+ }
60
+ data = {"threshold_confidence": 0.7, "threshold_iou": 0.7}
61
+
62
+ try:
63
+ response = requests.post(f"{BACKEND_URL}/inference", data=data, files=files)
64
+ if response.status_code == 200:
65
+ result = response.json()
66
+ # Store processed image
67
+ image_base64 = result.get("image_base64")
68
+ if image_base64:
69
+ image_data = base64.b64decode(image_base64)
70
+ image = Image.open(io.BytesIO(image_data))
71
+ st.session_state["processed_image"] = image
72
+ st.session_state["extracted_text"] = result.get("outputs")
73
+ st.success("Text extracted successfully!")
74
+ else:
75
+ st.error(f"Error: {response.text}")
76
+ except Exception as e:
77
+ st.error(f"Error: {str(e)}")
78
+ else:
79
+ st.warning("Please upload an image first.")
80
+
81
+ with col2:
82
+ if st.session_state["processed_image"]:
83
+ st.subheader("Processed Image")
84
+ st.image(st.session_state["processed_image"], caption="With Detected Text")
85
+
86
+ if st.session_state["extracted_text"]:
87
+ with st.expander("View Extracted Text", expanded=True):
88
+ st.json(st.session_state["extracted_text"])
89
+
90
+ # Tab 2: Format Resume
91
+ with tab2:
92
+ st.subheader("Format Resume")
93
+ if st.session_state["extracted_text"] is None:
94
+ st.warning("Please extract text from an image first.")
95
+ else:
96
+ if st.button("πŸ”„ Format Resume", type="primary"):
97
+ with st.spinner("Formatting resume..."):
98
+ try:
99
+ data = {"text": str(st.session_state["extracted_text"])}
100
+ response = requests.post(f"{BACKEND_URL}/reformat_output", json=data)
101
+ if response.status_code == 200:
102
+ st.session_state["reformatted_cv"] = response.json()
103
+ st.success("Resume formatted successfully!")
104
+
105
+ # Display formatted sections
106
+ col1, col2 = st.columns(2)
107
+ with col1:
108
+ with st.expander("πŸ“‹ Personal Information", expanded=True):
109
+ if "contact" in st.session_state["reformatted_cv"]:
110
+ st.write(st.session_state["reformatted_cv"]["contact"])
111
+
112
+ with st.expander("πŸ’Ό Experience", expanded=True):
113
+ if "experience" in st.session_state["reformatted_cv"]:
114
+ st.write(st.session_state["reformatted_cv"]["experience"])
115
+
116
+ with col2:
117
+ with st.expander("🎯 Skills", expanded=True):
118
+ if "skills" in st.session_state["reformatted_cv"]:
119
+ st.write(st.session_state["reformatted_cv"]["skills"])
120
+
121
+ with st.expander("🌟 Other Information", expanded=True):
122
+ if "interests" in st.session_state["reformatted_cv"]:
123
+ st.write("Interests:", st.session_state["reformatted_cv"]["interests"])
124
+ if "community" in st.session_state["reformatted_cv"]:
125
+ st.write("Community:", st.session_state["reformatted_cv"]["community"])
126
+ else:
127
+ st.error(f"Error: {response.text}")
128
+ except Exception as e:
129
+ st.error(f"Error: {str(e)}")
130
+
131
+ # Tab 3: Job Matching
132
+ with tab3:
133
+ st.subheader("Match with Job Description")
134
+
135
+ job_description = st.text_area("πŸ“ Paste Job Description", height=200)
136
+
137
+ if st.button("🎯 Match Resume", type="primary"):
138
+ if job_description:
139
+ if st.session_state["reformatted_cv"] is None:
140
+ st.warning("Formatting resume first...")
141
+ # Auto-format if not already formatted
142
+ data = {"text": str(st.session_state["extracted_text"])}
143
+ response = requests.post(f"{BACKEND_URL}/reformat_output", json=data)
144
+ if response.status_code == 200:
145
+ st.session_state["reformatted_cv"] = response.json()
146
+
147
+ # Proceed with job matching
148
+ with st.spinner("Analyzing match..."):
149
+ try:
150
+ data = {
151
+ "text": json.dumps(st.session_state["reformatted_cv"]),
152
+ "job_desciption": job_description
153
+ }
154
+ response = requests.post(f"{BACKEND_URL}/matching_job_desciption", json=data)
155
+
156
+ if response.status_code == 200:
157
+ result = response.json()
158
+
159
+ # Display match results
160
+ col1, col2 = st.columns([1, 2])
161
+ with col1:
162
+ st.metric("Match Score", f"{result['score']}%")
163
+
164
+ with col2:
165
+ st.markdown("### Match Analysis")
166
+ st.write(result["reasoning"])
167
+
168
+ with st.expander("View Detailed Analysis", expanded=False):
169
+ st.json(result)
170
+ else:
171
+ st.error(f"Error: {response.text}")
172
+ except Exception as e:
173
+ st.error(f"Error: {str(e)}")
174
+ else:
175
+ st.warning("Please enter a job description.")
176
+
177
+ if __name__ == "__main__":
178
+ main()
app.py ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ from PIL import Image
4
+ import io
5
+ import base64
6
+ import json
7
+
8
+ # Set the backend URL
9
+ BACKEND_URL = "https://abao77-cv-parsing.hf.space"
10
+
11
+ # Initialize session state
12
+ def init_session_state():
13
+ if "uploaded_image" not in st.session_state:
14
+ st.session_state["uploaded_image"] = None
15
+ if "processed_image" not in st.session_state:
16
+ st.session_state["processed_image"] = None
17
+ if "extracted_text" not in st.session_state:
18
+ st.session_state["extracted_text"] = None
19
+ if "reformatted_cv" not in st.session_state:
20
+ st.session_state["reformatted_cv"] = None
21
+ if "bounding_boxes" not in st.session_state:
22
+ st.session_state["bounding_boxes"] = None
23
+
24
+ def main():
25
+ st.set_page_config(page_title="Resume Analyzer", layout="wide")
26
+ init_session_state()
27
+
28
+ # Title and description
29
+ st.title("πŸ“„ Resume Analyzer & Job Matcher")
30
+ st.markdown("""
31
+ Upload your resume image, extract text, and match it with job descriptions.
32
+ """)
33
+
34
+ # Create tabs
35
+ tab1, tab2, tab3 = st.tabs(["πŸ“Έ Extract Text", "πŸ“ Format Resume", "🎯 Job Matching"])
36
+
37
+ # Tab 1: Extract Text
38
+ with tab1:
39
+ col1, col2 = st.columns([1, 1])
40
+
41
+ with col1:
42
+ st.subheader("Upload Resume")
43
+ uploaded_file = st.file_uploader("Choose an image file", type=["jpg", "jpeg", "png"])
44
+
45
+ if uploaded_file:
46
+ st.session_state["uploaded_image"] = uploaded_file
47
+ st.image(uploaded_file, caption="Uploaded Image", use_column_width=True)
48
+
49
+ if st.button("πŸ“· Extract Text", type="primary"):
50
+ if st.session_state["uploaded_image"]:
51
+ with st.spinner("Processing image..."):
52
+ image_bytes = st.session_state["uploaded_image"].read()
53
+ files = {
54
+ "image": (
55
+ st.session_state["uploaded_image"].name,
56
+ image_bytes,
57
+ st.session_state["uploaded_image"].type,
58
+ )
59
+ }
60
+ data = {"threshold_confidence": 0.7, "threshold_iou": 0.7}
61
+
62
+ try:
63
+ response = requests.post(f"{BACKEND_URL}/inference", data=data, files=files)
64
+ if response.status_code == 200:
65
+ result = response.json()
66
+ # Store processed image
67
+ image_base64 = result.get("image_base64")
68
+ if image_base64:
69
+ image_data = base64.b64decode(image_base64)
70
+ image = Image.open(io.BytesIO(image_data))
71
+ st.session_state["processed_image"] = image
72
+ st.session_state["extracted_text"] = result.get("outputs")
73
+ st.success("Text extracted successfully!")
74
+ else:
75
+ st.error(f"Error: {response.text}")
76
+ except Exception as e:
77
+ st.error(f"Error: {str(e)}")
78
+ else:
79
+ st.warning("Please upload an image first.")
80
+
81
+ with col2:
82
+ if st.session_state["processed_image"]:
83
+ st.subheader("Processed Image")
84
+ st.image(st.session_state["processed_image"], caption="With Detected Text")
85
+
86
+ if st.session_state["extracted_text"]:
87
+ with st.expander("View Extracted Text", expanded=True):
88
+ st.json(st.session_state["extracted_text"])
89
+
90
+ # Tab 2: Format Resume
91
+ with tab2:
92
+ st.subheader("Format Resume")
93
+ if st.session_state["extracted_text"] is None:
94
+ st.warning("Please extract text from an image first.")
95
+ else:
96
+ if st.button("πŸ”„ Format Resume", type="primary"):
97
+ with st.spinner("Formatting resume..."):
98
+ try:
99
+ data = {"text": str(st.session_state["extracted_text"])}
100
+ response = requests.post(f"{BACKEND_URL}/reformat_output", json=data)
101
+ if response.status_code == 200:
102
+ st.session_state["reformatted_cv"] = response.json()
103
+ st.success("Resume formatted successfully!")
104
+
105
+ # Display formatted sections
106
+ col1, col2 = st.columns(2)
107
+ with col1:
108
+ with st.expander("πŸ“‹ Personal Information", expanded=True):
109
+ if "contact" in st.session_state["reformatted_cv"]:
110
+ st.write(st.session_state["reformatted_cv"]["contact"])
111
+
112
+ with st.expander("πŸ’Ό Experience", expanded=True):
113
+ if "experience" in st.session_state["reformatted_cv"]:
114
+ st.write(st.session_state["reformatted_cv"]["experience"])
115
+
116
+ with col2:
117
+ with st.expander("🎯 Skills", expanded=True):
118
+ if "skills" in st.session_state["reformatted_cv"]:
119
+ st.write(st.session_state["reformatted_cv"]["skills"])
120
+
121
+ with st.expander("🌟 Other Information", expanded=True):
122
+ if "interests" in st.session_state["reformatted_cv"]:
123
+ st.write("Interests:", st.session_state["reformatted_cv"]["interests"])
124
+ if "community" in st.session_state["reformatted_cv"]:
125
+ st.write("Community:", st.session_state["reformatted_cv"]["community"])
126
+ else:
127
+ st.error(f"Error: {response.text}")
128
+ except Exception as e:
129
+ st.error(f"Error: {str(e)}")
130
+
131
+ # Tab 3: Job Matching
132
+ with tab3:
133
+ st.subheader("Match with Job Description")
134
+
135
+ job_description = st.text_area("πŸ“ Paste Job Description", height=200)
136
+
137
+ if st.button("🎯 Match Resume", type="primary"):
138
+ if job_description:
139
+ if st.session_state["reformatted_cv"] is None:
140
+ st.warning("Formatting resume first...")
141
+ # Auto-format if not already formatted
142
+ data = {"text": str(st.session_state["extracted_text"])}
143
+ response = requests.post(f"{BACKEND_URL}/reformat_output", json=data)
144
+ if response.status_code == 200:
145
+ st.session_state["reformatted_cv"] = response.json()
146
+
147
+ # Proceed with job matching
148
+ with st.spinner("Analyzing match..."):
149
+ try:
150
+ data = {
151
+ "text": json.dumps(st.session_state["reformatted_cv"]),
152
+ "job_desciption": job_description
153
+ }
154
+ response = requests.post(f"{BACKEND_URL}/matching_job_desciption", json=data)
155
+
156
+ if response.status_code == 200:
157
+ result = response.json()
158
+
159
+ # Display match results
160
+ col1, col2 = st.columns([1, 2])
161
+ with col1:
162
+ st.metric("Match Score", f"{result['score']}%")
163
+
164
+ with col2:
165
+ st.markdown("### Match Analysis")
166
+ st.write(result["reasoning"])
167
+
168
+ with st.expander("View Detailed Analysis", expanded=False):
169
+ st.json(result)
170
+ else:
171
+ st.error(f"Error: {response.text}")
172
+ except Exception as e:
173
+ st.error(f"Error: {str(e)}")
174
+ else:
175
+ st.warning("Please enter a job description.")
176
+
177
+ if __name__ == "__main__":
178
+ main()