Skip to content

Commit 071acdf

Browse files
committed
Refine profile handling in prime config
1 parent 8dfec09 commit 071acdf

5 files changed

Lines changed: 400 additions & 22 deletions

File tree

packages/prime/src/prime_cli/commands/config.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@
1616

1717
# Team ID validation pattern: CUID (v1)
1818
TEAM_ID_PATTERN = re.compile(r"^c[a-z0-9]{24}$")
19+
PROFILE_OVERRIDE_ENV_VARS = (
20+
"PRIME_API_KEY",
21+
"PRIME_TEAM_ID",
22+
"PRIME_USER_ID",
23+
"PRIME_API_BASE_URL",
24+
"PRIME_BASE_URL",
25+
"PRIME_FRONTEND_URL",
26+
"PRIME_INFERENCE_URL",
27+
"PRIME_CONTEXT",
28+
)
1929

2030

2131
def validate_team_id(team_id: str) -> bool:
@@ -32,6 +42,23 @@ def validate_team_id(team_id: str) -> bool:
3242
return bool(TEAM_ID_PATTERN.match(team_id))
3343

3444

45+
def _active_profile_override_env_vars() -> list[str]:
46+
return [name for name in PROFILE_OVERRIDE_ENV_VARS if (os.getenv(name) or "").strip()]
47+
48+
49+
def _require_profile_env_unset(command: str) -> None:
50+
names = _active_profile_override_env_vars()
51+
if not names:
52+
return
53+
joined = ", ".join(names)
54+
console.print(
55+
f"[red]Error:[/red] {joined} {'is' if len(names) == 1 else 'are'} set in your "
56+
f"environment, so [bold]prime config {command}[/bold] cannot make a saved profile "
57+
"active. Unset the environment override and rerun the command."
58+
)
59+
raise typer.Exit(1)
60+
61+
3562
@app.command()
3663
def view() -> None:
3764
"""View current configuration"""
@@ -127,6 +154,7 @@ def set_api_key(
127154

128155
config = Config()
129156
config.set_api_key(api_key)
157+
config.update_current_environment_file()
130158

131159
if api_key:
132160
masked_key = f"{api_key[:6]}***{api_key[-4:]}" if len(api_key) > 10 else "***"
@@ -187,6 +215,7 @@ def set_team_id(
187215
pass
188216

189217
config.set_team(team_id, team_name=team_name, team_role=team_role)
218+
config.update_current_environment_file()
190219
if team_id:
191220
if team_name:
192221
console.print(f"[green]Team '{team_name}' ({team_id}) configured successfully![/green]")
@@ -201,6 +230,7 @@ def remove_team_id() -> None:
201230
"""Remove team ID to use personal account"""
202231
config = Config()
203232
config.set_team(None)
233+
config.update_current_environment_file()
204234
console.print("[green]Team ID removed. Using personal account.[/green]")
205235

206236

@@ -278,6 +308,7 @@ def _set_environment(
278308
env: str,
279309
) -> None:
280310
"""Set URLs for a specific environment"""
311+
_require_profile_env_unset(f"use {env}")
281312
config = Config()
282313

283314
# Try to load the environment (handles both built-in and custom)

packages/prime/src/prime_cli/core/config.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -355,27 +355,30 @@ def load_environment(self, name: str, persist: bool = True) -> bool:
355355
return False
356356

357357
def update_current_environment_file(self) -> None:
358-
"""Update the current environment's saved file with current config"""
359-
if self.current_environment != "production":
360-
# Only update custom environments, not the built-in production
361-
try:
362-
sanitized_name = self._sanitize_environment_name(self.current_environment)
363-
env_file = self.environments_dir / f"{sanitized_name}.json"
364-
if env_file.exists():
365-
env_config = {
366-
"api_key": self.api_key,
367-
"team_id": self.team_id,
368-
"team_name": None if self.team_id_from_env else self.team_name,
369-
"team_role": None if self.team_id_from_env else self.team_role,
370-
"user_id": self.user_id,
371-
"base_url": self.base_url,
372-
"frontend_url": self.frontend_url,
373-
"inference_url": self.inference_url,
374-
}
375-
env_file.write_text(json.dumps(env_config, indent=2))
376-
except ValueError:
377-
# Skip updating if environment name is invalid
378-
pass
358+
"""Update the active saved environment with the persisted config values."""
359+
if self.current_environment == "production":
360+
return
361+
362+
try:
363+
sanitized_name = self._sanitize_environment_name(self.current_environment)
364+
except ValueError:
365+
return
366+
367+
env_file = self.environments_dir / f"{sanitized_name}.json"
368+
if not env_file.exists():
369+
return
370+
371+
env_config = {
372+
"api_key": self.config.get("api_key", ""),
373+
"team_id": self.config.get("team_id"),
374+
"team_name": self.config.get("team_name"),
375+
"team_role": self.config.get("team_role"),
376+
"user_id": self.config.get("user_id"),
377+
"base_url": self.config.get("base_url", self.DEFAULT_BASE_URL),
378+
"frontend_url": self.config.get("frontend_url", self.DEFAULT_FRONTEND_URL),
379+
"inference_url": self.config.get("inference_url", self.DEFAULT_INFERENCE_URL),
380+
}
381+
env_file.write_text(json.dumps(env_config, indent=2))
379382

380383
def list_environments(self) -> list[str]:
381384
"""List all saved environment names"""

packages/prime/src/prime_cli/main.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,17 @@ def callback(
107107
typer.echo(f" - {env_name}", err=True)
108108
raise typer.Exit(1)
109109

110-
# Set environment variable so Config instances in subcommands pick it up
110+
previous_context = os.environ.get("PRIME_CONTEXT")
111+
112+
def restore_context() -> None:
113+
if previous_context is None:
114+
os.environ.pop("PRIME_CONTEXT", None)
115+
else:
116+
os.environ["PRIME_CONTEXT"] = previous_context
117+
118+
ctx.call_on_close(restore_context)
119+
120+
# Set environment variable so Config instances in subcommands pick it up.
111121
os.environ["PRIME_CONTEXT"] = context
112122

113123
# Check for updates (only when a subcommand is being executed)

packages/prime/tests/test_config_delete.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,32 @@
1111
"COLUMNS": "200",
1212
"LINES": "50",
1313
"PRIME_DISABLE_VERSION_CHECK": "1",
14+
"PRIME_API_KEY": "",
15+
"PRIME_TEAM_ID": "",
16+
"PRIME_USER_ID": "",
17+
"PRIME_API_BASE_URL": "",
18+
"PRIME_BASE_URL": "",
19+
"PRIME_FRONTEND_URL": "",
20+
"PRIME_INFERENCE_URL": "",
21+
"PRIME_CONTEXT": "",
1422
}
1523

1624

1725
@pytest.fixture
1826
def temp_home(tmp_path: Any, monkeypatch: pytest.MonkeyPatch) -> Path:
1927
monkeypatch.setenv("HOME", str(tmp_path))
2028
monkeypatch.setattr("prime_cli.main.check_for_update", lambda: (False, None))
29+
for name in (
30+
"PRIME_API_KEY",
31+
"PRIME_TEAM_ID",
32+
"PRIME_USER_ID",
33+
"PRIME_API_BASE_URL",
34+
"PRIME_BASE_URL",
35+
"PRIME_FRONTEND_URL",
36+
"PRIME_INFERENCE_URL",
37+
"PRIME_CONTEXT",
38+
):
39+
monkeypatch.delenv(name, raising=False)
2140
return tmp_path
2241

2342

0 commit comments

Comments
 (0)