Skip to content

Release v0.6.0#17

Merged
loookashow merged 14 commits into
mainfrom
v0.6.0
Jul 21, 2026
Merged

Release v0.6.0#17
loookashow merged 14 commits into
mainfrom
v0.6.0

Conversation

@loookashow

Copy link
Copy Markdown
Contributor

Summary

Release of v0.6.0. Bumps foxnose-sdk to 0.6.0 and adds CHANGELOG.md.
All feature work is already merged into v0.6.0 via #12#16.

Warning

Breaking changes. This release renames the Folder API to Collection and
removes composite folder support. See the migration notes below.

Added

  • Typed billing exceptions in foxnose_sdk.errors (all subclasses of FoxnoseAPIError,
    exported from the package root and caught by except FoxnoseAPIError):
    • SpendCapExceeded (402 spend_cap_reached) — cap_usd, cycle_resets_at, raise_cap_url
    • PlanExhausted (402 plan_exhausted) — axis, window_resets_at, upgrade_url
    • PlanLimitExceeded (403 plan_limit_exceeded) — entity, limit, current, upgrade_url
    • RateLimitExceeded (429 rate_limited) — retry_after (from Retry-After header)
  • Components on CollectionsNestedFieldMeta helper and
    sync_collection_component() on ManagementClient / AsyncManagementClient
    to advance pinned nested fields to a target Component version. New models
    SyncComponentResponse, SyncComponentSkippedItem, ComponentSyncConflictDetail.

Changed

  • Renamed Folder → Collection across the Management API surface. New *_collection*
    methods (list_collections, create_collection, list_collection_versions,
    list_collection_fields, …) and models (CollectionSummary, CollectionList,
    APICollectionSummary, APICollectionList) are now preferred. The old *_folder*
    methods and FolderSummary / FolderList remain as deprecated aliases that emit a
    one-shot DeprecationWarning on first use and will be removed in 1.0.

Removed

  • Composite folder support.

Fixed

  • RolePermission.all_objects is now optional (bool | None) so non-object-based
    content types (API returns all_objects: null) parse without error.
  • Corrected the roles_and_permissions example and docs to the real permission
    wire-shape (content_type + actions), the renamed content-type keys
    (collection-structure / collection-items instead of folder-*), and the real
    API-key create shape (description + a single role).

Migration

  • Replace *_folder* calls with the *_collection* equivalents; old names still work
    but now emit a DeprecationWarning and go away in 1.0.
  • Content-type keys folder-structure / folder-itemscollection-structure / collection-items.
  • Remove any usage of composite folders.

Test plan

  • CI green (pytest matrix 3.9–3.12 + ruff)
  • New/updated suites: test_collections_methods*, test_collection_*, test_errors,
    test_deprecation, test_sync_collection_component (+27 files, ~3.0k additions)

loookashow and others added 12 commits May 26, 2026 10:13
…0.6.0)

Aligns the Python SDK with the FoxNose Management API naming change: the central entity is now Collection. All folder_* methods are kept as one-shot-deprecated aliases for a 90-day window so existing apps keep working unchanged.

What changed:
- New Collection-prefixed methods on ManagementClient covering the full CRUD + nested-tree + version-management surface (create_collection, list_collections, update_collection, delete_collection, get_collection_tree, get_collection_model, list_collection_versions, etc.).
- Existing folder_* methods now emit DeprecationWarning once per process on first call and delegate to the Collection-prefixed implementation.
- README updated to use Collection terminology; folder_* call-outs moved to a deprecation note.
- Wire payloads unchanged — JSON keys (folder, folder_key, folder_type, folder_id) are preserved, so server-side compatibility is unaffected.
…ections

feat: rename folder methods to collection across full SDK surface (0.6.0)
Adds first-class support for embedding Components into Collections via nested fields with explicit version pinning, and for advancing those pins with the new sync_component endpoint. Lands in the unreleased
0.6.0 branch.

