This project is a simple yet effective web-based data submission and processing system built using Django and RabbitMQ. The primary goal of this project is to demonstrate how asynchronous task queues can be integrated into web applications to handle time-consuming operations in the background.
Users submit data such as their name, department, university, semester, and academic year through a responsive web interface. Instead of processing this data immediately in the main thread, the system uses RabbitMQ as a message broker to queue the data and process it asynchronously, ensuring a smooth and responsive user experience.
This setup is particularly useful for handling:
- Background processing
- Scalability
- Decoupling of services
- Improved performance and user interaction
In this step, we configure a Publisher to send messages and a Consumer to receive and process them. Messages are transferred through RabbitMQ using the pika library.
The publisher is responsible for sending structured student data to a RabbitMQ queue named my_queue.
Code:
python``
import pika
import random
import json
def publish_message(message):
params = pika.URLParameters('amqps://your_credentials@your_host/your_vhost')
connection = pika.BlockingConnection(params)
channel = connection.channel()
channel.queue_declare(queue="my_queue")
message = json.dumps(message)
channel.basic_publish(
exchange='',
routing_key="my_queue",
body=message
)
print(f"Message Published: {message}")
connection.close()
``
What it does:
- Connects to the RabbitMQ cloud server using
pika.URLParameters - Declares a queue
my_queue(automatically created if it doesn't exist) - Serializes the message to JSON and sends it to the queue
- Prints confirmation and closes the connection
The consumer listens for messages on the same queue and generates a PDF report with the received data using the fpdf library.
Code:
python``
import pika
import json
from fpdf import FPDF
import uuid
import os
def generate_pdf(data):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt="Student Information", ln=True, align="C")
pdf.ln(10)
for key, value in data.items():
pdf.cell(200, 10, txt=f"{key.capitalize()}: {value}", ln=True)
folder_path = os.path.join(os.getcwd(), 'media', 'pdfs')
if not os.path.exists(folder_path):
os.makedirs(folder_path)
filename = f"report_{uuid.uuid4()}.pdf"
filepath = os.path.join(folder_path, filename)
pdf.output(filepath)
print(f"β
PDF saved to: {filepath}")
def callback(ch, method, properties, body):
data = json.loads(body.decode())
print("π© Received message:", data)
generate_pdf(data)
params = pika.URLParameters('amqps://your_credentials@your_host/your_vhost')
connection = pika.BlockingConnection(params)
channel = connection.channel()
channel.queue_declare(queue="my_queue")
channel.basic_consume(queue="my_queue", on_message_callback=callback, auto_ack=True)
print("π Consumer waiting for PDF tasks...")
channel.start_consuming()
``
What it does:
- Connects to RabbitMQ and listens on
my_queue - When a message is received, it decodes the JSON and prints it
- Calls
generate_pdf()to create and save a PDF from the message
This publisher-consumer design ensures that PDF generation runs asynchronously and does not block the user interface or main application flow.
This view handles the form data submitted by the user through a web interface. Once the user submits the form, the data is collected and passed to the publish_message function, which sends it to RabbitMQ for background processing.
Code:
python``
from django.shortcuts import render
from .publisher import publish_message
def form_data(request):
if request.method == 'POST':
data = {
"name": request.POST.get("name"),
"dept": request.POST.get("dept"),
"university": request.POST.get("university"),
"semester": request.POST.get("semester"),
"year": request.POST.get("year"),
}
publish_message(data)
return render(request, 'form.html', {"success": True})
return render(request, 'form.html')
``
What this code does:
- Defines a Django view function named
form_data. - Checks if the request method is
POST(i.e., form is submitted). - Retrieves form fields like
name,dept,university,semester, andyearfrom the request. - Packages the data into a Python dictionary.
- Calls the
publish_messagefunction to send this data to RabbitMQ for asynchronous processing. - Returns the
form.htmltemplate with asuccessflag if submission is successful. - If itβs a
GETrequest (i.e., first time loading the form), it simply renders the empty form.
This setup decouples user interaction from heavy tasks like PDF generation and ensures a fast, responsive experience by offloading processing to RabbitMQ.
This is the front-end template where users can input their academic details. It uses Bootstrap 5 for responsive styling and Django templating for secure form submission (e.g., CSRF protection).
Key Features:
- Clean and responsive design using Bootstrap 5
- Fields for Name, Department, University, Semester, and Year
- Dropdowns for selecting semester and year
- CSRF token included for Django's form security
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Student Info Submission</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: #f4f6f9;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.form-container {
background-color: white;
padding: 2rem 2.5rem;
border-radius: 15px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
max-width: 600px;
margin: auto;
}
h2 {
color: #333;
font-weight: 600;
}
.form-label {
margin-top: 10px;
}
</style>
</head>
<body>
<div class="container mt-5">
<div class="form-container">
<h2 class="mb-4 text-center">Submit Student Information</h2>
<form method="POST">
{% csrf_token %}
<label class="form-label">Full Name</label>
<input type="text" class="form-control" name="name" required>
<label class="form-label">Department</label>
<input type="text" class="form-control" name="dept" required>
<label class="form-label">University</label>
<input type="text" class="form-control" name="university" required>
<label class="form-label">Semester</label>
<select class="form-select" name="semester" required>
<option value="1">1st</option>
<option value="2">2nd</option>
<option value="3">3rd</option>
<option value="4">4th</option>
<option value="5">5th</option>
<option value="6">6th</option>
<option value="7">7th</option>
<option value="8">8th</option>
</select>
<label class="form-label">Year</label>
<select class="form-select" name="year" required>
<option value="1">1st</option>
<option value="2">2nd</option>
<option value="3">3rd</option>
<option value="4">4th</option>
<option value="5">5th</option>
</select>
<button type="submit" class="btn btn-primary w-100 mt-4">Submit</button>
</form>
</div>
</div>
</body>
</html><form method="POST">: Sends data via POST method to the Django view.{% csrf_token %}: Provides protection against cross-site request forgery.- Input fields capture name, department, university.
- Two
<select>dropdowns are used for semester and year. - The form is styled with CSS and Bootstrap to create a modern and centered layout.
4.1.Image of the Form UI
5.1.The Publisher publishing data
5.2.The Consumer listening to the messages and creating PDF through given data
This project demonstrates how to efficiently handle user-submitted data using asynchronous message processing with RabbitMQ and Django. By decoupling the data collection and processing logic, the system ensures smooth performance, better scalability, and an improved user experience. It serves as a practical example of integrating real-time web applications with background task queues to manage long-running operations like PDF generation.