A mini messenger application with the ability to send messages, store them in a database, and create group chats. Completed as part of a test assignment for the position of Backend developer.
- Connection via WebSocket
- Real-time text messaging
- Storing messages in PostgreSQL
- Tracking the reading of messages
- A REST endpoint for getting the message history
- Prevent duplicate messages when sending in parallel
- Swagger documentation
- Containerization with Docker
- Copy the example environment file:
cp example.env .env- Build the Docker containers:
docker-compose build- Start the app:
docker-compose up- Swagger UI: http://localhost:8000/docs
- pgAdmin: http://localhost:5050
This script (seed_test_data.sh) automatically fills your PostgreSQL database with test data β including users, chats, participants, and messages.
- Create a
.envfile in the root directory and add the following content:
cp example.env .env
- Make sure PostgreSQL client (
psql) is installed:
sudo apt install postgresql-clientbrew install libpq
brew link --force libpq- Make the script executable:
chmod +x seed_test_data.sh- Run the script:
./seed_test_data.shIf everything is set up correctly, youβll see:
β
Messenger database has been successfully filled with test data.
- Endpoint:
POST /users/ - Description: Creates a new user.
- Request Body (application/json):
{
"name": "John Doe",
"email": "[email protected]",
"password": "securepassword"
}- Response (200 OK):
{
"id": "uuid",
"name": "John Doe",
"email": "[email protected]"
}- Endpoint:
POST /chats/ - Description: Creates a new chat.
- Request Body (application/json):
{
"name": "Work Chat",
"type": "group",
"participantIds": ["uuid1", "uuid2"]
}- Response (200 OK):
{
"id": "uuid",
"name": "Work Chat",
"type": "group",
"participantIds": ["uuid1", "uuid2"]
}- Endpoint:
GET /chats/?user_id=uuid - Description: Retrieves all chats the user is a part of.
- Response (200 OK):
[
{
"id": "uuid",
"name": "Work Chat",
"type": "group",
"participantIds": ["uuid1", "uuid2"]
}
]- Endpoint:
POST /chats/{chat_id}/users/{user_id} - Description: Adds a user to the specified chat.
- Response (200 OK):
{
"id": "uuid",
"name": "Work Chat",
"type": "group",
"participantIds": ["uuid1", "uuid2", "uuid3"]
}- Endpoint:
GET /messages/history/{chat_id} - Description: Retrieves the message history for a given chat.
- Query Parameters (optional):
limit: Number of messages to return (default: 100)offset: Pagination offset (default: 0)
- Response (200 OK):
[
{
"id": "uuid",
"chatId": "uuid",
"senderId": "uuid",
"text": "Hello!",
"read": true,
"createdAt": "2025-04-24T12:00:00Z",
"updatedAt": "2025-04-24T12:00:00Z"
}
]- Endpoint:
ws://localhost:8000/messages/ws/{chat_id}/{user_id} - Description: Opens a real-time WebSocket connection for sending and receiving messages in a chat.
- Send a Message
- Sends a new chat message to all participants.
- Message Format:
{ "event": "message", "data": { "text": "Hey, how are you?" } }
- Mark as Read
- Notifies the server that a message has been read.
- Message Format:
{ "event": "read", "data": { "message_id": "f2abadb9-6a60-44c4-8c74-01aa2f520bf8" } }
To run the tests, load the dependencies using the pipenv package manager and run the command > pytest
- Copy the sample environment file if you haven't done this before:
cp example.env .env- Create a new virtual environment and install dependencies:
pipenv shell
pipenv install --dev- Start the postgres container:
docker-compose up postgres- To run the project's tests, you can execute
pytestfrom the root directory:
pytest- FastAPI: Fast web framework for building APIs with Python.
- SQLAlchemy 2 (Async): ORM for Python with async support.
- Databases: Asynchronous database query library.
- PostgreSQL: Relational database management system used for storage.
- Docker: To run the project in a container.
- Docker Compose: To define and manage multi-container Docker applications.
- Pipenv: To manage project dependencies.