What's new:
- NestedFieldMeta — Pydantic helper for building the `meta` block of a Collection nested field. Required: `component` (Component key) and `component_version` (specific published Component Version UID). Optional: `auto_update: bool = False` (when True, the server's
  auto-sync fanout advances this pin on each Component publish).
- ManagementClient.sync_collection_component and
  AsyncManagementClient.sync_collection_component — call the new `POST /v1/{env}/collections/{key}/sync_component/` endpoint. Accepts optional `field_paths: list[str]` and `to_versions: dict[str, str]` to scope the advance.
- Response types: SyncComponentResponse, SyncComponentSkippedItem, ComponentSyncConflictDetail.
- Skip reasons surfaced in `skipped[].reason`: `not_requested`, `auto_update_mode`, `already_at_target`, `component_not_found`, `component_unpublished`.
- Client-side preflight: when both `field_paths` and `to_versions` are supplied, every key in `to_versions` must also appear in `field_paths`. Misuse raises ValueError locally before any HTTP request.
- Server errors are mapped to FoxnoseAPIError:
  - 409 `component_sync_conflict` — target version would invalidate existing resources (structured `detail.conflicts`)
  - 422 `too_many_versions` — Collection schema quota exhausted
  - 422 `validation_error` — request body invalid
  - 404 — Collection or target version missing

Includes 15 new unit tests covering routing, body shape on both sync and async clients, the preflight check, and the NestedFieldMeta / SyncComponentResponse contracts.

README: new "Components on Collections" section with an end-to-end example (pin via NestedFieldMeta, sync via sync_collection_component).
SDK support for embedding Components into Collections
Composite folders and the per-resource component override have been
removed from the platform. This drops the matching SDK surface:

- FolderSummary no longer exposes `folder_type`
- ResourceSummary no longer exposes `component`
- create_resource / upsert_resource / batch_upsert_resources no longer
  accept a `component` argument (sync and async)
- BatchUpsertItem no longer accepts `component` and rejects it as an
  unknown field

A resource's schema is now always the schema of the collection it
belongs to. Passing a removed argument raises a clear error instead of
being silently ignored.
Add SpendCapExceeded, PlanExhausted, PlanLimitExceeded and RateLimitExceeded
as subclasses of FoxnoseAPIError, mapped by status_code + error_code at the
single raise point. Unknown codes on 402/403/429 stay generic; 402 is not
retried; 429 raises RateLimitExceeded after retries are exhausted.

Add CHANGELOG.md, a billing-errors README/docs section, and fix pre-existing
e.details -> e.detail references in docs and examples.
RolePermission.all_objects was a required bool, but the Management API
returns all_objects: null for non-object-based content types, so parsing
raised a ValidationError. Make it Optional. Rewrite the example and docs
to the real wire-shape (content_type + actions list, all_objects only on
object-based types collection-items/flux-apis) and the API-key create
shape (description + single role). Refresh docstrings and add tests.
FoxnoseAPIError exposes `detail`, not `details`, so the except blocks in
the examples would raise AttributeError when an API error was handled.
fix: align roles/permissions example and RolePermission with the real Management API wire-shape
feat: typed billing exceptions (402/403/429)
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

loookashow and others added 2 commits July 21, 2026 10:44
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
codecov/patch was failing (67% < 80%): the new v0.6.0 request-building
methods in management/client.py were not exercised by tests. Add wire-
behaviour tests asserting HTTP method, path, body and query for the
previously uncovered methods, bringing patch coverage to ~100%.
- test_collection_methods_wire.py: sync api-collection get/update,
  schema version CRUD, schema field get/update/delete, and the
  deprecated /folders/ aliases for all of the above
- test_collection_methods_wire_async.py: async parity for the same
- test_errors.py: malformed Retry-After (-> retry_after=None) and the
  _header_lookup edge cases
@loookashow
loookashow merged commit 9fed6dc into main Jul 21, 2026
6 checks passed
@loookashow
loookashow deleted the v0.6.0 branch July 21, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant