File size: 6,342 Bytes
e1f9362
 
 
 
 
 
 
 
 
2b80df9
7420aeb
 
0726b70
2b80df9
7420aeb
2b80df9
 
9b3b1bc
2f1b978
2b80df9
 
 
 
 
020b94a
e1f9362
7420aeb
 
 
 
e1f9362
7420aeb
e1f9362
2b80df9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e1f9362
 
7420aeb
8de44db
7420aeb
 
 
e1f9362
7420aeb
8de44db
7420aeb
 
9b3b1bc
 
 
8de44db
7420aeb
 
 
 
 
 
 
e1f9362
7420aeb
8de44db
e54baff
7420aeb
e1f9362
 
591ae97
8de44db
b2bedce
7420aeb
e1f9362
591ae97
8de44db
9b3b1bc
 
793cdd0
2b80df9
 
d61cc16
 
 
0726b70
 
 
2f1b978
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0726b70
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Author: Caitlin Blackmore
# Project: Pathfinder
# Project Description: This is a web application designed to facilitate job-mobility. 
# It uses NLP to help job seekers find jobs that match their skills and interests.
# Date: 2023-02-03
# File Description: This is the main file, containing the FastAPI app and all the endpoints.
# License: MIT License

# IMPORTS
from fastapi import FastAPI, Request, Form, File, UploadFile, BackgroundTasks, Depends
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, Response
from sqlalchemy.orm.session import Session
import pandas as pd
import time
from uuid import uuid1
from scrape_onet import get_onet_code, get_onet_description, get_onet_tasks
from match_utils import neighborhoods, get_resume, skillNER, sim_result_loop, get_links
from db_utils import get_db, Base, engine
from user_utils import DBUsers, Hash

# DB SETUP
Base.metadata.create_all(engine)

# APP SETUP
app = FastAPI()
app.mount("/static", StaticFiles(directory='static'), name="static")
templates = Jinja2Templates(directory="templates/")

# LOAD DATA
onet = pd.read_csv('static/ONET_JobTitles.csv')

@app.get("/register/", response_class=HTMLResponse)
def get_register(request: Request):
    return templates.TemplateResponse('register.html', context={'request': request})

@app.get("/login/", response_class=HTMLResponse)
def get_login(request: Request):
    return templates.TemplateResponse('login.html', context={'request': request})

@app.post('/register/', response_class=HTMLResponse)
def post_register(request: Request, username: str = Form(...), password: str = Form(...), email: str = Form(...), db: Session = Depends(get_db)):
    new_user = DBUsers(id = str(uuid1()), username = username, email = email, password = Hash.bcrypt(password))
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    message = "You have registered successfully. Please log in to continue"
    return templates.TemplateResponse('register.html', context={'request': request, 'message': message})

@app.post("/login/", response_class=HTMLResponse)
def post_login(request: Request, username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
    un = db.query(DBUsers).filter(DBUsers.username == username).first()
    pw = db.query(DBUsers).filter(DBUsers.username == username).first().password
    if un and Hash.verify(password, pw) == True:
        response = Response()
        response.set_cookie(key="id", value=db.query(DBUsers).filter(DBUsers.username == username).first().id)
        message = "You have been successfully logged in."
        return templates.TemplateResponse('login.html', context={'request': request, "message": message})
    else:
        message = "Username or password not found. Please try again."
        return templates.TemplateResponse('login.html', context={'request': request, "message": message})

@app.get("/logout/", response_class=HTMLResponse)
def get_logout(request: Request):
    with open('static/log.txt', 'w') as l:
        l.write('')
    message = "You have been successfully logged out."
    return templates.TemplateResponse('login.html', context={'request': request, "message": message})

### JOB INFORMATION CENTER ###
# GET
@app.get("/")
def get_job(request: Request):
    joblist = onet['JobTitle']
    return templates.TemplateResponse('job_list.html', context={'request': request, 'joblist': joblist})

# POST
@app.post("/")
def post_job(request: Request, bt: BackgroundTasks, jobtitle: str = Form(enum=[x for x in onet['JobTitle']])):
    joblist = onet['JobTitle']
    if jobtitle: 
        onetCode = get_onet_code(jobtitle)
        jobdescription = get_onet_description(onetCode)
        tasks = get_onet_tasks(onetCode)
        bt.add_task(neighborhoods, jobtitle)
        return templates.TemplateResponse('job_list.html', context={
            'request': request, 
            'joblist': joblist, 
            'jobtitle': jobtitle, 
            'jobdescription': jobdescription, 
            'tasks': tasks})

### JOB NEIGHBORHOODS ###
@app.get("/explore-job-neighborhoods/", response_class=HTMLResponse)
async def get_job_neighborhoods(request: Request):
    return templates.TemplateResponse('job_neighborhoods.html', context={'request': request})

### FIND-MY-MATCH ###
# GET
@app.get("/find-my-match/", response_class=HTMLResponse)
def get_matches(request: Request):
    return templates.TemplateResponse('find_my_match.html', context={'request': request})

# POST
@app.post('/find-my-match/', response_class=HTMLResponse)
async def post_matches(request: Request, resume: UploadFile = File(...)):
    resume = get_resume(resume)
    skills = await skillNER(resume)
    simResults = await sim_result_loop(resume)
    links = get_links(simResults[0])
    return templates.TemplateResponse('find_my_match.html', context={'request': request, 'resume': resume, 'skills': skills, 'simResults': simResults[0], 'links': links})

@app.get("/find-match/", response_class=HTMLResponse)
def find_match(request: Request):
    jobselection = str(request.url).split("=")[1].replace('HTTP/1.1', '').replace("-", " ")
    print(jobselection)
    return templates.TemplateResponse('find_match.html', context={'request': request, 'jobselection': jobselection})

@app.get("/find-my-hire/", response_class=HTMLResponse)
def get_hires(request: Request):
    return templates.TemplateResponse('candidate_matcher.html', context={'request': request})

# POST
@app.post('/find-my-hire/', response_class=HTMLResponse)
async def post_matches(request: Request, jobdesc: UploadFile = File(...)):
    t = time.time()
    jobdesc = get_resume(jobdesc)
    skills = await skillNER(jobdesc)
    simResults = await sim_result_loop(jobdesc)
    links = get_links(simResults)
    print(time.time() - t)
    return templates.TemplateResponse('candidate_matcher.html', context={'request': request, 'jobdesc': jobdesc, 'skills': skills, 'simResults': simResults, 'links': links})

@app.get("/find-hire/", response_class=HTMLResponse)
def find_hire(request: Request):
    jobselection = str(request.url).split("=")[1].replace('HTTP/1.1', '').replace("-", " ")
    print(jobselection)
    return templates.TemplateResponse('find_hire.html', context={'request': request, 'jobselection': jobselection})