Samfredoly commited on
Commit
997c360
·
verified ·
1 Parent(s): 4b6b291

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -21
app.py CHANGED
@@ -4,32 +4,41 @@ import re
4
  from email.mime.text import MIMEText
5
  from fastapi import FastAPI
6
  from pydantic import BaseModel, Field
7
- from dotenv import load_dotenv
8
- import os
9
  from aiosmtpd.controller import Controller
10
  from aiosmtpd.handlers import Sink
11
  import uvicorn
12
 
13
- # Load environment variables
14
- load_dotenv()
 
15
 
16
- # Configure logging
17
- logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
18
- logger = logging.getLogger("bot_brain")
 
 
 
 
 
 
19
 
20
- # SMTP server configuration for our own SMTP server
21
- SMTP_SERVER_HOST = os.getenv("SMTP_SERVER_HOST", "localhost")
22
- SMTP_SERVER_PORT = int(os.getenv("SMTP_SERVER_PORT", "1025"))
23
 
24
- # Configuration for the SMTP client (sending emails via our own SMTP server)
25
- CLIENT_SMTP_HOST = os.getenv("CLIENT_SMTP_HOST", SMTP_SERVER_HOST)
26
- SMTP_PORT = int(os.getenv("SMTP_PORT", SMTP_SERVER_PORT))
27
- SMTP_USER = os.getenv("SMTP_USER", "noreply@yourdomain.com")
28
- SMTP_PASSWORD = os.getenv("SMTP_PASSWORD", "password")
29
 
30
- # Global conversation state: maps sender's WhatsApp number to conversation data.
 
 
 
31
  conversations = {}
32
 
 
 
 
 
33
  # Regex for validating email addresses
34
  EMAIL_REGEX = re.compile(r"^[^@]+@[^@]+\.[^@]+$")
35
 
@@ -40,6 +49,7 @@ def validate_email(email: str) -> bool:
40
  def send_email(from_addr: str, to_addr: str, subject: str, body: str) -> bool:
41
  """
42
  Sends an email using the SMTP client.
 
43
  """
44
  msg = MIMEText(body)
45
  msg['Subject'] = subject
@@ -50,7 +60,7 @@ def send_email(from_addr: str, to_addr: str, subject: str, body: str) -> bool:
50
 
51
  try:
52
  with smtplib.SMTP(CLIENT_SMTP_HOST, SMTP_PORT) as server:
53
- server.starttls() # Upgrade to TLS
54
  server.login(SMTP_USER, SMTP_PASSWORD)
55
  server.sendmail(from_addr, [to_addr], msg.as_string())
56
  logger.info(f"Email sent successfully from {from_addr} to {to_addr}")
@@ -59,7 +69,10 @@ def send_email(from_addr: str, to_addr: str, subject: str, body: str) -> bool:
59
  logger.error(f"Error sending email: {e}")
60
  return False
61
 
62
- # Pydantic models for request validation
 
 
 
63
  class Text(BaseModel):
64
  body: str
65
 
@@ -70,11 +83,15 @@ class BotRequest(BaseModel):
70
  from_: str = Field(..., alias="from")
71
  message: Message
72
 
73
- # Create FastAPI app
 
 
 
74
  app = FastAPI()
75
 
76
  @app.post("/bot")
77
  async def bot_endpoint(request_data: BotRequest):
 
78
  payload = request_data.dict(by_alias=True)
79
  logger.debug("Received request payload: %s", payload)
80
 
@@ -85,6 +102,7 @@ async def bot_endpoint(request_data: BotRequest):
85
  state = conversations.get(sender_number, {})
86
 
87
  if not state:
 
88
  conversations[sender_number] = {"step": "from"}
89
  response_msg = "Welcome to SMTP Assistant! Please provide your 'From' email address."
90
  else:
@@ -129,6 +147,10 @@ async def bot_endpoint(request_data: BotRequest):
129
  logger.debug("Response message to %s: %s", sender_number, response_msg)
130
  return {"status": "success", "message": response_msg}
131
 
 
 
 
 
132
  def start_smtp_server():
