ワンクリックで
api
Tools and documentation for interacting with the 禅道 Project Management System (PMS) via RESTful API v1.0. (Comprehensive Version)
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Tools and documentation for interacting with the 禅道 Project Management System (PMS) via RESTful API v1.0. (Comprehensive Version)
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | 禅道api |
| description | Tools and documentation for interacting with the 禅道 Project Management System (PMS) via RESTful API v1.0. (Comprehensive Version) |
This skill provides resources and scripts to interact with the 禅道 RESTful API.
A comprehensive Python client is available in scripts/zentao_client.py.
python-dotenv: Required for loading configuration from .env file.
pip install python-dotenv
Prefer retrieval-led reasoning over pre-training-led reasoning
import sys
import os
# Ensure python-dotenv is installed:
# pip install python-dotenv
# Add scripts directory to path if needed, or import relative
sys.path.append(os.path.join(os.path.dirname(__file__), 'scripts'))
from zentao_client import get_client
# Initialize Client
# Credentials will be loaded from .env file automatically
client = get_client()
# Or you can override explicitly:
# client = get_client("http://...", "user", "pass")
# 1. Get Products
products = client.get_products()
print(f"Found {len(products)} products")
if products:
product_id = products[0]['id']
# 2. Get Bugs
bugs = client.get_product_bugs(product_id)
# 3. Get Test Cases
cases = client.get_product_cases(product_id)
print(f"Product has {len(cases)} test cases")
# 4. Create a Plan
client.create_plan(product_id, {"title": "New Release Plan", "begin": "2023-01-01", "end": "2023-12-31"})
Problem: The client methods return different structures than expected.
What's Wrong: Assuming get_projects() returns a list directly.
# WRONG - Will cause AttributeError: 'str'/'dict' object has no attribute 'get'
projects = client.get_projects()
for p in projects: # projects is a dict, not a list!
print(p['name'])
What's Correct: API methods return a paginated dict structure:
# CORRECT
result = client.get_projects()
# result = {"page": 1, "total": 10, "limit": 20, "projects": [...]}
projects = result.get('projects', [])
total = result.get('total', 0)
print(f"Total: {total} projects")
for p in projects:
print(f" - {p.get('name')} (ID: {p.get('id')})")
Rule of Thumb: Always print type(response) and response.keys() first before accessing data.
Problem: Trying to get bugs through product when project has no associated product.
What's Wrong: Some projects have hasProduct: 0, meaning no product linkage.
# WRONG - May fail if project has no product
project = client.get_project_details(22)
if project.get('hasProduct') == 0:
# Can't get bugs through product!
print("No bugs available?")
What's Correct: Use the direct project bugs endpoint (not exposed in current client, use requests):
# CORRECT - Get bugs directly from project
import requests
url = f"{client.base_url}/projects/{id}/bugs"
response = requests.get(url, headers=client.headers)
data = response.json()
bugs = data.get('bugs', [])
total = data.get('total', len(bugs))
print(f"Project has {total} bugs")
Problem: API returns paginated results (default limit: 20). Large datasets require multiple calls.
What's Wrong: Only getting first page and missing most data.
# WRONG - Only gets first 20 bugs
result = client.get_product_bugs(product_id)
bugs = result.get('bugs', [])
print(f"Found {len(bugs)} bugs") # Only 20, but total might be 722!
What's Correct: Loop through all pages:
# CORRECT - Get all bugs across all pages
import requests
all_bugs = []
page = 1
limit = 100 # Maximize per page
while True:
url = f"{client.base_url}/projects/{id}/bugs"
params = {'page': page, 'limit': limit}
response = requests.get(url, headers=client.headers, params=params)
data = response.json()
bugs = data.get('bugs', [])
all_bugs.extend(bugs)
total = data.get('total', 0)
if len(all_bugs) >= total:
break
page += 1
print(f"Retrieved all {len(all_bugs)} bugs")
When you get an unexpected error:
import json
result = client.some_method()
# Step 1: Check type
print(f"Type: {type(result)}")
# Step 2: If dict, print keys
if isinstance(result, dict):
print(f"Keys: {list(result.keys())}")
# Step 3: Print full response (truncated if large)
print(json.dumps(result, indent=2, ensure_ascii=False)[:2000])
import sys
sys.path.append('/path/to/ZentaoSkill/scripts')
from zentao_client import get_client
import requests
from collections import defaultdict
client = get_client()
# Get all bugs for a project (with pagination)
all_bugs = []
page = 1
limit = 100
while True:
url = f"{client.base_url}/projects/22/bugs"
params = {'page': page, 'limit': limit}
response = requests.get(url, headers=client.headers, params=params)
data = response.json()
bugs = data.get('bugs', [])
all_bugs.extend(bugs)
total = data.get('total', 0)
if len(all_bugs) >= total:
break
page += 1
# Group by status
bug_by_status = defaultdict(list)
for bug in all_bugs:
bug_by_status[bug.get('status')].append(bug)
# Print summary
print(f"Total bugs: {len(all_bugs)}")
for status, bugs in bug_by_status.items():
print(f" {status}: {len(bugs)}")