bonito-cli 0.7.0__tar.gz → 0.7.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 (47) hide show
  1. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/PKG-INFO +1 -1
  2. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/__init__.py +1 -1
  3. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/api.py +41 -5
  4. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/pyproject.toml +1 -1
  5. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/.gitignore +0 -0
  6. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/CHANGELOG.md +0 -0
  7. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/CLI_SPEC.md +0 -0
  8. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/README.md +0 -0
  9. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/__main__.py +0 -0
  10. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/app.py +0 -0
  11. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/__init__.py +0 -0
  12. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/admin.py +0 -0
  13. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/agents.py +0 -0
  14. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/analytics.py +0 -0
  15. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/approval.py +0 -0
  16. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/audit.py +0 -0
  17. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/auth.py +0 -0
  18. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/chat.py +0 -0
  19. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/compliance.py +0 -0
  20. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/deploy.py +0 -0
  21. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/deployments.py +0 -0
  22. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/gateway.py +0 -0
  23. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/groups.py +0 -0
  24. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/init.py +0 -0
  25. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/kb.py +0 -0
  26. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/mcp.py +0 -0
  27. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/memory.py +0 -0
  28. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/models.py +0 -0
  29. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/plan.py +0 -0
  30. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/policies.py +0 -0
  31. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/projects.py +0 -0
  32. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/providers.py +0 -0
  33. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/rbac.py +0 -0
  34. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/routing.py +0 -0
  35. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/scheduler.py +0 -0
  36. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/secrets.py +0 -0
  37. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/commands/sso.py +0 -0
  38. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/config.py +0 -0
  39. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/examples/__init__.py +0 -0
  40. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/examples/enterprise.yaml +0 -0
  41. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/examples/multi-provider-failover.yaml +0 -0
  42. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/examples/quickstart.yaml +0 -0
  43. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/examples/support-agent.yaml +0 -0
  44. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/utils/__init__.py +0 -0
  45. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/utils/auth.py +0 -0
  46. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/utils/display.py +0 -0
  47. {bonito_cli-0.7.0 → bonito_cli-0.7.2}/bonito_cli/utils/feature_gate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bonito-cli
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: Bonito CLI — Unified multi-cloud AI management from your terminal
5
5
  Author-email: Bonito <hello@getbonito.com>
6
6
  License: MIT
@@ -1,3 +1,3 @@
1
1
  """Bonito CLI — Unified multi-cloud AI management from your terminal."""
2
2
 
3
- __version__ = "0.6.0"
3
+ __version__ = "0.7.2"
@@ -9,7 +9,7 @@ import httpx
9
9
  from rich.console import Console
10
10
 
11
11
  from . import __version__
12
- from .config import get_api_key, get_api_url
12
+ from .config import get_api_key, get_api_url, get_refresh_token, save_credentials, load_credentials
13
13
 
14
14
  console = Console()
15
15
 
@@ -28,6 +28,7 @@ class BonitoAPI:
28
28
  def __init__(self) -> None:
29
29
  self.base_url: str = get_api_url()
30
30
  self._client: Optional[httpx.Client] = None
31
+ self._refreshing: bool = False
31
32
 
32
33
  # ── internal helpers ────────────────────────────────────────
33
34
 
@@ -51,6 +52,32 @@ class BonitoAPI:
51
52
  headers["Authorization"] = f"Bearer {token}"
52
53
  return headers
53
54
 
55
+ def _try_refresh(self) -> bool:
56
+ """Attempt to refresh the access token using the stored refresh token."""
57
+ refresh_token = get_refresh_token()
58
+ if not refresh_token:
59
+ return False
60
+ self._refreshing = True
61
+ try:
62
+ resp = self.client.request(
63
+ "POST", "/api/auth/refresh",
64
+ json={"refresh_token": refresh_token},
65
+ headers={"Content-Type": "application/json", "User-Agent": f"bonito-cli/{__version__}"},
66
+ )
67
+ if resp.status_code == 200:
68
+ tokens = resp.json()
69
+ creds = load_credentials()
70
+ creds["access_token"] = tokens["access_token"]
71
+ if tokens.get("refresh_token"):
72
+ creds["refresh_token"] = tokens["refresh_token"]
73
+ save_credentials(creds)
74
+ return True
75
+ except Exception:
76
+ pass
77
+ finally:
78
+ self._refreshing = False
79
+ return False
80
+
54
81
  def _request(
55
82
  self,
56
83
  method: str,
@@ -66,10 +93,19 @@ class BonitoAPI:
66
93
  except httpx.RequestError as exc:
67
94
  raise APIError(f"Connection failed: {exc}") from exc
68
95
 
69
- if resp.status_code == 401:
70
- raise APIError(
71
- "Authentication failed — run [cyan]bonito auth login[/cyan].", 401
72
- )
96
+ if resp.status_code == 401 and not self._refreshing:
97
+ if self._try_refresh():
98
+ # Retry the request with the new token
99
+ try:
100
+ resp = self.client.request(
101
+ method, url, json=data, params=params, headers=self._headers()
102
+ )
103
+ except httpx.RequestError as exc:
104
+ raise APIError(f"Connection failed: {exc}") from exc
105
+ if resp.status_code == 401:
106
+ raise APIError(
107
+ "Authentication failed — run [cyan]bonito auth login[/cyan].", 401
108
+ )
73
109
  if resp.status_code == 204:
74
110
  return {"status": "ok"}
75
111
  if resp.status_code >= 400:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bonito-cli"
7
- version = "0.7.0"
7
+ version = "0.7.2"
8
8
  description = "Bonito CLI — Unified multi-cloud AI management from your terminal"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes
File without changes
File without changes
File without changes