sovaria-cli 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/PKG-INFO +1 -1
  2. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/__init__.py +1 -1
  3. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/login.py +3 -3
  4. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/utils/config.py +29 -8
  5. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/tests/test_config_profiles.py +18 -0
  6. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/tests/test_main_startup.py +1 -1
  7. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/pyproject.toml +1 -1
  8. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/.github/workflows/ci.yml +0 -0
  9. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/.github/workflows/publish.yml +0 -0
  10. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/.gitignore +0 -0
  11. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/.python-version +0 -0
  12. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/Makefile +0 -0
  13. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/README.md +0 -0
  14. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/__init__.py +0 -0
  15. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/__init__.py +0 -0
  16. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/admin.py +0 -0
  17. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/api.py +0 -0
  18. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/audit.py +0 -0
  19. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/auth_product.py +0 -0
  20. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/billing.py +0 -0
  21. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/chrono.py +0 -0
  22. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/context.py +0 -0
  23. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/data.py +0 -0
  24. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/db.py +0 -0
  25. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/deploy.py +0 -0
  26. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/governance.py +0 -0
  27. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/iam.py +0 -0
  28. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/init_cmd.py +0 -0
  29. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/keys.py +0 -0
  30. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/org.py +0 -0
  31. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/policy.py +0 -0
  32. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/project.py +0 -0
  33. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/realtime.py +0 -0
  34. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/scope.py +0 -0
  35. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/shell.py +0 -0
  36. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/sim.py +0 -0
  37. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/storage.py +0 -0
  38. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/commands/vector.py +0 -0
  39. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/main.py +0 -0
  40. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/utils/__init__.py +0 -0
  41. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/utils/api_client.py +0 -0
  42. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/utils/auth_store.py +0 -0
  43. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/utils/display.py +0 -0
  44. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/utils/migrations.py +0 -0
  45. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/src/utils/project_context.py +0 -0
  46. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/tests/test_auth_store_profiles.py +0 -0
  47. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/tests/test_cli_security.py +0 -0
  48. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/tests/test_cli_smoke_paths.py +0 -0
  49. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/apps/cli/tests/test_project_and_commands.py +0 -0
  50. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/pytest.ini +0 -0
  51. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/requirements-dev.txt +0 -0
  52. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/requirements.txt +0 -0
  53. {sovaria_cli-0.2.0 → sovaria_cli-0.2.2}/scripts/cli_sdk_happy_path.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sovaria-cli
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Sovaria BaaS command-line interface (sov)
5
5
  Project-URL: Homepage, https://sovaria.in
6
6
  Project-URL: Documentation, https://docs.sovaria.in/cli
