Skip to content

feat: Add lite list endpoints, project role distribution, and cycle status filtering to the SDK#56

Merged
dheeru0198 merged 4 commits into
mainfrom
lite-endpoints
Jun 30, 2026
Merged

feat: Add lite list endpoints, project role distribution, and cycle status filtering to the SDK#56
dheeru0198 merged 4 commits into
mainfrom
lite-endpoints

Conversation

@gurusainath

@gurusainath gurusainath commented Jun 25, 2026

Copy link
Copy Markdown
Member

Description

Added support for new SDK APIs to improve project, cycle, module, and workspace querying.

Changes

Lite List Endpoints

Added support for:

  • projects.list_lite()
  • cycles.list_lite()
  • modules.list_lite()

These endpoints return lightweight, cursor-paginated responses for picker and lookup use cases.

Project Role Distribution

Added:

  • workspaces.get_project_role_distribution()

This endpoint returns project member distribution across workspace roles.

Cycle Status Filtering

Added support for cycle status filtering using:

  • current
  • upcoming
  • completed
  • draft
  • incomplete

Also added support for the deprecated cycle_view alias on the full cycle list endpoint.

SDK Updates

  • Added new query parameter models.
  • Added new response models for project role distribution.
  • Updated enums and model exports.
  • Updated README with new APIs and usage examples.

Test Scenarios

  • Verified lite project, cycle, and module endpoints.
  • Tested workspace project role distribution endpoint.
  • Verified cycle status filtering for all supported values.
  • Tested pagination and query parameter serialization.
  • Confirmed backward compatibility with existing SDK APIs.
  • Verified documentation examples and unit tests.

@gurusainath gurusainath self-assigned this Jun 25, 2026
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds lite-list query parameters, lite response models, client list_lite methods for projects, cycles, and modules, plus a workspace project-role distribution endpoint with models, tests, docs, and a version bump.

Changes

Lite list endpoints

Layer / File(s) Summary
Lite contracts and exports
plane/models/query_params.py, plane/models/enums.py, plane/models/__init__.py, plane/models/projects.py, plane/models/cycles.py, plane/models/modules.py
Defines the shared lite query-parameter models, cycle status enum, lite response models, and public exports used by the lite list endpoints.
Lite client methods and validation
plane/api/projects.py, plane/api/cycles.py, plane/api/modules.py, tests/unit/test_projects.py, tests/unit/test_cycles.py, tests/unit/test_modules.py, README.md, pyproject.toml
Adds list_lite client methods for projects, cycles, and modules, updates full cycle listing query handling, and validates the new response shapes in tests and README examples.

Workspace role distribution

Layer / File(s) Summary
Role distribution contract and flow
plane/models/workspaces.py, plane/api/workspaces.py, tests/unit/test_workspaces.py, README.md
Defines the workspace role-distribution models, wires the workspaces client to the role-distribution endpoint, validates the response, and adds a matching unit test and README example.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • sriramveeraghanta
  • dheeru0198
  • Prashant-Surya

Poem

🐰 I hopped through lite lists, quick and bright,
With cycles and modules trimmed just right.
Projects and roles now count and gleam,
In paged little bundles, a tidy stream.
Thump-thump, the burrow sings tonight 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main additions: lite list endpoints, role distribution support, and cycle status filtering.
✨ 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 lite-endpoints

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.

@gurusainath
gurusainath marked this pull request as ready for review June 25, 2026 13:17
@akhil-vamshi-konam

Copy link
Copy Markdown
Contributor

@gurusainath Can we bump the SDK version

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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

39-48: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the cycle_view test assert the filter behavior, not just the response shape.

This still passes if cycle_view is never serialized, because it only checks envelope/types. Please assert the outgoing params through a stubbed request path, or add a result-level check that the returned cycles actually fit the "current" window.

