A simple Python messenger application using Redis as the datastore. The application allows creating users, sending messages between users, listing messages for a user, and listing all users.
Communication with redis -> redis_messenger.py
Communication with user -> chat.py
Schema:
user:<user_id> (HASH)
- user_id (STRING): UUID of the user
- username (STRING): Username of the user
usernames (HASH)
- <username> (FIELD): User's username
- <user_id> (VALUE): Corresponding user UUID
user_contacts:<user_id> (SET)
- <contact_id> (STRING): UUID of a contact in the user's contact list
messages (LIST)
- <message_key> (STRING): Key of the message stored in Redis
message:<message_id> (HASH)
- message_id (STRING): UUID of the message
- sender_id (STRING): UUID of the sender
- recipient_id (STRING): UUID of the recipient
- timestamp (STRING): Timestamp when the message was sent
- message (STRING): Content of the message
- seen (STRING): 'True' if the message has been seen, 'False' otherwise
The application uses the following Redis data structures:
-
Hashes: User data and message data are stored as Redis hashes. Each user has a unique hash with a key in the format
user:<user_id>
, and each message has a unique hash with a key in the formatmessage:<message_id>
. Additionally, there is ausernames
hash that maps usernames to user IDs, ensuring unique usernames. -
Sorted Sets: Messages for each user are stored as Redis sorted sets with keys in the format
user_messages:<user_id>
. The score for each message in the sorted set is its timestamp, allowing the messages to be ordered by the time they were sent.
This function initializes the Redis connection with the provided host, port, and db values.
This function creates a new user with a unique username.
- Check if the username already exists in the
usernames
hash. If it does, raise a ValueError with an appropriate error message. - Generate a unique user ID using a UUID.
- Create a user_key in the format
user:<user_id>
. - Set the user data (username, user_id, and created_at timestamp) in the Redis hash associated with the user_key.
- Add the username and user_id to the
usernames
hash to ensure unique usernames. - Return the user_id.
This function sends a message from one user to another.
- Generate a unique message ID using a UUID.
- Create a message_key in the format
message:<message_id>
. - Get the current timestamp.
- Set the message data (message_id, sender_id, receiver_id, message, and timestamp) in the Redis hash associated with the message_key.
- Add the message_key to the sorted set of messages for the receiver, using the timestamp as the score.
- Return the message_id.
This function lists messages for a user, ordered by timestamp.
- Get the message_keys from the sorted set of messages for the user.
- For each message_key:
- Get the message data from the Redis hash associated with the message_key.
- Decode the keys and values of the message data into strings.
- Append the decoded message data to the messages list.
- Return the messages list.
This function lists all users in the system.
- Scan the Redis keys that match the pattern
user:*
. - For each user_key:
- Get the user data from the Redis hash associated with the user_key.
- Decode the keys and values of the user data into strings.
- Append the decoded user data to the users list.
- Return the users list.
The main()
function in the script demonstrates how to use the RedisMessenger class to create users, send messages, list messages for a user, and list all users. Run the script to see the application in action.