Skip to main content

Command Palette

Search for a command to run...

Building a Robust Python Application with MongoDB: From Docker Setup to Testing

Updated
3 min read
Building a Robust Python Application with MongoDB: From Docker Setup to Testing

In modern software development, creating an application involves more than just writing code. You need a reliable database environment, secure logic, and automated testing to ensure quality.

In this comprehensive guide, we will walk through the entire lifecycle of integrating MongoDB with Python:

  1. Infrastructure: Setting up MongoDB using Docker.

  2. Implementation: Connecting with PyMongo and building a secure User Login system.

  3. Quality Assurance: Writing automated tests using Pytest.


Part 1: Setting Up MongoDB with Docker

Gone are the days of manually installing database services on your local machine. Docker allows us to spin up an isolated MongoDB instance in seconds.

Step 1: Pull the Image

First, ensure Docker is installed, then pull the official MongoDB image:

docker pull mongo

Step 2: Run the Container

We will run the container with port mapping so our Python script can access it. We’ll also give it a specific name (my-mongo) for easy management.

docker run -d -p 27017:27017 --name my-mongo mongo:latest
  • -d: Runs the container in detached mode (background).

  • -p 27017:27017: Maps the container’s port to your localhost port.

  • --name: Assigns a readable name to the container.

To verify it's running, use:

docker ps

Part 2: Connecting & Building a Login System

Now that our database is running, let's write a Python script to interact with it. We will build a simple authentication system (Sign Up and Login).

Prerequisites

Install the required library:

pip install pymongo bcrypt

(Note: We use bcrypt because saving plain-text passwords is a major security risk. Always hash passwords!)

The Application Code (app.py)

Here is a clean implementation of the database connection and user authentication logic:

from pymongo import MongoClient
import bcrypt

class UserManager:
    def __init__(self, uri="mongodb://localhost:27017/", db_name="auth_db"):
        self.client = MongoClient(uri)
        self.db = self.client[db_name]
        self.users = self.db["users"]

    def register_user(self, username, password):
        """Hashes password and saves user to MongoDB."""
        if self.users.find_one({"username": username}):
            return False, "Username already exists"

        # Hash the password
        hashed_pw = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())

        user_data = {
            "username": username,
            "password": hashed_pw
        }
        self.users.insert_one(user_data)
        return True, "User created successfully"

    def login_user(self, username, password):
        """Checks username and verifies hashed password."""
        user = self.users.find_one({"username": username})

        if not user:
            return False, "User not found"

        # Verify password
        if bcrypt.checkpw(password.encode('utf-8'), user['password']):
            return True, "Login successful"
        else:
            return False, "Invalid password"

Part 3: Automated Testing with Pytest

How do we know our login system works without manually running the script every time? We write tests.

Pytest is a powerful framework for this. We will use a fixture to set up a clean database connection before each test and tear it down afterward.

Prerequisites

pip install pytest

The Test Code (test_app.py)

import pytest
from app import UserManager

# Fixture to setup and teardown the database for testing
@pytest.fixture
def user_manager():
    # Use a separate database for testing to avoid deleting real data
    manager = UserManager(db_name="test_auth_db")

    # Clean up: Ensure the collection is empty before starting
    manager.users.delete_many({})

    yield manager

    # Teardown: Clean up after tests run
    manager.users.delete_many({})

def test_registration(user_manager):
    success, message = user_manager.register_user("testuser", "secret123")
    assert success is True
    assert message == "User created successfully"
    # Verify user is actually in DB
    assert user_manager.users.count_documents({"username": "testuser"}) == 1

def test_login_success(user_manager):
    # First, register the user
    user_manager.register_user("validuser", "pass123")

    # Then try to login
    success, message = user_manager.login_user("validuser", "pass123")
    assert success is True
    assert message == "Login successful"

def test_login_failure(user_manager):
    user_manager.register_user("validuser", "pass123")

    # Wrong password
    success, message = user_manager.login_user("validuser", "wrongpass")
    assert success is False
    assert message == "Invalid password"

Running the Tests

Open your terminal and run:

pytest

You should see green text indicating that all tests passed!


Conclusion

By following this guide, you have successfully:

  1. Deployed MongoDB using Docker.

  2. Built a secure User Authentication system using PyMongo and Bcrypt.

  3. Ensured code quality by writing automated tests with Pytest.

This stack (Docker + MongoDB + Python) provides a solid foundation for building scalable and maintainable applications.


More from this blog

E

Exploring Python, GIS, and LLMs, GeoChat

11 posts

OSGeo Advocate | GeoAI Engineer | Python × GIS × AI