Developing a chat application in Python

Developing a chat application in Python involves integrating various components such as a backend server, a database for message storage, and a frontend interface for user interaction. We’ll use Flask for the backend, Socket.IO for real-time communication, and SQLite for message storage. Let’s break down the process step by step.

Dependencies:

Before we start coding, we need to install the necessary dependencies. We’ll use Flask for our backend server and Socket.IO for real-time communication. You can install these dependencies using pip:

pip install Flask flask-socketio

Setting Up the Backend:

We’ll start by setting up our Flask application to handle HTTP requests and WebSocket connections for real-time messaging.

from flask import Flask, render_template
from flask_socketio import SocketIO, join_room, leave_room, emit
import sqlite3

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
socketio = SocketIO(app)

# Connect to SQLite database
conn = sqlite3.connect('chat.db')
c = conn.cursor()

# Create table to store chat messages
c.execute('''CREATE TABLE IF NOT EXISTS messages (
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             room TEXT,
             username TEXT,
             message TEXT
             )''')
conn.commit()

if __name__ == '__main__':
    socketio.run(app, debug=True)

In this code snippet, we set up a Flask application and initialize a SocketIO instance. We also connect to a SQLite database and create a table to store chat messages. The if __name__ == '__main__': block ensures that the application runs when executed as a script.

Frontend Integration:

Now, let’s create the frontend interface for our chat application. We’ll use HTML and JavaScript to render the UI and handle user interactions.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chat Application</title>
</head>
<body>
    <div id="chat-room">
        <div id="messages"></div>
        <input type="text" id="message-input">
        <button onclick="sendMessage()">Send</button>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.1/socket.io.js"></script>
    <script>
        var socket = io();
        var username = prompt('Enter your username:');

        socket.emit('join', { username: username });

        socket.on('receive_message', function(data) {
            var messageElement = document.createElement('div');
            messageElement.innerText = data.username + ': ' + data.message;
            document.getElementById('messages').appendChild(messageElement);
        });

        function sendMessage() {
            var message = document.getElementById('message-input').value;
            socket.emit('send_message', { message: message });
            document.getElementById('message-input').value = '';
        }
    </script>
</body>
</html>

This HTML file contains a simple chat room interface with an input field for sending messages. We use Socket.IO to establish a WebSocket connection with the backend server and send/receive messages in real-time.

Backend Implementation:

Now, let’s implement the backend logic to handle WebSocket events and database operations.

@socketio.on('join')
def handle_join(data):
    room = data['room']
    join_room(room)
    emit('status', {'msg': data['username'] + ' has entered the room.'}, room=room)

@socketio.on('leave')
def handle_leave(data):
    room = data['room']
    leave_room(room)
    emit('status', {'msg': data['username'] + ' has left the room.'}, room=room)

@socketio.on('send_message')
def handle_message(data):
    room = data['room']
    username = data['username']
    message = data['message']

    # Save message to database
    c.execute("INSERT INTO messages (room, username, message) VALUES (?, ?, ?)", (room, username, message))
    conn.commit()

    emit('receive_message', {'username': username, 'message': message}, room=room)

In these event handlers, we handle joining and leaving chat rooms, sending and receiving messages, and storing messages in the database. When a user sends a message, it’s emitted to all users in the same chat room via Socket.IO, and the message is also saved to the database.

Emoji Support and Message History:

To add emoji support, you can use JavaScript libraries like EmojiPicker to allow users to select emojis from a picker. You can then send the selected emojis as part of the message to the backend, which will handle storing and displaying them.

For message history, you can query the database for previous messages when a user joins a chat room and display them in the chat interface. This ensures that users have access to past messages and can catch up on conversations they missed.

Here’s the consolidated code for the chat application in Python using Flask, Socket.IO, and SQLite:

from flask import Flask, render_template
from flask_socketio import SocketIO, join_room, leave_room, emit
import sqlite3

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
socketio = SocketIO(app)

# Connect to SQLite database
conn = sqlite3.connect('chat.db')
c = conn.cursor()

# Create table to store chat messages
c.execute('''CREATE TABLE IF NOT EXISTS messages (
             id INTEGER PRIMARY KEY AUTOINCREMENT,
             room TEXT,
             username TEXT,
             message TEXT
             )''')
conn.commit()

@socketio.on('join')
def handle_join(data):
    room = data['room']
    join_room(room)
    emit('status', {'msg': data['username'] + ' has entered the room.'}, room=room)

@socketio.on('leave')
def handle_leave(data):
    room = data['room']
    leave_room(room)
    emit('status', {'msg': data['username'] + ' has left the room.'}, room=room)

@socketio.on('send_message')
def handle_message(data):
    room = data['room']
    username = data['username']
    message = data['message']

    # Save message to database
    c.execute("INSERT INTO messages (room, username, message) VALUES (?, ?, ?)", (room, username, message))
    conn.commit()

    emit('receive_message', {'username': username, 'message': message}, room=room)

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    socketio.run(app, debug=True)

This single snippet includes the setup for the Flask application, Socket.IO integration for real-time communication, SQLite database connection, table creation for storing messages, event handlers for joining, leaving, and sending messages, and a basic HTML template for the chat interface.

You can run this script, and the chat application will be up and running, allowing users to join chat rooms, send messages in real-time, and view message history stored in the SQLite database.

How to test the code and provide expected responses.

  1. Testing Socket.IO Connection:
    • Run the Flask application.
    • Open your web browser and navigate to the URL where the application is running.
    • Verify that the connection to the Socket.IO server is established without errors.
  2. Joining a Chat Room:
    • Enter a username when prompted.
    • Verify that the server emits a message indicating that you have entered the chat room.
    • Ensure that the chat interface updates to display the message.
  3. Sending a Message:
    • Type a message in the input field and press the send button.
    • Verify that the message is sent to the server via Socket.IO.
    • Ensure that the server emits the message to all users in the chat room.
    • Check that the message appears in the chat interface for all users.
  4. Leaving a Chat Room:
    • Close the browser tab or navigate away from the chat interface.
    • Verify that the server emits a message indicating that you have left the chat room.
    • Ensure that the chat interface updates to display the message.
  5. Database Verification:
    • Use a SQLite database browser to inspect the messages table.
    • Verify that the messages sent during testing are correctly stored in the database.

By following these testing steps, you can ensure that the chat application behaves as expected, handles user interactions gracefully, and stores messages accurately in the database.

Leave a Comment