Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Instruções da origem · Visualização somente leitura
name
trello-api
version
1.0.0
description
Kanban board automation with Trello API including boards, lists, cards, members, webhooks, power-ups, and Python SDK (py-trello) integration
author
workspace-hub
category
productivity
type
skill
capabilities
["Board creation and management","List CRUD operations","Card creation and manipulation","Labels and checklists","Member management","Attachments and comments","Webhook integration","Power-up development","Batch operations","Custom fields"]
Master the Trello API for Kanban board automation, including boards, lists, cards, members, webhooks, and the py-trello Python SDK. Build powerful workflow automations and custom integrations with Trello's comprehensive REST API.
Building workflow integrations - Connect Trello with other tools
Card automation - Auto-create cards from external events
Progress tracking - Build dashboards from Trello data
Notification systems - React to board changes via webhooks
Bulk operations - Move/update many cards at once
Custom reporting - Extract data for analysis
Power-up development - Extend Trello functionality
DON'T USE Trello API when:
Need complex dependencies - Use Jira or Asana
Require time tracking - Built-in feature limited, use Toggl integration
Database-style queries - Use Notion API instead
Enterprise compliance - May need Enterprise-grade solutions
Complex workflows - Consider Monday.com or Linear
Prerequisites
API Authentication
# Get API Key from:# https://trello.com/app-key# Get Token (authorize your app):# https://trello.com/1/authorize?expiration=never&scope=read,write,account&response_type=token&name=MyApp&key=YOUR_API_KEY# Set environment variablesexport TRELLO_API_KEY="your-api-key"export TRELLO_TOKEN="your-token"# Verify authentication
curl -s "https://api.trello.com/1/members/me?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq '.fullName'
from trello import TrelloClient
import os
client = TrelloClient(
api_key=os.environ["TRELLO_API_KEY"],
token=os.environ["TRELLO_TOKEN"]
)
# List all boards
boards = client.list_boards()
for board in boards:
print(f"{board.name} (ID: {board.id})")
# Get specific board
board = client.get_board("BOARD_ID")
print(f"Board: {board.name}")
print(f"URL: {board.url}")
# Create new board
new_board = client.add_board(
board_name="Development Sprint",
source_board=None, # Or source board for template
permission_level="private"# "private", "org", "public"
)
print(f"Created board: {new_board.id}")
# Get board lists
lists = board.list_lists()
for lst in lists:
print(f" List: {lst.name}")
# Get all cards on board
cards = board.get_cards()
for card in cards:
print(f" Card: {card.name}")
# Get board members
members = board.get_members()
for member in members:
print(f" Member: {member.full_name}")
# Close board
board.close()
# Reopen board
board.open()
2. List Management
REST API - Lists:
# Get lists for board
curl -s "https://api.trello.com/1/boards/BOARD_ID/lists?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
# Create list
curl -s -X POST "https://api.trello.com/1/lists" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "name=In Progress" \
-d "idBoard=BOARD_ID" \
-d "pos=bottom" | jq
# Update list name
curl -s -X PUT "https://api.trello.com/1/lists/LIST_ID" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "name=Currently Working" | jq
# Move list to different position
curl -s -X PUT "https://api.trello.com/1/lists/LIST_ID" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "pos=top" | jq
# Archive list
curl -s -X PUT "https://api.trello.com/1/lists/LIST_ID/closed" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "value=true" | jq
# Move all cards in list to another list
curl -s -X POST "https://api.trello.com/1/lists/LIST_ID/moveAllCards" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "idBoard=BOARD_ID" \
-d "idList=TARGET_LIST_ID" | jq
# Archive all cards in list
curl -s -X POST "https://api.trello.com/1/lists/LIST_ID/archiveAllCards?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN"
Python SDK - Lists:
from trello import TrelloClient
import os
client = TrelloClient(
api_key=os.environ["TRELLO_API_KEY"],
token=os.environ["TRELLO_TOKEN"]
)
board = client.get_board("BOARD_ID")
# Get all lists
lists = board.list_lists()
for lst in lists:
print(f"List: {lst.name} (ID: {lst.id})")
# Create new list
new_list = board.add_list(
name="Backlog",
pos="bottom"# "top", "bottom", or position number
)
print(f"Created list: {new_list.id}")
# Get specific list
target_list = board.get_list("LIST_ID")
# Get cards in list
cards = target_list.list_cards()
for card in cards:
print(f" Card: {card.name}")
# Rename list
target_list.set_name("New Backlog")
# Change list position
target_list.set_pos("top")
# Archive list
target_list.close()
# Move all cards from one list to another
source_list = board.get_list("SOURCE_LIST_ID")
dest_list = board.get_list("DEST_LIST_ID")
for card in source_list.list_cards():
card.change_list(dest_list.id)
3. Card Management
REST API - Cards:
# Get cards for list
curl -s "https://api.trello.com/1/lists/LIST_ID/cards?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
# Get single card
curl -s "https://api.trello.com/1/cards/CARD_ID?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
# Create card with all options
curl -s -X POST "https://api.trello.com/1/cards" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "idList=LIST_ID" \
-d "name=Implement feature X" \
-d "desc=Detailed description of the feature" \
-d "pos=top" \
-d "due=2025-01-30T12:00:00.000Z" \
-d "dueComplete=false" \
-d "idMembers=MEMBER_ID1,MEMBER_ID2" \
-d "idLabels=LABEL_ID1,LABEL_ID2" | jq
# Update card
curl -s -X PUT "https://api.trello.com/1/cards/CARD_ID" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "name=Updated card name" \
-d "desc=Updated description" \
-d "due=2025-02-15" | jq
# Move card to different list
curl -s -X PUT "https://api.trello.com/1/cards/CARD_ID" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "idList=NEW_LIST_ID" | jq
# Move card to different board
curl -s -X PUT "https://api.trello.com/1/cards/CARD_ID" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "idBoard=NEW_BOARD_ID" \
-d "idList=NEW_LIST_ID" | jq
# Archive card
curl -s -X PUT "https://api.trello.com/1/cards/CARD_ID" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "closed=true" | jq
# Delete card permanently
curl -s -X DELETE "https://api.trello.com/1/cards/CARD_ID?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN"# Add comment to card
curl -s -X POST "https://api.trello.com/1/cards/CARD_ID/actions/comments" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "text=This is a comment on the card" | jq
# Add attachment via URL
curl -s -X POST "https://api.trello.com/1/cards/CARD_ID/attachments" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "url=https://example.com/file.pdf" \
-d "name=Important Document" | jq
Python SDK - Cards:
from trello import TrelloClient
from datetime import datetime, timedelta
import os
client = TrelloClient(
api_key=os.environ["TRELLO_API_KEY"],
token=os.environ["TRELLO_TOKEN"]
)
board = client.get_board("BOARD_ID")
target_list = board.get_list("LIST_ID")
# Create card
new_card = target_list.add_card(
name="Complete API integration",
desc="Full description of the task with acceptance criteria",
labels=None, # Add labels later
due="2025-02-01",
source=None, # Or source card ID to copy from
position="top"# "top", "bottom", or number
)
print(f"Created card: {new_card.id}")
# Get card
card = client.get_card("CARD_ID")
print(f"Card: {card.name}")
print(f"Description: {card.description}")
print(f"Due: {card.due_date}")
# Update card properties
card.set_name("Updated: Complete API integration")
card.set_description("Updated description with more details")
# Set due date
due_date = datetime.now() + timedelta(days=7)
card.set_due(due_date)
# Mark due date complete
card.set_due_complete()
# Add label to card
labels = board.get_labels()
for label in labels:
if label.name == "High Priority":
card.add_label(label)
break# Assign member
members = board.get_members()
for member in members:
if member.username == "target_user":
card.add_member(member)
break# Add comment
card.comment("This task is now in progress")
# Add checklist
checklist = card.add_checklist(
title="Implementation Steps",
items=["Design API", "Write code", "Write tests", "Deploy"]
)
# Move card to different list
done_list = board.get_list("DONE_LIST_ID")
card.change_list(done_list.id)
# Archive card
card.set_closed(True)
# Unarchive card
card.set_closed(False)
# Delete card
card.delete()
# Get checklists on card
checklists = card.fetch_checklists()
for checklist in checklists:
print(f"Checklist: {checklist.name}")
for item in checklist.items:
status = "[x]"if item["checked"] else"[ ]"print(f" {status}{item['name']}")
# Create checklist with items
checklist = card.add_checklist(
title="Release Checklist",
items=[
"Code review completed",
"Tests passing",
"Documentation updated",
"Changelog updated",
"Version bumped"
]
)
# Check/uncheck item
checklist.set_checklist_item("Code review completed", checked=True)
# Delete checklist item
checklist.delete_checklist_item("Documentation updated")
# Rename checklist
checklist.rename("Pre-Release Checklist")
# Delete checklist
checklist.delete()
6. Member Management
REST API - Members:
# Get board members
curl -s "https://api.trello.com/1/boards/BOARD_ID/members?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
# Get member info
curl -s "https://api.trello.com/1/members/MEMBER_ID?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
# Add member to board
curl -s -X PUT "https://api.trello.com/1/boards/BOARD_ID/members/MEMBER_ID" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "type=normal" | jq # "admin", "normal", "observer"# Remove member from board
curl -s -X DELETE "https://api.trello.com/1/boards/BOARD_ID/members/MEMBER_ID?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN"# Assign member to card
curl -s -X POST "https://api.trello.com/1/cards/CARD_ID/idMembers" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "value=MEMBER_ID" | jq
# Remove member from card
curl -s -X DELETE "https://api.trello.com/1/cards/CARD_ID/idMembers/MEMBER_ID?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN"# Get cards assigned to member
curl -s "https://api.trello.com/1/members/MEMBER_ID/cards?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
Python SDK - Members:
# Get current user
me = client.get_member("me")
print(f"Name: {me.full_name}")
print(f"Username: {me.username}")
print(f"Email: {me.email}")
# Get board members
members = board.get_members()
for member in members:
print(f"Member: {member.full_name} (@{member.username})")
# Assign member to card
card.add_member(member)
# Remove member from card
card.remove_member(member)
# Get all cards for a member
member_cards = client.get_member("me").fetch_cards()
for card in member_cards:
print(f"Assigned card: {card.name}")
# Get boards for member
member_boards = client.get_member("me").fetch_boards()
for board in member_boards:
print(f"Board: {board.name}")
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route("/webhook/trello", methods=["HEAD", "POST"])deftrello_webhook():
# HEAD request is for webhook verificationif request.method == "HEAD":
return"", 200# Process webhook payload
data = request.json
action = data.get("action", {})
action_type = action.get("type")
print(f"Received Trello webhook: {action_type}")
# Handle different action typesif action_type == "createCard":
handle_card_created(action)
elif action_type == "updateCard":
handle_card_updated(action)
elif action_type == "moveCardToBoard":
handle_card_moved(action)
elif action_type == "addMemberToCard":
handle_member_assigned(action)
elif action_type == "commentCard":
handle_comment_added(action)
elif action_type == "updateCheckItemStateOnCard":
handle_checklist_item_updated(action)
return jsonify({"status": "ok"})
defhandle_card_created(action):
card_data = action.get("data", {}).get("card", {})
print(f"Card created: {card_data.get('name')}")
defhandle_card_updated(action):
card_data = action.get("data", {}).get("card", {})
old_data = action.get("data", {}).get("old", {})
print(f"Card updated: {card_data.get('name')}")
# Check if moved to different listif"idList"in old_data:
list_after = action.get("data", {}).get("listAfter", {})
list_before = action.get("data", {}).get("listBefore", {})
print(f" Moved from '{list_before.get('name')}' to '{list_after.get('name')}'")
defhandle_card_moved(action):
card_data = action.get("data", {}).get("card", {})
print(f"Card moved to different board: {card_data.get('name')}")
defhandle_member_assigned(action):
card_data = action.get("data", {}).get("card", {})
member_data = action.get("data", {}).get("member", {})
print(f"Member {member_data.get('username')} assigned to: {card_data.get('name')}")
defhandle_comment_added(action):
card_data = action.get("data", {}).get("card", {})
text = action.get("data", {}).get("text", "")
print(f"Comment on {card_data.get('name')}: {text[:100]}")
defhandle_checklist_item_updated(action):
card_data = action.get("data", {}).get("card", {})
item = action.get("data", {}).get("checkItem", {})
state = item.get("state")
print(f"Checklist item '{item.get('name')}' marked {state}")
if __name__ == "__main__":
app.run(port=5000)
Webhook Events:
# Common Trello webhook action types
WEBHOOK_ACTIONS = {
# Board events"updateBoard": "Board settings changed",
"addMemberToBoard": "Member added to board",
"removeMemberFromBoard": "Member removed from board",
# List events"createList": "List created",
"updateList": "List updated (renamed, moved, archived)",
"moveListToBoard": "List moved to different board",
# Card events"createCard": "Card created",
"updateCard": "Card updated (name, desc, due date, position, list)",
"deleteCard": "Card deleted",
"moveCardToBoard": "Card moved to different board",
"copyCard": "Card copied",
"convertToCardFromCheckItem": "Checklist item converted to card",
# Card member events"addMemberToCard": "Member assigned to card",
"removeMemberFromCard": "Member removed from card",
# Card label events"addLabelToCard": "Label added to card",
"removeLabelFromCard": "Label removed from card",
# Card attachment events"addAttachmentToCard": "Attachment added",
"deleteAttachmentFromCard": "Attachment deleted",
# Comment events"commentCard": "Comment added to card",
"updateComment": "Comment updated",
"deleteComment": "Comment deleted",
# Checklist events"addChecklistToCard": "Checklist added to card",
"removeChecklistFromCard": "Checklist removed",
"updateChecklist": "Checklist updated",
"updateCheckItemStateOnCard": "Checklist item checked/unchecked",
"createCheckItem": "Checklist item created",
"deleteCheckItem": "Checklist item deleted",
}
8. Custom Fields
REST API - Custom Fields:
# Get custom fields on board
curl -s "https://api.trello.com/1/boards/BOARD_ID/customFields?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
# Create custom field
curl -s -X POST "https://api.trello.com/1/customFields" \
-d "key=$TRELLO_API_KEY" \
-d "token=$TRELLO_TOKEN" \
-d "idModel=BOARD_ID" \
-d "modelType=board" \
-d "name=Priority Score" \
-d "type=number" \
-d "pos=top" | jq
# Field types: number, text, date, checkbox, list# Create dropdown custom field
curl -s -X POST "https://api.trello.com/1/customFields" \
-H "Content-Type: application/json" \
-d '{
"key": "'$TRELLO_API_KEY'",
"token": "'$TRELLO_TOKEN'",
"idModel": "BOARD_ID",
"modelType": "board",
"name": "Status",
"type": "list",
"pos": "bottom",
"options": [
{"value": {"text": "Not Started"}, "pos": 1},
{"value": {"text": "In Progress"}, "pos": 2},
{"value": {"text": "Completed"}, "pos": 3}
]
}' | jq
# Set custom field value on card
curl -s -X PUT "https://api.trello.com/1/cards/CARD_ID/customField/FIELD_ID/item" \
-H "Content-Type: application/json" \
-d '{
"key": "'$TRELLO_API_KEY'",
"token": "'$TRELLO_TOKEN'",
"value": {"number": "85"}
}' | jq
# For dropdown, use idValue
curl -s -X PUT "https://api.trello.com/1/cards/CARD_ID/customField/FIELD_ID/item" \
-H "Content-Type: application/json" \
-d '{
"key": "'$TRELLO_API_KEY'",
"token": "'$TRELLO_TOKEN'",
"idValue": "OPTION_ID"
}' | jq
# Get custom field values for card
curl -s "https://api.trello.com/1/cards/CARD_ID/customFieldItems?key=$TRELLO_API_KEY&token=$TRELLO_TOKEN" | jq
Python Custom Fields:
import requests
import os
API_KEY = os.environ["TRELLO_API_KEY"]
TOKEN = os.environ["TRELLO_TOKEN"]
defget_custom_fields(board_id):
"""Get all custom fields for a board."""
url = f"https://api.trello.com/1/boards/{board_id}/customFields"
response = requests.get(url, params={"key": API_KEY, "token": TOKEN})
return response.json()
defset_custom_field_value(card_id, field_id, value, field_type="text"):
"""Set custom field value on a card."""
url = f"https://api.trello.com/1/cards/{card_id}/customField/{field_id}/item"# Build value based on typeif field_type == "number":
data = {"value": {"number": str(value)}}
elif field_type == "text":
data = {"value": {"text": value}}
elif field_type == "checkbox":
data = {"value": {"checked": str(value).lower()}}
elif field_type == "date":
data = {"value": {"date": value}} # ISO formatelif field_type == "list":
data = {"idValue": value} # Option ID for dropdownelse:
data = {"value": {"text": str(value)}}
response = requests.put(
url,
json={**data, "key": API_KEY, "token": TOKEN}
)
return response.json()
defget_card_custom_fields(card_id):
"""Get all custom field values for a card."""
url = f"https://api.trello.com/1/cards/{card_id}/customFieldItems"
response = requests.get(url, params={"key": API_KEY, "token": TOKEN})
return response.json()
# Example usage
fields = get_custom_fields("BOARD_ID")
for field in fields:
print(f"Field: {field['name']} (Type: {field['type']})")
# Set a numeric field
set_custom_field_value("CARD_ID", "FIELD_ID", 95, "number")
# Get field values
values = get_card_custom_fields("CARD_ID")
for value in values:
print(f"Field {value['idCustomField']}: {value.get('value', value.get('idValue'))}")
Complete Examples
Example 1: Sprint Board Automation
#!/usr/bin/env python3"""sprint_automation.py - Automate sprint board management"""from trello import TrelloClient
from datetime import datetime, timedelta
import os
import json
defcreate_sprint_board(client, sprint_name, team_members=None):
"""
Create a new sprint board with standard structure.
Args:
client: TrelloClient instance
sprint_name: Name for the sprint
team_members: List of member usernames to add
Returns:
Created board object
"""# Create board
board = client.add_board(
board_name=f"Sprint: {sprint_name}",
permission_level="private"
)
print(f"Created board: {board.name}")
# Create standard sprint lists
lists_config = [
{"name": "Backlog", "pos": "bottom"},
{"name": "To Do", "pos": "bottom"},
{"name": "In Progress", "pos": "bottom"},
{"name": "In Review", "pos": "bottom"},
{"name": "Done", "pos": "bottom"},
]
created_lists = {}
for list_cfg in lists_config:
new_list = board.add_list(name=list_cfg["name"])
created_lists[list_cfg["name"]] = new_list
print(f" Created list: {list_cfg['name']}")
# Create standard labels
labels_config = [
{"name": "Bug", "color": "red"},
{"name": "Feature", "color": "green"},
{"name": "Enhancement", "color": "blue"},
{"name": "Technical Debt", "color": "orange"},
{"name": "Documentation", "color": "purple"},
{"name": "Blocked", "color": "black"},
]
for label_cfg in labels_config:
board.add_label(name=label_cfg["name"], color=label_cfg["color"])
print(f" Created label: {label_cfg['name']}")
# Add sprint info card
sprint_end = datetime.now() + timedelta(days=14)
info_card = created_lists["Backlog"].add_card(
name="Sprint Information",
desc=f"""# Sprint: {sprint_name}
**Start Date:** {datetime.now().strftime('%Y-%m-%d')}
**End Date:** {sprint_end.strftime('%Y-%m-%d')}
## Sprint Goals
- [ ] Goal 1
- [ ] Goal 2
- [ ] Goal 3
## Team
Add team member assignments here.
""",
position="top"
)
# Add checklist for sprint ceremonies
info_card.add_checklist(
title="Sprint Ceremonies",
items=[
"Sprint Planning",
"Daily Standup (Day 1-10)",
"Sprint Review",
"Sprint Retrospective"
]
)
return board, created_lists
defadd_sprint_tasks(board, lists, tasks):
"""
Add tasks to the sprint board.
Args:
board: Board object
lists: Dictionary of list objects by name
tasks: List of task dictionaries
"""
labels = {label.name: label for label in board.get_labels()}
for task in tasks:
list_name = task.get("list", "Backlog")
target_list = lists.get(list_name)
ifnot target_list:
print(f"Warning: List '{list_name}' not found")
continue# Create card
card = target_list.add_card(
name=task["name"],
desc=task.get("description", ""),
due=task.get("due_date")
)
# Add labelsfor label_name in task.get("labels", []):
if label_name in labels:
card.add_label(labels[label_name])
# Add checklist if providedif"checklist"in task:
card.add_checklist(
title=task["checklist"].get("name", "Tasks"),
items=task["checklist"].get("items", [])
)
print(f" Created task: {task['name']}")
defgenerate_sprint_report(board):
"""Generate sprint progress report."""
lists = board.list_lists()
list_cards = {}
for lst in lists:
cards = lst.list_cards()
list_cards[lst.name] = cards
total_cards = sum(len(cards) for cards in list_cards.values())
done_cards = len(list_cards.get("Done", []))
report = {
"board_name": board.name,
"generated_at": datetime.now().isoformat(),
"total_tasks": total_cards,
"completed_tasks": done_cards,
"completion_percentage": round(done_cards / total_cards * 100, 1) if total_cards > 0else0,
"by_list": {}
}
for list_name, cards in list_cards.items():
report["by_list"][list_name] = {
"count": len(cards),
"cards": [{"name": c.name, "due": str(c.due_date)} for c in cards]
}
return report
# Example usageif __name__ == "__main__":
client = TrelloClient(
api_key=os.environ["TRELLO_API_KEY"],
token=os.environ["TRELLO_TOKEN"]
)
# Create sprint board
board, lists = create_sprint_board(
client,
sprint_name="2025-W05",
team_members=["user1", "user2"]
)
# Add sample tasks
tasks = [
{
"name": "Implement user authentication",
"description": "Add JWT-based authentication",
"list": "To Do",
"labels": ["Feature"],
"due_date": "2025-02-07",
"checklist": {
"name": "Implementation Steps",
"items": ["Design API", "Implement backend", "Add tests", "Update docs"]
}
},
{
"name": "Fix login page bug",
"description": "Users can't login with special characters",
"list": "To Do",
"labels": ["Bug"],
"due_date": "2025-02-03"
},
{
"name": "Refactor database queries",
"description": "Optimize slow queries",
"list": "Backlog",
"labels": ["Technical Debt"]
}
]
add_sprint_tasks(board, lists, tasks)
# Generate report
report = generate_sprint_report(board)
print(f"\n{'='*50}")
print(f"Sprint Report: {report['board_name']}")
print(f"{'='*50}")
print(f"Total Tasks: {report['total_tasks']}")
print(f"Completed: {report['completed_tasks']} ({report['completion_percentage']}%)")
Example 2: Card Migration Tool
#!/usr/bin/env python3"""card_migration.py - Migrate cards between boards"""from trello import TrelloClient
import os
import json
from datetime import datetime
defmigrate_cards(
client,
source_board_id,
target_board_id,
list_mapping,
include_labels=True,
include_checklists=True,
include_attachments=False,
archive_source=False):
"""
Migrate cards from source board to target board.
Args:
client: TrelloClient instance
source_board_id: Source board ID
target_board_id: Target board ID
list_mapping: Dict mapping source list names to target list names
include_labels: Copy labels to new cards
include_checklists: Copy checklists to new cards
include_attachments: Copy attachments (URLs only)
archive_source: Archive source cards after migration
Returns:
Migration report dictionary
"""
source_board = client.get_board(source_board_id)
target_board = client.get_board(target_board_id)
# Build target lists lookup
target_lists = {lst.name: lst for lst in target_board.list_lists()}
# Build target labels lookup
target_labels = {}
if include_labels:
for label in target_board.get_labels():
target_labels[label.name] = label
report = {
"started_at": datetime.now().isoformat(),
"source_board": source_board.name,
"target_board": target_board.name,
"migrated": [],
"skipped": [],
"errors": []
}
# Process each source listfor source_list in source_board.list_lists():
source_list_name = source_list.name
# Check if this list should be migratedif source_list_name notin list_mapping:
print(f"Skipping list: {source_list_name} (not in mapping)")
continue
target_list_name = list_mapping[source_list_name]
target_list = target_lists.get(target_list_name)
ifnot target_list:
print(f"Warning: Target list '{target_list_name}' not found")
continueprint(f"\nMigrating: {source_list_name} -> {target_list_name}")
# Migrate each cardfor card in source_list.list_cards():
try:
# Create new card
new_card = target_list.add_card(
name=card.name,
desc=card.description,
due=str(card.due_date) if card.due_date elseNone
)
# Copy labelsif include_labels:
for label in card.labels or []:
if label.name in target_labels:
new_card.add_label(target_labels[label.name])
# Copy checklistsif include_checklists:
for checklist in card.fetch_checklists():
items = [item["name"] for item in checklist.items]
new_checklist = new_card.add_checklist(
title=checklist.name,
items=items
)
# Copy checked statefor item in checklist.items:
if item["checked"]:
new_checklist.set_checklist_item(
item["name"],
checked=True
)
# Archive source card if requestedif archive_source:
card.set_closed(True)
report["migrated"].append({
"name": card.name,
"source_list": source_list_name,
"target_list": target_list_name,
"new_card_id": new_card.id
})
print(f" Migrated: {card.name}")
except Exception as e:
report["errors"].append({
"name": card.name,
"error": str(e)
})
print(f" Error migrating {card.name}: {e}")
report["completed_at"] = datetime.now().isoformat()
report["total_migrated"] = len(report["migrated"])
report["total_errors"] = len(report["errors"])
return report
# Example usageif __name__ == "__main__":
client = TrelloClient(
api_key=os.environ["TRELLO_API_KEY"],
token=os.environ["TRELLO_TOKEN"]
)
# Define list mapping
list_mapping = {
"Backlog": "Product Backlog",
"To Do": "Sprint Backlog",
"In Progress": "In Development",
"Done": "Completed"
}
report = migrate_cards(
client=client,
source_board_id="SOURCE_BOARD_ID",
target_board_id="TARGET_BOARD_ID",
list_mapping=list_mapping,
include_labels=True,
include_checklists=True,
archive_source=False
)
# Save reportwithopen("migration_report.json", "w") as f:
json.dump(report, f, indent=2)
print(f"\n{'='*50}")
print(f"Migration Complete!")
print(f"Migrated: {report['total_migrated']} cards")
print(f"Errors: {report['total_errors']}")
Example 3: Board Analytics Dashboard
#!/usr/bin/env python3"""board_analytics.py - Generate board analytics"""from trello import TrelloClient
from datetime import datetime, timedelta
from collections import defaultdict
import os
import json
defanalyze_board(client, board_id, days_back=30):
"""
Generate comprehensive analytics for a board.
Args:
client: TrelloClient instance
board_id: Board ID to analyze
days_back: Number of days of history to analyze
Returns:
Analytics dictionary
"""
board = client.get_board(board_id)
cutoff_date = datetime.now() - timedelta(days=days_back)
analytics = {
"board_name": board.name,
"analyzed_at": datetime.now().isoformat(),
"period_days": days_back,
"summary": {},
"lists": {},
"labels": {},
"members": {},
"cards": {
"total": 0,
"with_due_date": 0,
"overdue": 0,
"completed": 0
}
}
# Analyze lists
lists = board.list_lists()
for lst in lists:
cards = lst.list_cards()
analytics["lists"][lst.name] = {
"card_count": len(cards),
"cards": []
}
for card in cards:
analytics["cards"]["total"] += 1
card_info = {
"name": card.name,
"has_due": card.due_date isnotNone,
"labels": [l.name for l in (card.labels or [])],
"members": len(card.member_ids) if card.member_ids else0,
"checklists": len(card.fetch_checklists())
}
if card.due_date:
analytics["cards"]["with_due_date"] += 1if card.due_date < datetime.now() andnot card.is_due_complete:
analytics["cards"]["overdue"] += 1
card_info["overdue"] = True
analytics["lists"][lst.name]["cards"].append(card_info)
# Identify done list (common names)
done_lists = ["Done", "Completed", "Finished", "Closed"]
for done_name in done_lists:
if done_name in analytics["lists"]:
analytics["cards"]["completed"] = analytics["lists"][done_name]["card_count"]
break# Analyze labels
labels = board.get_labels()
label_usage = defaultdict(int)
for lst_data in analytics["lists"].values():
for card in lst_data["cards"]:
for label in card["labels"]:
label_usage[label] += 1
analytics["labels"] = dict(label_usage)
# Calculate summary metrics
total = analytics["cards"]["total"]
analytics["summary"] = {
"total_cards": total,
"total_lists": len(lists),
"total_labels": len(labels),
"completion_rate": round(
analytics["cards"]["completed"] / total * 100, 1
) if total > 0else0,
"overdue_rate": round(
analytics["cards"]["overdue"] / total * 100, 1
) if total > 0else0,
"due_date_coverage": round(
analytics["cards"]["with_due_date"] / total * 100, 1
) if total > 0else0
}
return analytics
defgenerate_report_markdown(analytics):
"""Generate markdown report from analytics."""
report = f"""# Board Analytics Report
**Board:** {analytics['board_name']}
**Generated:** {analytics['analyzed_at']}
**Period:** Last {analytics['period_days']} days
## Summary
| Metric | Value |
|--------|-------|
| Total Cards | {analytics['summary']['total_cards']} |
| Total Lists | {analytics['summary']['total_lists']} |
| Completion Rate | {analytics['summary']['completion_rate']}% |
| Overdue Rate | {analytics['summary']['overdue_rate']}% |
| Due Date Coverage | {analytics['summary']['due_date_coverage']}% |
## Cards by List
"""for list_name, list_data in analytics["lists"].items():
report += f"### {list_name} ({list_data['card_count']} cards)\n\n"if list_data["cards"]:
for card in list_data["cards"][:5]: # Show top 5
overdue_marker = " [OVERDUE]"if card.get("overdue") else""
report += f"- {card['name']}{overdue_marker}\n"iflen(list_data["cards"]) > 5:
report += f"- ... and {len(list_data['cards']) - 5} more\n"
report += "\n"
report += "## Label Usage\n\n"
report += "| Label | Count |\n"
report += "|-------|-------|\n"for label, count insorted(
analytics["labels"].items(),
key=lambda x: x[1],
reverse=True
):
report += f"| {label} | {count} |\n"return report
# Example usageif __name__ == "__main__":
client = TrelloClient(
api_key=os.environ["TRELLO_API_KEY"],
token=os.environ["TRELLO_TOKEN"]
)
# Analyze board
analytics = analyze_board(
client=client,
board_id="BOARD_ID",
days_back=30
)
# Save JSONwithopen("board_analytics.json", "w") as f:
json.dump(analytics, f, indent=2, default=str)
# Generate markdown report
report = generate_report_markdown(analytics)
withopen("board_report.md", "w") as f:
f.write(report)
print("Analytics generated!")
print(f"Total cards: {analytics['summary']['total_cards']}")
print(f"Completion rate: {analytics['summary']['completion_rate']}%")