Skip to content

Commit

Permalink
update EnvConfigValue to support optional override from env
Browse files Browse the repository at this point in the history
  • Loading branch information
cwharris committed May 16, 2024
1 parent f4ef956 commit a7e5921
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 27 deletions.
6 changes: 3 additions & 3 deletions morpheus/llm/services/nemo_llm_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,13 @@ class NeMoLLMService(LLMService):
"""

class APIKey(EnvConfigValue):
_CONFIG_NAME: str = "NGC_API_KEY"
_ENV_KEY: str = "NGC_API_KEY"

class OrgId(EnvConfigValue):
_CONFIG_NAME: str = "NGC_ORG_ID"
_ENV_KEY: str = "NGC_ORG_ID"

class BaseURI(EnvConfigValue):
_CONFIG_NAME: str = "NGC_API_BASE"
_ENV_KEY: str = "NGC_API_BASE"

def __init__(self,
*,
Expand Down
6 changes: 3 additions & 3 deletions morpheus/llm/services/openai_chat_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ class OpenAIChatClient(LLMClient):
"""

class OrgId(EnvConfigValue):
_CONFIG_NAME: str = "OPENAI_ORG_ID"
_ENV_KEY: str = "OPENAI_ORG_ID"

class APIKey(EnvConfigValue):
_CONFIG_NAME: str = "OPENAI_API_KEY"
_ENV_KEY: str = "OPENAI_API_KEY"

class BaseURL(EnvConfigValue):
_CONFIG_NAME: str = "OPENAI_BASE_URL"
_ENV_KEY: str = "OPENAI_BASE_URL"

_prompt_key: str = "prompt"
_assistant_key: str = "assistant"
Expand Down
20 changes: 14 additions & 6 deletions morpheus/utils/env_config_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,30 @@

class EnvConfigValue(ABC):

_CONFIG_NAME: str | None = None
_ENV_KEY: str | None = None
_ENV_KEY_OVERRIDE: str | None = None

def __init__(self, value: str, use_env: bool = True):

if use_env:
assert self.__class__._CONFIG_NAME is not None

if value is None:
value = os.environ.get(f"{self.__class__._CONFIG_NAME}_DEFAULT", None)
if value is None and self.__class__._ENV_KEY is not None:
value = os.environ.get(f"{self.__class__._ENV_KEY}", None)

if self.__class__._ENV_KEY_OVERRIDE is not None:
value = os.environ.get(f"{self.__class__._ENV_KEY_OVERRIDE}", value)

value = os.environ.get(f"{self.__class__._CONFIG_NAME}_OVERRIDE", value)
if value is None:
raise ValueError("value must not be None, but provided value was None and no environment-based default or override was found")

else:
if value is None:
raise ValueError("value is None and no environment-based default or override was found")
raise ValueError("value must not be none")

self._value = value

def __str__(self):
return self._value


# PB, DOCA, Asynchronious Programming, Strong C++ Programmer
56 changes: 41 additions & 15 deletions tests/test_env_config_value.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,54 @@
import os
from morpheus.utils.env_config_value import EnvConfigValue
from unittest import mock
import pytest

class MyApi:
class EnvDrivenValue(EnvConfigValue):
_ENV_KEY = "DEFAULT"
_ENV_KEY_OVERRIDE = "OVERRIDE"

class BaseUri(EnvConfigValue):
_CONFIG_NAME = "MY_API_BASE_URI"

def __init__(self, base_uri: BaseUri):
self._base_uri = str(base_uri)
class EnvDriverValueNoOverride(EnvConfigValue):
_ENV_KEY = "DEFAULT"


from unittest import mock
class EnvDrivenValueNoDefault(EnvConfigValue):
_ENV_KEY_OVERRIDE = "OVERRIDE"


def test_env_driven_value():
with mock.patch.dict(os.environ, clear=True, values={"DEFAULT": "default.api.com"}):
assert str(EnvDrivenValue(None)) == "default.api.com"
assert str(EnvDrivenValue("api.com")) == "api.com"

with mock.patch.dict(os.environ, clear=True, values={"DEFAULT": "default.api.com", "OVERRIDE": "override.api.com"}):
assert str(EnvDrivenValue("api.com")) == "override.api.com"
assert str(EnvDrivenValue("api.com", use_env=False)) == "api.com"

with pytest.raises(ValueError):
EnvDrivenValue(None, use_env=False)


def test_env_driven_value_no_override():
with mock.patch.dict(os.environ, clear=True, values={"DEFAULT": "default.api.com"}):
assert str(EnvDriverValueNoOverride(None)) == "default.api.com"
assert str(EnvDriverValueNoOverride("api.com")) == "api.com"

with mock.patch.dict(os.environ, clear=True, values={"DEFAULT": "default.api.com", "OVERRIDE": "override.api.com"}):
assert str(EnvDriverValueNoOverride("api.com")) == "api.com"
assert str(EnvDriverValueNoOverride("api.com", use_env=False)) == "api.com"

def test_os_config_value():

with mock.patch.dict(os.environ, clear=True, values={"MY_API_BASE_URI_DEFAULT": "default.api.com"}):
assert str(MyApi.BaseUri(None)) == "default.api.com"
def test_env_driven_value_no_default():
with mock.patch.dict(os.environ, clear=True, values={"DEFAULT": "default.api.com"}):
with pytest.raises(ValueError):
EnvDrivenValueNoDefault(None)

with mock.patch.dict(os.environ, clear=True, values={"MY_API_BASE_URI_DEFAULT": "default.api.com"}):
assert str(MyApi.BaseUri("api.com")) == "api.com"
assert str(EnvDrivenValueNoDefault("api.com")) == "api.com"

with mock.patch.dict(os.environ, clear=True, values={"MY_API_BASE_URI_DEFAULT": "default.api.com", "MY_API_BASE_URI_OVERRIDE": "override.api.com"}):
assert str(MyApi.BaseUri("api.com")) == "override.api.com"
with mock.patch.dict(os.environ, clear=True, values={"DEFAULT": "default.api.com", "OVERRIDE": "override.api.com"}):
assert str(EnvDrivenValueNoDefault("api.com")) == "override.api.com"
assert str(EnvDrivenValueNoDefault("api.com", use_env=False)) == "api.com"

with mock.patch.dict(os.environ, clear=True, values={"MY_API_BASE_URI_DEFAULT": "default.api.com", "MY_API_BASE_URI_OVERRIDE": "override.api.com"}):
assert str(MyApi.BaseUri("api.com", use_env=False)) == "api.com"
with pytest.raises(ValueError):
EnvDrivenValueNoDefault(None, use_env=False)

0 comments on commit a7e5921

Please sign in to comment.