Skip to content

Commit

Permalink
Refactor environment variable loading using pydantic-settings
Browse files Browse the repository at this point in the history
  • Loading branch information
K-dash committed May 29, 2024
1 parent ca16e7a commit c2f5bf5
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 37 deletions.
13 changes: 7 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
PORT=8000
IP_ADDRESS="localhost"
SMTP_SERVER ='smtp.gmail.com'
EMAIL=your-email
EMAIL_PW=email-password
EMAIL_RECEIVER=email-to-receive-surf-report
COMMAND=localhost:8000
SUBJECT='Surf Report'
SMTP_SERVER="smtp.gmail.com"
SMTP_PORT=587
EMAIL="your-email"
EMAIL_PW="email-password"
EMAIL_RECEIVER="email-to-receive-surf-report"
COMMAND="localhost:8000"
SUBJECT="Surf Report"
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ python-dotenv==1.0.1
Requests==2.32.2
requests_cache==1.2.0
retry_requests==2.0.0
pydantic==2.7.1
pydantic-settings==2.2.1
email-validator==2.1.1
4 changes: 2 additions & 2 deletions src/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
Main module
"""

import os
import sys
from pathlib import Path

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(str(Path(__file__).parent.parent))

from src import api, helper

Expand Down
34 changes: 11 additions & 23 deletions src/send_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,29 @@
Module to send surf report emails
"""

import os
import smtplib
import subprocess
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

from dotenv import load_dotenv
from settings import EmailSettings

# Load environment variables from .env file
load_dotenv(override=True)

# Email server configuration
SMTP_SERVER = os.getenv("SMTP_SERVER")
PORT = 587 # Port for TLS connection

# Sender's email credentials
SENDER_EMAIL = os.getenv("EMAIL")
PASSWORD = os.getenv("EMAIL_PW")

# Receiver's email
RECEIVER_EMAIL = os.getenv("EMAIL_RECEIVER")
env = EmailSettings()

# Create a multipart message and set headers
message = MIMEMultipart()
message["From"] = SENDER_EMAIL
message["To"] = RECEIVER_EMAIL
message["Subject"] = os.getenv("SUBJECT")
message["From"] = env.EMAIL
message["To"] = env.EMAIL_RECEIVER
message["Subject"] = env.SUBJECT


def send_user_email():
"""
Sends user an email
"""
SURF = subprocess.run(
["curl", os.getenv("COMMAND")],
["curl", env.COMMAND],
capture_output=True,
text=True,
check=True,
Expand All @@ -48,12 +36,12 @@ def send_user_email():
message.attach(MIMEText(BODY, "plain"))

# Connect to the SMTP server
with smtplib.SMTP(SMTP_SERVER, PORT) as server:
with smtplib.SMTP(env.SMTP_SERVER, env.SMTP_PORT) as server:
server.starttls() # Secure the connection
server.login(SENDER_EMAIL, PASSWORD)
server.login(env.EMAIL, env.EMAIL_PW)
text = message.as_string()
server.sendmail(SENDER_EMAIL, RECEIVER_EMAIL, text)
server.sendmail(env.EMAIL, env.EMAIL_RECEIVER, text)
print("Email sent successfully.")


send_user_email()
if __name__ == "__main__":
send_user_email()
15 changes: 9 additions & 6 deletions src/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
"""

import asyncio
import os
import subprocess
import urllib.parse

from dotenv import dotenv_values, load_dotenv
from pathlib import Path
from flask import (
Flask,
render_template,
Expand All @@ -17,21 +16,25 @@
)
from flask_cors import CORS

from settings import ServerSettings

# Load environment variables from .env file
load_dotenv(override=True)
env = ServerSettings()

app = Flask(__name__)
CORS(app)


@app.route("/help")
def serve_help():
return send_from_directory("../", "help.txt")
return send_from_directory(
f"{str(Path(__file__).parent)}/", "help.txt"
)


@app.route("/home")
def serve_index():
return render_template("index.html", env_vars=dict(dotenv_values()))
return render_template("index.html", env_vars=env.model_dump())


@app.route("/script.js")
Expand Down Expand Up @@ -78,4 +81,4 @@ async def run_subprocess():


if __name__ == "__main__":
app.run(host="0.0.0.0", port=os.getenv("PORT"))
app.run(host="0.0.0.0", port=env.PORT)
45 changes: 45 additions & 0 deletions src/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from pathlib import Path
from typing import Literal, Union

from pydantic import EmailStr, Field, IPvAnyAddress
from pydantic_settings import BaseSettings, SettingsConfigDict


class CommonSettings(BaseSettings):
"""
Base class for defining common settings.
model_config (SettingsConfigDict)Configuration dictionary
for specifying the settings file and encoding.
"""
model_config = SettingsConfigDict(
env_file=f"{Path(__file__).parent.parent}/.env",
env_file_encoding="utf-8",
extra="ignore",
)


class ServerSettings(CommonSettings):
"""
Class for defining server env settings.
"""

PORT: int = Field(default=8000)
IP_ADDRESS: Union[IPvAnyAddress | Literal["localhost"]] = Field(
default="localhost"
)


class EmailSettings(ServerSettings):
"""
Class for defining email env settings.
"""

SMTP_SERVER: str = Field(default="smtp.gmail.com") # default gmail server
SMTP_PORT: int = Field(default=587) # default 587
EMAIL: EmailStr # required
EMAIL_PW: str # required
EMAIL_RECEIVER: EmailStr # required
COMMAND: str = Field(
default_factory=lambda cls: f"{cls.IP_ADDRESS}:{cls.PORT}"
)
SUBJECT: str = Field(default="Surf Report")

0 comments on commit c2f5bf5

Please sign in to comment.