TASH_Reward_Evaluation / clickup_source.py
yusiff's picture
Upload 25 files
94088ea verified
Raw History Blame Contribute Delete
3.81 kB
"""
ClickUp Data Source โ€” ู…ุญุงูƒุงุฉ ClickUp API.
ูŠู‚ุฑุฃ data/clickup_tasks.csv ูˆูŠูุฑุฌุนู‡ ุจู†ูุณ ุงู„ุดูƒู„ ุงู„ุฐูŠ ุณูŠูุฑุฌุนู‡ ClickUp API ุงู„ุญู‚ูŠู‚ูŠุŒ
ูˆุจู†ูุณ ุงู„ู€ interface ุจุงู„ุถุจุท. ูŠูˆู… ุงู„ุฅู†ุชุงุฌ: ู†ูƒุชุจ ClickUpAPISource ุจู†ูุณ ุฏุงู„ุฉ
fetch_tasks() ุงู„ุชูŠ ุชุณุชุฏุนูŠ GET /api/v2/list/{list_id}/task โ€” ูˆุงู„ู€ Sync Engine ููŠ
logic.py ู„ุง ูŠุชุบูŠุฑ ุญุฑูู‹ุง ูˆุงุญุฏู‹ุง.
ุฎุฑูŠุทุฉ ุงู„ุญู‚ูˆู„ (ุงู„ู…ุญุงูƒุงุฉ โ† ClickUp API):
task_id โ† task["id"]
task_name โ† task["name"]
client โ† task["list"]["name"] (ุงู„ู€ List = ุงู„ุนู…ูŠู„)
assignee_id โ† task["assignees"][0]["id"]
status โ† task["status"]["status"]
priority โ† task["priority"]["priority"]
task_value โ† custom_field "Task Value" (ุงู„ุญู…ุงูŠุฉ ู…ู† ุชู‚ุณูŠู… ุงู„ู…ู‡ุงู…)
due_date โ† task["due_date"] (ms epoch โ†’ date)
completed_at โ† task["date_done"] (ms epoch โ†’ date)
quality_rating โ† custom_field "Quality Rating"
client_feedback โ† custom_field "Client Feedback"
"""
from __future__ import annotations
import os
from abc import ABC, abstractmethod
import pandas as pd
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
TASKS_FILE = os.path.join(BASE_DIR, "data", "clickup_tasks.csv")
TASK_COLUMNS = [
"task_id", "task_name", "client", "assignee_id", "status", "priority",
"task_value", "due_date", "completed_at", "quality_rating", "client_feedback",
]
class TaskSource(ABC):
"""ุงู„ูˆุงุฌู‡ุฉ ุงู„ุชูŠ ูŠุนุชู…ุฏ ุนู„ูŠู‡ุง ุงู„ู€ Sync Engine."""
@abstractmethod
def fetch_tasks(self) -> pd.DataFrame:
"""ูŠูุฑุฌุน ูƒู„ ุงู„ู…ู‡ุงู… ุจุฃุนู…ุฏุฉ TASK_COLUMNS."""
class CSVClickUpSource(TaskSource):
"""ู…ุญุงูƒุงุฉ: ุงู„ู…ุตุฏุฑ ู…ู„ู CSV ุจุฏู„ ุงุณุชุฏุนุงุก ุงู„ู€ API."""
def __init__(self, path: str = TASKS_FILE):
self.path = path
def fetch_tasks(self) -> pd.DataFrame:
df = pd.read_csv(self.path)
# ู†ูุณ ุงู„ุชุทุจูŠุน ุงู„ุฐูŠ ุณูŠู„ุฒู… ู…ุน ุงู„ู€ API ุงู„ุญู‚ูŠู‚ูŠ (ms epoch โ†’ datetime)
df["due_date"] = pd.to_datetime(df["due_date"], errors="coerce")
df["completed_at"] = pd.to_datetime(df["completed_at"], errors="coerce")
df["task_value"] = pd.to_numeric(df["task_value"], errors="coerce").fillna(0).astype(int)
df["quality_rating"] = pd.to_numeric(df["quality_rating"], errors="coerce")
return df
def fetch_tasks_for(self, employee_id: str) -> pd.DataFrame:
df = self.fetch_tasks()
return df[df["assignee_id"] == employee_id]
# ---------------------------------------------------------------------------
# ู†ุณุฎุฉ ุงู„ุฅู†ุชุงุฌ โ€” ุชููุนูŽู‘ู„ ูŠูˆู… ุงู„ุฑุจุท ุงู„ุญู‚ูŠู‚ูŠุŒ ุจู†ูุณ ุงู„ู€ interface ุชู…ุงู…ู‹ุง.
#
# class ClickUpAPISource(TaskSource):
# def __init__(self, api_token: str, list_ids: list[str]):
# self.api_token = api_token
# self.list_ids = list_ids
#
# def fetch_tasks(self) -> pd.DataFrame:
# rows = []
# for list_id in self.list_ids:
# r = requests.get(
# f"https://api.clickup.com/api/v2/list/{list_id}/task",
# headers={"Authorization": self.api_token},
# params={"include_closed": "true"},
# )
# for t in r.json()["tasks"]:
# rows.append(_map_api_task(t))
# return pd.DataFrame(rows, columns=TASK_COLUMNS)
# ---------------------------------------------------------------------------
def get_task_source() -> TaskSource:
"""ู†ู‚ุทุฉ ุงู„ุชุจุฏูŠู„ ุงู„ูˆุญูŠุฏุฉ: return ClickUpAPISource(token, lists) ููŠ ุงู„ุฅู†ุชุงุฌ."""
return CSVClickUpSource()