Skip to content

Tasks API

The TasksAPI client exposes the single task-detail read endpoint added in v0.4.0.

Resource grouping

The endpoint is grouped under client.tasks (D-v0.4-1), even though a task belongs to a post. This mirrors the M16 decision to give attachments their own resource group rather than folding into PostsAPI.

Usage

from pynteracta.client import InteractaClient

with InteractaClient(base_url="https://tenant.example.com", credentials=...) as client:
    task = client.tasks.get(7001)
    print(task.id, task.title, task.state)
    print(task.description_plain_text)

    # Sub-tasks and reminders (typed via …1 siblings)
    for st in task.sub_tasks:
        print(st.id, st.description, st.state)
    for r in task.reminders:
        print(r.id, r.value, r.range)

    # Capabilities
    if task.capabilities and task.capabilities.can_modify:
        print("task is editable")

    # Rich-text delta and survey data — reachable only via .raw (D-v0.4-4)
    print(task.raw.descriptionDelta)
    print(task.raw.surveyData)

    # occToken is carried on .raw for future write use
    print(task.raw.occToken)

state vs currentWorkflowState

Task.state is an integer lifecycle code (open/closed etc.) — the recommended field to display and filter on. Task.current_workflow_state is the post's workflow-state DTO (PostWorkflowDefinitionStateDTO) and represents the post-level workflow, not the task lifecycle. Both are exposed on the facade; the CLI default table shows state (Q-v0.4-3).

Description and survey data

Per D-v0.4-4, the facade surfaces description_plain_text (curated scalar). The Quill rich-text JSON (descriptionDelta) and survey payloads (surveyData, surveyDataCommentsInfo) are left on .rawsurveyData is an untyped object → object map with no DTO, making .raw the only faithful surface.

API Reference

pynteracta.api.tasks.TasksAPI

Bases: ResourceClient

Client for the tasks read endpoint.

get(task_id)

GET /communication/tasks/data/task-detail-by-id/{taskId}.

Parameters:

Name Type Description Default
task_id int

The task ID to fetch.

required

Returns:

Name Type Description
A Task

class:~pynteracta.models.facade.tasks.Task facade.

Facade Reference

pynteracta.models.facade.tasks.Task

Narrow facade over :class:~generated.GetTaskDetailResponseDTO.

Nested TaskCapabilitiesDTO, SubTaskDTO, and TaskReminderDTO are generated as RootModel[Any] stubs; this facade re-validates them against their typed …1 siblings.

descriptionDelta (Quill rich-text JSON), surveyData, and surveyDataCommentsInfo are left on .raw per D-v0.4-4.

Attributes:

Name Type Description
raw

The underlying generated DTO; access additional fields via this escape hatch.

Source code in src/pynteracta/models/facade/tasks.py
class Task:
    """Narrow facade over :class:`~generated.GetTaskDetailResponseDTO`.

    Nested ``TaskCapabilitiesDTO``, ``SubTaskDTO``, and ``TaskReminderDTO`` are generated as
    ``RootModel[Any]`` stubs; this facade re-validates them against their typed ``…1`` siblings.

    ``descriptionDelta`` (Quill rich-text JSON), ``surveyData``, and ``surveyDataCommentsInfo``
    are left on ``.raw`` per D-v0.4-4.

    Attributes:
        raw: The underlying generated DTO; access additional fields via this escape hatch.
    """

    def __init__(self, raw: generated.GetTaskDetailResponseDTO) -> None:
        self.raw = raw
        self._capabilities: TaskCapabilities | None = None
        if raw.capabilities is not None:
            root = _resolve_root(raw.capabilities)
            if isinstance(root, dict):
                self._capabilities = TaskCapabilities(
                    generated.TaskCapabilitiesDTO1.model_validate(root)
                )

    @property
    def id(self) -> int | None:
        return self.raw.id

    @property
    def post_id(self) -> int | None:
        return self.raw.postId

    @property
    def title(self) -> str | None:
        return self.raw.title

    @property
    def description_plain_text(self) -> str | None:
        return self.raw.descriptionPlainText

    @property
    def expiration(self) -> generated.ZonedDatetimeDTO | None:
        return self.raw.expiration

    @property
    def priority(self) -> int | None:
        return self.raw.priority

    @property
    def state(self) -> int | None:
        """Task lifecycle state (integer code). Use ``.raw.currentWorkflowState`` for the post
        workflow state DTO."""
        return self.raw.state

    @property
    def current_workflow_state(self) -> generated.PostWorkflowDefinitionStateDTO | None:
        return self.raw.currentWorkflowState

    @property
    def attachments_count(self) -> int | None:
        return self.raw.attachmentsCount

    @property
    def creation_timestamp(self) -> int | None:
        return self.raw.creationTimestamp

    @property
    def creator_user(self) -> generated.UserDTO | None:
        return self.raw.creatorUser

    @property
    def assignee_user(self) -> generated.UserDTO | None:
        return self.raw.assigneeUser

    @property
    def assignee_group(self) -> generated.GroupDTO | None:
        return self.raw.assigneeGroup

    @property
    def watcher_users(self) -> list[generated.UserDTO] | None:
        return self.raw.watcherUsers

    @property
    def watcher_groups(self) -> list[generated.GroupDTO] | None:
        return self.raw.watcherGroups

    @property
    def capabilities(self) -> TaskCapabilities | None:
        """Typed capabilities facade."""
        return self._capabilities

    @property
    def sub_tasks(self) -> list[SubTask]:
        """Re-validate each opaque ``SubTaskDTO`` stub into :class:`SubTask`."""
        if not self.raw.subTasks:
            return []
        result = []
        for item in self.raw.subTasks:
            root = _resolve_root(item)
            if isinstance(root, dict):
                result.append(SubTask(generated.SubTaskDTO1.model_validate(root)))
        return result

    @property
    def reminders(self) -> list[TaskReminder]:
        """Re-validate each opaque ``TaskReminderDTO`` stub into :class:`TaskReminder`."""
        if not self.raw.reminders:
            return []
        result = []
        for item in self.raw.reminders:
            root = _resolve_root(item)
            if isinstance(root, dict):
                result.append(TaskReminder(generated.TaskReminderDTO1.model_validate(root)))
        return result

    @classmethod
    def from_dict(cls, data: dict) -> Task:  # type: ignore[type-arg]
        """Parse from a raw API response dict.

        Args:
            data: Parsed JSON response body.

        Returns:
            A new :class:`Task`.
        """
        raw = generated.GetTaskDetailResponseDTO.model_validate(data)
        return cls(raw)