133
  """
134
  Start our own SMTP server using aiosmtpd.
@@ -140,9 +162,13 @@ def start_smtp_server():
140
  logger.info(f"SMTP server started at {SMTP_SERVER_HOST}:{SMTP_SERVER_PORT}")
141
  return controller
142
 
 
 
 
 
143
  if __name__ == "__main__":
144
- # Start the SMTP server (our own SMTP server)
145
  smtp_controller = start_smtp_server()
146
 
147
- # Run the FastAPI app using Uvicorn
148
  uvicorn.run("main:app", host="0.0.0.0", port=5000, reload=True)
 
4
  from email.mime.text import MIMEText
5
  from fastapi import FastAPI
6
  from pydantic import BaseModel, Field
 
 
7
  from aiosmtpd.controller import Controller
8
  from aiosmtpd.handlers import Sink
9
  import uvicorn
10
 
11
+ # =======================
12
+ # Configuration Settings
13
+ # =======================
14
 
15
+ # SMTP server settings for our own SMTP server (listening on a custom port)
16
+ SMTP_SERVER_HOST = "localhost" # Hostname for our SMTP server
17
+ SMTP_SERVER_PORT = 1025 # Port for our SMTP server
18
+
19
+ # SMTP client settings (used by the bot to send emails via our SMTP server)
20
+ CLIENT_SMTP_HOST = "localhost" # Must match SMTP_SERVER_HOST for local testing
21
+ SMTP_PORT = 1025 # Must match SMTP_SERVER_PORT
22
+ SMTP_USER = "noreply@yourdomain.com" # SMTP username (if required by your server)
23
+ SMTP_PASSWORD = "password" # SMTP password (if required by your server)
24
 
25
+ # =======================
26
+ # Logging Configuration
27
+ # =======================
28
 
29
+ logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
30
+ logger = logging.getLogger("bot_brain")
 
 
 
31
 
32
+ # =======================
33
+ # Global Conversation State
34
+ # =======================
35
+ # Maps sender's WhatsApp number to conversation data.
36
  conversations = {}
37
 
38
+ # =======================
39
+ # Helper Functions
40
+ # =======================
41
+
42
  # Regex for validating email addresses
43
  EMAIL_REGEX = re.compile(r"^[^@]+@[^@]+\.[^@]+$")
44
 
 
49
  def send_email(from_addr: str, to_addr: str, subject: str, body: str) -> bool:
50
  """
51
  Sends an email using the SMTP client.
52
+ Connects to our own SMTP server (CLIENT_SMTP_HOST on SMTP_PORT).
53
  """
54
  msg = MIMEText(body)
55
  msg['Subject'] = subject
 
60
 
61
  try:
62
  with smtplib.SMTP(CLIENT_SMTP_HOST, SMTP_PORT) as server:
63
+ server.starttls() # Upgrade connection to TLS
64
  server.login(SMTP_USER, SMTP_PASSWORD)
65
  server.sendmail(from_addr, [to_addr], msg.as_string())
66
  logger.info(f"Email sent successfully from {from_addr} to {to_addr}")
 
69
  logger.error(f"Error sending email: {e}")
70
  return False
71
 
72
+ # =======================
73
+ # Pydantic Models
74
+ # =======================
75
+
76
  class Text(BaseModel):
77
  body: str
78
 
 
83
  from_: str = Field(..., alias="from")
84
  message: Message
85
 
86
+ # =======================
87
+ # FastAPI Application
88
+ # =======================
89
+
90
  app = FastAPI()
91
 
92
  @app.post("/bot")
93
  async def bot_endpoint(request_data: BotRequest):
94
+ # Convert payload to dictionary using aliases
95
  payload = request_data.dict(by_alias=True)
96
  logger.debug("Received request payload: %s", payload)
97
 
 
102
  state = conversations.get(sender_number, {})
103
 
104
  if not state:
105
+ # Start a new conversation
106
  conversations[sender_number] = {"step": "from"}
107
  response_msg = "Welcome to SMTP Assistant! Please provide your 'From' email address."
108
  else:
 
147
  logger.debug("Response message to %s: %s", sender_number, response_msg)
148
  return {"status": "success", "message": response_msg}
149
 
150
+ # =======================
151
+ # SMTP Server (using aiosmtpd)
152
+ # =======================
153
+
154
  def start_smtp_server():
155
  """
156
  Start our own SMTP server using aiosmtpd.
 
162
  logger.info(f"SMTP server started at {SMTP_SERVER_HOST}:{SMTP_SERVER_PORT}")
163
  return controller
164
 
165
+ # =======================
166
+ # Main Execution
167
+ # =======================
168
+
169
  if __name__ == "__main__":
170
+ # Start the SMTP server
171
  smtp_controller = start_smtp_server()
172
 
173
+ # Run the FastAPI app with Uvicorn
174
  uvicorn.run("main:app", host="0.0.0.0", port=5000, reload=True)