DEV Community

Cover image for Messaging System with Flask App and RabbitMQ/Celery for Email Handling ๐Ÿš€
akintola abdulazeez oladele
akintola abdulazeez oladele

Posted on

Messaging System with Flask App and RabbitMQ/Celery for Email Handling ๐Ÿš€

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.

Prerequisites

  • Python 3.12+
  • Virtualenv
  • RabbitMQ/Celery
  • An SMTP email account
  • Nginx
  • Ngrok for external access

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 os 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) 
Enter fullscreen mode Exit fullscreen mode

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.

import os 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}") 
Enter fullscreen mode Exit fullscreen mode

Setup

1. Clone the Repository

git clone https://github.com/hayzedak/HNG3.git cd HNG3/messaging_system 
Enter fullscreen mode Exit fullscreen mode

2. Create and Activate a Virtual Environment

python3 -m venv venv source venv/bin/activate 
Enter fullscreen mode Exit fullscreen mode

3. Install Dependencies

pip install Flask celery 
Enter fullscreen mode Exit fullscreen mode

4. Configure Environment Variable
Set the EMAIL_PASSWORD environment variable:

export EMAIL_PASSWORD=your_email_password 
Enter fullscreen mode Exit fullscreen mode

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:

sudo systemctl start rabbitmq-server 
Enter fullscreen mode Exit fullscreen mode

6. Ensure Log Directory Exists
Ensure the /var/log/messaging_system.log file exists and set the appropriate permissions:

sudo touch /var/log/messaging_system.log sudo chmod 666 /var/log/messaging_system.log 
Enter fullscreen mode Exit fullscreen mode

7. Configure Nginx
Install Nginx if it's not already installed:

sudo apt update sudo apt install nginx 
Enter fullscreen mode Exit fullscreen mode

Create an Nginx configuration file for your Flask application. For example, create /etc/nginx/sites-available/messaging_system:

sudo nano /etc/nginx/sites-available/messaging_system 
Enter fullscreen mode Exit fullscreen mode

Add the following configuration, remember to replace your_domain_or_ip with your actual IP address or domain:

server { 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; } 
Enter fullscreen mode Exit fullscreen mode

Enable the configuration by creating a symlink:

sudo ln -s /etc/nginx/sites-available/messaging_system /etc/nginx/sites-enabled 
Enter fullscreen mode Exit fullscreen mode

Test the Nginx configuration and restart Nginx:

sudo nginx -t sudo systemctl restart nginx 
Enter fullscreen mode Exit fullscreen mode

Now, your Flask application should be accessible via your domain or IP.

Running the Application ๐Ÿš€

  1. Start the Flask Application

Remember to activate the virtual environment.

python3 app.py 
Enter fullscreen mode Exit fullscreen mode
  1. Start the Celery Worker: In another terminal, ensure you activate the virtual env.
celery -A tasks worker --loglevel=info 
Enter fullscreen mode Exit fullscreen mode

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:

ngrok http 5000 
Enter fullscreen mode Exit fullscreen mode
  • Copy the generated ngrok URL and use it to access your Flask application from the internet.

Usage

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! ๐ŸŽ‰

Top comments (0)