Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions plane/api/intake.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,28 @@ def update(
)
return IntakeWorkItem.model_validate(response)

def update_status(
self,
workspace_slug: str,
project_id: str,
work_item_id: str,
data: UpdateIntakeWorkItem,
) -> IntakeWorkItem:
"""Update the triage status of an intake work item.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
work_item_id: UUID of the work item (use the issue field from
IntakeWorkItem response, not the intake work item ID)
data: Triage data — status, snoozed_till, duplicate_to
"""
response = self._patch(
f"{workspace_slug}/projects/{project_id}/intake-issues/{work_item_id}/status",
data.model_dump(exclude_none=True),
Comment thread
akhil-vamshi-konam marked this conversation as resolved.
)
return IntakeWorkItem.model_validate(response)

def delete(self, workspace_slug: str, project_id: str, work_item_id: str) -> None:
"""Delete an intake work item by work item ID.

Expand Down
54 changes: 53 additions & 1 deletion plane/api/pages.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from collections.abc import Mapping
from typing import Any

from ..models.pages import CreatePage, Page, PaginatedPageResponse
Expand All @@ -10,6 +9,40 @@ class Pages(BaseResource):
def __init__(self, config: Any) -> None:
super().__init__(config, "/workspaces/")

def list_workspace_pages(
self,
workspace_slug: str,
params: PaginatedQueryParams | None = None,
) -> PaginatedPageResponse:
"""List all workspace pages.

Args:
workspace_slug: The workspace slug identifier
params: Optional pagination/query parameters
"""
query_params = params.model_dump(exclude_none=True) if params else None
response = self._get(f"{workspace_slug}/pages", params=query_params)
return PaginatedPageResponse.model_validate(response)
Comment thread
akhil-vamshi-konam marked this conversation as resolved.

def list_project_pages(
self,
workspace_slug: str,
project_id: str,
params: PaginatedQueryParams | None = None,
) -> PaginatedPageResponse:
"""List all pages in a project.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
params: Optional pagination/query parameters
"""
query_params = params.model_dump(exclude_none=True) if params else None
response = self._get(
f"{workspace_slug}/projects/{project_id}/pages", params=query_params
)
return PaginatedPageResponse.model_validate(response)

def retrieve_workspace_page(
self,
workspace_slug: str,
Expand Down Expand Up @@ -83,3 +116,22 @@ def create_project_page(
data.model_dump(exclude_none=True),
)
return Page.model_validate(response)

def delete_workspace_page(self, workspace_slug: str, page_id: str) -> None:
"""Delete a workspace page by ID.

Args:
workspace_slug: The workspace slug identifier
page_id: UUID of the page
"""
return self._delete(f"{workspace_slug}/pages/{page_id}")

def delete_project_page(self, workspace_slug: str, project_id: str, page_id: str) -> None:
"""Delete a project page by ID.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
page_id: UUID of the page
"""
return self._delete(f"{workspace_slug}/projects/{project_id}/pages/{page_id}")
21 changes: 21 additions & 0 deletions plane/api/work_items/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .attachments import WorkItemAttachments
from .comments import WorkItemComments
from .links import WorkItemLinks
from .pages import WorkItemPages
from .relations import WorkItemRelations
from .work_logs import WorkLogs

Expand All @@ -33,6 +34,7 @@ def __init__(self, config: Any) -> None:
self.comments = WorkItemComments(config)
self.activities = WorkItemActivities(config)
self.work_logs = WorkLogs(config)
self.pages = WorkItemPages(config)

def create(self, workspace_slug: str, project_id: str, data: CreateWorkItem) -> WorkItem:
"""Create a new work item.
Expand Down Expand Up @@ -237,6 +239,25 @@ def advanced_search(
)
return [AdvancedSearchResult.model_validate(item) for item in response]

def list_archived(
self,
workspace_slug: str,
project_id: str,
params: WorkItemQueryParams | None = None,
) -> PaginatedWorkItemResponse:
"""List archived work items in a project.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
params: Optional query parameters for filtering, ordering, and pagination
"""
query_params = params.model_dump(exclude_none=True) if params else None
response = self._get(
f"{workspace_slug}/projects/{project_id}/archived-work-items", params=query_params
)
Comment thread
akhil-vamshi-konam marked this conversation as resolved.
return PaginatedWorkItemResponse.model_validate(response)

def archive(self, workspace_slug: str, project_id: str, work_item_id: str) -> None:
"""Archive a work item.

Expand Down
95 changes: 95 additions & 0 deletions plane/api/work_items/pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from collections.abc import Mapping
from typing import Any

from ...models.work_item_pages import (
CreateWorkItemPage,
PaginatedWorkItemPageResponse,
WorkItemPage,
)
from ..base_resource import BaseResource


class WorkItemPages(BaseResource):
def __init__(self, config: Any) -> None:
super().__init__(config, "/workspaces/")

def list(
self,
workspace_slug: str,
project_id: str,
work_item_id: str,
params: Mapping[str, Any] | None = None,
) -> PaginatedWorkItemPageResponse:
"""List page links for a work item.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
work_item_id: UUID of the work item
params: Optional query parameters
"""
response = self._get(
f"{workspace_slug}/projects/{project_id}/work-items/{work_item_id}/pages",
params=params,
)
Comment thread
akhil-vamshi-konam marked this conversation as resolved.
return PaginatedWorkItemPageResponse.model_validate(response)

def retrieve(
self,
workspace_slug: str,
project_id: str,
work_item_id: str,
work_item_page_id: str,
) -> WorkItemPage:
"""Retrieve a specific page link for a work item.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
work_item_id: UUID of the work item
work_item_page_id: UUID of the work item page link
"""
response = self._get(
f"{workspace_slug}/projects/{project_id}/work-items/{work_item_id}/pages/{work_item_page_id}"
)
return WorkItemPage.model_validate(response)

def create(
self,
workspace_slug: str,
project_id: str,
work_item_id: str,
data: CreateWorkItemPage,
) -> WorkItemPage:
"""Link a page to a work item.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
work_item_id: UUID of the work item
data: Page link data containing page_id
"""
response = self._post(
f"{workspace_slug}/projects/{project_id}/work-items/{work_item_id}/pages",
data.model_dump(exclude_none=True),
)
return WorkItemPage.model_validate(response)

def delete(
self,
workspace_slug: str,
project_id: str,
work_item_id: str,
work_item_page_id: str,
) -> None:
"""Remove a page link from a work item.

Args:
workspace_slug: The workspace slug identifier
project_id: UUID of the project
work_item_id: UUID of the work item
work_item_page_id: UUID of the work item page link
"""
return self._delete(
f"{workspace_slug}/projects/{project_id}/work-items/{work_item_id}/pages/{work_item_page_id}"
)
5 changes: 4 additions & 1 deletion plane/models/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@
"URL",
"EMAIL",
"FILE",
"FORMULA",
]
RelationTypeEnum = Literal["ISSUE", "USER"]
RelationTypeEnum = Literal["ISSUE", "USER", "RELEASE"]


# Proper Enum classes for better type safety and IDE support
Expand All @@ -62,13 +63,15 @@ class PropertyType(Enum):
URL = "URL"
EMAIL = "EMAIL"
FILE = "FILE"
FORMULA = "FORMULA"


class RelationType(Enum):
"""Relation type enumeration."""

ISSUE = "ISSUE"
USER = "USER"
RELEASE = "RELEASE"


class Priority(Enum):
Expand Down
1 change: 1 addition & 0 deletions plane/models/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class UpdateProject(BaseModel):

name: str | None = None
description: str | None = None
network: NetworkEnum | None = None
project_lead: str | None = None
default_assignee: str | None = None
identifier: str | None = None
Expand Down
50 changes: 50 additions & 0 deletions plane/models/work_item_pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from typing import Any

from pydantic import BaseModel, ConfigDict

from .pagination import PaginatedResponse


class WorkItemPageLite(BaseModel):
"""Nested page info returned inside a WorkItemPage response."""

model_config = ConfigDict(extra="allow", populate_by_name=True)

id: str | None = None
name: str | None = None
created_at: str | None = None
updated_at: str | None = None
created_by: str | None = None
is_global: bool | None = None
logo_props: Any | None = None


class WorkItemPage(BaseModel):
"""Work item to page link."""

model_config = ConfigDict(extra="allow", populate_by_name=True)

id: str | None = None
page: WorkItemPageLite | None = None
issue: str | None = None
project: str | None = None
workspace: str | None = None
created_at: str | None = None
updated_at: str | None = None
created_by: str | None = None


class CreateWorkItemPage(BaseModel):
"""Request model for linking a page to a work item."""

model_config = ConfigDict(extra="ignore", populate_by_name=True)

page_id: str


class PaginatedWorkItemPageResponse(PaginatedResponse):
"""Paginated response for work item page links."""

model_config = ConfigDict(extra="allow", populate_by_name=True)

results: list[WorkItemPage]
12 changes: 6 additions & 6 deletions plane/models/work_item_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ class WorkItemProperty(BaseModel):
options: list["WorkItemPropertyOption"] | None = None

@field_serializer("property_type")
def serialize_property_type(self, value: PropertyType) -> str:
def serialize_property_type(self, value: PropertyType) -> str | None:
return value.value if value else None

@field_serializer("relation_type")
def serialize_relation_type(self, value: RelationType) -> str:
def serialize_relation_type(self, value: RelationType) -> str | None:
return value.value if value else None


Expand All @@ -72,11 +72,11 @@ class CreateWorkItemProperty(BaseModel):
options: list["CreateWorkItemPropertyOption"] | None = None

@field_serializer("property_type")
def serialize_property_type(self, value: PropertyType) -> str:
def serialize_property_type(self, value: PropertyType) -> str | None:
return value.value if value else None

@field_serializer("relation_type")
def serialize_relation_type(self, value: RelationType) -> str:
def serialize_relation_type(self, value: RelationType) -> str | None:
return value.value if value else None

@model_validator(mode="after")
Expand Down Expand Up @@ -131,11 +131,11 @@ class UpdateWorkItemProperty(BaseModel):
external_id: str | None = None

@field_serializer("property_type")
def serialize_property_type(self, value: PropertyType) -> str:
def serialize_property_type(self, value: PropertyType) -> str | None:
return value.value if value else None

@field_serializer("relation_type")
def serialize_relation_type(self, value: RelationType) -> str:
def serialize_relation_type(self, value: RelationType) -> str | None:
return value.value if value else None

@model_validator(mode="after")
Expand Down
2 changes: 2 additions & 0 deletions plane/models/work_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ class CreateWorkItemLink(BaseModel):
model_config = ConfigDict(extra="ignore", populate_by_name=True)

url: str
title: str | None = None


class UpdateWorkItemLink(BaseModel):
Expand All @@ -376,6 +377,7 @@ class UpdateWorkItemLink(BaseModel):
model_config = ConfigDict(extra="ignore", populate_by_name=True)

url: str | None = None
title: str | None = None


class WorkItemAttachment(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "plane-sdk"
version = "0.2.11"
version = "0.2.12"
description = "Python SDK for Plane API"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
Loading