Repository navigation
refactor(no-ticket): share one v2 API client - #478
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Redirects can expose API keys, and retries prevent the advertised 30-second overall timeout.
3 open findings
What changed in this PR
Introduces a shared client for unsupported v2 API endpoints and migrates metadata requests to it.
Changes:
- Adds shared v2 request, authentication, URL validation, and JSON helpers.
- Applies request timeouts and adds focused tests.
- Refactors metadata operations to use the shared client.
| File | Description |
|---|---|
cloudsmith_cli/core/api/v2.py |
Adds the shared v2 API client. |
cloudsmith_cli/core/api/metadata.py |
Delegates metadata requests to the shared client. |
cloudsmith_cli/core/tests/test_v2.py |
Tests origin validation and timeout propagation. |
CHANGELOG.md |
Documents timeout behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
tigh-latte
approved these changes
Oct 13, 2026
tigh-latte
left a comment
Collaborator
There was a problem hiding this comment.
Looks good! one non blocking q
Move the v2 HTTP client from core/api/metadata.py to core/api/v2.py so that other v2 endpoints can use it. Add request_url for absolute URLs such as pagination links. It refuses a URL on another scheme or host, so the API key goes only to the configured host. Give every v2 request a 30-second timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Requests drops the Authorization header on a redirect to another host, but it sends the X-Api-Key header on. The v2 session now drops that header under the same rule. Add the copyright header to the new files. The CHANGELOG now says that the 30-second timeout applies to each attempt, because the CLI retries a request that times out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntial The v2 client read the API key and the SSO header back from the SDK Configuration. That copied the auth logic from initialise_api. Now each v2 call takes the CredentialResult that resolve_credentials gives, and uses its auth_headers(). Tests cover the API key, the SAML access token, no credential, the user agent, extra headers, the proxy and SSL verification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shared retry setup retries a request after a read timeout for every method. A slow POST that the server accepts is then sent again, and can create a second metadata entry. A v2 POST now gets only a connect timeout. The SAML metadata test now gets its bearer token only from the credential argument. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_requests_session now builds the session that drops X-Api-Key on a redirect to another host. The v1 SDK client, uploads, downloads and the v2 client all use it. Requests already drops the Authorization header in the same case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cloudsmith-iduffy
force-pushed
the
iduffy/shared-v2-client
branch
from
October 14, 2026 23:07
a399cb8 to
6300a05
Compare
cloudsmith-iduffy
added this pull request to the merge queue
Oct 14, 2026
Any commits made after this event will not be merged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
The CLI calls a few v2 API endpoints that the generated
cloudsmith_apiSDK does not cover. The HTTP code for those calls lived as private helpers incore/api/metadata.py. This PR moves it tocore/api/v2.py, so the next v2 endpoint can use the same code without copying it. The metadata functions now callv2.get_client(),v2.request()andv2.response_json().The v2 client now authenticates with the credential that
resolve_credentialsgives the command (opts.credential), throughCredentialResult.auth_headers(). Before, it read the API key and the SSOAuthorizationheader back from the SDKConfiguration, and copied the precedence logic frominitialise_api. An API key goes inX-Api-Key. A SAML access token goes inAuthorization: Bearer. Each metadata function takes acredentialkeyword argument, and themetadataandpushcommands passopts.credential. The host, proxy, SSL verification, user agent,--api-headersand retry settings still come from theConfigurationthatinitialise_apisets.The client also gets these changes:
request_url()sends a request to an absolute URL, such as aLink: rel="next"pagination link. It refuses a URL on another scheme or host, so the API key or SSO token goes only to the configured API host.Authorizationheader in that case, but it sendsX-Api-Keyon.create_requests_session()now builds anApiKeySafeSessionthat drops that header under the same rule. The v1 SDK client, uploads, downloads and the v2 client all use it.--error-retry-maxsets. With the default of 6 retries and the backoff, a stalled API holds a command for some minutes.metadata addthat the server accepts would be sent again and create a second entry.The v1 SDK client does not get the timeout in this PR. Its calls need their own timeout values, so I will fix that separately.
When
--api-headerssets anAuthorizationheader and an API key also resolves, the v2 client now sends both headers. The v1 SDK client already does this.Type of Change
Additional Notes
core/tests/test_v2.pycovers the API key, the SAML access token, no credential, the origin check, the redirect for both credential types, the timeout, the user agent and extra headers, and the proxy and SSL verification settings.core/tests/test_rest.pycovers the redirect rule for the shared session.I tested
metadata listagainst staging with the CLI's credential chain:CLOUDSMITH_NO_KEYRING=1 CLOUDSMITH_API_KEY=<service key> cloudsmith metadata list <workspace>/<repo>/<package> --api-host <staging host>returns 200.Authorization: Bearer.🤖 Generated with Claude Code