How can you enhance the session handling of your Python/MySQL application using Redis on Ubuntu?

How can you enhance the session handling of your Python/MySQL application using Redis on Ubuntu?

Introduction

Authentication verifies user identity during login. Users provide a username and password, which are compared with stored database credentials. If matched, access is granted.
While relational databases like MySQL or PostgreSQL commonly store login credentials, this approach has challenges:

– Database Overload: Every login request requires querying the database, impacting performance as other tasks run simultaneously.
– Scalability Issues: Handling thousands of login requests can strain traditional databases. Using Redis, a fast in-memory data store, can alleviate these issues by caching login data. This guide explains how to enhance session handling in a Python/MySQL application using Redis on an Ubuntu 20.04 server.


Prerequisites

Ensure the following before starting:
– Ubuntu 20.04 or later
– Root access to your system

– Installed MySQL and Redis servers

Accessing the Ubuntu Server

You can connect to your Ubuntu server through Web SSH:

1. Log in to your dashboard.
2. Navigate to the environment hosting your Ubuntu server.
3. Select the Web SSH option.

Web SSH

Setting Up Python Database Drivers

Save $100 in the next
5:00 minutes?

Register Here

1. Install Python modules to interact with MySQL and Redis:
Install pip:

sudo apt install python3-pip

2. Install the MySQL driver:

pip install mysql-connector-python

Install the MySQL driver

3. Install the Redis driver:

pip install redis

Install the Redis driver

4. Creating a Sample MySQL Database
Log in to MySQL:

mysql -u root -p

Log in to MySQL

5. Create a database and user:
sql

CREATE DATABASE db_name;
CREATE USER 'db_user'@'localhost' IDENTIFIED BY 'db_user_password';
GRANT ALL PRIVILEGES ON db_name.* TO 'db_user'@'localhost';
FLUSH PRIVILEGES;
CREATE DATABASE db_test;
CREATE USER 'db_test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'db_user_password';
GRANT ALL PRIVILEGES ON db_name.* TO 'db_test'@'localhost';
FLUSH PRIVILEGES;

Save $100 in the next
5:00 minutes?

Register Here

Switch to the new database:

USE db_name;

New database

Create a table:
sql

CREATE TABLE system_users (
user_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
first_name VARCHAR(50),
last_name VARCHAR(50),
password VARCHAR(50)
) ENGINE=InnoDB;

Create a table

Add sample data:
sql

INSERT INTO system_users (username, first_name, last_name, password) VALUES
('Maggie', 'Micheal', 'Sandy', MD5('iuyrbijy5hd'));
('Chin', 'dave', 'Rogen', MD5('hfehkwjdikjd6')),
('Phobee', Racheal', 'Joey', MD5('9fehkwjdikjd6'));

Add sample data

Check the data in the table to confirm it’s stored correctly:

SELECT user_id, first_name, last_name, password FROM system_users;

Check the data

Exit the MySQL shell:

QUIT;

Exit the MySQL shell

Creating a MySQL Gateway Module for Pythonsql

1. Create a project directory to keep your Python code organized. Here, we use accuweb-project as an example. You can use the project name as per your requirements or choice.

mkdir accuweb-test

 Create a project directory
2. Open a new file named mysql_db.py using a text editor like Nano. This file will contain the module that interacts with MySQL:

vi mysql_db.py

import mysql.connector
class MysqlDb:
def db_con(self):
mysql_con = mysql.connector.connect(
host="localhost",
user="db_user",
password="db-password",
database="db_name",
port="3306"
)
return mysql_con
def query(self, username, password):
db = self.db_con()
db_cursor = db.cursor()
db_query = "SELECT username, password FROM system_users WHERE username = %s AND password = MD5(%s)"
db_cursor.execute(db_query, (username, password))
result = db_cursor.fetchone()
row_count = db_cursor.rowcount
if row_count < 1:
return False
else:
return result[1]

Save $100 in the next
5:00 minutes?

Register Here
SELECT * FROM
system_users;
Building the MySQL Gateway Module
Create mysql_db.py:
python
Copy code
import mysql.connector
class MysqlDb:
def db_con(self):
return mysql.connector.connect(
host="localhost",
user="db_user",
password="db_user_password",
database="db_name"
)
def query(self, username, password):
db = self.db_con()
cursor = db.cursor()
cursor.execute(
"SELECT username, password FROM system_users WHERE username=%s AND password=MD5(%s)",
(username, password)
)
result = cursor.fetchone()
return result[1] if result else False
Creating the Redis Module
Create redis_db.py:
python
Copy code
import redis
class RedisDb:
def db_con(self):
return redis.Redis(host='localhost', port=6379, password='your_redis_password')
Application Entry Point
Create index.py:
python
Copy code
import base64
from hashlib import md5
import json
import datetime
from http.server import SimpleHTTPRequestHandler
import socketserver
import mysql_db
import redis_db
class HttpHandler(SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
auth_header = self.headers.get('Authorization').split(' ')[1]
auth_user, auth_password = base64.b64decode(auth_header).decode('utf8').split(':')
mysql_server = mysql_db.MysqlDb()
redis_server = redis_db.RedisDb()
redis_client = redis_server.db_con()
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
response = {}
if redis_client.exists(auth_user):
if md5(auth_password.encode('utf8')).hexdigest() == redis_client.get(auth_user).decode('utf8'):
response = {"time": now, "authorized by": "Redis server"}
else:
response = {"error": "Invalid username/password"}
else:
mysql_resp = mysql_server.query(auth_user, auth_password)
if not mysql_resp:
response = {"error": "Invalid username/password"}
else:
redis_client.set(auth_user, mysql_resp)
response = {"time": now, "authorized by": "MySQL server"}
self.wfile.write(bytes(json.dumps(response, indent=2), "utf8"))
if __name__ == "__main__":
with socketserver.TCPServer(("", 8080), HttpHandler) as httpd:
print("Server running on port 8080...")
httpd.serve_forever()

Testing the Application

Run the application:

python3 index.py

Test using curl:

curl -X GET -u Chin:hfehkwjdikjd6 http://localhost:8080

The first response should indicate MySQL authentication.

Subsequent responses should indicate Redis caching.

Conclusion

This guide demonstrates how Redis can optimize session handling in Python/MySQL applications, reducing database load and improving performance. This approach is ideal for scalable, high-performance systems.

Save $100 in the next
5:00 minutes?

Register Here