from collections.abc import Iterator from dataclasses import dataclass, field from json import loads from pydantic import BaseModel from requests import HTTPError, get from .common import EnvVar, JSONDataMap, JSONData, JSONDataList, JSONDataScalar class ClickupStatus(BaseModel): status: str @property def status_symbol(self) -> str: match self.status: case "backlog": return "󰧟" case "selected for development": return "󱥸" case "in progress": return "󰝦" case "in review": return "󰬫" case "done": return "󰻃" case "closed": return "󰄴" case "on hold": return "󰏦" case _: return self.status class ClickupTask(BaseModel): id: str name: str markdown_description: str status: ClickupStatus class ClickupList(BaseModel): task_count: int @dataclass class ClickupSession: auth_key: str = field( default_factory=EnvVar( "CLICKUP_AUTH", "clickup auth token is required to be set", ) ) workspace_id: str = field( default_factory=EnvVar( "CLICKUP_WORKSPACE_ID", "clickup workspace id is required to be set", ) ) user_id: str = field( default_factory=EnvVar( "CLICKUP_USER_ID", "clickup user id is required to be set", ) ) base_url: str = "https://api.clickup.com/api/v2" def _get(self, endpoint: str, **query_params: str) -> JSONDataMap: with get( self.base_url + endpoint, query_params, headers={ "accept": "application/json", "Authorization": self.auth_key, }, ) as resp: return resp.json() def get_tasks(self, **filters: str) -> Iterator[ClickupTask]: pix = 0 while True: partial_data = self._get( f"/team/{self.workspace_id}/task", **{ "subtasks": "true", "include_markdown_description": "true", "include_closed": "true", "assignees[]": self.user_id, "page": pix, } | filters, ).get("tasks", []) pix += 1 for inst in partial_data: yield ClickupTask.model_validate(inst) if len(partial_data) < 100: break def get_task(self, task_id: str) -> ClickupTask: return ClickupTask.model_validate( self._get( f"/task/{task_id}", include_markdown_description="true", ), ) def get_list(self, list_id: str) -> ClickupList: return ClickupList.model_validate(self._get(f"/list/{list_id}"))