Modern async Python client for ClickUp API with type hints, rate limiting and fluent interface
Project description
ClickUp Async โจ
A production-ready, high-performance Python client for the ClickUp API with first-class async support. Built for developers who need robust, type-safe, and efficient ClickUp integration in their Python applications.
๐ Version 1.0.0 Now Available! - First stable release with complete API coverage and production-ready features.
๐ Why Choose ClickUp Async?
Transform your ClickUp workflow automation with a library that prioritizes developer experience and performance:
| Feature | ClickUp Async | Other Libraries |
|---|---|---|
| Async Support | โ Full async/await with concurrent operations | โ Synchronous only |
| Type Safety | โ Comprehensive type hints & Pydantic validation | โ Limited or none |
| Rate Limiting | โ Smart handling with exponential backoff | โ Basic or none |
| Fluent Interface | โ Intuitive, chainable API design | โ Verbose calls |
| Modern Python | โ Leverages Python 3.9+ features | โ Legacy compatibility |
| Error Handling | โ Detailed exceptions with context | โ Basic exceptions |
| Pagination | โ Automatic with async iterators | โ Manual handling |
| Documentation | โ Comprehensive with examples | โ Limited coverage |
| Maintenance | โ Active development & support | โ Irregular updates |
๐ Quick Start
Installation
pip install clickup-async
Basic Usage
import asyncio
from clickup_async import ClickUp
from clickup_async.models import Priority, Task
async def main():
async with ClickUp(api_token="your_token_here") as client:
# Get user info
user = await client.get_authenticated_user()
print(f"๐ Welcome, {user.username}!")
# Create a task with rich metadata
task = await client.list("list_id").tasks.create_task(
name="Launch New Feature",
description="## Objective\nImplement the new feature with following requirements:\n\n- High performance\n- User friendly\n- Well tested",
priority=Priority.HIGH,
due_date="next Friday",
tags=["feature", "backend"],
notify_all=True
)
print(f"โจ Created task: {task.name} (ID: {task.id})")
if __name__ == "__main__":
asyncio.run(main())
๐ Comprehensive Feature Guide
๐ Authentication & Setup
from clickup_async import ClickUp
# Basic setup
client = ClickUp(api_token="your_token")
# Advanced configuration
client = ClickUp(
api_token="your_token",
retry_rate_limited_requests=True,
rate_limit_buffer=5,
timeout=30,
base_url="https://api.clickup.com/api/v2"
)
๐ Task Management
Create, update, and manage tasks with rich functionality:
# Create a task with custom fields
task = await client.list("list_id").tasks.create_task(
name="New Feature Implementation",
description="Implement the new feature",
assignees=["user_id"],
tags=["feature"],
custom_fields=[{
"id": "field_id",
"value": "High Impact"
}]
)
# Update task status
updated_task = await client.task(task.id).update(
status="In Progress",
priority=Priority.URGENT
)
# Add time tracking
await client.task(task.id).time.add_time_entry(
duration=3600, # 1 hour in seconds
description="Initial implementation"
)
# Add a comment with attachments
await client.task(task.id).comments.create_comment(
text="Please review the implementation",
assignee="user_id",
notify_all=True
)
๐ Working with Lists and Views
Manage task lists and custom views efficiently:
# Create a new list
new_list = await client.folder("folder_id").lists.create_list(
name="Q4 Projects",
content="Strategic projects for Q4",
due_date="end of quarter"
)
# Get tasks with advanced filtering
tasks = await client.list("list_id").tasks.get_tasks(
due_date_gt="today",
due_date_lt="next month",
assignees=["user_id"],
include_closed=False,
subtasks=True,
order_by="due_date"
)
# Create a custom view
view = await client.list("list_id").views.create_view(
name="High Priority Tasks",
type="list",
filters={
"priority": [Priority.HIGH, Priority.URGENT]
}
)
๐ Workspace, Space, and Folder Management
Navigate and manage your ClickUp hierarchy with ease:
# Get all workspaces
workspaces = await client.workspaces.get_workspaces()
# Working with Spaces
# Create a new space
space = await client.workspace("workspace_id").spaces.create_space(
name="Product Development",
features={"due_dates", "time_tracking", "tags"},
private=True
)
# Update space settings
updated_space = await client.space(space.id).update(
name="Product Development 2023",
features={"due_dates", "time_tracking", "tags", "priorities"}
)
# Get all spaces in a workspace
spaces = await client.workspace("workspace_id").spaces.get_spaces()
# Working with Folders
# Create a folder in a space
folder = await client.space("space_id").folders.create_folder(
name="Q4 Projects",
description="All projects for Q4 2023"
)
# Update folder
updated_folder = await client.folder(folder.id).update(
name="Q4 Strategic Projects"
)
# Get all folders in a space
folders = await client.space("space_id").folders.get_folders()
# Working with Lists
# Create a list in a folder
task_list = await client.folder("folder_id").lists.create_list(
name="Backend Development",
description="Backend tasks and features",
assignee="user_id",
due_date="next month"
)
# Create a folderless list in a space
space_list = await client.space("space_id").lists.create_list(
name="Quick Tasks",
description="Tasks without folder organization"
)
# Update list
updated_list = await client.list(task_list.id).update(
name="Backend Development Sprint 1",
due_date="next friday",
priority=Priority.HIGH
)
# Get all lists
folder_lists = await client.folder("folder_id").lists.get_lists()
space_lists = await client.space("space_id").lists.get_lists(include_archived=False)
# Advanced folder operations
# Move a folder to a different space
moved_folder = await client.folder("folder_id").move(
destination_space="new_space_id"
)
# Advanced list operations
# Move a list to a different folder
moved_list = await client.list("list_id").move(
destination_folder="new_folder_id"
)
# Bulk operations
# Create multiple lists in a folder
lists = await asyncio.gather(*[
client.folder("folder_id").lists.create_list(
name=f"Sprint {i}",
description=f"Tasks for Sprint {i}"
) for i in range(1, 4)
])
๐ Goals and Tracking
Set up and track goals with key results:
# Create a new goal
goal = await client.team("team_id").goals.create_goal(
name="Increase Performance",
due_date="end of quarter",
description="Improve system performance metrics"
)
# Add key results
key_result = await client.goal(goal.id).key_results.create_key_result(
name="Reduce Response Time",
steps=100,
unit="ms",
start_value=200,
target_value=50
)
๐ Webhooks and Automation
Set up real-time notifications and automation:
# Create a webhook
webhook = await client.workspace("workspace_id").webhooks.create_webhook(
endpoint="https://your-domain.com/webhook",
events=["taskCreated", "taskUpdated"],
space_id="space_id"
)
# Get webhook history
history = await client.webhook(webhook.id).get_webhook_history()
๐ Smart Pagination
Handle large datasets efficiently with automatic pagination:
async def get_all_tasks(list_id: str) -> list[Task]:
tasks_page = await client.list(list_id).tasks.get_tasks()
all_tasks = []
while True:
all_tasks.extend(tasks_page.items)
if not tasks_page.has_more:
break
tasks_page = await tasks_page.next_page()
return all_tasks
๐ ๏ธ Development and Testing
Setting Up Development Environment
-
Clone the repository
git clone https://github.com/catorch/clickup-async.git cd clickup-async
-
Create virtual environment
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install development dependencies
pip install -e ".[dev,test]"
Running Tests
# Set up environment variables
export CLICKUP_API_KEY=your_token_here
# Run tests with coverage
pytest --cov=clickup_async
๐ Changelog
1.0.0 (2025-04-10)
First stable release! ๐
โจ Features
- Complete coverage of ClickUp API
- Fully typed interface with Pydantic models
- Comprehensive documentation with examples
- Production-ready with extensive test coverage
- Smart rate limiting and error handling
- Async-first design with concurrent operation support
- Fluent interface for intuitive API navigation
๐ก Improvements
- Enhanced error messages and debugging support
- Optimized performance for large-scale operations
- Comprehensive test suite with 90%+ coverage
- Extended documentation with real-world examples
๐ Breaking Changes
- Stable API interface established
- Minimum Python version: 3.8+
- All core features implemented and tested
License
MIT License - See LICENSE for details.
โญ If you find this library helpful, please consider starring it on GitHub!
๐ก Need help? Open an issue.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clickup_async-1.0.0.tar.gz.
File metadata
- Download URL: clickup_async-1.0.0.tar.gz
- Upload date:
- Size: 39.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
007fa3fe426458a8f465026dbb33cdaf1d222c134ecd00cc1638edd7f7417a5a
|
|
| MD5 |
0b92027094cecff5fa07fcedadc2d9fa
|
|
| BLAKE2b-256 |
c5b51c7db967caf526ab9bc92976f6f5525fbcf15e45d1a878ed052ddfb90956
|
File details
Details for the file clickup_async-1.0.0-py3-none-any.whl.
File metadata
- Download URL: clickup_async-1.0.0-py3-none-any.whl
- Upload date:
- Size: 21.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9440e1c87b58d26e48e0954df14610b57ddc5d59ee8ed33cac0a883e1b7fa2e
|
|
| MD5 |
1c461930410c7351b5938423bf9b3242
|
|
| BLAKE2b-256 |
d448b9159d6a2a23fa73b44aedc07b1825b9738f00be8897f9d751e0c4d95fcf
|