@@ -1,3 +1,3 @@
1
1
  """Sovaria CLI — sov command."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.2.2"
@@ -7,7 +7,7 @@ Phase 1 §9 Sprint 3.2:
7
7
 
8
8
  Flow:
9
9
  1. Generate code_verifier (43-128 random chars) + code_challenge = BASE64URL(SHA-256(verifier))
10
- 2. Open https://{api}/oauth/authorize?response_type=code&...&code_challenge=...
10
+ 2. Open https://{console}/cli/oauth/authorize?response_type=code&...&code_challenge=...
11
11
  3. Start a temporary HTTP callback server (configured via env variables).
12
12
  4. Exchange authorization_code + verifier for token pair.
13
13
  5. Persist tokens via auth_store.save_tokens().
@@ -33,7 +33,7 @@ import typer
33
33
 
34
34
  from apps.cli.src.utils.api_client import CLIMfaRequiredError, _apply_login_response
35
35
  from apps.cli.src.utils.auth_store import clear_mfa_pending, clear_tokens, load_mfa_pending, load_tokens, save_tokens
36
- from apps.cli.src.utils.config import get_api_url
36
+ from apps.cli.src.utils.config import get_api_url, get_console_url
37
37
 
38
38
  app = typer.Typer()
39
39
 
@@ -240,7 +240,7 @@ def _pkce_login(api_url: str, *, profile: str | None = None) -> None:
240
240
  state = secrets.token_hex(16)
241
241
  redirect_uri = _redirect_uri()
242
242
 
243
- auth_url = f"{api_url}/oauth/authorize?" + urlencode(
243
+ auth_url = f"{get_console_url(profile)}/cli/oauth/authorize?" + urlencode(
244
244
  {
245
245
  "response_type": "code",
246
246
  "client_id": "sovaria-cli",
@@ -30,6 +30,8 @@ from typing import Any, cast
30
30
  import yaml # PyYAML
31
31
 
32
32
  _CONFIG_FILE = Path.home() / ".sovaria" / "config.yaml"
33
+ DEFAULT_CLOUD_API_URL = "https://api.sovaria.in"
34
+ _DEFAULT_LOCAL_API_URL = "http://localhost:8000"
33
35
  _DEFAULT_API_URL = os.getenv("SOVARIA_CLI_DEFAULT_API_URL", "").strip()
34
36
  _DEFAULT_STAGING_API_URL = os.getenv("SOVARIA_CLI_STAGING_API_URL", "").strip()
35
37
  _DEFAULT_PROD_API_URL = os.getenv("SOVARIA_CLI_PROD_API_URL", "").strip()
@@ -66,6 +68,27 @@ def _expand_env(val: str) -> str:
66
68
  return re.sub(r"\$\{([^}]+)\}", _replace, val)
67
69
 
68
70
 
71
+ def _profile_env_default(profile: str) -> str:
72
+ if profile == "prod":
73
+ return _DEFAULT_PROD_API_URL or DEFAULT_CLOUD_API_URL
74
+ if profile == "staging":
75
+ return _DEFAULT_STAGING_API_URL or DEFAULT_CLOUD_API_URL
76
+ return _DEFAULT_API_URL or DEFAULT_CLOUD_API_URL
77
+
78
+
79
+ def get_console_url(profile: str | None = None) -> str:
80
+ """Console origin used for browser OAuth (PKCE) flows."""
81
+ explicit = os.getenv("SOVARIA_CLI_CONSOLE_URL", "").strip()
82
+ if explicit:
83
+ return explicit.rstrip("/")
84
+
85
+ api_url = get_api_url(profile)
86
+ if "://api." in api_url:
87
+ return api_url.replace("://api.", "://console.", 1).rstrip("/")
88
+
89
+ return "https://console.sovaria.in"
90
+
91
+
69
92
  def get_api_url(profile: str | None = None) -> str:
70
93
  cfg = _load_yaml()
71
94
  prof = profile or get_active_profile()
@@ -77,11 +100,9 @@ def get_api_url(profile: str | None = None) -> str:
77
100
  if should_save and _CONFIG_FILE.exists():
78
101
  _save_yaml(cfg)
79
102
  raw = cast(str, entry.get("api_url", "")).strip()
80
- api_url = _expand_env(raw) if raw else _DEFAULT_API_URL
103
+ api_url = _expand_env(raw) if raw else _profile_env_default(prof)
81
104
  if api_url:
82
- return api_url
83
- if _DEFAULT_API_URL:
84
- return _DEFAULT_API_URL
105
+ return api_url.rstrip("/")
85
106
  raise ValueError(
86
107
  "API URL is not configured. Set it in ~/.sovaria/config.yaml or "
87
108
  "SOVARIA_CLI_DEFAULT_API_URL."
@@ -166,18 +187,18 @@ def write_default_config() -> None:
166
187
  _CONFIG_FILE.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
167
188
  default = {
168
189
  "version": _SCHEMA_VERSION,
169
- "default_profile": "dev",
190
+ "default_profile": "prod",
170
191
  "profiles": {
171
192
  "dev": {
172
- "api_url": _DEFAULT_API_URL,
193
+ "api_url": _DEFAULT_API_URL or _DEFAULT_LOCAL_API_URL,
173
194
  "scope": {"org_id": "", "project_id": "", "env_id": ""},
174
195
  },
175
196
  "staging": {
176
- "api_url": _DEFAULT_STAGING_API_URL,
197
+ "api_url": _DEFAULT_STAGING_API_URL or DEFAULT_CLOUD_API_URL,
177
198
  "scope": {"org_id": "", "project_id": "", "env_id": ""},
178
199
  },
179
200
  "prod": {
180
- "api_url": _DEFAULT_PROD_API_URL,
201
+ "api_url": _DEFAULT_PROD_API_URL or DEFAULT_CLOUD_API_URL,
181
202
  "scope": {"org_id": "", "project_id": "", "env_id": ""},
182
203
  },
183
204
  },
@@ -34,6 +34,24 @@ def test_get_api_url_upgrades_unversioned_string_profile(
34
34
  assert parsed["profiles"]["dev"] == {"api_url": "http://localhost:8000"}
35
35
 
36
36
 
37
+ def test_get_api_url_defaults_to_cloud_when_unconfigured(
38
+ monkeypatch: pytest.MonkeyPatch, tmp_path: Path,
39
+ ) -> None:
40
+ config_file = tmp_path / ".sovaria" / "config.yaml"
41
+ monkeypatch.setattr(config, "_CONFIG_FILE", config_file)
42
+ monkeypatch.delenv("SOVARIA_CLI_DEFAULT_API_URL", raising=False)
43
+ monkeypatch.delenv("SOVARIA_CLI_PROD_API_URL", raising=False)
44
+
45
+ assert config.get_api_url("prod") == config.DEFAULT_CLOUD_API_URL
46
+
47
+
48
+ def test_get_console_url_defaults_from_api(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
49
+ monkeypatch.setattr(config, "_CONFIG_FILE", tmp_path / "missing.yaml")
50
+ monkeypatch.delenv("SOVARIA_CLI_CONSOLE_URL", raising=False)
51
+ monkeypatch.delenv("SOVARIA_CLI_DEFAULT_API_URL", raising=False)
52
+ assert config.get_console_url() == "https://console.sovaria.in"
53
+
54
+
37
55
  def test_get_scope_coerces_string_profile(
38
56
  monkeypatch: pytest.MonkeyPatch, tmp_path: Path
39
57
  ) -> None:
@@ -26,4 +26,4 @@ def test_sov_console_script_help() -> None:
26
26
  )
27
27
 
28
28
  assert result.returncode == 0
29
- assert "sov version 0.2.0" in result.stdout
29
+ assert "sov version 0.2.2" in result.stdout
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sovaria-cli"
7
- version = "0.2.0"
7
+ version = "0.2.2"
8
8
  description = "Sovaria BaaS command-line interface (sov)"
9
9
  readme = "apps/cli/README.md"
10
10
  requires-python = ">=3.11"
File without changes
File without changes
File without changes
File without changes