Skip to content

feat: custom property context methods#44

Open
sunder-ch wants to merge 1 commit into
mainfrom
feat-custom-property-context
Open

feat: custom property context methods#44
sunder-ch wants to merge 1 commit into
mainfrom
feat-custom-property-context

Conversation

@sunder-ch
Copy link
Copy Markdown
Collaborator

@sunder-ch sunder-ch commented Jun 1, 2026

Overview

This PR implements workspace-level work item property contexts in the Plane Python SDK. This allows managing property visibility, requirement status, and default values across specific projects and work item types at the workspace level.

Key Changes

🚀 Workspace Work Item Property Contexts

  • New Sub-Resource: Created WorkspaceWorkItemPropertyContexts under the workspace_work_item_properties endpoint namespace (accessible via client.workspace_work_item_properties.contexts).
  • Endpoints Supported:
    • list(workspace_slug, property_id)
    • create(workspace_slug, property_id, data)
    • retrieve(workspace_slug, property_id, context_id)
    • update(workspace_slug, property_id, context_id, data)
    • delete(workspace_slug, property_id, context_id)
  • Data Models: Added WorkItemPropertyContext, CreateWorkItemPropertyContext, and UpdateWorkItemPropertyContext validation models.

Additionally, this PR fixes several pre-commit lint issues (Ruff, line lengths, duplicate methods, and variable shadowing).


Test Plan

1. Automated Integration & Unit Tests

Run the newly created unit/integration test suite:

conda run -n plane-pi pytest tests/unit/test_workspace_work_item_property_contexts.py
  • Coverage Details:
    • test_list_contexts_for_workspace_property: Verifies retrieving all contexts for a workspace property, checking that default contexts exist.
    • test_retrieve_context_for_workspace_property: Asserts specific property contexts can be retrieved by ID.
    • test_create_update_delete_context: Validates the full CRUD lifecycle on custom property contexts.
    • test_context_response_shape: Ensures the fields of WorkItemPropertyContext correctly parse all expected types (e.g. lists of projects, type IDs, options).

Summary by CodeRabbit

  • New Features

    • Added support for workspace-level work item property contexts with full CRUD operations (create, list, retrieve, update, delete).
  • Documentation

    • Updated SDK documentation to include workspace work item properties and property contexts with usage examples.
  • Chores

    • Bumped package version to 0.2.14.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces workspace-level work item property contexts as a new API sub-resource. Four context models are defined (response and request shapes), a new WorkspaceWorkItemPropertyContexts client class implements full CRUD operations, and the sub-resource is wired into the SDK's public API. Query parameter handling for workspace item listing is aligned, tests validate context operations, and README documentation covers usage patterns.

Changes

Workspace Work Item Property Contexts Feature

