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?