Skip to content

Commit 6140e0b

Browse files
committed
database
1 parent 9eaf88b commit 6140e0b

File tree

7 files changed

+151
-60
lines changed

7 files changed

+151
-60
lines changed

.vscode/settings.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,13 @@
2828
"editor.defaultFormatter": "ms-azuretools.vscode-docker"
2929
},
3030
"python.autoComplete.extraPaths": ["./server"],
31-
"python.analysis.extraPaths": ["./server"]
31+
"python.analysis.extraPaths": ["./server"],
32+
"files.associations": {
33+
".env*": "dotenv"
34+
},
35+
"github.copilot.enable": {
36+
"*": true,
37+
// ...
38+
"dotenv": false
39+
}
3240
}

server/api.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
jwt = JWTManager(app)
3434

3535

36+
@app.before_first_request
37+
def my_func():
38+
print("before first request")
39+
40+
3641
api.add_resource(GetFeatures, "/api/features")
3742
api.add_resource(
3843
RunAssistant, "/api/run_assistant", resource_class_kwargs={"socketio": socketio}

server/controllers/email_client.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import os
2+
import boto3
3+
from email.mime.multipart import MIMEMultipart
4+
from email.mime.text import MIMEText
5+
from email.mime.application import MIMEApplication
6+
from dotenv import load_dotenv
7+
8+
load_dotenv()
9+
10+
11+
def send_ses_email(
12+
subject, body_text, body_html, sender_email, recipient_emails, attachment=None
13+
):
14+
# Create a multipart/mixed parent container
15+
msg = MIMEMultipart("mixed")
16+
msg["Subject"] = subject
17+
msg["From"] = sender_email
18+
msg["To"] = ", ".join(recipient_emails)
19+
20+
# Add body to email
21+
msg_body = MIMEMultipart("alternative")
22+
textpart = MIMEText(body_text.encode("utf-8"), "plain", "utf-8")
23+
htmlpart = MIMEText(body_html.encode("utf-8"), "html", "utf-8")
24+
25+
msg_body.attach(textpart)
26+
msg_body.attach(htmlpart)
27+
msg.attach(msg_body)
28+
29+
# Attachment
30+
if attachment:
31+
with open(attachment, "rb") as f:
32+
part = MIMEApplication(f.read())
33+
part.add_header(
34+
"Content-Disposition",
35+
"attachment",
36+
filename=os.path.basename(attachment),
37+
)
38+
msg.attach(part)
39+
40+
# Connect to AWS SES
41+
client = boto3.client(
42+
"ses",
43+
aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
44+
aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
45+
region_name=os.getenv("AWS_REGION"),
46+
)
47+
48+
# Try to send the email.
49+
try:
50+
response = client.send_raw_email(
51+
Source=sender_email,
52+
Destinations=recipient_emails,
53+
RawMessage={"Data": msg.as_string()},
54+
)
55+
except Exception as e:
56+
print(e)
57+
return False
58+
return True
59+
60+
61+
if __name__ == "__main__":
62+
63+
subject = "Your magic link to log in to Atlas"
64+
body_text = "Content of your email."
65+
body_html = """<html>
66+
<head></head>
67+
<body>
68+
<h1>Welcome to Atlas!</h1>
69+
<p>Click <a href='https://atlas.scaledhumanity.org'>here</a> to log in</p>
70+
</body>
71+
</html>"""
72+
sender_email = "[email protected]"
73+
recipient_emails = ["[email protected]"]
74+
75+
# Send the email
76+
send_ses_email(subject, body_text, body_html, sender_email, recipient_emails)

server/db/database.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import asyncio
2+
import os
3+
from dotenv import load_dotenv
4+
from beanie import init_beanie
5+
from motor.motor_asyncio import AsyncIOMotorClient
6+
7+
from models.users import User
8+
9+
10+
load_dotenv()
11+
12+
13+
# Call this from within your event loop to get beanie setup.
14+
async def init_db():
15+
# Create Motor client
16+
client = AsyncIOMotorClient(os.getenv("DB_URI"))
17+
18+
# Init beanie with the Product document class
19+
await init_beanie(database=client.atlas_main, document_models=[User])
20+
21+
22+
async def main():
23+
await init_db()
24+
us = User(
25+
26+
magic_link="1234",
27+
magic_link_expiration="2021-01-01",
28+
number_of_tokens=5,
29+
)
30+
31+
await us.create()
32+
33+
34+
if __name__ == "__main__":
35+
asyncio.run(main())

server/db/db.py

Lines changed: 0 additions & 59 deletions
This file was deleted.

server/db/models/users.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from datetime import datetime
2+
from typing import Optional
3+
from beanie import Document
4+
from beanie.operators import *
5+
6+
7+
class User(Document):
8+
email: str
9+
magic_link: str
10+
magic_link_expiration: datetime
11+
number_of_tokens: Optional[int]
12+
created_at: datetime = datetime.now()
13+
updated_at: datetime = datetime.now()
14+
15+
class Settings:
16+
name = "users"

server/requirements.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
aniso8601==9.0.1
22
annotated-types==0.7.0
33
anyio==4.4.0
4+
beanie==1.26.0
45
bidict==0.23.1
56
blinker==1.8.2
7+
boto3==1.34.143
8+
botocore==1.34.143
69
certifi==2024.7.4
710
click==8.1.7
811
distro==1.9.0
@@ -18,20 +21,27 @@ httpx==0.27.0
1821
idna==3.7
1922
itsdangerous==2.2.0
2023
Jinja2==3.1.4
24+
jmespath==1.0.1
25+
lazy-model==0.2.0
2126
MarkupSafe==2.1.5
27+
motor==3.5.1
2228
openai==1.35.6
2329
pydantic==2.7.4
2430
pydantic_core==2.18.4
2531
PyJWT==2.8.0
2632
pymongo==4.8.0
33+
python-dateutil==2.9.0.post0
2734
python-dotenv==1.0.1
2835
python-engineio==4.9.1
2936
python-socketio==5.11.3
3037
pytz==2024.1
38+
s3transfer==0.10.2
3139
simple-websocket==1.0.0
3240
six==1.16.0
3341
sniffio==1.3.1
42+
toml==0.10.2
3443
tqdm==4.66.4
3544
typing_extensions==4.12.2
45+
urllib3==2.2.2
3646
Werkzeug==3.0.3
3747
wsproto==1.2.0

0 commit comments

Comments
 (0)