Package: lazy-env-configurator
LAZY_ENV_CONFIGURATORA utility library for Dynamic Config class generation. Now no more repeated boilerplate code...Beforelazy_env_configurator, config classes used to be created as below.classBaseConfig:APP=os.environ.get("APP")APP_ENV=os.environ.get("APP_ENV")# authentication related configuration# DB CredentialsDB_USERNAME=os.environ.get("DB_USERNAME")DB_PASSWORD=os.environ.get("DB_PASSWORD")DB_HOST=os.environ.get("DB_HOST")DB_PORT=os.environ.get("DB_PORT")DB_NAME=os.environ.get("DB_NAME")DB_DRIVER=os.environ.get("DB_DRIVER")This use to require a lot of boiler plate and redundant code Withlazy_env_configuratorthis can be reduced to below:fromlazy_env_configuratorimportBaseEnv,BaseConfigasConfig_classBaseConfig(BaseEnv):classConfig(Config_):envs=('APP','APP_ENV','DB_USERNAME','DB_PASSWORD','DB_PASSWORD','DB_HOST',# defaults('DB_PORT',3306),'DB_NAME','DB_DRIVER')Benefits of usinglazy_env_configuratorover Normal classesLow memory footprint.Lazily evaluates environment variable and only loads them when used.Once loaded, env variables are cached.Get defaults populated, in case of missingenvvariables.env attributes can be overridden easily.classes exposeinstanceattribute preventing need to initialization and making it behave singleton.Loads.envfiles by default so you only need to focus on essentials.Self Contained Objects if you do not want to sanatise global env variables.containedattribute.ComponentsBaseConfig: Main Config class for library. This changes behavior of the container class.envs:ListorTupleofenvvariable to be populated as attributes in container class. Elements of iterable can be astringortuplewith first element as attribute name and second asdefault, second element Defaults toNone. Eg:classConfig(Config_):envs=('APP','APP_ENV','DB_USERNAME','DB_PASSWORD','DB_PASSWORD','DB_HOST',# defaults('DB_PORT',3306),'DB_NAME','DB_DRIVER')dot_env_path: Path to.envfile. This can be a string orpathlib.Pathobject. defaults toNone. Eg:classConfig(Config_):dot_env_path=Path(__file__).parent/'.env'contained: This variable is responsible for behaviour of the container. If this is set toFalse, all theenvvariables read from.envfile would be populated toos.environand available globally. If this is set toTrue, environment variables would only be contained in the container itself. This would help to create configuration containers with different env settings. Itcontainedis set to true and no.envfile is present, it raisesEnvWarningand fallback to Environment variables. Eg:classConfig(BaseConfig):envs=("FOO","APP")dot_env_path=Path(__file__).parent/".env.contained"contained=TrueBaseEnv: This class will be used as aBase Classfor all the containers. It usesEnvMetaas metaclass to populateenvvariables as attributes on Container Class. Eg:fromlazy_env_configuratorimportBaseEnv,BaseConfigasConfig_classBaseConfig(BaseEnv):classConfig(Config_):envs=('APP','APP_ENV','DB_USERNAME','DB_PASSWORD','DB_PASSWORD','DB_HOST',# defaults('DB_PORT',3306),'DB_NAME','DB_DRIVER')Note:Configclass is optional. If not provided, it will not load any env variables.Configclass won't be available as an attribute on the child class.EnvMeta: Metaclass for populating env variables
as class attributes to the child class.
if the child class has a Config class, it will
be used to populate the env variables.by default, the env variables are populated on first access
and cached for subsequent access. This can be overriden by
setting the value on the instance.if the env variable is not set, it uses the default value provided.This class also initializes the instance of the child class and
make it available asinstanceattribute on the child class. So it can be accessed asChildClass.instance.Example:classABC(BaseEnv):defgenerate_uri(self):returnf'{self.DB_HOST}:{self.DB_PORT}'classConfig(BaseConfig):envs=('dev',('test','test_value'),'prd','DB_HOST','DB_PORT')dot_env_path=Path(__file__).parent/'.env.test'>>># access env variables>>>ABC.instance.dev>>>ABC.instance.test>>>ABC.instance.prdHow to useLet us refer below example:fromlazy_env_configuratorimportBaseEnv,BaseConfigasConfig_classBaseConfig(BaseEnv):classConfig(Config_):envs=('APP','APP_ENV','DB_USERNAME','DB_PASSWORD','DB_PASSWORD','DB_HOST',# defaults('DB_PORT',3306),'DB_NAME','DB_DRIVER')We can now useBaseConfigclass create as below.>>>BaseConfig.instance.APPEvery class, subclassed fromBaseEnvwould expose.instanceattribute which will be instance of the subclass. This instance can be used to access all the attributes on the class.For simplicity,metaclasspre-initialises created class, so to make it behave as singleton.How this works ?lazy_env_configuratorusesdescriptorsunder the hood to dynamically populate env variables as attributes, thus making them available on demand,Lazily.