Layer / File(s) Summary
Work Item Property Context Data Models
plane/models/work_item_property_context.py
Pydantic models define request/response schemas: WorkItemPropertyContextOption with permissive extra-field handling, WorkItemPropertyContext response with scope/applicability/settings/audit fields, and CreateWorkItemPropertyContext/UpdateWorkItemPropertyContext request models with restrictive field configs.
WorkspaceWorkItemPropertyContexts API Client
plane/api/workspace_work_item_properties/contexts.py
New BaseResource-extending client class implements list(), create(), update(), retrieve(), and delete() methods; constructs workspace/property/context URL paths and delegates HTTP operations while validating responses into context models.
Public API Integration and Wiring
plane/api/workspace_work_item_properties/base.py, plane/__init__.py, plane/api/work_items/base.py, pyproject.toml
Contexts sub-resource wired into WorkspaceWorkItemProperties.__init__, context models exported from top-level plane package, WorkItems.list_workspace refactored to use prepare_work_item_params() for consistent filter normalization, and SDK version bumped to 0.2.14.
Tests, Documentation, and Supporting Changes
tests/unit/test_workspace_work_item_property_contexts.py, README.md, plane/models/milestones.py, tests/scripts/*, tests/unit/test_work_item_properties.py
New smoke and integration tests validate listing, retrieving, creating/updating/deleting contexts with response shape assertions; README documents contexts examples and adds resource to client structure; test suite import cleanup, formatting adjustments, and unused import removal across scripts.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • makeplane/plane-python-sdk#39: Introduces the base WorkspaceWorkItemProperties resource that this PR extends with the new contexts sub-resource.
  • makeplane/plane-python-sdk#37: Shared work on prepare_work_item_params() and filter JSON-encoding for workspace work-item listing, which this PR aligns list_workspace to use.
  • makeplane/plane-python-sdk#42: Related changes to WorkItems.list_workspace query parameter handling in the same workspace-level work-item listing flow.

Suggested reviewers

  • Prashant-Surya

Poem

🐰 Hopping through the property contexts, new models hop along,
CRUD clients dance in harmony, a workspace API song,
Tests bloom bright to validate, as docs show paths to take,
A sub-resource springs to life—with filters' gentle shake! 🌱

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature being added: custom property context methods for workspace-level work item properties.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-custom-property-context

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sunder-ch sunder-ch requested a review from Prashant-Surya June 1, 2026 06:10
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/unit/test_workspace_work_item_property_contexts.py (1)

63-114: 🏗️ Heavy lift

Method name/docstring don't match behavior; contexts.create/contexts.delete remain untested.

This test creates a property, updates the default context, and in teardown deletes the property. It never calls client.workspace_work_item_properties.contexts.create(...) or contexts.delete(...), so the two new CRUD endpoints introduced in this PR have no coverage. Either rename to reflect what it does (create-property / update-default-context) or extend it to actually create and delete a non-default context as the docstring claims.

Want me to draft a test that creates a non-default context (with project + work-item-type IDs) and deletes it via contexts.delete?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_workspace_work_item_property_contexts.py` around lines 63 -
114, The test currently only creates a property and updates the default context
but never exercises the new contexts.create and contexts.delete endpoints;
either rename the test to reflect it only updates the default context or extend
it to create and delete a non-default context: call
client.workspace_work_item_properties.contexts.create(workspace_slug, prop.id,
CreateWorkItemPropertyContext(...)) supplying explicit project and work item
type IDs (so applies_to_all_* are false), assert the returned context fields,
then retrieve it via contexts.retrieve, update if needed, and finally call
client.workspace_work_item_properties.contexts.delete(workspace_slug, prop.id,
created_ctx.id) and assert deletion (or that list no longer contains it); update
the test docstring to match the new behavior if you choose to extend rather than
rename.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/scripts/test_estimates_methods.py`:
- Line 24: The test currently performs a no-op os.getenv("PLANE_ACCESS_TOKEN")
and always initializes the client with only api_key, breaking the "API key or
access token" path; change the setup in tests/scripts/test_estimates_methods.py
to read and use the access token: assign access_token =
os.getenv("PLANE_ACCESS_TOKEN") (or similar), then initialize the client with
the access token when present (e.g., pass access_token or choose between api_key
and access_token) so the test covers the access-token auth path instead of
ignoring the env value.

---

Nitpick comments:
In `@tests/unit/test_workspace_work_item_property_contexts.py`:
- Around line 63-114: The test currently only creates a property and updates the
default context but never exercises the new contexts.create and contexts.delete
endpoints; either rename the test to reflect it only updates the default context
or extend it to create and delete a non-default context: call
client.workspace_work_item_properties.contexts.create(workspace_slug, prop.id,
CreateWorkItemPropertyContext(...)) supplying explicit project and work item
type IDs (so applies_to_all_* are false), assert the returned context fields,
then retrieve it via contexts.retrieve, update if needed, and finally call
client.workspace_work_item_properties.contexts.delete(workspace_slug, prop.id,
created_ctx.id) and assert deletion (or that list no longer contains it); update
the test docstring to match the new behavior if you choose to extend rather than
rename.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a9a02852-47c0-4777-86bc-2aa1be2337de

📥 Commits

Reviewing files that changed from the base of the PR and between 8e8240d and e7c5ad0.

📒 Files selected for processing (19)
  • README.md
  • plane/__init__.py
  • plane/api/milestones.py
  • plane/api/work_items/base.py
  • plane/api/workspace_work_item_properties/base.py
  • plane/api/workspace_work_item_properties/contexts.py
  • plane/models/__init__.py
  • plane/models/milestones.py
  • plane/models/work_item_property_configurations.py
  • plane/models/work_item_property_context.py
  • plane/models/workspaces.py
  • pyproject.toml
  • tests/scripts/test_archive.py
  • tests/scripts/test_cycles.py
  • tests/scripts/test_estimates_methods.py
  • tests/scripts/test_milestones.py
  • tests/scripts/test_work_item_types_and_properties.py
  • tests/unit/test_work_item_properties.py
  • tests/unit/test_workspace_work_item_property_contexts.py
💤 Files with no reviewable changes (3)
  • plane/api/milestones.py
  • plane/models/work_item_property_configurations.py
  • plane/api/work_items/base.py

base_url = os.getenv("PLANE_BASE_URL")
api_key = os.getenv("PLANE_API_KEY")
access_token = os.getenv("PLANE_ACCESS_TOKEN")
os.getenv("PLANE_ACCESS_TOKEN")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore access-token auth path in test setup.

Line 24 is now a no-op env read, and the client still initializes with only api_key. This breaks the documented “API key or access token” flow for this script.

Proposed fix
-    os.getenv("PLANE_ACCESS_TOKEN")
+    access_token = os.getenv("PLANE_ACCESS_TOKEN")
@@
-    client = PlaneClient(base_url=base_url, api_key=api_key)
+    client = PlaneClient(base_url=base_url, api_key=api_key, access_token=access_token)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/scripts/test_estimates_methods.py` at line 24, The test currently
performs a no-op os.getenv("PLANE_ACCESS_TOKEN") and always initializes the
client with only api_key, breaking the "API key or access token" path; change
the setup in tests/scripts/test_estimates_methods.py to read and use the access
token: assign access_token = os.getenv("PLANE_ACCESS_TOKEN") (or similar), then
initialize the client with the access token when present (e.g., pass
access_token or choose between api_key and access_token) so the test covers the
access-token auth path instead of ignoring the env value.

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