celise88/Pathfinder
3
1# Author: Caitlin Blackmore2# Project: Pathfinder3# Project Description: This is a web application designed to facilitate job-mobility. 4# It uses NLP to help job seekers find jobs that match their skills and interests.5# Date: 2023-02-036# File Description: This is the main file, containing the FastAPI app and all the endpoints.7# License: MIT License8 9# IMPORTS10from fastapi import FastAPI, Request, Form, File, UploadFile, BackgroundTasks11from fastapi.templating import Jinja2Templates12from fastapi.staticfiles import StaticFiles13from fastapi.responses import HTMLResponse14import pandas as pd15from uuid import uuid116from mangum import Mangum17from localStoragePy import localStoragePy18localStorage = localStoragePy('pathfinder', 'text')19 20from scrape_onet import get_onet_code, get_onet_description, get_onet_tasks, get_onet_activities, get_onet_abilities, get_onet_interests, get_onet_knowledge, get_onet_context, get_onet_skills, get_onet_styles, get_onet_values, get_job_postings21from match_utils import neighborhoods, get_resume, skill_extractor, sim_result_loop, get_links, skillEmbed, sim_result_loop_jobFinder, sim_result_loop_candFinder22from user_utils import Hash23 24# APP SETUP25app = FastAPI()26handler = Mangum(app)27app.mount("/static", StaticFiles(directory='static'), name="static")28templates = Jinja2Templates(directory="templates/")29 30# LOAD DATA31onet = pd.read_csv('static/ONET_JobTitles.csv')32 33# REGISTER, LOGIN, LOGOUT34@app.get("/register/", response_class=HTMLResponse)35def get_register(request: Request):36 return templates.TemplateResponse('register.html', context={'request': request})37 38@app.get("/login/", response_class=HTMLResponse)39def get_login(request: Request):40 return templates.TemplateResponse('login.html', context={'request': request})41 42@app.post('/register/', response_class=HTMLResponse)43def post_register(request: Request, username: str = Form(...), password: str = Form(...), email: str = Form(...), account_type: str = Form(...)):44 if account_type == "candidate":45 db = pd.read_csv('static/res_embeddings.csv')46 else:47 db = pd.read_csv('static/jd_embeddings.csv')48 if username not in db['username'] and email not in db['email']:49 new_row = len(db.index)+150 db.loc[new_row, 'id'] = uuid1()51 db.loc[new_row, 'username'] = username52 db.loc[new_row, 'password'] = Hash.bcrypt(password)53 db.loc[new_row, 'email'] = email54 db.loc[new_row, 'account_type'] = account_type55 message = "You have registered successfully. Please log in to continue"56 if account_type == "candidate":57 db.to_csv('static/res_embeddings.csv', index=False)58 else:59 db.to_csv('static/jd_embeddings.csv', index=False)60 return templates.TemplateResponse('register.html', context={'request': request, 'message': message})61 elif email in db['email']:62 message = "That email address has already been registered. Please try again."63 return templates.TemplateResponse('register.html', context={'request': request, 'message': message})64 elif username in db['username']:65 message = "That username has already been taken. Please select another."66 return templates.TemplateResponse('register.html', context={'request': request, 'message': message})67 68@app.post("/login/", response_class=HTMLResponse)69def post_login(request: Request, username: str = Form(...), password: str = Form(...)):70 71 pd.set_option('display.max_colwidth', 100)72 dbres = pd.read_csv('static/res_embeddings.csv')73 dbjd = pd.read_csv('static/jd_embeddings.csv')74 75 if username in list(dbres['username']):76 pw = dbres.loc[dbres['username'] == username,'password'].to_string()77 pw = pw.split(' ')[4]78 if Hash.verify(password, pw) == True:79 un = dbres.loc[dbres['username'] == username,'username'].to_string().split(' ')[4]80 localStorage.setItem('username', un)81 print(localStorage.getItem('username'))82 message = "You have been successfully logged in."83 else:84 message = "Username or password not found. Please try again."85 elif username in list(dbjd['username']):86 pw = dbjd.loc[dbjd['username'] == username,'password'].to_string()87 pw = pw.split(' ')[4]88 if Hash.verify(password, pw) == True:89 un = dbjd.loc[dbjd['username'] == username,'username'].to_string().split(' ')[4]90 localStorage.setItem('username', un)91 print(localStorage.getItem('username'))92 message = "You have been successfully logged in."93 else:94 message = "Username or password not found. Please try again."95 else:96 message = "Username or password not found. Please try again."97 return templates.TemplateResponse('login.html', context={'request': request, "message": message})98 99@app.get("/logout/", response_class=HTMLResponse)100def get_logout(request: Request):101 return templates.TemplateResponse('logout.html', context={'request': request})102 103@app.post("/logout/", response_class=HTMLResponse)104def post_logout(request: Request):105 localStorage.clear()106 print(localStorage.getItem('username'))107 message = "You have been successfully logged out."108 return templates.TemplateResponse('logout.html', context={'request': request, 'message': message})109 110 111### JOB INFORMATION CENTER ###112# GET113@app.get("/")114def get_job(request: Request, bt: BackgroundTasks):115 joblist = onet['JobTitle']116 bt.add_task(neighborhoods)117 return templates.TemplateResponse('job_list.html', context={'request': request, 'joblist': joblist})118 119# POST120@app.post("/")121def post_job(request: Request, bt: BackgroundTasks, jobtitle: str = Form(enum=[x for x in onet['JobTitle']])):122 joblist = onet['JobTitle']123 if jobtitle: 124 onetCode = get_onet_code(jobtitle)125 jobdescription = get_onet_description(onetCode)126 tasks = get_onet_tasks(onetCode)127 activities = get_onet_activities(onetCode)128 conditions = get_onet_context(onetCode)129 skills = get_onet_skills(onetCode)130 knowledge = get_onet_knowledge(onetCode)131 abilities = get_onet_abilities(onetCode)132 interests = get_onet_interests(onetCode)133 values = get_onet_values(onetCode)134 styles = get_onet_styles(onetCode)135 136 return templates.TemplateResponse('job_list.html', context={137 'request': request, 138 'joblist': joblist, 139 'jobtitle': jobtitle, 140 'jobdescription': jobdescription, 141 'tasks': tasks, 142 'activities': activities, 143 'conditions': conditions,144 'knowledge': knowledge,145 'abilities': abilities,146 'skills': skills,147 'interests': interests,148 'values': values, 149 'styles': styles150 })151 152### JOB NEIGHBORHOODS ###153@app.get("/explore-job-neighborhoods/", response_class=HTMLResponse)154async def get_job_neighborhoods(request: Request):155 return templates.TemplateResponse('job_neighborhoods.html', context={'request': request})156 157 158### FIND-MY-MATCH ###159# GET160@app.get("/find-my-match/", response_class=HTMLResponse)161def get_matches(request: Request):162 return templates.TemplateResponse('find_my_match.html', context={'request': request})163 164# POST165@app.post('/find-my-match/', response_class=HTMLResponse)166async def post_matches(request: Request, bt: BackgroundTasks, resume: UploadFile = File(...)):167 168 statelist = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',169 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',170 'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',171 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',172 'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']173 174 username = localStorage.getItem('username')175 176 def add_data_to_db(skills):177 db = pd.read_csv('static/res_embeddings.csv')178 embeds = format(skillEmbed(skills)).replace('[[','').replace(']]','').replace('[','').replace(']','').split(',')179 db.iloc[db['username']== username,5:] = embeds180 db.to_csv('static/res_embeddings.csv', index=False)181 182 def get_jobs_from_db(skills):183 job_matches = sim_result_loop_jobFinder(skills)184 print(job_matches)185 186 resume = get_resume(resume)187 skills = skill_extractor(resume)188 simResults = await sim_result_loop(skills)189 links = get_links(simResults[0])190 191 if username is not None:192 bt.add_task(add_data_to_db, skills)193 bt.add_task(get_jobs_from_db, skills)194 195 return templates.TemplateResponse('find_my_match.html', context={'request': request, 'resume': resume, 'skills': skills, 'simResults': simResults[0], 'links': links, 'statelist': statelist})196 197@app.get("/find-match/", response_class=HTMLResponse)198def find_match(request: Request):199 jobtitle = str(request.url).split("=")[1].replace('HTTP/1.1', '').replace("-", " ").replace("%2C", "").replace('&state', '')200 state = str(request.url).split("=")[2]201 onetCode = get_onet_code(jobtitle)202 postings = get_job_postings(onetCode, state)203 jobpostings = postings[0]204 linklist = postings[1]205 return templates.TemplateResponse('find_match.html', context={'request': request, 'jobpostings': jobpostings, 'linklist': linklist, 'jobtitle': jobtitle, 'state': state})206 207@app.get("/find-my-hire/", response_class=HTMLResponse)208def get_hires(request: Request):209 return templates.TemplateResponse('candidate_matcher.html', context={'request': request})210 211# POST212@app.post('/find-my-hire/', response_class=HTMLResponse)213async def post_matches(request: Request, bt: BackgroundTasks, jobdesc: UploadFile = File(...)):214 215 username = localStorage.getItem('username')216 217 def add_data_to_db(skills):218 db = pd.read_csv('static/jd_embeddings.csv')219 embeds = format(skillEmbed(skills)).replace('[[','').replace(']]','').split(',')220 db.iloc[db['username']== username,5:] = embeds221 db.to_csv('static/jd_embeddings.csv', index=False)222 223 def get_cand_from_db(skills):224 cand_matches = sim_result_loop_candFinder(skills)225 print(cand_matches)226 227 jobdesc = get_resume(jobdesc)228 skills = skill_extractor(jobdesc)229 simResults = await sim_result_loop(skills)230 links = get_links(simResults[0])231 232 if username is not None:233 bt.add_task(add_data_to_db, skills)234 bt.add_task(get_cand_from_db, skills)235 236 return templates.TemplateResponse('candidate_matcher.html', context={'request': request, 'jobdesc': jobdesc, 'skills': skills, 'simResults': simResults[0], 'links': links})237 238@app.get("/find-hire/", response_class=HTMLResponse)239def find_hire(request: Request):240 jobselection = str(request.url).split("=")[1].replace('HTTP/1.1', '').replace("-", " ").replace("%2C", "")241 print(jobselection)242 return templates.TemplateResponse('find_hire.html', context={'request': request, 'jobselection': jobselection})243 244@app.get("/find-job/", response_class=HTMLResponse)245def find_job(request: Request):246 pass