capabilities property

Typed capabilities facade.

reminders property

Re-validate each opaque TaskReminderDTO stub into :class:TaskReminder.

state property

Task lifecycle state (integer code). Use .raw.currentWorkflowState for the post workflow state DTO.

sub_tasks property

Re-validate each opaque SubTaskDTO stub into :class:SubTask.

from_dict(data) classmethod

Parse from a raw API response dict.

Parameters:

Name Type Description Default
data dict

Parsed JSON response body.

required

Returns:

Type Description
Task

A new :class:Task.

Source code in src/pynteracta/models/facade/tasks.py
@classmethod
def from_dict(cls, data: dict) -> Task:  # type: ignore[type-arg]
    """Parse from a raw API response dict.

    Args:
        data: Parsed JSON response body.

    Returns:
        A new :class:`Task`.
    """
    raw = generated.GetTaskDetailResponseDTO.model_validate(data)
    return cls(raw)

pynteracta.models.facade.tasks.TaskCapabilities

Thin facade over :class:~generated.TaskCapabilitiesDTO1.

Attributes:

Name Type Description
raw

The underlying typed DTO.

Source code in src/pynteracta/models/facade/tasks.py
class TaskCapabilities:
    """Thin facade over :class:`~generated.TaskCapabilitiesDTO1`.

    Attributes:
        raw: The underlying typed DTO.
    """

    def __init__(self, raw: generated.TaskCapabilitiesDTO1) -> None:
        self.raw = raw

    @property
    def can_view_detail(self) -> bool | None:
        return self.raw.canViewDetail

    @property
    def can_modify(self) -> bool | None:
        return self.raw.canModify

    @property
    def can_update_state(self) -> bool | None:
        return self.raw.canUpdateState

    @property
    def can_copy(self) -> bool | None:
        return self.raw.canCopy

    @property
    def can_delete(self) -> bool | None:
        return self.raw.canDelete

    @property
    def can_add_comment(self) -> bool | None:
        return self.raw.canAddComment

    @property
    def can_edit_attachments(self) -> bool | None:
        return self.raw.canEditAttachments

    @property
    def can_edit_reminders(self) -> bool | None:
        return self.raw.canEditReminders

pynteracta.models.facade.tasks.SubTask

Thin facade over :class:~generated.SubTaskDTO1.

Attributes:

Name Type Description
raw

The underlying typed DTO.

Source code in src/pynteracta/models/facade/tasks.py
class SubTask:
    """Thin facade over :class:`~generated.SubTaskDTO1`.

    Attributes:
        raw: The underlying typed DTO.
    """

    def __init__(self, raw: generated.SubTaskDTO1) -> None:
        self.raw = raw

    @property
    def id(self) -> int | None:
        return self.raw.id

    @property
    def description(self) -> str | None:
        return self.raw.description

    @property
    def state(self) -> int | None:
        return self.raw.state

pynteracta.models.facade.tasks.TaskReminder

Thin facade over :class:~generated.TaskReminderDTO1.

Attributes:

Name Type Description
raw

The underlying typed DTO.

Source code in src/pynteracta/models/facade/tasks.py
class TaskReminder:
    """Thin facade over :class:`~generated.TaskReminderDTO1`.

    Attributes:
        raw: The underlying typed DTO.
    """

    def __init__(self, raw: generated.TaskReminderDTO1) -> None:
        self.raw = raw

    @property
    def id(self) -> int | None:
        return self.raw.id

    @property
    def value(self) -> int | None:
        return self.raw.value

    @property
    def range(self) -> int | None:
        return self.raw.range

    @property
    def types(self) -> list[int] | None:
        return self.raw.types