[SILO-1466] feat: api_v2 support via client.v2 (406 operations) - #70
[SILO-1466] feat: api_v2 support via client.v2 (406 operations)#70Prashant-Surya wants to merge 2 commits into
Conversation
…operations
`client.v2` exposes every api_v2 operation through a single chained form rooted at
the workspace, mirroring the API's own scope tree:
ws = client.v2.workspace("acme") # zero-I/O locator
proj = ws.project("ENG") # key or UUID
proj.work_items.create(WorkItemWrite(name="Fix login bug", state="Todo"))
ws.work_items.retrieve_by_identifier("ENG-12")
ws.wiki.pages.create(PageWrite(name="Runbook")) # public page -> default collection
client.v2.users.me() # the six non-workspace operations
- Kernel: transport with RFC 9457 errors, offset/cursor envelopes with a stall
guard, ?fields/?expand/?order_by validated per operation against the golden,
upsert, bulk create/update/delete with per-row results, find_by_name, custom
verb actions, scope-bound resources (`V2Resource(transport, **scope)`).
- Spec-generated constants (`scripts/generate_v2_constants.py`) for all 406
operations; every implemented operation is declared in exactly one resource's
`operations` map and a two-way coverage test enforces 406/406.
- Method set is identical to @makeplane/plane-node-sdk (snake_case vs camelCase).
- Offline tests under tests/v2 (responses); live tests under tests/v2/integration
skip without PLANE_BASE_URL/PLANE_API_KEY/WORKSPACE_SLUG.
- CI: .github/workflows/test.yml runs the offline suite; a secret-gated
`v2-golden-drift` job regenerates the constants against plane-ee's golden.
- Version 0.3.0. v1 surface untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XXZ9CT96T1dZoiSYmtiNe
|
Important Review skippedToo many files! This PR contains 249 files, which is 149 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (249)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Linked to Plane Work Item(s)
This comment was auto-generated by Plane |
…ookups (review feedback)
Review feedback on the v2 surface (runs/sdk-v2-foundation/plans/2026-09-03-team-feedback.md,
items 1, 2 and the SDK-now part of 5).
Renames (work item type properties, project + workspace scoped):
- work_item_types.properties.attach(type_id, property_ids) -> link(type_id, property_ids)
- work_item_types.properties.detach(type_id, property_id) -> unlink(type_id, property_id)
(operations keys stay attach/detach; unlink docstring carries the web app warning)
Removed (manage verbs) -> replaced by bridge sub-resources with add/remove:
- cycles.manage_work_items -> cycles.work_items.add/remove
- modules.manage_work_items -> modules.work_items.add/remove
- milestones.manage_work_items -> milestones.work_items.add/remove
- customers.manage_work_items -> customers.work_items.add/remove
- releases.manage_work_items -> releases.work_items.add/remove
- releases.manage_labels -> releases.labels.add/remove
- initiatives.manage_work_items -> initiatives.work_items.add/remove
- initiatives.manage_projects -> initiatives.projects.add/remove
- initiatives.manage_labels -> initiatives.labels.add/remove
- wiki.collections.members.manage -> wiki.collections.members.add/remove
- wiki.collections.pages.manage -> wiki.collections.pages.add/remove
add POSTs {"add": [...]} and returns `added`; remove POSTs {"remove": [...]} and
returns `removed`; 0 or >100 ids raise ValueError before any request. One kernel
helper, V2Resource._bridge(key=, ids=, **path_params), plus `bridge_path` for
catalog resources whose own path is not the bridge URL. Each golden manage
operationId moves to its bridge class (406/406 still declared exactly once).
*Manage* request/response models stay as files but are no longer exported from
plane.models.v2 (CollectionMemberAdd stays public).
Added lookups (server-side via _find_one, golden filters verified):
- roles.find_by_slug(slug, *, namespace=None)
- estimates.points.find_by_key(estimate_id, key)
- work_item_properties.find_by_name(name) and workspace sibling (name = property key)
- work_item_properties.options.find_by_name(property_id, name), workspace sibling,
and workspace work_item_properties.contexts.find_by_name(property_id, name)
Tests: offline coverage for every new/renamed method incl. the 0/101-id guard and
exact JSON body per verb; all call sites converted, integration suite still
all-skip without env. README + CLAUDE.md v2 sections updated.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QwQ1tqb3831E7rezg5zqs
|
Review feedback landed as one commit on top (a57823e), so the delta is reviewable on its own. Public method tree stays identical to the Node SDK (513 = 513 after normalisation).
Checks on the new commit: |
◈ PR Lens
Architecture 14 components touched across 5 lanes. Inside the changed components — 3 viewsComponent view — V2 Kernel, Transport & Engine The core engine powering api_v2: V2Transport with session retry and RFC 9457 error decoding, generic V2Resource CRUD and bridge handler, pagination discrimination, and OpenAPI golden constants validation. Component view — Zero-I/O Locators & Scoping Hierarchy Zero-network-I/O locator chaining (client.v2.workspace(slug).project(id)) that binds path parameters in memory and exposes domain resources without making API calls. Component view — V2 Domain Resources & Membership Bridges The v2 domain resource suites for work items, planning, governance, and CRM/automations connecting to the V2Resource kernel for CRUD, bulk writes, and 100-item capped membership bridging. Data flow
The other flows — 2 sequences
Drill down
|
Description
Adds the complete Plane api_v2 surface to the Python SDK — 406 operations across 120 resource groups — as a single chained form rooted at the workspace, mirroring the API's own scope tree. v1 is untouched (every existing symbol resolves to the same v1 module).
plane/api/v2/_kernel/): transport with RFC 9457problem+jsonerrors, offset/cursor pagination with a stall guard,?fields/?expand/?order_byvalidated per operation against the OpenAPI golden, upsert, bulk create/update/delete with per-row results,find_by_name, custom verb actions, scope-bound resources.scripts/generate_v2_constants.py) for all 406 operations; every implemented operation is declared in exactly one resource'soperationsmap and a two-way coverage test enforces 406/406.Create<Resource>/Update<Resource>; models live inplane.models.v2.@makeplane/plane-node-sdk(snake_case vs camelCase).Type of Change
Test Scenarios
pytest tests/v2 --ignore=tests/v2/integration— 421 tests againstresponsesmocks asserting verb, exact URL, query, and body; error paths, stall guard, field/expand rejection, bulk cap, find-by-name ambiguity, two-way operation coverage.tests/v2/integrationskips withoutPLANE_BASE_URL/PLANE_API_KEY/WORKSPACE_SLUG; against a plane-dev instance: 362 passed, 23 skipped (feature-mode conflicts), 0 failed — includes an end-to-end scenario (test_full_scenario.py) and the two work-item-type flows ported from plane-ee.ruffclean on the v2 tree;mypyunchanged frommain(56 pre-existing v1 findings, 0 in v2).test.ymlruns the offline suite; a secret-gatedv2-golden-driftjob regenerates the constants against plane-ee's golden.Follow-ups (not in this PR)
pages_*operationIds sit on/collections/.References
[SILO-1463], plane-ee[SILO-1464](the live suite depends on that permission fix forusers/me,permissions/me,worklogs/summary).🤖 Generated with Claude Code
https://claude.ai/code/session_015XXZ9CT96T1dZoiSYmtiNe