def test_basic_configclass_with_env_reader(): env_src = EnvironmentSource( environ={ "ENVIRONMENT": "test", "LOG_LEVEL": "info", "HOST": "localhost", "PORT": "8080", "API_KEY": "secret api key", "DISTRIBUTED": "FALSE", }) @configclass(sources=[env_src]) class Configuration: ENVIRONMENT: Environment LOG_LEVEL: LogLevel HOST: str PORT: int API_KEY: str DISTRIBUTED: bool config = Configuration() assert config.ENVIRONMENT == Environment.Test assert config.LOG_LEVEL == LogLevel.Info assert config.HOST == "localhost" assert config.PORT == 8080 assert config.API_KEY == "secret api key" assert config.DISTRIBUTED == False
def test_configclass_with_defaults(): env_src = EnvironmentSource(environ={}) @configclass(sources=[env_src]) class Configuration: INT_FIELD: int = 1 STRING_FIELD: str = "default string" config = Configuration() assert config.INT_FIELD == 1 assert config.STRING_FIELD == "default string"
def test_basic_configclass_with_missing_values(): env_src = EnvironmentSource(environ={ "HOST": "localhost", }) @configclass(sources=[env_src]) class Configuration: HOST: str PORT: int with pytest.raises(ValueError): config = Configuration()
def test_basic_configclass_reload(): environ = { "HOST": "localhost", } env_src = EnvironmentSource(environ=environ) @configclass(sources=[env_src]) class Configuration: HOST: str config = Configuration() assert config.HOST == "localhost" environ["HOST"] = "newhost" assert config.HOST == "localhost" config.reload() assert config.HOST == "newhost"
def test_environment_source(): environ = {"VAR1": "1", "var2": "2"} src = EnvironmentSource(environ=environ) assert src.get("VAR1") == "1" assert src.get("var2") == "2" assert src.get("var3", "3") == "3" assert src.get("Var1") is MISSING assert src.get("VAR2") is MISSING assert src.get("var3") is MISSING
def test_converter_configclass(): json_field = {"a": 1, "b": 2} kv_field = {"c": "3", "d": "4"} env_src = EnvironmentSource( environ={ "JSON_FIELD": json.dumps(json_field), "KV_FIELD": ",".join(f"{k}={v}" for k, v in kv_field.items()), }) @configclass(sources=[env_src]) class Configuration: JSON_FIELD: dict = field(converter=json.loads) KV_FIELD: dict = field(converter=csv_pairs) config = Configuration() assert config.JSON_FIELD == json_field assert config.KV_FIELD == kv_field
def test_environment_source_reload(): environ = {"VAR1": "1", "var2": "2"} src = EnvironmentSource(environ=environ) assert src.get("VAR1") == "1" assert src.get("VAR3") is MISSING environ["VAR1"] = "one" environ["VAR3"] = "three" src.reload() assert src.get("VAR1") == "one" assert src.get("VAR3") == "three"
def test_basic_configclass_with_multiple_readers(): env_src = EnvironmentSource( environ={ "ENVIRONMENT": "test", "LOG_LEVEL": "info", "HOST": "localhost", "PORT": "8080", "API_KEY": "secret api key", "DISTRIBUTED": "FALSE", }) # single nesting json_str = json.dumps({ "APP-1": { "HOST": "app-1-localhost", "PORT": 1234 }, "APP-2": { "HOST": "app-2-localhost", "PORT": 5678 }, }) json_src = JsonSource(filehandle=io.StringIO(json_str), namespace=["APP-1"]) # json_src values take precidence over env_src values @configclass(sources=[env_src, json_src]) class Configuration: ENVIRONMENT: Environment LOG_LEVEL: LogLevel HOST: str PORT: int API_KEY: str DISTRIBUTED: bool config = Configuration() assert config.ENVIRONMENT == Environment.Test assert config.LOG_LEVEL == LogLevel.Info assert config.HOST == "app-1-localhost" assert config.PORT == 1234 assert config.API_KEY == "secret api key" assert config.DISTRIBUTED == False
def test_namespaced_environment_source(): environ = {"JB_VAR1": "1", "VAR1": "not 1", "jb_VAR2": "2"} src = EnvironmentSource(namespace="JB_", environ=environ) assert src.get("VAR1") == "1" assert src.get("VAR2") is MISSING assert src.get("VAR2", "2") == "2"