Spaces:
Runtime error
Runtime error
add user registration/login/SQL database
Browse files- db_utils.py +16 -0
- embedding_db.db +0 -0
- main.py +48 -6
- match_utils.py +1 -1
- requirements.txt +4 -1
- static/styles.css +13 -0
- templates/candidate_matcher.html +1 -0
- templates/find_hire.html +1 -0
- templates/find_match.html +1 -0
- templates/find_my_match.html +1 -0
- templates/job_list.html +1 -0
- templates/login.html +55 -0
- templates/register.html +54 -0
- user_utils.py +19 -0
db_utils.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sqlalchemy import create_engine
|
2 |
+
from sqlalchemy.ext.declarative import declarative_base
|
3 |
+
from sqlalchemy.orm import sessionmaker
|
4 |
+
|
5 |
+
SQLALCHEMY_DATABASE_URL = "sqlite:///./embedding_db.db"
|
6 |
+
|
7 |
+
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
|
8 |
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
9 |
+
Base = declarative_base()
|
10 |
+
|
11 |
+
def get_db():
|
12 |
+
db = SessionLocal()
|
13 |
+
try:
|
14 |
+
yield db
|
15 |
+
finally:
|
16 |
+
db.close()
|
embedding_db.db
ADDED
Binary file (12.3 kB). View file
|
|
main.py
CHANGED
@@ -7,14 +7,21 @@
|
|
7 |
# License: MIT License
|
8 |
|
9 |
# IMPORTS
|
10 |
-
from fastapi import FastAPI, Request, Form, File, UploadFile, BackgroundTasks
|
11 |
from fastapi.templating import Jinja2Templates
|
12 |
from fastapi.staticfiles import StaticFiles
|
13 |
from fastapi.responses import HTMLResponse, Response
|
|
|
14 |
import pandas as pd
|
|
|
|
|
15 |
from scrape_onet import get_onet_code, get_onet_description, get_onet_tasks
|
16 |
from match_utils import neighborhoods, get_resume, skillNER, sim_result_loop, get_links
|
17 |
-
import
|
|
|
|
|
|
|
|
|
18 |
|
19 |
# APP SETUP
|
20 |
app = FastAPI()
|
@@ -24,6 +31,43 @@ templates = Jinja2Templates(directory="templates/")
|
|
24 |
# LOAD DATA
|
25 |
onet = pd.read_csv('static/ONET_JobTitles.csv')
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
### JOB INFORMATION CENTER ###
|
28 |
# GET
|
29 |
@app.get("/")
|
@@ -61,13 +105,11 @@ def get_matches(request: Request):
|
|
61 |
# POST
|
62 |
@app.post('/find-my-match/', response_class=HTMLResponse)
|
63 |
async def post_matches(request: Request, resume: UploadFile = File(...)):
|
64 |
-
t = time.time()
|
65 |
resume = get_resume(resume)
|
66 |
skills = await skillNER(resume)
|
67 |
simResults = await sim_result_loop(resume)
|
68 |
-
links = get_links(simResults)
|
69 |
-
|
70 |
-
return templates.TemplateResponse('find_my_match.html', context={'request': request, 'resume': resume, 'skills': skills, 'simResults': simResults, 'links': links})
|
71 |
|
72 |
@app.get("/find-match/", response_class=HTMLResponse)
|
73 |
def find_match(request: Request):
|
|
|
7 |
# License: MIT License
|
8 |
|
9 |
# IMPORTS
|
10 |
+
from fastapi import FastAPI, Request, Form, File, UploadFile, BackgroundTasks, Depends
|
11 |
from fastapi.templating import Jinja2Templates
|
12 |
from fastapi.staticfiles import StaticFiles
|
13 |
from fastapi.responses import HTMLResponse, Response
|
14 |
+
from sqlalchemy.orm.session import Session
|
15 |
import pandas as pd
|
16 |
+
import time
|
17 |
+
from uuid import uuid1
|
18 |
from scrape_onet import get_onet_code, get_onet_description, get_onet_tasks
|
19 |
from match_utils import neighborhoods, get_resume, skillNER, sim_result_loop, get_links
|
20 |
+
from db_utils import get_db, Base, engine
|
21 |
+
from user_utils import DBUsers, Hash
|
22 |
+
|
23 |
+
# DB SETUP
|
24 |
+
Base.metadata.create_all(engine)
|
25 |
|
26 |
# APP SETUP
|
27 |
app = FastAPI()
|
|
|
31 |
# LOAD DATA
|
32 |
onet = pd.read_csv('static/ONET_JobTitles.csv')
|
33 |
|
34 |
+
@app.get("/register/", response_class=HTMLResponse)
|
35 |
+
def get_register(request: Request):
|
36 |
+
return templates.TemplateResponse('register.html', context={'request': request})
|
37 |
+
|
38 |
+
@app.get("/login/", response_class=HTMLResponse)
|
39 |
+
def get_login(request: Request):
|
40 |
+
return templates.TemplateResponse('login.html', context={'request': request})
|
41 |
+
|
42 |
+
@app.post('/register/', response_class=HTMLResponse)
|
43 |
+
def post_register(request: Request, username: str = Form(...), password: str = Form(...), email: str = Form(...), db: Session = Depends(get_db)):
|
44 |
+
new_user = DBUsers(id = str(uuid1()), username = username, email = email, password = Hash.bcrypt(password))
|
45 |
+
db.add(new_user)
|
46 |
+
db.commit()
|
47 |
+
db.refresh(new_user)
|
48 |
+
message = "You have registered successfully. Please log in to continue"
|
49 |
+
return templates.TemplateResponse('register.html', context={'request': request, 'message': message})
|
50 |
+
|
51 |
+
@app.post("/login/", response_class=HTMLResponse)
|
52 |
+
def post_login(request: Request, username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
|
53 |
+
un = db.query(DBUsers).filter(DBUsers.username == username).first()
|
54 |
+
pw = db.query(DBUsers).filter(DBUsers.username == username).first().password
|
55 |
+
if un and Hash.verify(password, pw) == True:
|
56 |
+
response = Response()
|
57 |
+
response.set_cookie(key="id", value=db.query(DBUsers).filter(DBUsers.username == username).first().id)
|
58 |
+
message = "You have been successfully logged in."
|
59 |
+
return templates.TemplateResponse('login.html', context={'request': request, "message": message})
|
60 |
+
else:
|
61 |
+
message = "Username or password not found. Please try again."
|
62 |
+
return templates.TemplateResponse('login.html', context={'request': request, "message": message})
|
63 |
+
|
64 |
+
@app.get("/logout/", response_class=HTMLResponse)
|
65 |
+
def get_logout(request: Request):
|
66 |
+
with open('static/log.txt', 'w') as l:
|
67 |
+
l.write('')
|
68 |
+
message = "You have been successfully logged out."
|
69 |
+
return templates.TemplateResponse('login.html', context={'request': request, "message": message})
|
70 |
+
|
71 |
### JOB INFORMATION CENTER ###
|
72 |
# GET
|
73 |
@app.get("/")
|
|
|
105 |
# POST
|
106 |
@app.post('/find-my-match/', response_class=HTMLResponse)
|
107 |
async def post_matches(request: Request, resume: UploadFile = File(...)):
|
|
|
108 |
resume = get_resume(resume)
|
109 |
skills = await skillNER(resume)
|
110 |
simResults = await sim_result_loop(resume)
|
111 |
+
links = get_links(simResults[0])
|
112 |
+
return templates.TemplateResponse('find_my_match.html', context={'request': request, 'resume': resume, 'skills': skills, 'simResults': simResults[0], 'links': links})
|
|
|
113 |
|
114 |
@app.get("/find-match/", response_class=HTMLResponse)
|
115 |
def find_match(request: Request):
|
match_utils.py
CHANGED
@@ -91,7 +91,7 @@ async def sim_result_loop(resume):
|
|
91 |
simResults.reset_index(drop=True, inplace=True)
|
92 |
for x in range(len(simResults)):
|
93 |
simResults.iloc[x,1] = format_sim(simResults.iloc[x,1])
|
94 |
-
return simResults
|
95 |
|
96 |
async def skillNER(resume):
|
97 |
def clean_my_text(text):
|
|
|
91 |
simResults.reset_index(drop=True, inplace=True)
|
92 |
for x in range(len(simResults)):
|
93 |
simResults.iloc[x,1] = format_sim(simResults.iloc[x,1])
|
94 |
+
return simResults, embeds
|
95 |
|
96 |
async def skillNER(resume):
|
97 |
def clean_my_text(text):
|
requirements.txt
CHANGED
@@ -16,4 +16,7 @@ python-dotenv==0.21.1
|
|
16 |
transformers==4.25.1
|
17 |
torch==1.13.1
|
18 |
accelerate==0.16.0
|
19 |
-
plotly-express==0.4.1
|
|
|
|
|
|
|
|
16 |
transformers==4.25.1
|
17 |
torch==1.13.1
|
18 |
accelerate==0.16.0
|
19 |
+
plotly-express==0.4.1
|
20 |
+
sqlalchemy==2.0.3
|
21 |
+
bcrypt==4.0.1
|
22 |
+
passlib==1.7.4
|
static/styles.css
CHANGED
@@ -230,6 +230,19 @@ html {
|
|
230 |
align-content: left;
|
231 |
}
|
232 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
.output__table-item {
|
234 |
font-size: 14px;
|
235 |
color: #2c2161;
|
|
|
230 |
align-content: left;
|
231 |
}
|
232 |
|
233 |
+
.form__login {
|
234 |
+
display: flex;
|
235 |
+
flex-direction: column;
|
236 |
+
justify-content: center;
|
237 |
+
align-items: center;
|
238 |
+
}
|
239 |
+
|
240 |
+
.form__login-label {
|
241 |
+
font-size: 14px;
|
242 |
+
color: #2c2161;
|
243 |
+
text-align: center;
|
244 |
+
}
|
245 |
+
|
246 |
.output__table-item {
|
247 |
font-size: 14px;
|
248 |
color: #2c2161;
|
templates/candidate_matcher.html
CHANGED
@@ -17,6 +17,7 @@
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
|
|
20 |
</ul>
|
21 |
</header>
|
22 |
<main class="main">
|
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
20 |
+
<li class="navbar__navigation-item"><a href="/login/" class="navbar__link">Login</a></li>
|
21 |
</ul>
|
22 |
</header>
|
23 |
<main class="main">
|
templates/find_hire.html
CHANGED
@@ -17,6 +17,7 @@
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
|
|
20 |
</ul>
|
21 |
</header>
|
22 |
<main class="main">
|
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
20 |
+
<li class="navbar__navigation-item"><a href="/login/" class="navbar__link">Login</a></li>
|
21 |
</ul>
|
22 |
</header>
|
23 |
<main class="main">
|
templates/find_match.html
CHANGED
@@ -17,6 +17,7 @@
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
|
|
20 |
</ul>
|
21 |
</header>
|
22 |
<main class="main">
|
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
20 |
+
<li class="navbar__navigation-item"><a href="/login/" class="navbar__link">Login</a></li>
|
21 |
</ul>
|
22 |
</header>
|
23 |
<main class="main">
|
templates/find_my_match.html
CHANGED
@@ -17,6 +17,7 @@
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
|
|
20 |
</ul>
|
21 |
</header>
|
22 |
<main class="main">
|
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
20 |
+
<li class="navbar__navigation-item"><a href="/login/" class="navbar__link">Login</a></li>
|
21 |
</ul>
|
22 |
</header>
|
23 |
<main class="main">
|
templates/job_list.html
CHANGED
@@ -17,6 +17,7 @@
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
|
|
20 |
</ul>
|
21 |
</header>
|
22 |
<main class="main">
|
|
|
17 |
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
20 |
+
<li class="navbar__navigation-item"><a href="/login/" class="navbar__link">Login</a></li>
|
21 |
</ul>
|
22 |
</header>
|
23 |
<main class="main">
|
templates/login.html
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
+
<title>Dashboard</title>
|
8 |
+
<link rel="stylesheet" href="/static/styles.css">
|
9 |
+
</head>
|
10 |
+
<body>
|
11 |
+
<header class="navbar">
|
12 |
+
<div class="navbar__brand">
|
13 |
+
<img src="/static/PF.png" class="navbar__logo" alt="Pathfinder logo" />
|
14 |
+
<a href="/" class="navbar__logo">Pathfinder</a>
|
15 |
+
</div>
|
16 |
+
<ul class="navbar__navigation">
|
17 |
+
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
+
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
+
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
20 |
+
<li class="navbar__navigation-item"><a href="/login/" class="navbar__link">Login</a></li>
|
21 |
+
</ul>
|
22 |
+
</header>
|
23 |
+
<main class="main">
|
24 |
+
<h1 class="pagetitle">User Login</h1>
|
25 |
+
<h2 class="pagesubtitle">Welcome to Pathfinder!</h2>
|
26 |
+
<h2 class="pagesubtitle">Enter your username and password below to get started</h2>
|
27 |
+
<section>
|
28 |
+
<form class="form__login" method="POST" enctype="application/x-www-form-urlencoded">
|
29 |
+
<label for="username" class="form__login-label" style="color: #2c2161">username:</label>
|
30 |
+
<input type="text" name="username" id="username" style="margin-bottom: 20px" class="form__input-field" />
|
31 |
+
<label for="password" class="form__login-label" style="color: #2c2161">password:</label>
|
32 |
+
<input type="text" name="password" id="password" class="form__input-field" />
|
33 |
+
<br>
|
34 |
+
<br>
|
35 |
+
<br>
|
36 |
+
<button type="submit" class="form__submit">Submit</button>
|
37 |
+
<br>
|
38 |
+
<button formaction="/register/" formmethod="GET" type="submit" class="form__submit">Create a new account</button>
|
39 |
+
</form>
|
40 |
+
<br>
|
41 |
+
<br>
|
42 |
+
{% if message %}
|
43 |
+
<h2 class="pagesubtitle">{{ message }}</h2>
|
44 |
+
{% endif %}
|
45 |
+
</section>
|
46 |
+
<br>
|
47 |
+
<br>
|
48 |
+
</main>
|
49 |
+
<footer class="footer">
|
50 |
+
<ul class="footer__text">
|
51 |
+
<li class="footer__text-item">© 2023 Pathfinder</li>
|
52 |
+
</ul>
|
53 |
+
</footer>
|
54 |
+
</body>
|
55 |
+
</html>
|
templates/register.html
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
+
<title>Dashboard</title>
|
8 |
+
<link rel="stylesheet" href="/static/styles.css">
|
9 |
+
</head>
|
10 |
+
<body>
|
11 |
+
<header class="navbar">
|
12 |
+
<div class="navbar__brand">
|
13 |
+
<img src="/static/PF.png" class="navbar__logo" alt="Pathfinder logo" />
|
14 |
+
<a href="/" class="navbar__logo">Pathfinder</a>
|
15 |
+
</div>
|
16 |
+
<ul class="navbar__navigation">
|
17 |
+
<li class="navbar__navigation-item"><a href="/explore-job-neighborhoods/" class="navbar__link">Explore Job Neighborhoods</a></li>
|
18 |
+
<li class="navbar__navigation-item"><a href="/find-my-match/" class="navbar__link">Find My Match</a></li>
|
19 |
+
<li class="navbar__navigation-item"><a href="/find-my-hire/" class="navbar__link">Find My Next Hire</a></li>
|
20 |
+
<li class="navbar__navigation-item"><a href="/login/" class="navbar__link">Login</a></li>
|
21 |
+
</ul>
|
22 |
+
</header>
|
23 |
+
<main class="main">
|
24 |
+
<h1 class="pagetitle">User Registration</h1>
|
25 |
+
<h2 class="pagesubtitle">Welcome to Pathfinder!</h2>
|
26 |
+
<h2 class="pagesubtitle">Fill out the form below to register for an account</h2>
|
27 |
+
<section>
|
28 |
+
<form class="form__login" method="POST">
|
29 |
+
<label for="username" class="form__login-label" style="color: #2c2161;">username:</label>
|
30 |
+
<input type="text" name="username" id="username" style="margin-bottom: 20px" class="form__input-field" />
|
31 |
+
<label for="password" class="form__login-label" style="color: #2c2161;">password:</label>
|
32 |
+
<input type="text" name="password" id="password" style="margin-bottom: 20px" class="form__input-field" />
|
33 |
+
<label for="email" class="form__login-label" style="color: #2c2161;">email:</label>
|
34 |
+
<input type="text" name="email" id="email" style="margin-bottom: 20px" class="form__input-field" />
|
35 |
+
<br>
|
36 |
+
<br>
|
37 |
+
<button type="submit" class="form__submit">Submit</button>
|
38 |
+
</form>
|
39 |
+
<br>
|
40 |
+
<br>
|
41 |
+
{% if message %}
|
42 |
+
<h2 class="pagesubtitle">{{ message }}</h2>
|
43 |
+
{% endif %}
|
44 |
+
<br>
|
45 |
+
<br>
|
46 |
+
</section>
|
47 |
+
</main>
|
48 |
+
<footer class="footer">
|
49 |
+
<ul class="footer__text">
|
50 |
+
<li class="footer__text-item">© 2023 Pathfinder</li>
|
51 |
+
</ul>
|
52 |
+
</footer>
|
53 |
+
</body>
|
54 |
+
</html>
|
user_utils.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from db_utils import Base
|
2 |
+
from sqlalchemy import Column, String
|
3 |
+
from passlib.context import CryptContext
|
4 |
+
|
5 |
+
pwd_cxt = CryptContext(schemes=['bcrypt'], deprecated="auto")
|
6 |
+
|
7 |
+
class Hash():
|
8 |
+
def bcrypt(password: str):
|
9 |
+
return pwd_cxt.hash(password)
|
10 |
+
|
11 |
+
def verify(plain_password: str, hashed_password: str):
|
12 |
+
return pwd_cxt.verify(plain_password, hashed_password)
|
13 |
+
|
14 |
+
class DBUsers(Base):
|
15 |
+
__tablename__ = 'users'
|
16 |
+
id = Column(String, primary_key=True)
|
17 |
+
username = Column(String)
|
18 |
+
password = Column(String)
|
19 |
+
email = Column(String)
|