ticktick sdk:ticktick MCP服务器和完整的Python sdk
  ](https://pepy.tech/projects/ticktick-sdk)
一个全面的异步Python SDK 滴答清单 随着 主控程序 (模型上下文协议)服务器支持。
包括对以下内容的全面支持 Dida365 (滴答清单) 也。
从Python以编程方式使用TickTick,或让AI助手管理您的任务。
目录
- 第一步:注册您的应用 - 步骤2:获取OAuth2访问令牌 - 步骤3:配置您的AI助手 - CLI 参考 - 对话示例 - 可用的MCP工具
- 设置 - 快速开始 - 任务 - 项目和文件夹 - 标签 - 习惯 - 焦点/番茄 - 用户和统计 - 错误处理
______________________________________________________________________
特性
MCP 服务器
- 43工具:简化TickTick功能的覆盖范围
- 批量操作:所有突变都接受批量操作的列表(1-100个项目)
- AI就绪:与Claude、GPT和其他MCP兼容的助手配合使用
- 双输出:Markdown用于人类,JSON用于机器
Python库
- 完全异步支持:基于
httpx用于高性能异步操作 - 批量操作:在一次通话中创建、更新、删除、完成多达100个任务
- 完成任务管理:创建、读取、更新、删除、完成、移动、固定任务
- 看板:完整列管理(创建、更新、删除、在列之间移动任务)
- 项目组织机构:项目、文件夹、看板
- 标签系统:带颜色的分层标签
- 习惯追踪:完整的CRUD,用于批量签入、条纹和目标的习惯
- 焦点/番茄:获取焦点会议数据和统计数据
- 用户分析:生产率得分、水平、完成率
开发者体验
- 类型安全:具有全面类型提示的完整Pydantic v2验证
- 测试良好:300多项测试,涵盖模拟和现场API交互
- 已记录:大量的文档字符串和示例
______________________________________________________________________
为什么是这个图书馆?
Two-API问题
TickTick已经 两种不同的API:
| API | 类型 | 我们使用它的用途 |
|---|---|---|
| V1(OAuth2) | 正式的、有文件记录的 | 包含所有任务和基本操作的项目 |
| V2(会话) | 非官方、逆向工程 | 标签、文件夹、习惯、焦点、子任务等 |
API的官方V1是有限的。TickTick的大多数强大功能(标签、习惯、焦点跟踪)只能通过未记录的V2 web API获得。 这个图书馆结合了两者,将每个操作自动路由到相应的API。
与其他图书馆相比
基于对可用TickTick Python库的实际源代码的分析:
|---------|:------------:|:----------:|:-----------:|:--------:|:---------------:| | I/O模型 |异步|异步|同步|同步|| | 类型系统 |Pydantic V2 | Pydantic V2|骰子|诱饵|瘾君子| | MCP 服务器 | 是 |否|否|否| | 习惯 | 完整CRUD |否|基本|基本|否| | 焦点/波莫 |是|是|是|Yes |是|否| | 统一V1+V2 | 智能路由 |分开|两者|仅V2 |仅V2| | 子任务 |高级|批处理|是|基本|基本| | 标签 |完整(合并/重命名)|是|是|否|
主要区别:
- MCP 服务器:只有ticktick sdk通过模型上下文协议提供AI助手集成
- 统一API路由:根据功能要求自动将操作路由到V1或V2
- 全习惯CRUD:完整的习惯管理,包括签到、记录、存档/取消存档
- 异步优先:基于
httpx用于高性能异步操作
______________________________________________________________________
安装
pip install ticktick-sdk要求:
- Python 3.11+
- TickTick帐户(免费或专业版)
______________________________________________________________________
MCP服务器设置和使用
通过模型上下文协议将TickTick与Claude等AI助手一起使用。
第一步:注册您的应用
- 去 TickTick开发者门户
- 点击 “创建应用程序”
- 填写:
- 应用程序名称:例如,“我的TickTick MCP” - 重定向URI: http://127.0.0.1:8080/callback
- 保存你的 客户端ID 和 客户端密钥
步骤2:获取OAuth2访问令牌
使用您的凭据运行auth命令:
TICKTICK_CLIENT_ID=your_client_id \
TICKTICK_CLIENT_SECRET=your_client_secret \
ticktick-sdk auth这将:
- 打开浏览器 转到TickTick的授权页面
- 授权应用程序 -点击“授权”以授予访问权限
- 返回终端 -授权后,您将看到如下输出:
============================================================
SUCCESS! Here is your access token:
============================================================
a]234abc-5678-90de-f012-34567890abcd
============================================================
NEXT STEPS:
For Claude Code users:
Run (replace YOUR_* placeholders):
claude mcp add ticktick \
-e TICKTICK_CLIENT_ID=YOUR_CLIENT_ID \
...- 复制此令牌 -下一步你需要它
备注:有时浏览器会显示“无效凭据”错误页面。只需刷新页面,它就应该工作了。
SSH/无头用户:添加 --manual 标记不需要浏览器的基于文本的流。步骤3:配置您的AI助手
克劳德代码(推荐)
claude mcp add ticktick \
-e TICKTICK_CLIENT_ID=your_client_id \
-e TICKTICK_CLIENT_SECRET=your_client_secret \
-e TICKTICK_ACCESS_TOKEN=your_access_token \
-e TICKTICK_USERNAME=your_email \
-e TICKTICK_PASSWORD=your_password \
-- ticktick-sdk备注:为 TICKTICK_ACCESS_TOKEN,粘贴您从步骤2中复制的令牌。验证它是否正常工作:
claude mcp list # See all configured servers
/mcp # Within Claude Code, check server status克劳德桌面版
添加到您的Claude Desktop配置中:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json 视窗: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"ticktick": {
"command": "ticktick-sdk",
"env": {
"TICKTICK_CLIENT_ID": "your_client_id",
"TICKTICK_CLIENT_SECRET": "your_client_secret",
"TICKTICK_ACCESS_TOKEN": "your_access_token",
"TICKTICK_USERNAME": "your_email",
"TICKTICK_PASSWORD": "your_password"
}
}
}
}其他MCP兼容工具
该服务器可与任何支持模型上下文协议的工具配合使用,其中包括大多数现代AI助手和IDE。配置类似-您只需提供以下命令(ticktick-sdk)以及上面显示的环境变量。
CLI 参考
这 ticktick-sdk 命令提供了几个子命令:
| 命令 | 描述 |
|---|---|
ticktick-sdk | 启动MCP服务器(默认) |
ticktick-sdk server | 启动MCP服务器(显式) |
ticktick-sdk server --host HOST | 使用特定的API主机(ticktick.com 或 dida365.com) |
ticktick-sdk server --enabledModules MODULES | 仅启用特定的工具模块(逗号分隔) |
ticktick-sdk server --enabledTools TOOLS | 仅启用特定工具(逗号分隔) |
ticktick-sdk auth | 获取OAuth2访问令牌(打开浏览器) |
ticktick-sdk auth --manual | 获取OAuth2访问令牌(SSH友好) |
ticktick-sdk --version | 显示版本信息 |
ticktick-sdk --help | 显示帮助消息 |
工具筛选 (减少AI助手的上下文窗口使用):
# Enable only task and project tools
ticktick-sdk server --enabledModules tasks,projects
# Enable specific tools only
ticktick-sdk server --enabledTools ticktick_create_tasks,ticktick_list_tasks
# Available modules: tasks, projects, folders, columns, tags, habits, user, focus对话示例
配置后,您可以向Claude询问以下问题:
- “我今天有什么任务要交?”
- “创建一个任务,明天下午2点给约翰打电话”
- “显示我的高优先级任务”
- “将杂货店购物任务标记为已完成”
- “我目前的锻炼习惯是什么?”
- “检查我今天的冥想习惯”
- “养成每天喝8杯水的新习惯”
可用MCP工具(共43个)
所有变异工具都接受批量操作的列表(1-100个项目)。
任务工具(支持批处理)
| 工具 | 说明 |
|---|---|
ticktick_create_tasks | 创建1-50个任务,包括标题、日期、标签等。 |
ticktick_get_task | 按ID获取任务详细信息 |
ticktick_list_tasks | 列出任务(通过状态过滤器显示活动/已完成/放弃/已删除) |
ticktick_update_tasks | 更新1-100个任务(包括列分配) |
ticktick_complete_tasks | 完成1-100个任务 |
ticktick_delete_tasks | 删除1-100个任务(移至回收站) |
ticktick_move_tasks | 在项目之间移动1-50个任务 |
ticktick_set_task_parents | 为1-50个任务设置父子关系 |
ticktick_unparent_tasks | 从1-50个任务中删除父关系 |
ticktick_search_tasks | 按文本搜索任务 |
ticktick_pin_tasks | 固定或取消固定1-100个任务 |
项目工具
| 工具 | 说明 |
|---|---|
ticktick_list_projects | 列出所有项目 |
ticktick_get_project | 通过任务获取项目详细信息 |
ticktick_create_project | 创建新项目 |
ticktick_update_project | 更新项目属性 |
ticktick_delete_project | 删除项目 |
文件夹工具
| 工具 | 说明 |
|---|---|
ticktick_list_folders | 列出所有文件夹 |
ticktick_create_folder | 创建文件夹 |
ticktick_rename_folder | 重命名文件夹 |
ticktick_delete_folder | 删除文件夹 |
看板柱工具
| 工具 | 说明 |
|---|---|
ticktick_list_columns | 列出看板项目的列 |
ticktick_create_column | 创建看板栏 |
ticktick_update_column | 更新列名或顺序 |
ticktick_delete_column | 删除看板列 |
标记工具
| 工具 | 说明 |
|---|---|
ticktick_list_tags | 列出所有标签 |
ticktick_create_tag | 创建带有颜色的标签 |
ticktick_update_tag | 更新标签属性(包括通过标签重命名) |
ticktick_delete_tag | 删除标签 |
ticktick_merge_tags | 合并两个标签 |
习惯工具(可批量处理)
| 工具 | 说明 |
|---|---|
ticktick_habits | 列出所有习惯 |
ticktick_habit | 获取习惯详细信息 |
ticktick_habit_sections | 列出部分(上午/下午/晚上) |
ticktick_create_habit | 养成新习惯 |
ticktick_update_habit | 更新习惯属性(包括存档/取消存档) |
ticktick_delete_habit | 改掉一个习惯 |
ticktick_checkin_habits | 签入1-50个习惯(支持回溯) |
ticktick_habit_checkins | 获取入住历史记录 |
用户和分析工具
| 工具 | 说明 |
|---|---|
ticktick_get_profile | 获取用户资料 |
ticktick_get_status | 获取帐户状态 |
ticktick_get_statistics | 获取生产力统计数据 |
ticktick_get_preferences | 获取用户首选项 |
ticktick_focus_heatmap | 获取焦点热图数据 |
ticktick_focus_by_tag | 通过标签获取焦点时间 |
______________________________________________________________________
Python库设置和使用
在Python应用程序中以编程方式使用TickTick。
设置
第一步:注册您的应用
与MCP设置相同-转到 TickTick开发者门户 并创建一个应用程序。
步骤2:创建.env文件
创建一个 .env 项目目录中的文件:
# V1 API (OAuth2)
TICKTICK_CLIENT_ID=your_client_id_here
TICKTICK_CLIENT_SECRET=your_client_secret_here
TICKTICK_REDIRECT_URI=http://127.0.0.1:8080/callback
TICKTICK_ACCESS_TOKEN= # Will be filled in Step 3
# V2 API (Session)
TICKTICK_USERNAME=your_ticktick_email@example.com
TICKTICK_PASSWORD=your_ticktick_password
# Optional
TICKTICK_TIMEOUT=30步骤3:获取OAuth2访问令牌
# Source your .env file first, or export the variables
ticktick-sdk auth将访问令牌复制到您的 .env 文件。
步骤4:验证设置
import asyncio
from ticktick_sdk import TickTickClient
async def test():
async with TickTickClient.from_settings() as client:
profile = await client.get_profile()
print(f'Connected as: {profile.display_name}')
asyncio.run(test())快速开始
import asyncio
from ticktick_sdk import TickTickClient
async def main():
async with TickTickClient.from_settings() as client:
# Create a task
task = await client.create_task(
title="Learn ticktick-sdk",
tags=["python", "productivity"],
)
print(f"Created: {task.title} (ID: {task.id})")
# List all tasks
tasks = await client.get_all_tasks()
print(f"You have {len(tasks)} active tasks")
# Complete the task
await client.complete_task(task.id, task.project_id)
print("Task completed!")
asyncio.run(main())任务
创建任务
from datetime import datetime, timedelta
from ticktick_sdk import TickTickClient
async with TickTickClient.from_settings() as client:
# Simple task
task = await client.create_task(title="Buy groceries")
# Task with due date and priority
task = await client.create_task(
title="Submit report",
due_date=datetime.now() + timedelta(days=1),
priority="high", # none, low, medium, high
)
# Task with tags and content
task = await client.create_task(
title="Review PR #123",
content="Check for:\n- Code style\n- Tests\n- Documentation",
tags=["work", "code-review"],
)
# Recurring task (MUST include start_date!)
task = await client.create_task(
title="Daily standup",
start_date=datetime(2025, 1, 20, 9, 0),
recurrence="RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR",
)
# Task with reminder
task = await client.create_task(
title="Meeting with team",
due_date=datetime(2025, 1, 20, 14, 0),
reminders=["TRIGGER:-PT15M"], # 15 minutes before
)
# All-day task
task = await client.create_task(
title="Project deadline",
due_date=datetime(2025, 1, 31),
all_day=True,
)管理任务
async with TickTickClient.from_settings() as client:
# Get a specific task
task = await client.get_task(task_id="...")
# Update a task
task.title = "Updated title"
task.priority = 5 # high priority
await client.update_task(task)
# Complete a task
await client.complete_task(task_id="...", project_id="...")
# Delete a task (moves to trash)
await client.delete_task(task_id="...", project_id="...")
# Move task to another project
await client.move_task(
task_id="...",
from_project_id="...",
to_project_id="...",
)子任务
async with TickTickClient.from_settings() as client:
# Create parent task
parent = await client.create_task(title="Main task")
# Create child task
child = await client.create_task(title="Subtask")
# Make it a subtask (parent_id in create is ignored by API)
await client.make_subtask(
task_id=child.id,
parent_id=parent.id,
project_id=child.project_id,
)
# Remove parent relationship
await client.unparent_subtask(
task_id=child.id,
project_id=child.project_id,
)查询任务
async with TickTickClient.from_settings() as client:
# All active tasks
all_tasks = await client.get_all_tasks()
# Tasks due today
today = await client.get_today_tasks()
# Overdue tasks
overdue = await client.get_overdue_tasks()
# Tasks by tag
work_tasks = await client.get_tasks_by_tag("work")
# Tasks by priority
urgent = await client.get_tasks_by_priority("high")
# Search tasks
results = await client.search_tasks("meeting")
# Recently completed
completed = await client.get_completed_tasks(days=7, limit=50)
# Abandoned tasks ("won't do")
abandoned = await client.get_abandoned_tasks(days=30)
# Deleted tasks (in trash)
deleted = await client.get_deleted_tasks(limit=50)项目和文件夹
项目
async with TickTickClient.from_settings() as client:
# List all projects
projects = await client.get_all_projects()
for project in projects:
print(f"{project.name} ({project.id})")
# Get project with all its tasks
project_data = await client.get_project_tasks(project_id="...")
print(f"Project: {project_data.project.name}")
print(f"Tasks: {len(project_data.tasks)}")
# Create a project
project = await client.create_project(
name="Q1 Goals",
color="#4A90D9",
view_mode="kanban", # list, kanban, timeline
)
# Update a project
await client.update_project(
project_id=project.id,
name="Q1 Goals 2025",
color="#FF5500",
)
# Delete a project
await client.delete_project(project_id="...")文件夹(项目组)
async with TickTickClient.from_settings() as client:
# List all folders
folders = await client.get_all_folders()
# Create a folder
folder = await client.create_folder(name="Work Projects")
# Create project in folder
project = await client.create_project(
name="Client A",
folder_id=folder.id,
)
# Rename a folder
await client.rename_folder(folder_id=folder.id, name="Work")
# Delete a folder
await client.delete_folder(folder_id="...")标签
TickTick中的标签支持层次结构(父子关系)和自定义颜色。
async with TickTickClient.from_settings() as client:
# List all tags
tags = await client.get_all_tags()
for tag in tags:
print(f"{tag.label} ({tag.name}) - {tag.color}")
# Create a tag
tag = await client.create_tag(
name="urgent",
color="#FF0000",
)
# Create nested tag
child_tag = await client.create_tag(
name="critical",
parent="urgent", # Parent tag name
)
# Rename a tag
await client.rename_tag(old_name="urgent", new_name="priority")
# Update tag color or parent
await client.update_tag(
name="priority",
color="#FF5500",
)
# Merge tags (move all tasks from source to target)
await client.merge_tags(source="old-tag", target="new-tag")
# Delete a tag
await client.delete_tag(name="obsolete")习惯
TickTick习惯是您希望每天跟踪的重复活动。
习惯类型
| 类型 | 描述 | 示例 |
|---|---|---|
Boolean | 简单的是/否 | “你今天锻炼了吗?” |
Real | 数字计数器 | “你读了多少页?” |
养成和管理习惯
async with TickTickClient.from_settings() as client:
# List all habits
habits = await client.get_all_habits()
# Boolean habit (yes/no)
exercise = await client.create_habit(
name="Exercise",
color="#4A90D9",
reminders=["07:00", "19:00"],
target_days=30,
encouragement="Stay strong!",
)
# Numeric habit
reading = await client.create_habit(
name="Read",
habit_type="Real",
goal=30, # 30 pages per day
step=5, # +5 button increment
unit="Pages",
)
# Check in a habit (today)
habit = await client.checkin_habit("habit_id")
print(f"Streak: {habit.current_streak} days!")
# Check in for a past date (backdate)
from datetime import date
habit = await client.checkin_habit("habit_id", checkin_date=date(2025, 12, 15))
# Archive/unarchive
await client.archive_habit("habit_id")
await client.unarchive_habit("habit_id")习惯重复规则(RRULE格式)
| 时间表 | RRULE |
|---|---|
| 每日(每天) | RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA |
| 仅限工作日 | RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR |
| 仅限周末 | RRULE:FREQ=WEEKLY;BYDAY=SA,SU |
| 每周X次 | RRULE:FREQ=WEEKLY;TT_TIMES=5 |
| 具体日期 | RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR |
焦点/番茄
from datetime import date, timedelta
async with TickTickClient.from_settings() as client:
# Focus heatmap (like GitHub contribution graph)
heatmap = await client.get_focus_heatmap(
start_date=date.today() - timedelta(days=90),
end_date=date.today(),
)
# Focus time by tag
by_tag = await client.get_focus_by_tag(days=30)
for tag, seconds in sorted(by_tag.items(), key=lambda x: -x[1]):
hours = seconds / 3600
print(f" {tag}: {hours:.1f} hours")用户和统计
async with TickTickClient.from_settings() as client:
# User profile
profile = await client.get_profile()
print(f"Username: {profile.username}")
# Account status
status = await client.get_status()
print(f"Pro User: {status.is_pro}")
print(f"Inbox ID: {status.inbox_id}")
# Productivity statistics
stats = await client.get_statistics()
print(f"Level: {stats.level}")
print(f"Score: {stats.score}")
print(f"Tasks completed today: {stats.today_completed}")错误处理
from ticktick_sdk import (
TickTickClient,
TickTickError,
TickTickNotFoundError,
TickTickAuthenticationError,
TickTickRateLimitError,
TickTickValidationError,
)
async with TickTickClient.from_settings() as client:
try:
task = await client.get_task("nonexistent-id")
except TickTickNotFoundError as e:
print(f"Task not found: {e}")
except TickTickAuthenticationError:
print("Authentication failed - check credentials")
except TickTickRateLimitError:
print("Rate limited - wait and retry")
except TickTickValidationError as e:
print(f"Invalid input: {e}")
except TickTickError as e:
print(f"TickTick error: {e}")______________________________________________________________________
建筑
┌─────────────────────────────────────────────────────────────┐
│ Your Application │
│ (or MCP Server for AI Assistants) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ TickTickClient │
│ High-level, user-friendly async API │
│ (tasks, projects, tags, habits, focus, user methods) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ UnifiedTickTickAPI │
│ Routes calls to V1 or V2, converts responses │
│ to unified Pydantic models │
└─────────────────────────┬───────────────────────────────────┘
│
┌──────────────┴──────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ V1 API │ │ V2 API │
│ (OAuth2) │ │ (Session) │
│ │ │ │
│ • Official API │ │ • Unofficial API │
│ • Project with tasks │ │ • Tags, folders │
│ • Limited features │ │ • Habits, focus │
│ │ │ • Full subtasks │
└──────────────────────┘ └──────────────────────┘关键设计决策
- V2优先:大多数操作使用V2 API(更多功能),只有在需要时才返回到V1
- 统一模型:单组Pydantic模型,无论哪一个API提供数据
- 异步贯穿始终:所有I/O操作都是异步的,以提高性能
- 类型安全:完整的类型提示和Pydantic验证
______________________________________________________________________
API 参考
模型
| 型号 | 描述 |
|---|---|
Task | 带有标题、日期、优先级、标签、子任务、重复等的任务。 |
Project | 任务的项目/列表容器 |
ProjectGroup | 用于组织项目的文件夹 |
ProjectData | 项目及其任务(来自get_Project_tasks) |
Column | 看板栏,用于在板中组织任务 |
Tag | 标记名称、标签、颜色和可选父项 |
Habit | 反复出现的习惯,包括类型、目标、连续性和签到 |
HabitSection | 一天中的时间分组(上午/下午/晚上) |
HabitCheckin | 个人习惯登记记录 |
HabitPreferences | 用户习惯设置 |
User | 用户资料信息 |
UserStatus | 帐户状态(专业版、收件箱ID等) |
UserStatistics | 生产率统计(水平、分数、计数) |
ChecklistItem | 任务中的子任务/清单项 |
枚举
| 枚举 | 值 |
|---|---|
TaskStatus | ABANDONED (-1), ACTIVE (0), COMPLETED (2) |
TaskPriority | NONE (0), LOW (1), MEDIUM (3), HIGH (5) |
TaskKind | TEXT, NOTE, CHECKLIST |
ProjectKind | TASK, NOTE |
ViewMode | LIST, KANBAN, TIMELINE |
异常
| 异常 | 描述 |
|---|---|
TickTickError | 所有错误的基本异常 |
TickTickAuthenticationError | 身份验证失败 |
TickTickNotFoundError | 未找到资源 |
TickTickValidationError | 输入数据无效 |
TickTickRateLimitError | 超出费率限制 |
TickTickConfigurationError | 缺少配置 |
TickTickForbiddenError | 访问被拒绝 |
TickTickServerError | 服务器端错误 |
______________________________________________________________________
重要提示:TickTick API测验
TickTick的API有几个你应该知道的独特行为:
1.重复需要start_date
如果创建没有start_date的重复任务,TickTick会自动忽略重复规则。
# WRONG - recurrence will be ignored!
task = await client.create_task(
title="Daily standup",
recurrence="RRULE:FREQ=DAILY",
)
# CORRECT
task = await client.create_task(
title="Daily standup",
start_date=datetime(2025, 1, 20, 9, 0),
recurrence="RRULE:FREQ=DAILY",
)2.子任务需要单独呼叫
设置 parent_id 在任务创建过程中 忽略 API:
# Create the child task first
child = await client.create_task(title="Subtask")
# Then make it a subtask
await client.make_subtask(
task_id=child.id,
parent_id="parent_task_id",
project_id=child.project_id,
)3.软删除
删除任务会将其移至回收站(deleted=1)而不是永久地移除它们。
4.日期清算
清除任务的 due_date,您还必须清除 start_date:
task.due_date = None
task.start_date = None
await client.update_task(task)5.标签订单未保留
API不保留标记顺序-标记可以按任何顺序返回。
6.收件箱很特别
收件箱是一个无法删除的特殊项目。通过以下方式获取其ID await client.get_status().
______________________________________________________________________
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
TICKTICK_CLIENT_ID | 是 | 来自开发人员门户的OAuth2客户端ID |
TICKTICK_CLIENT_SECRET | 是 | OAuth2客户端机密 |
TICKTICK_ACCESS_TOKEN | 是 | OAuth2访问令牌(来自auth命令) |
TICKTICK_USERNAME | 是 | 您的TickTick电子邮件 |
TICKTICK_PASSWORD | 是 | 您的TickTick密码 |
TICKTICK_REDIRECT_URI | 否 | OAuth 2重定向类型(默认值: http://127.0.0.1:8080/callback) |
TICKTICK_HOST | 没有 | API主机: ticktick.com (默认)或 dida365.com (中文) |
TICKTICK_TIMEOUT | 否 | 请求超时(秒)(默认值: 30) |
TICKTICK_DEVICE_ID | 否 | V2 API的设备ID(自动生成) |
______________________________________________________________________
运行测试
# Install dev dependencies
pip install -e ".[dev]"
# All tests (mock mode - no API calls)
pytest
# With verbose output
pytest -v
# Live tests (requires credentials)
pytest --live
# With coverage
pytest --cov=ticktick_sdk --cov-report=term-missing测试标记
| 标记 | 描述 |
|---|---|
unit | 单元测试(快速、隔离) |
tasks | 任务相关测试 |
projects | 项目相关测试 |
tags | 标签相关测试 |
habits | 习惯相关测试 |
focus | 注意力/番茄钟测试 |
pinning | 任务固定测试 |
columns | 看板柱测试 |
mock_only | 仅适用于模拟的测试 |
live_only | 仅在以下情况下运行的测试 --live |
______________________________________________________________________
故障排除
“令牌交换失败”
- 验证您的客户端ID和客户端密码是否正确
- 确保重定向URI完全匹配(包括尾随斜线)
- 检查您是否使用了正确的TickTick开发人员门户
“身份验证失败”
- 检查您的TickTick用户名(电子邮件)和密码
- 尝试登录ticktick.com以验证凭据
“V2初始化失败”
- 您的密码可能包含特殊字符-请尝试更改它
- 检查2FA/MFA(目前不支持)
“超出费率限制”
- 等待30-60秒后重试
- 降低API调用频率
______________________________________________________________________
贡献
欢迎投稿!拜托:
- 分叉存储库
- 创建要素分支(
git checkout -b feature/amazing-feature) - 为新功能编写测试
- 确保所有测试通过(
pytest) - 运行类型检查(
mypy src/) - 提交拉取请求
开发设置
git clone https://github.com/dev-mirzabicer/ticktick-sdk.git
cd ticktick-sdk
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"______________________________________________________________________
许可证
MIT许可证-请参阅 许可证 了解详情。
______________________________________________________________________
