Overview
Welcome to the Messaging System!. This system is designed to handle two main tasks: sending emails and logging requests. It’s built using Flask for the web application and Celery for asynchronous task management, ensuring efficient and scalable processing.
Key Components:
app.py: This is the main entry point of our web application. It handles incoming HTTP requests, routes them appropriately, and interacts with the Celery tasks for sending emails or logging requests.
tasks.py: This file contains the Celery task for sending emails. It ensures that email sending is handled asynchronously, allowing the web application to remain responsive.
Celery: An asynchronous task queue/job queue that distributes tasks to multiple workers, making the system scalable and efficient.
app.py 📄
This file sets up the Flask web application. It includes routes to handle sending emails and logging requests.
Logging Setup: Ensures the logging directory and log file exist.
Route Handling: Defines a route (/) that can handle two types of requests: sendmail to send an email and talktome to log a message with a timestamp.
import logging
import time # Import the time module
from flask import Flask, request
from tasks import send_email
app = Flask(__name__)
# Ensure logging directory exists
log_dir = “/var/log”
log_file = os.path.join(log_dir, “messaging_system.log”)
if not os.path.exists(log_dir):
os.makedirs(log_dir)
if not os.path.exists(log_file):
open(log_file, ‘a’).close()
logging.basicConfig(filename=log_file, level=logging.INFO)
@app.route(‘/’)
def index():
sendmail = request.args.get(‘sendmail’)
talktome = request.args.get(‘talktome’)
try:
if sendmail:
recipient_email = sendmail.replace(‘mailto:’, ”)
send_email.delay(recipient_email)
return “Email sent!”
if talktome:
logging.info(f”Talk to me request at {time.strftime(‘%Y-%m-%d %H:%M:%S’)}”)
return “Logged time!”
return “Welcome to the messaging system!”
except Exception as e:
logging.error(f”Error occurred: {e}”)
return “An error occurred. Check the logs for details.”, 500
if __name__ == ‘__main__’:
app.run(host=’0.0.0.0′, port=5000)
tasks.py 📄
This file contains the Celery task for sending emails.
Celery Setup: Configures Celery to use RabbitMQ as the message broker.
send_email Task: Defines a task to send an email asynchronously using SMTP.
from celery import Celery
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
celery = Celery(‘tasks’, broker=’amqp://guest@localhost//’)
@celery.task
def send_email(recipient_email):
email_password = os.environ.get(“EMAIL_PASSWORD”)
if not email_password:
raise ValueError(“EMAIL_PASSWORD not set”)
msg = MIMEText(‘This is a test email.’)
msg[‘Subject’] = ‘Test Email’
msg[‘From’] = ‘akintola130@gmail.com’
msg[‘To’] = recipient_email
try:
with SMTP_SSL(‘smtp.gmail.com’, 465) as server:
server.login(‘akintola130@gmail.com’, email_password)
server.sendmail(‘akintola130@gmail.com’, recipient_email, msg.as_string())
print(“Email sent successfully!”)
except Exception as e:
print(f”Failed to send email: {e}”)
Prerequisites
Python 3.12+
Virtualenv
RabbitMQ/Celery
An SMTP email account
Nginx
Ngrok for external access
Setup
1. Clone the Repository
cd HNG3/messaging_system
2. Create and Activate a Virtual Environment
source venv/bin/activate
3. Install Dependencies
4. Configure Environment Variable
Set the EMAIL_PASSWORD environment variable:
Make sure to replace your_email_password with your actual email app password.
5. Initialize RabbitMQ 🐇
Ensure that RabbitMQ is running on your system. You can start RabbitMQ with:
6. Ensure Log Directory Exists
Ensure the /var/log/messaging_system.log file exists and set the appropriate permissions:
sudo chmod 666 /var/log/messaging_system.log
7. Configure Nginx
Install Nginx if it’s not already installed:
sudo apt install nginx
Create an Nginx configuration file for your Flask application. For example, create /etc/nginx/sites-available/messaging_system:
Add the following configuration, remember to replace your_domain_or_ip with your actual IP address or domain:
listen 80;
server_name your_domain_or_ip;
location / {
proxy_pass http://your_domain_or_ip:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_log /var/log/nginx/messaging_system_error.log;
access_log /var/log/nginx/messaging_system_access.log;
}
Enable the configuration by creating a symlink:
Test the Nginx configuration and restart Nginx:
sudo systemctl restart nginx
Now, your Flask application should be accessible via your domain or IP.
Running the Application 🚀
Start the Flask Application
Remember to activate the virtual environment.
Start the Celery Worker: In another terminal, ensure you activate the virtual env.
Exposing with ngrok 🌍
To expose your local server to the internet using ngrok, follow these steps:
Download and install ngrok from ngrok.com.
Start ngrok with the following command:
Copy the generated ngrok URL and use it to access your Flask application from the internet.
Usage
To send an email, navigate to http://your_ngrok_endpoint/?sendmail=mailto:recipient@example.com.
To log a request, navigate to http://your_ngrok_endpoint/?talktome.
Troubleshooting 🛠️
If you encounter any issues, check the logs for more information:
Flask application logs: /var/log/messaging_system.log
Celery worker logs: Run sudo journalctl -u celery.service -f to view real-time logs.
Nginx logs: /var/log/nginx/error.log and /var/log/nginx/access.log
By following these steps, you can set up and run your own messaging system with Flask and Celery. Enjoy! 🎉