-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackend.py
More file actions
244 lines (189 loc) · 7.62 KB
/
backend.py
File metadata and controls
244 lines (189 loc) · 7.62 KB
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# Importing AWS SDK for Python and other helper libraries
import os
import boto3
import json
from random import randint
from decimal import Decimal
from boto3.dynamodb.conditions import Key
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from fastapi.responses import JSONResponse
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
from botocore.exceptions import NoCredentialsError, ClientError
app = FastAPI()
origins = [
"http://10.182.149.211:8000",
"https://10.182.149.211:8000",
"exp://10.182.149.211:8000", # This is for Expo
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Keeping resources ready for use inside FastAPI functions
dynamoDB = boto3.resource('dynamodb')
s3 = boto3.client('s3')
# Defining Classes for proper reading of JSON input from incoming React Native requests
class LoginCredential(BaseModel):
email: str
password: str
class SignUpCredential(BaseModel):
email: str
password: str
firstName: str
lastName: str
city: str
state: str
zipCode: int
country: str
phone_number: int
bio: str
user_type: str
class UserEmail(BaseModel):
email: str
# Verify Login Credential Validity
@app.post('/login')
async def receive_data(credential: LoginCredential):
# Process the data
table = dynamoDB.Table('Users')
query_key = 'email'
query_value = credential.email
key_condition_expression = Key(query_key).eq(query_value)
# Execute the query
response = table.query(
KeyConditionExpression=key_condition_expression
)
# Process the results to check for password
if len(response['Items']) > 0:
if credential.password == response['Items'][0]['password']:
return JSONResponse(content=True, status_code=200)
return JSONResponse(content=False, status_code=400)
# Add Sign Up details to DynamoDB
@app.post('/signup')
async def signup(credential: SignUpCredential):
table = dynamoDB.Table('Users')
item = {
'email': credential.email, #already applied toLower() in frontend
'password': credential.password,
'firstname': credential.firstName,
'lastname': credential.lastName,
'city': credential.city,
'state': credential.state,
'zipcode': credential.zipCode,
'country': credential.country,
'phone': credential.phone_number,
'bio': credential.bio,
'Type': credential.user_type
}
try:
# Only put item into table if the partition (primary) does not already have an associated entry
response = table.put_item(Item=item)
except Exception as e:
return JSONResponse(content= str(e), status_code=400)
return JSONResponse(content= "Successfully Signed Up!", status_code= 200)
# Check if Email already exists in `Users` table
@app.post('/verify_email_dne')
def verify_email_dne(user: UserEmail):
table = dynamoDB.Table('Users')
item = {'email': user.email}
try:
response = table.put_item(Item=item, ConditionExpression= 'attribute_not_exists(email)')
except Exception as e:
if "ConditionalCheckFailedException" in str(e):
return JSONResponse(content= "Email already exists, navigate to sign in", status_code=400)
else:
return JSONResponse(content= str(e), status_code=400)
return JSONResponse(content= "Email does not exist in records", status_code=200)
# Handle Delete User Request
@app.post('/delete_user')
async def delete(user: UserEmail):
primary_key = {'email': user.email}
try:
response = table.delete_item(
Key = primary_key
)
except Exception as e:
print(f'DynamoDB Error: {e}')
return JSONResponse(content=False, status_code=400)
return JSONResponse(content)
# Generate Confirmation Code during Sign Up/ Forgot Password
@app.post('/confirmation_code')
async def generate_confirmation_code(user: UserEmail):
with open("confirmation_email.html", 'r') as html:
confirmation_email_content = html.read()
CONFIRMATION_CODE = randint(12345, 98765)
# Substitute in the actual confirmation code into the HTML file
confirmation_email_content = confirmation_email_content.replace("{{CONFIRMATION_CODE}}", str(CONFIRMATION_CODE))
message = Mail(
from_email= 'syndicatesquad9@gmail.com',
to_emails= user.email,
subject= 'Syndicate - Confirmation Email',
html_content= confirmation_email_content)
try:
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
except Exception as e:
return JSONResponse(content=f'Error: {e}', status_code=400)
return JSONResponse(content= str(CONFIRMATION_CODE), status_code=200)
@app.post('/uploadToDeveloper')
async def upload_to_s3(user_email: str, file: UploadFile = File(...)):
try:
bucket_name = 'developerimages'
response = upload_to_user_folder(bucket_name, user_email, file.file, file.filename, file.content_type)
return JSONResponse(content={"message": response})
except NoCredentialsError:
raise HTTPException(status_code=401, detail='AWS credentials not found or invalid')
except ClientError as e:
raise HTTPException(status_code=400, detail=f'AWS Client Error: {e}')
except Exception as e:
raise HTTPException(status_code=500, detail=f'Server Error: {e}')
# @app.post('/uploadToInvestor')
# async def upload_to_s3(file: UploadFile = File(...)):
# try:
# bucket_name = 'investorimages'
# s3.Bucket(bucket_name).upload_fileobj(
# file.file,
# file.filename,
# ExtraArgs={"ContentType": file.content_type}
# )
# return JSONResponse(content={"message": "Successfully uploaded"})
# except NoCredentialsError:
# raise HTTPException(status_code=401, detail='AWS credentials not found or invalid')
# except ClientError as e:
# raise HTTPException(status_code=400, detail=f'AWS Client Error: {e}')
# except Exception as e:
# raise HTTPException(status_code=500, detail=f'Server Error: {e}')
def folder_exists(bucket_name, folder_name):
response = s3.list_objects_v2(Bucket=bucket_name, Prefix=folder_name)
return 'Contents' in response
def upload_to_user_folder(bucket_name, user_email, file_obj, file_name, content_type):
folder_name = user_email + '/' # Folder name is the user's email
if not folder_exists(bucket_name, folder_name):
print(f"Creating folder for {user_email}")
full_file_path = f"{folder_name}{file_name}"
try:
s3.upload_fileobj(
file_obj,
bucket_name,
full_file_path,
ExtraArgs={"ContentType": content_type}
)
return "File uploaded successfully."
except Exception as e:
return str(e)
# # Receive the Investor's (User's) email id, get the preferences, sort ALL property listings based on preferences, return order of properties by ID
# @app.post('/property_swipe_list')
# async def get_property_swipe_list(investor: UserEmail):
# # get minimum investment preference of the investor
# key_condition_expression = Key('Email').eq(email)
# table = dynamoDB.Table('Investor')
# response = table.query(
# KeyConditionExpression=key_condition_expression
# )
# min_investment = response['Items'][0]['Min_Investment']
# # sort property listings by min investment asc and return