Skip to content

Commit

Permalink
fix: handle invalid profiles (#141)
Browse files Browse the repository at this point in the history
Signed-off-by: Panos Vagenas <[email protected]>
  • Loading branch information
vagenas authored Oct 20, 2023
1 parent fa52a66 commit 61469d8
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ dmypy.json
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
pyvenv.cfg
.env
*.env
.venv
env/
venv/
Expand Down
7 changes: 6 additions & 1 deletion deepsearch/core/cli/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)
from deepsearch.core.cli.utils import cli_handler
from deepsearch.core.client.settings import ProfileSettings
from deepsearch.core.client.settings_manager import settings_mgr
from deepsearch.core.client.settings_manager import SettingsManager

app = typer.Typer(no_args_is_help=True)

Expand All @@ -35,6 +35,7 @@ def add_profile(
),
activate_profile: bool = typer.Option(default=True),
):
settings_mgr = SettingsManager()
prfl_name = (
profile_name if profile_name else settings_mgr.get_profile_name_suggestion()
)
Expand Down Expand Up @@ -63,6 +64,7 @@ def list_profiles() -> None:
"active",
"profile",
)
settings_mgr = SettingsManager()
profiles = settings_mgr.get_all_profile_settings()
active_profile = settings_mgr.get_active_profile()

Expand Down Expand Up @@ -98,6 +100,7 @@ def show_profile(
"profile",
"config",
)
settings_mgr = SettingsManager()
prfl_name = profile_name or settings_mgr.get_active_profile()
profile = settings_mgr.get_profile_settings(profile_name=prfl_name)

Expand All @@ -117,6 +120,7 @@ def show_profile(
def set_default_profile(
profile_name: str,
) -> None:
settings_mgr = SettingsManager()
settings_mgr.activate_profile(profile_name=profile_name)


Expand All @@ -129,4 +133,5 @@ def set_default_profile(
def remove_profile(
profile_name: str,
) -> None:
settings_mgr = SettingsManager()
settings_mgr.remove_profile(profile_name=profile_name)
5 changes: 3 additions & 2 deletions deepsearch/core/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import typer

from deepsearch.core.client.settings_manager import settings_mgr
from deepsearch.core.client.settings import CLISettings


def cli_handler():
Expand All @@ -14,7 +14,8 @@ def wrap(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
if settings_mgr.get_show_cli_stack_traces():
settings = CLISettings()
if settings.show_cli_stack_traces:
raise e
else:
typer.secho(str(e), fg=typer.colors.RED)
Expand Down
7 changes: 6 additions & 1 deletion deepsearch/core/client/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ def from_cli_prompt(cls) -> ProfileSettings:


class MainSettings(DumpableSettings):
profile: Optional[str] = None

profile: Optional[str] = None # None only when profiles not yet iniitialized
class Config:
env_prefix = "DEEPSEARCH_"


class CLISettings(DumpableSettings):
show_cli_stack_traces: bool = False

class Config:
Expand Down
34 changes: 21 additions & 13 deletions deepsearch/core/client/settings_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import Dict, Optional
from typing import Dict, List, Optional

import platformdirs
from pydantic import ValidationError
Expand All @@ -23,13 +23,13 @@

class KnownProfile(str, Enum):
SDS = "sds"
# DS_EXPERIENCE = "ds-experience" # TODO: uncomment once applicable
DS_EXPERIENCE = "ds-experience"
DS_INTERNAL = "ds-internal"


HOST_BY_PROFILE = {
KnownProfile.SDS.value: "https://sds.app.accelerate.science",
# KnownProfile.DS_EXPERIENCE.value: "https://deepsearch-experience.res.ibm.com", # TODO: uncomment once applicable
KnownProfile.DS_EXPERIENCE.value: "https://deepsearch-experience.res.ibm.com",
KnownProfile.DS_INTERNAL.value: "https://cps.foc-deepsearch.zurich.ibm.com",
}

Expand Down Expand Up @@ -61,15 +61,29 @@ def __init__(self) -> None:

# initialize internal profile cache from Pydantic Settings based on dotenv
self._profile_cache: Dict[str, ProfileSettingsEntry] = {}
paths_to_remove: List[Path] = []
for f in os.listdir(self._profile_root_path):
file_path = self._profile_root_path / f
if file_path.suffix == ".env":
profile_name = file_path.stem
self._profile_cache[profile_name] = ProfileSettingsEntry(
path=file_path,
settings=ProfileSettings(_env_file=file_path), # type: ignore
try:
profile_settings = ProfileSettings(_env_file=file_path) # type: ignore
# suppressing due to known Pydantic bug https://github.com/pydantic/pydantic/issues/3072
)

self._profile_cache[profile_name] = ProfileSettingsEntry(
path=file_path,
settings=profile_settings,
)
except ValidationError:
paths_to_remove.append(file_path)

# handle any invalid profiles
if paths_to_remove:
for path_to_rem in paths_to_remove:
path_to_rem.unlink()
profile_names = ", ".join([f'"{p.stem}"' for p in paths_to_remove])
err_msg = f"Following profiles were invalid and have been removed: {profile_names}; if needed please re-add"
raise RuntimeError(err_msg)

# reset any stale active profile config
if (
Expand Down Expand Up @@ -197,9 +211,3 @@ def remove_profile(self, profile_name: str) -> None:

prfl_settgs_entry = self._profile_cache.pop(profile_name) # update cache
prfl_settgs_entry.path.unlink() # remove file

def get_show_cli_stack_traces(self) -> bool:
return self._main_settings.show_cli_stack_traces


settings_mgr = SettingsManager()
3 changes: 2 additions & 1 deletion deepsearch/cps/client/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
DeepSearchKeyAuth,
)
from deepsearch.core.client.settings import ProfileSettings
from deepsearch.core.client.settings_manager import settings_mgr
from deepsearch.core.client.settings_manager import SettingsManager
from deepsearch.cps.apis import public as sw_client
from deepsearch.cps.client.components import (
CpsApiDataCatalogs,
Expand Down Expand Up @@ -164,6 +164,7 @@ def from_env(cls, profile_name: Optional[str] = None) -> CpsApi:
try:
settings = ProfileSettings()
except ValidationError:
settings_mgr = SettingsManager()
settings = settings_mgr.get_profile_settings(profile_name=profile_name)
return cls.from_settings(settings=settings)

Expand Down

0 comments on commit 61469d8

Please sign in to comment.