Hone logo
Hone
Problems

Robust Configuration Management System in Python

Configuration management is crucial for any application, allowing you to easily adjust settings without modifying code. This challenge asks you to build a simple configuration management system in Python that loads settings from a file (INI-style) and provides a clean interface for accessing and modifying them. This is useful for managing application behavior, database connections, API keys, and other environment-specific parameters.

Problem Description

You are tasked with creating a ConfigManager class that handles loading and accessing configuration settings from a file. The configuration file will be in a simple INI-like format, where each section is denoted by a header enclosed in square brackets [], and each setting within a section is a key=value pair.

The ConfigManager class should have the following methods:

  • __init__(self, filepath): Initializes the ConfigManager with the path to the configuration file. The file should be read and parsed during initialization. If the file doesn't exist, an exception should be raised.
  • get(self, section, key): Retrieves the value associated with a given key within a specified section. If the section or key doesn't exist, return None.
  • set(self, section, key, value): Sets the value of a given key within a specified section. If the section doesn't exist, it should be created.
  • save(self): Saves the current configuration back to the file specified in the constructor. The file should be overwritten with the updated configuration.

Key Requirements:

  • The configuration file format is simple INI-like:
    • Sections are enclosed in [].
    • Settings are in the format key=value.
    • Whitespace around the = is allowed.
    • Empty lines and lines starting with # (comments) should be ignored.
  • The ConfigManager should handle cases where sections or keys are missing gracefully.
  • The save method should write the configuration back to the file in the same format.
  • Error handling: Raise a FileNotFoundError if the configuration file does not exist.

Expected Behavior:

The ConfigManager should provide a simple and reliable way to load, access, modify, and save configuration settings. The code should be well-structured and easy to understand.

Examples

Example 1:

Input:
config_file.ini:
[Database]
host=localhost
port=5432
user=admin
password=secret

[API]
key=abcdef123456
url=https://api.example.com

Code:
config = ConfigManager("config_file.ini")
print(config.get("Database", "host"))
print(config.get("API", "url"))
print(config.get("Unknown", "key"))
Output:
localhost
https://api.example.com
None

Explanation: The code loads the configuration from config_file.ini, retrieves the values for "host" and "url" from their respective sections, and attempts to retrieve a value from a non-existent section, resulting in None.

Example 2:

Input:
config_file.ini:
[Application]
name=My App
version=1.0

Code:
config = ConfigManager("config_file.ini")
config.set("Application", "version", "1.1")
config.set("Logging", "level", "DEBUG")
config.save()

config_file.ini (after save):
[Application]
name=My App
version=1.1
[Logging]
level=DEBUG

Explanation: The code loads the configuration, updates the "version" setting in the "Application" section, creates a new "Logging" section and sets its "level" setting, and then saves the updated configuration back to the file.

Example 3: (Edge Case - File Not Found)

Input:
config_file.ini (does not exist)

Code:
config = ConfigManager("config_file.ini")
Output:
FileNotFoundError: config_file.ini not found

Explanation: The code attempts to load a configuration file that does not exist, resulting in a FileNotFoundError.

Constraints

  • The configuration file path will be a string.
  • Section and key names will be strings.
  • Values will be strings.
  • The configuration file will not exceed 1MB in size.
  • The code should be reasonably efficient for typical configuration file sizes. Avoid unnecessary file reads or writes.

Notes

  • Consider using a dictionary to store the configuration data internally.
  • Pay close attention to error handling, especially when dealing with file operations.
  • The INI-like format is simplified; you don't need to handle complex features like nested sections or different data types.
  • Focus on clarity and readability of your code.
  • The save method should preserve the original order of sections and settings as much as possible.
  • Whitespace around the = sign in the configuration file should be ignored.
  • Comments (lines starting with #) should be ignored.
Loading editor...
python