opal
opal copied to clipboard
Support .env config from other folders
Describe the bug
No easy way of setting .env
OPAL uses decouple to parse configuration from .env
and .ini
files (As part of Confi)
BY default it looks for them in the folder of the importing module - we should add support for a configurable folder or at least the current-directory
Hey @orweis can you explain me the issue and the changes needed, I don't know the tech stack but definitely want to give it a try if possible
Hi @money8203 , Sure thing! We'd love some help with these : )
Confi is OPAL's configuration framework (homebrewed) - https://github.com/permitio/opal/blob/master/packages/opal-common/opal_common/confi/confi.py
It loads config values for OPAL from 3 potential sources - ENV-var, cmd line parameters, and config files (.env and .ini). The decouple is the one reading the files and it's AutoConfig class has the setting of where to look for the files.
We'd like to have the default location it searches for config files in as the current working dir, and maybe also an ENV_VAR that controls that path
Some suggestions I found on how we can fix the bug:
-
Add support for a configurable folder: We can add an option for the user to specify the location of the config files. We can do this by adding a command line argument or an environment variable that lets the user specify the path to the config files.
-
Add support for the current-directory: We can make the current-directory as the default location that Confi looks for the config files. This way, if the user does not specify a different location, Confi will look for the files in the current-directory by default.
-
Add an ENV_VAR that controls the path of the config files: We can add an environment variable that lets the user specify the path to the config files. This way, the user can set the path to the config files using an environment variable instead of specifying it on the command line.
Here's a sample of updated code for the above feedback:
import os
class Confi:
def __init__(self, prefix=None, is_model=True) -> None:
self._is_model = is_model
self._prefix = prefix
self._counter = 0
self._entries: Dict[str, ConfiEntry] = OrderedDict()
self._delayed_entries: Dict[str, ConfiDelay] = OrderedDict()
self._delayed_defaults: Dict[str, ConfiEntry] = OrderedDict()
def _load_config_file(self, file_path):
"""
Loads the config file located at file_path
"""
# add code to read and parse config file
def load_config(self):
"""
Loads the config files from the specified location
"""
# check for location specified by user
config_path = os.environ.get("CONFI_PATH")
if config_path:
self._load_config_file(config_path)
else:
# use current directory as default location
current_dir = os.getcwd()
self._load_config_file(current_dir)
-
The updated code creates a new class called "Confi" that has a constructor that sets some initial values and creates some instance variables. The class also contains a new method called "_load_config_file" which accepts a file path as its parameter, this method is responsible for reading and parsing the config files.
-
The class also contains a new method called "load_config" which is responsible for loading the config files from the specified location. This method first checks for the location specified by the user through the environment variable "CONFI_PATH", if it exists, it will use that location to load the config files. If the environment variable is not set, it will use the current directory as the default location to load the config files.
-
This allows the users to have more control over their config files, they can specify the location of their config files using the environment variable "CONFI_PATH" or if not set, the default location will be the current directory.
Hi I think you got the right direction here, but note the trick is with "_load_config_file" as this bit of the code is within decouple, and not part of OPAL's direct code
Hi @orweis One approach is to modify the decouple library to accept an additional parameter that specifies the location of the configuration files. This could be done by adding a new argument to the config function that takes the path to the config files as input.
Hi @Rajat0002 :)
As we don't want to fork decouple - I think we can work with inheritance -
In confi
we import and use config
from decouple, which is an instance of AutoConfig
Instead we can inherit from AutoConfig
and create another class - which overrides the internal SUPPORTED
static member or the method _find_file
https://github.com/HBNetwork/python-decouple/blob/9cc2f7e3b2f82d306b981975da2925f05a816f51/decouple.py#L188