Skip to content

Commit ae56246

Browse files
MaorDavidzonclaude
andcommitted
Address self-review findings
- Use auth client for spec fetch (retries, headers, SSL handling) - Rename _resolve_credentials to public resolve_credentials - Replace SystemExit(1) with click.Abort for proper framework cleanup - Document monkey-patch of typer.main.get_group - Remove unused requests import from openapi_spec Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b1d97a9 commit ae56246

File tree

3 files changed

+24
-22
lines changed

3 files changed

+24
-22
lines changed

cycode/cli/app.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@
6464
_api_groups_to_register = get_api_command_groups()
6565

6666

67-
# Override the Typer's main to inject API groups into the Click group
67+
# Monkey-patch typer.main.get_group to inject API Click groups into the Typer CLI.
68+
# This is necessary because Typer doesn't support adding native Click groups directly.
69+
# Typer creates a new Click group on each get_group() call, so we intercept that call
70+
# and add our API groups to the result. The `app_typer is app` guard ensures we only
71+
# modify our own app, not other Typer apps in the process.
6872
_original_get_group = typer.main.get_group
6973

7074

cycode/cli/apps/api/api_command.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ def _make_api_request(
8282
"""Execute an API request using the CLI's standard auth client."""
8383
from urllib.parse import quote
8484

85-
from cycode.cli.apps.api.openapi_spec import _resolve_credentials
85+
from cycode.cli.apps.api.openapi_spec import resolve_credentials
8686
from cycode.cyclient.cycode_token_based_client import CycodeTokenBasedClient
8787

88-
cid, csecret = _resolve_credentials(client_id, client_secret)
88+
cid, csecret = resolve_credentials(client_id, client_secret)
8989
client = CycodeTokenBasedClient(cid, csecret)
9090

9191
# Substitute path parameters (URL-encoded to prevent path traversal)
@@ -234,7 +234,7 @@ def _callback(**kwargs: Any) -> None:
234234
)
235235
except Exception as e:
236236
click.echo(f'Error: {e}', err=True)
237-
raise SystemExit(1) from e
237+
raise click.Abort from e
238238

239239
click.echo(json.dumps(result, indent=2))
240240

cycode/cli/apps/api/openapi_spec.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
from pathlib import Path
77
from typing import Optional
88

9-
import requests
10-
119
from cycode.cli.consts import CYCODE_CONFIGURATION_DIRECTORY
1210
from cycode.cli.user_settings.credentials_manager import CredentialsManager
1311
from cycode.cyclient import config as cyclient_config
@@ -61,7 +59,7 @@ def _load_cached_spec() -> Optional[dict]:
6159
return None
6260

6361

64-
def _resolve_credentials(
62+
def resolve_credentials(
6563
client_id: Optional[str] = None, client_secret: Optional[str] = None
6664
) -> tuple[str, str]:
6765
"""Resolve credentials from args or the CLI's standard credential chain."""
@@ -81,28 +79,28 @@ def _resolve_credentials(
8179

8280

8381
def _fetch_and_cache_spec(client_id: Optional[str] = None, client_secret: Optional[str] = None) -> dict:
84-
"""Fetch OpenAPI spec from API and cache to disk."""
82+
"""Fetch OpenAPI spec from API and cache to disk.
83+
84+
Uses CycodeTokenBasedClient for auth and retries. The spec is served from the app URL,
85+
so we create a client with app_url as base instead of the default api_url.
86+
"""
8587
from cycode.cyclient.cycode_token_based_client import CycodeTokenBasedClient
8688

87-
cid, csecret = _resolve_credentials(client_id, client_secret)
88-
token = CycodeTokenBasedClient(cid, csecret).get_access_token()
89+
cid, csecret = resolve_credentials(client_id, client_secret)
8990

90-
# Fetch spec from app URL (spec is served from app, not api)
91-
app_url = cyclient_config.cycode_app_url
92-
spec_url = f'{app_url}{_OPENAPI_SPEC_PATH}'
93-
logger.info('Fetching OpenAPI spec from %s', spec_url)
91+
# Create a token-based client pointed at app URL (spec is served from app, not api)
92+
client = CycodeTokenBasedClient(cid, csecret)
93+
client.api_url = cyclient_config.cycode_app_url
94+
95+
spec_path = _OPENAPI_SPEC_PATH.lstrip('/')
96+
logger.info('Fetching OpenAPI spec from %s/%s', cyclient_config.cycode_app_url, spec_path)
9497

9598
try:
96-
response = requests.get(
97-
spec_url,
98-
headers={'Authorization': f'Bearer {token}'},
99-
timeout=60,
100-
)
101-
response.raise_for_status()
99+
response = client.get(spec_path)
102100
spec = response.json()
103-
except requests.RequestException as e:
101+
except Exception as e:
104102
raise OpenAPISpecError(
105-
f'Failed to fetch OpenAPI spec from {spec_url}. Check your authentication and network connectivity.'
103+
f'Failed to fetch OpenAPI spec. Check your authentication and network connectivity. Error: {e}'
106104
) from e
107105

108106
# Override server URL with API URL (supports on-premise installations)

0 commit comments

Comments
 (0)