I have a Python package that defines various configuration settings in a config.py module. The layout of the package is shown below:
mypackage/
├── src/
│ └── mypackage/
│ ├── __init__.py
│ ├── adder.py
│ ├── config.py
│ └── logger.py
├── README.md
└── pyproject.toml
The contents of config.py, adder.py, and logger.py are shown below. For this example, the config.py module only contains three variables, but the actual module may contain 10 to 20 variables that are used for configuration.
# --- adder.py ---
from . import config
def adder(x) -> float:
"""Add value to config price."""
a = x + config.PRICE
return a
# --- config.py ---
HOST = "localhost"
PORT = 8080
PRICE = 5.89
# --- logger.py ---
from . import config
def log_config():
"""Display the configuration settings."""
host = config.HOST
port = config.PORT
price = config.PRICE
print("host", host)
print("port", port)
print("price", price)
A simple example of using the package is shown next:
import mypackage as pkg
pkg.log_config()
new_price = pkg.adder(10)
print("new price", new_price)
This prints the following:
host localhost
port 8080
price 5.89
new price 15.89
By defining the configuration in the config.py module, I can import the settings into the other files for use by the functions in those files. This approach is fine if I never want to change the configuration settings defined in config.py. However, I want users of the package to be able to provide their own configuration file which would override the default config values.
A possible solution is something like the example shown below. In the example, a configuration class is created with the path to a config file. That class is passed as an input parameter to the other functions. But I don’t want to pass a config object to every function or class that is imported from the package.
import mypackage as pkg
config = pkg.Config("~/Users/home/config.json")
pkg.log_config(config)
new_price = pkg.adder(10, config)
print("new price", new_price)
What I would like to accomplish in this package is the following:
- Use default configuration settings in the package if a configuration file is not available.
- Override the default configuration values in the package if the user provides a configuration file. The configuration file could be a
config.json, orsettings.toml, or something else.
So how can I implement these features in the example package that I provided above? Is it even possible to do this with a module or is there a better approach that I should use?