Add enriched classification output and Todoist dedupe sync
This commit is contained in:
48
app/todoist.py
Normal file
48
app/todoist.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
|
||||
class TodoistClient:
|
||||
def __init__(self, api_key: str | None = None, base_url: str | None = None):
|
||||
self.api_key = api_key or os.getenv("TODOIST_API_KEY")
|
||||
self.base_url = (base_url or os.getenv("TODOIST_API_BASE_URL") or "https://api.todoist.com/rest/v2").rstrip("/")
|
||||
self.project_id = os.getenv("TODOIST_PROJECT_ID")
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
return bool(self.api_key)
|
||||
|
||||
def _headers(self) -> dict[str, str]:
|
||||
if not self.api_key:
|
||||
raise RuntimeError("TODOIST_API_KEY is not configured")
|
||||
return {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"}
|
||||
|
||||
async def create_task(self, *, content: str, description: str, due_string: str | None = None) -> dict[str, Any]:
|
||||
payload: dict[str, Any] = {"content": content, "description": description}
|
||||
if self.project_id:
|
||||
payload["project_id"] = self.project_id
|
||||
if due_string:
|
||||
payload["due_string"] = due_string
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
response = await client.post(f"{self.base_url}/tasks", headers=self._headers(), json=payload)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
async def update_task(self, task_id: str, *, content: str, description: str, due_string: str | None = None) -> None:
|
||||
payload: dict[str, Any] = {"content": content, "description": description}
|
||||
if due_string:
|
||||
payload["due_string"] = due_string
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
response = await client.post(f"{self.base_url}/tasks/{task_id}", headers=self._headers(), json=payload)
|
||||
response.raise_for_status()
|
||||
|
||||
async def add_comment(self, task_id: str, content: str) -> dict[str, Any]:
|
||||
payload = {"task_id": task_id, "content": content}
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
response = await client.post(f"{self.base_url}/comments", headers=self._headers(), json=payload)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
Reference in New Issue
Block a user