Skip to content

Commit

Permalink
fix: attempt to parse env vars into python types in config (#51)
Browse files Browse the repository at this point in the history
* fix: attempt to parse env vars into python types in config

* add negatives + more bool cases
  • Loading branch information
matt-codecov committed Sep 29, 2023
1 parent acbebf5 commit ef9f461
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
18 changes: 18 additions & 0 deletions shared/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import logging
import os
import re
from base64 import b64decode
from copy import deepcopy
from typing import Any, List, Tuple
Expand Down Expand Up @@ -89,6 +90,22 @@ def load_env_var(self):
current[multiple_level_vars[-1].lower()] = data
return val

def _env_var_value_cast(self, data):
if isinstance(data, str):
if data in ("true", "True", "TRUE", "on", "On", "ON"):
return True
elif data in ("false", "False", "FALSE", "off", "Off", "OFF"):
return False
elif re.match(r"^-?\d+$", data):
return int(data)
elif re.match(r"^-?\d+\.\d+$", data):
try:
return float(data)
except ValueError as e:
pass

return data

def _parse_path_and_value_from_envvar(
self, env_var_name: str
) -> Tuple[List[str], Any]:
Expand All @@ -112,6 +129,7 @@ def _parse_path_and_value_from_envvar(
path_to_use = env_var_name if not should_load_from_json else env_var_name[13:]
data = os.getenv(env_var_name)
data = data if not should_load_from_json else json.loads(data)
data = self._env_var_value_cast(data)
return (path_to_use.split("__"), data)

@property
Expand Down
46 changes: 43 additions & 3 deletions tests/unit/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,46 @@ def test_get_config_minio_with_port(self, mocker):
"hash_key": "ab164bf3f7d947f2a0681b215404873e",
}

def test_parse_path_and_value_from_envvar(self, mocker):
this_config = ConfigHelper()
mock_env = {
"CONVERT__TO__BOOL__TRUE1": ("true", True),
"CONVERT__TO__BOOL__TRUE2": ("True", True),
"CONVERT__TO__BOOL__TRUE3": ("TRUE", True),
"CONVERT__TO__BOOL__TRUE4": ("on", True),
"CONVERT__TO__BOOL__TRUE5": ("On", True),
"CONVERT__TO__BOOL__TRUE6": ("ON", True),
"CONVERT__TO__BOOL__FALSE1": ("false", False),
"CONVERT__TO__BOOL__FALSE2": ("False", False),
"CONVERT__TO__BOOL__FALSE3": ("FALSE", False),
"CONVERT__TO__BOOL__FALSE4": ("off", False),
"CONVERT__TO__BOOL__FALSE5": ("Off", False),
"CONVERT__TO__BOOL__FALSE6": ("OFF", False),
"CONVERT__TO__INT__123": ("123", 123),
"CONVERT__TO__INT__-123": ("-123", -123),
"CONVERT__TO__FLOAT__12.3": ("12.3", 12.3),
"CONVERT__TO__FLOAT__-12.3": ("-12.3", -12.3),
"LEAVE__ALONE__MALFORMED__TRUE1": ("TrUe", "TrUe"),
"LEAVE__ALONE__MALFORMED__TRUE2": ("oN", "oN"),
"LEAVE__ALONE__MALFORMED__FALSE1": ("FaLse", "FaLse"),
"LEAVE__ALONE__MALFORMED__FALSE2": ("oFF", "oFF"),
"LEAVE__ALONE__MALFORMED__FLOAT": ("12.3.4", "12.3.4"),
"LEAVE__ALONE__STRING": ("hello world", "hello world"),
}

mocker.patch.dict(
os.environ,
{k: v[0] for k, v in mock_env.items()},
)

for k, v in mock_env.items():
expected_path = k.split("__")
env_val, expected_val = v
assert this_config._parse_path_and_value_from_envvar(k) == (
expected_path,
expected_val,
)

def test_load_env_var(self, mocker):
this_config = ConfigHelper()
mocker.patch.dict(
Expand Down Expand Up @@ -379,7 +419,7 @@ def test_load_env_var(self, mocker):
"minio": {
"hash_key": "hash_key",
"host": "minio-proxy",
"port": "9000",
"port": 9000,
"access_key_id": "SERVICES__MINIO__ACCESS_KEY_ID",
"secret_access_key": "SERVICES__MINIO__SECRET_ACCESS_KEY",
},
Expand All @@ -404,8 +444,8 @@ def test_load_env_var(self, mocker):
"media": {"assets": "aaa", "dependancies": "bbb"},
"encryption_secret": "secret",
"tasks": {"status": {"queue": "new_tasks"}},
"segment": {"enabled": "True", "key": "abc"},
"timeseries": {"enabled": "True"},
"segment": {"enabled": True, "key": "abc"},
"timeseries": {"enabled": True},
},
"github": {
"bot": {"key": "GITHUB__BOT__KEY"},
Expand Down

0 comments on commit ef9f461

Please sign in to comment.