DEV Community

Bahman Shadmehr
Bahman Shadmehr

Posted on

Handling Configuration in Your RabbitMQ and Python Project

Title: Managing Configuration in a RabbitMQ and Python Project

Table of Contents:

  1. Introduction
  2. Singleton Design Pattern
  3. Initialization and Lazy Loading
  4. Using .env Files
  5. Key Configuration Settings
  6. Utility Methods
  7. Conclusion

Introduction:
In our RabbitMQ and Python project, it's crucial to have a well-organized and flexible configuration system. This allows us to easily manage our application's behavior, adapt to different environments, and maintain security. In this section, we'll explore how to handle configuration using the Config class provided in the code snippet below. Let's dive in!

Part 1: Singleton Design Pattern
The Config class utilizes the Singleton design pattern to ensure that only one instance of the class is created throughout the project. This approach guarantees that all components of the application share the same configuration, promoting consistency and simplicity.

import os
from dotenv import load_dotenv

class Config:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance.__initialized = False

        return cls._instance

    def __init__(self, load_from_file=True, override=False):
        if self.__initialized and not override:
            return

        # Configuration settings
        self.RUN_MODE = os.environ.get("RUN_MODE", "debug")

        if load_from_file:
            env_file_path = self.RUN_MODE + ".env"
            load_dotenv(env_file_path)

        self.RABBITMQ_HOST = os.environ.get("RABBITMQ_HOST", "localhost")
        self.RABBITMQ_PORT = os.environ.get("RABBITMQ_PORT", 5672)
        self.RABBITMQ_USER = os.environ.get("RABBITMQ_USER", "admin")
        self.RABBITMQ_PASSWORD = os.environ.get("RABBITMQ_PASSWORD", "admin")
        self.RABBITMQ_VHOST = os.environ.get("RABBITMQ_VHOST", "localhost")
        self.EXCHANGE_NAME = os.environ.get("EXCHANGE_NAME", "notification_exchange")

        self.__initialized = True

    def is_test_mode(self):
        return self.RUN_MODE == "test"

    def is_debug_mode(self):
        return self.RUN_MODE == "debug"

    def waiting_factor(self):
        if self.is_test_mode():
            return 0

        return 2
Enter fullscreen mode Exit fullscreen mode

Part 2: Initialization and Lazy Loading
The __init__ method of the Config class initializes the configuration settings. The load_from_file parameter determines whether the configuration should be loaded from a file or solely from environment variables. By default, the configuration is loaded from a file specific to the RUN_MODE.

Part 3: Using .env Files
To manage environment-specific variables, the load_dotenv function from the dotenv library is employed. The .env file corresponding to the RUN_MODE is loaded, allowing us to conveniently store and access sensitive information without exposing it in the codebase.

Part 4: Key Configuration Settings
The Config class provides several essential configuration settings, including RabbitMQ connection details and exchange configuration. These settings allow us to establish connections, authenticate with RabbitMQ, and define the necessary components for our notification service.

Part 5: Utility Methods
The Config class also offers utility methods that provide additional functionality. These methods include determining the application's mode (test or debug) and calculating a waiting factor for handling connection retries.

Part 6: Conclusion
With the Config class in place, we have a reliable and flexible system for managing configuration in our

RabbitMQ and Python project. By leveraging environment variables and .env files, we can easily adapt our application to different environments and securely store sensitive information. The provided utility methods enable us to customize our application's behavior based on the runtime mode, ensuring smooth operation in test and debug environments. Now, armed with this powerful configuration system, you can confidently move forward and focus on implementing the remaining components of your notification service. Happy coding!

Top comments (0)