Add versioned management API wrappers#126
Open
kesmit13 wants to merge 15 commits into
Open
Conversation
Implement version-switchable management API layer so clients can access specific API versions (v1, v2) from an existing manager or entity without creating separate managers from scratch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Store resolved token (not input None) in Manager._access_token so versioned clones don't re-resolve or fail - Handle wrapper managers (JobsManager, InferenceAPIManager) in VersionedMixin._get_versioned via a third code path that clones with the versioned parent manager - Remove manage_* factory re-exports from v2 modules (they'd return v1 objects since they hardcode v1 class construction) - Add missing re-exports: Organization in workspace shim, FileSpace in v2/files, space constants in files shim, _get_exports in v2/export - Add tests for wrapper manager version-switching and token storage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the never-production ClusterManager (v0beta) entirely and fix three VersionedMixin bugs: entity from_dict arity mismatch, wrapper manager misclassification, and FilesObject missing _response/_manager. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix import error masking in _import_versioned_module by validating version format and only catching ModuleNotFoundError for the expected path. Add None guards on _manager in entity/wrapper paths. Fix docstring copy/paste error, clarify ADR re-export behavior, remove dead .flake8 entry. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route entity and wrapper-manager version switches through getattr(self._manager, version) instead of calling _get_versioned directly, so they share the same cached versioned manager instance that mgr.v2 returns. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ports - Replace fromisoformat() with to_datetime_strict() in UsageItem.from_dict() - Fix snake_case key access (resource_type -> resourceType, Usage -> usage) - Propagate _location and region after entity version-switch reconstruction - Return List[ExportStatus] from _get_exports() instead of raw JSON - Fix region.py module docstring and manage_files docstring Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v2 region listings have no regionID, so v2 Region instances carry id=None. The previous lookup matched only on id, falling back to a '<unknown>' placeholder for every workspace group on a v2 manager. Now match by id first, then by (regionName, provider), and use payload fields for the final fallback so users see real region info even when no listing match exists. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Addresses Copilot PR review comments 3365002592 and 3365002611 on PR #126. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- v2/workspace.py: fall back to self._manager.v1.organization.id in WorkspaceGroup.get_metrics. v2 has no organizations/current endpoint and the OpenAPI spec for the v2 metrics endpoint explicitly directs callers to /v1/organizations/current. Docstring updated to make this cross-version exception explicit. - versioned.py: _import_versioned_module now distinguishes between an unsupported API version (the version package itself is missing) and a missing submodule under a valid version. Unrelated ModuleNotFound errors (e.g., transitive deps inside a valid module) propagate untouched instead of being masked. - test_versioned_management.py: updated tests to assert the new submodule-missing message and rewired metrics fallback tests to stub the v1 clone's organization via _version_cache. Addresses Copilot PR review comments 3375344342 and 3375344393 on PR #126. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5196df8. Configure here.
- Add path-traversal containment check in recursive folder downloads. New `singlestoredb.management.utils.ensure_within` resolves both the destination root and the candidate target via realpath and raises ManagementError if the target escapes the root. Applied in `FileLocation.download_folder` (file and directory branches) and `Stage.download_folder`. Defends against `../` segments and symlink escapes from a malicious or compromised remote listing. - Route the v1-namespace `manage_regions`, `manage_workspaces`, and `manage_files` factories through `_import_versioned_module` so that `version='v2'` returns the correct v2 manager class instead of a v1 manager pointed at a `/v2/` base URL. - Convert `singlestoredb/management/v1/inference_api.py` imports from absolute (`from singlestoredb.*`) to the relative form used by the rest of the v1 modules. - Fix over-indented continuation lines on two `get_executions` signatures in `v1/job.py`. - Rename `self` to `cls` (and use `cls(...)` for construction) in `ExportService.from_export_id`, which is a `@classmethod`. - Add tests for path-traversal rejection in both download_folder methods and for v1-namespace factory routing to v2. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Stage.upload_folder ignored stage_path and built remote targets from the
local filesystem path (with os.getcwd() basename when include_root=True),
and crashed on subdirectories because glob('**') yields directories.
FileSpace.upload_folder used str.lstrip(local_path), which strips a
character set rather than a prefix, producing incorrect remote paths.
Both now walk files via os.walk, compute the per-file suffix with
os.path.relpath, and honor include_root and recursive=False consistently.
…nager The v2 RegionManager raised a custom ManagementError when callers used list_shared_tier_regions, on the grounds that /v2/regions/sharedtier has no OpenAPI counterpart. Every other v1 endpoint without a v2 counterpart just 404s through the inherited request path, so singling out this one method gave a misleading impression of v2 endpoint coverage. Drop the override, the related docstring paragraph, the now-unused ManagementError import, and the test that asserted the raise — falling back to the same 404 path used by the rest of the v2 surface. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.



Summary
mgr.v2/entity.v2attribute syntaxmanagement/v1/andmanagement/v2/folders; top-level modules become thin re-export shims routing viaconfig.get_option('management.version')VersionedMixinproviding cached__getattr__-based version switching for both managers and entities, with credential cloning andfrom_dictreconstructionTest plan
test_versioned_management.pycovering:__getattr__pattern matching and cachingfrom_dict+ versioned managermanage_*()version routingManagementError)management.versionconfig option routing🤖 Generated with Claude Code
Note
Medium Risk
Large refactor of management client layout plus removal of
manage_cluster; version switching and factory routing affect how all management HTTP calls are targeted.Overview
Introduces a versioned management API layer (ADR 0001): implementations live under
management/v1/andmanagement/v2/, while top-level modules stay as v1 re-export shims so existing imports keep working.VersionedMixinonManagerand entities enables cached.v1/.v2access—managers clone credentials to the right API base URL; entities rebuild from stored_responsevia the target version’sfrom_dict.manage_*()factories (e.g.manage_files,manage_regions) now pick the module frommanagement.version(or theversionargument) through dynamic import.Breaking cleanup: deprecated
manage_clusterandcluster.pyare removed from the package surface.Alongside the move, v1 picks up small fixes (billing usage JSON keys, export status listing,
ensure_withinon folder downloads, files upload path handling) and entities gain_response/ mixin wiring for version switching.Reviewed by Cursor Bugbot for commit b01a039. Bugbot is set up for automated code reviews on this repo. Configure here.