🤖 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_cycles.py` around lines 39 - 48, The list_lite cycle_view
test only verifies the response envelope and types, so it can pass even if the
filter is ignored. Update test_list_lite_cycle_view to assert the actual
behavior of CycleLiteListQueryParams(cycle_view="current") by stubbing or
inspecting the request sent from client.cycles.list_lite, or by adding a
stronger result assertion that every returned CycleLite falls within the current
window. Use the existing test_list_lite_cycle_view and CycleLiteListQueryParams
symbols to locate the test and make it fail when cycle_view is not serialized or
honored.
🤖 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 `@plane/api/cycles.py`:
- Around line 112-114: The Cycles API call in the get-lite path is missing the
required trailing slash, which can break routing in stricter setups. Update the
endpoint string used in the _get call within the cycles API method so it follows
the same trailing-slash convention as the other plane/api resources, keeping the
change localized to the cycles-lite request path.

In `@plane/api/modules.py`:
- Around line 106-108: The new lite endpoint in the `modules` API method is
missing the required trailing slash, which breaks the repo’s URL convention.
Update the request path in the `Modules` client method that calls `modules-lite`
so it ends with `/`, keeping it consistent with the other API endpoints and
avoiding redirect-dependent behavior.

In `@plane/api/workspaces.py`:
- Around line 58-69: Rename the new public method on WorkspacesAPI from
get_project_role_distribution to retrieve_project_role_distribution so it
matches the SDK’s CRUD-style naming convention. Update the _get call in that
method to use the trailing-slash endpoint literal
f"{workspace_slug}/project-role-distribution/" to align with the repository’s
API URL conventions. Keep the existing behavior and return type unchanged.

---

Nitpick comments:
In `@tests/unit/test_cycles.py`:
- Around line 39-48: The list_lite cycle_view test only verifies the response
envelope and types, so it can pass even if the filter is ignored. Update
test_list_lite_cycle_view to assert the actual behavior of
CycleLiteListQueryParams(cycle_view="current") by stubbing or inspecting the
request sent from client.cycles.list_lite, or by adding a stronger result
assertion that every returned CycleLite falls within the current window. Use the
existing test_list_lite_cycle_view and CycleLiteListQueryParams symbols to
locate the test and make it fail when cycle_view is not serialized or honored.
🪄 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: d2587688-19bd-46de-afea-944a50d42409

📥 Commits

Reviewing files that changed from the base of the PR and between c8a7449 and 82927fe.

📒 Files selected for processing (13)
  • README.md
  • plane/api/cycles.py
  • plane/api/modules.py
  • plane/api/projects.py
  • plane/api/workspaces.py
  • plane/models/__init__.py
  • plane/models/enums.py
  • plane/models/projects.py
  • plane/models/query_params.py
  • plane/models/workspaces.py
  • tests/unit/test_cycles.py
  • tests/unit/test_projects.py
  • tests/unit/test_workspaces.py
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • plane/api/projects.py
  • plane/models/projects.py
  • plane/models/init.py
  • tests/unit/test_projects.py

Comment thread plane/api/cycles.py
Comment thread plane/api/modules.py
Comment on lines +106 to +108
response = self._get(
f"{workspace_slug}/projects/{project_id}/modules-lite",
params=params.to_query_params() if params else None,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add the trailing slash to the new lite endpoint path.

modules-lite is called without the terminal /, so this new resource method is off the repository's API URL convention and may rely on redirect behavior.

Suggested fix
-            f"{workspace_slug}/projects/{project_id}/modules-lite",
+            f"{workspace_slug}/projects/{project_id}/modules-lite/",

As per coding guidelines, plane/api/**/*.py: "All API endpoints should end with a trailing / and follow URL convention: {base_path}/api/v1{resource_base_path}/{endpoint}/".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
response = self._get(
f"{workspace_slug}/projects/{project_id}/modules-lite",
params=params.to_query_params() if params else None,
response = self._get(
f"{workspace_slug}/projects/{project_id}/modules-lite/",
params=params.to_query_params() if params else None,
🤖 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 `@plane/api/modules.py` around lines 106 - 108, The new lite endpoint in the
`modules` API method is missing the required trailing slash, which breaks the
repo’s URL convention. Update the request path in the `Modules` client method
that calls `modules-lite` so it ends with `/`, keeping it consistent with the
other API endpoints and avoiding redirect-dependent behavior.

Source: Coding guidelines

Comment thread plane/api/workspaces.py
Comment on lines +58 to +69
def get_project_role_distribution(self, workspace_slug: str) -> ProjectRoleDistribution:
"""Get the distribution of project members by role across the workspace.

Aggregates member counts per role over all active (non-archived)
projects in the workspace. Both built-in roles (admin, contributor,
commenter, guest) and custom roles are included.

Args:
workspace_slug: The workspace slug identifier
"""
response = self._get(f"{workspace_slug}/project-role-distribution")
return ProjectRoleDistribution.model_validate(response)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Align this new method with the SDK's API conventions.

This adds a new public get_* method and a slashless endpoint literal. Please rename it to retrieve_project_role_distribution and call f"{workspace_slug}/project-role-distribution/" so the new surface matches the repository conventions before it ships.

Suggested patch
-    def get_project_role_distribution(self, workspace_slug: str) -> ProjectRoleDistribution:
+    def retrieve_project_role_distribution(self, workspace_slug: str) -> ProjectRoleDistribution:
         """Get the distribution of project members by role across the workspace.
@@
-        response = self._get(f"{workspace_slug}/project-role-distribution")
+        response = self._get(f"{workspace_slug}/project-role-distribution/")
         return ProjectRoleDistribution.model_validate(response)

As per coding guidelines, plane/api/**/*.py resource methods follow CRUD verbs (create, retrieve, update, delete, list) and all API endpoints should end with a trailing /.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def get_project_role_distribution(self, workspace_slug: str) -> ProjectRoleDistribution:
"""Get the distribution of project members by role across the workspace.
Aggregates member counts per role over all active (non-archived)
projects in the workspace. Both built-in roles (admin, contributor,
commenter, guest) and custom roles are included.
Args:
workspace_slug: The workspace slug identifier
"""
response = self._get(f"{workspace_slug}/project-role-distribution")
return ProjectRoleDistribution.model_validate(response)
def retrieve_project_role_distribution(self, workspace_slug: str) -> ProjectRoleDistribution:
"""Get the distribution of project members by role across the workspace.
Aggregates member counts per role over all active (non-archived)
projects in the workspace. Both built-in roles (admin, contributor,
commenter, guest) and custom roles are included.
Args:
workspace_slug: The workspace slug identifier
"""
response = self._get(f"{workspace_slug}/project-role-distribution/")
return ProjectRoleDistribution.model_validate(response)
🤖 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 `@plane/api/workspaces.py` around lines 58 - 69, Rename the new public method
on WorkspacesAPI from get_project_role_distribution to
retrieve_project_role_distribution so it matches the SDK’s CRUD-style naming
convention. Update the _get call in that method to use the trailing-slash
endpoint literal f"{workspace_slug}/project-role-distribution/" to align with
the repository’s API URL conventions. Keep the existing behavior and return type
unchanged.

Source: Coding guidelines

@gurusainath gurusainath changed the title chore: Implemented lite project, cycle, and module endpoints in the Plane SDK feat: Add lite list endpoints, project role distribution, and cycle status filtering to the SDK Jun 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

50-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add one test for the deprecated cycle_view alias.

These cases lock in the new status contract, but the PR also promises backward compatibility. A small assertion using CycleListQueryParams(cycle_view="current") would keep that deprecated path covered too.

🤖 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_cycles.py` around lines 50 - 67, Add a test covering the
deprecated cycle_view alias so backward compatibility is locked in alongside the
new status behavior. In test_cycles.py, extend the existing cycle list tests to
call client.cycles.list with CycleListQueryParams(cycle_view="current") and
assert it still returns the bare list/Cycle items, using the same
client.cycles.list and CycleListQueryParams symbols to keep the legacy path
covered.
🤖 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.

Nitpick comments:
In `@tests/unit/test_cycles.py`:
- Around line 50-67: Add a test covering the deprecated cycle_view alias so
backward compatibility is locked in alongside the new status behavior. In
test_cycles.py, extend the existing cycle list tests to call client.cycles.list
with CycleListQueryParams(cycle_view="current") and assert it still returns the
bare list/Cycle items, using the same client.cycles.list and
CycleListQueryParams symbols to keep the legacy path covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3d3c4a8e-a209-470e-bca5-a25e06f4355e

📥 Commits

Reviewing files that changed from the base of the PR and between ac6634b and b911c54.

📒 Files selected for processing (6)
  • README.md
  • plane/api/cycles.py
  • plane/models/__init__.py
  • plane/models/enums.py
  • plane/models/query_params.py
  • tests/unit/test_cycles.py
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • plane/models/init.py

@dheeru0198
dheeru0198 merged commit 125d8f8 into main Jun 30, 2026
4 checks passed
@dheeru0198
dheeru0198 deleted the lite-endpoints branch June 30, 2026 09:53
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.

3 participants