-
Notifications
You must be signed in to change notification settings - Fork 4
/
database.py
98 lines (78 loc) · 3.03 KB
/
database.py
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
from decouple import config
from fastapi import HTTPException
from typing import Union
import motor.motor_asyncio
from bson import ObjectId
from auth_utils import AuthJwtCsrf
import asyncio
MONGO_API_KEY = config('MONGO_API_KEY')
client = motor.motor_asyncio.AsyncIOMotorClient(MONGO_API_KEY)
client.get_io_loop = asyncio.get_event_loop
database = client.API_DB
collection_todo = database.todo
collection_user = database.user
auth = AuthJwtCsrf()
def todo_serializer(todo) -> dict:
return {
"id": str(todo["_id"]),
"title": todo["title"],
"description": todo["description"]
}
def user_serializer(user) -> dict:
return {
"id": str(user["_id"]),
"email": user["email"],
}
async def db_create_todo(data: dict) -> Union[dict, bool]:
todo = await collection_todo.insert_one(data)
new_todo = await collection_todo.find_one({"_id": todo.inserted_id})
if new_todo:
return todo_serializer(new_todo)
return False
async def db_get_todos() -> list:
todos = []
for todo in await collection_todo.find().to_list(length=100):
todos.append(todo_serializer(todo))
return todos
async def db_get_single_todo(id: str) -> Union[dict, bool]:
todo = await collection_todo.find_one({"_id": ObjectId(id)})
if todo:
return todo_serializer(todo)
return False
async def db_update_todo(id: str, data: dict) -> Union[dict, bool]:
todo = await collection_todo.find_one({"_id": ObjectId(id)})
if todo:
updated_todo = await collection_todo.update_one(
{"_id": ObjectId(id)}, {"$set": data}
)
if (updated_todo.modified_count > 0):
new_todo = await collection_todo.find_one({"_id": ObjectId(id)})
return todo_serializer(new_todo)
return False
async def db_delete_todo(id: str) -> bool:
todo = await collection_todo.find_one({"_id": ObjectId(id)})
if todo:
deleted_todo = await collection_todo.delete_one({"_id": ObjectId(id)})
if (deleted_todo.deleted_count > 0):
return True
return False
async def db_signup(data: dict) -> dict:
email = data.get("email")
password = data.get("password")
overlap_user = await collection_user.find_one({"email": email})
if overlap_user:
raise HTTPException(status_code=400, detail='Email is already taken')
if not password or len(password) < 6:
raise HTTPException(status_code=400, detail='Password too short')
user = await collection_user.insert_one({"email": email, "password": auth.generate_hashed_pw(password)})
new_user = await collection_user.find_one({"_id": user.inserted_id})
return user_serializer(new_user)
async def db_login(data: dict) -> str:
email = data.get("email")
password = data.get("password")
user = await collection_user.find_one({"email": email})
if not user or not auth.verify_pw(password, user["password"]):
raise HTTPException(
status_code=401, detail='Invalid email or password')
token = auth.encode_jwt(user['email'])
return token