openproject
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenProject Integration
OpenProject 集成
Full OpenProject API v3 integration with Python packages for project management automation.
基于Python包的完整OpenProject API v3集成,用于项目管理自动化。
When to Use
适用场景
- Project management (create, update, delete projects)
- Task/issue tracking (work packages, relations, activities)
- Time tracking (log hours, generate reports)
- Document management (attachments, wiki pages)
- User/team management (users, groups, memberships)
- Notification handling (read, mark, clear)
- Custom views/queries (saved filters, views)
- System configuration (types, statuses, roles)
- 项目管理(创建、更新、删除项目)
- 任务/问题追踪(工作包、关联关系、活动记录)
- 工时追踪(记录工时、生成报表)
- 文档管理(附件、维基页面)
- 用户/团队管理(用户、群组、成员身份)
- 通知处理(读取、标记、清除)
- 自定义视图/查询(已保存的筛选器、视图)
- 系统配置(类型、状态、角色)
Sub-Skills
子技能
| Skill | Purpose | Package |
|---|---|---|
| Base client, auth, HAL parsing | |
| Project CRUD | |
| Tasks, issues, features | |
| Time tracking | |
| User management | |
| Files & wiki | |
| Saved queries | |
| Notifications | |
| System config | |
| 技能 | 用途 | 包 |
|---|---|---|
| 基础客户端、认证、HAL解析 | |
| 项目增删改查 | |
| 任务、问题、功能管理 | |
| 工时追踪 | |
| 用户管理 | |
| 文件与维基管理 | |
| 已保存查询管理 | |
| 通知管理 | |
| 系统配置 | |
Setup
配置步骤
bash
undefinedbash
undefined1. Navigate to skill directory
1. 导航到技能目录
cd .claude/skills/openproject
cd .claude/skills/openproject
2. Install dependencies
2. 安装依赖
uv sync
uv sync
3. Configure .env
3. 配置 .env 文件
OPENPROJECT_URL=https://your-instance.com
OPENPROJECT_API_KEY=your-api-key
API key from: **OpenProject → My Account → Access Tokens**OPENPROJECT_URL=https://your-instance.com
OPENPROJECT_API_KEY=your-api-key
API密钥获取位置:**OpenProject → 我的账户 → 访问令牌**Config Initialization (REQUIRED)
配置初始化(必须执行)
CRITICAL: Phải init config trước khi sử dụng bất kỳ tính năng nào!
Config lưu project metadata vào để tránh gọi API lặp lại mỗi lần. Bao gồm: project info, members, types, statuses, priorities, versions, categories, custom fields.
.openproject-config.yml重要提示:在使用任何功能之前必须初始化配置!
配置会将项目元数据保存到文件中,避免重复调用API。包含:项目信息、成员、类型、状态、优先级、版本、分类、自定义字段。
.openproject-config.ymlInit Config (lần đầu)
初始化配置(首次)
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import init_config, print_config_summary
from dotenv import load_dotenv
load_dotenv()
init_config(PROJECT_ID) # Thay PROJECT_ID bằng ID số của project
print_config_summary()
"bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import init_config, print_config_summary
from dotenv import load_dotenv
load_dotenv()
init_config(PROJECT_ID) # 将PROJECT_ID替换为项目的数字ID
print_config_summary()
"Refresh Config (khi có thay đổi)
刷新配置(有变更时)
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import refresh_config, print_config_summary
from dotenv import load_dotenv
load_dotenv()
refresh_config()
print_config_summary()
"bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import refresh_config, print_config_summary
from dotenv import load_dotenv
load_dotenv()
refresh_config()
print_config_summary()
"Sử dụng Config
使用配置
python
from openproject_core import (
load_config, # Load toàn bộ config
require_config, # Load config, raise error nếu chưa init
get_project_id, # Lấy project ID đã config
get_type_id, # Lấy type ID theo tên: get_type_id("Task") → 1
get_status_id, # Lấy status ID theo tên: get_status_id("New") → 1
get_priority_id, # Lấy priority ID theo tên: get_priority_id("Normal") → 8
get_version_id, # Lấy version ID theo tên
get_custom_field_name, # Lấy tên custom field: get_custom_field_name("customField8", 1) → "Excute Point"
is_config_initialized, # Kiểm tra config đã init chưa
)Luôn dùng hoặc trước khi thực hiện operations!
require_config()is_config_initialized()python
from openproject_core import (
load_config, # 加载完整配置
require_config, # 加载配置,未初始化则抛出异常
get_project_id, # 获取已配置的项目ID
get_type_id, # 根据名称获取类型ID:get_type_id("Task") → 1
get_status_id, # 根据名称获取状态ID:get_status_id("New") → 1
get_priority_id, # 根据名称获取优先级ID:get_priority_id("Normal") → 8
get_version_id, # 根据名称获取版本ID
get_custom_field_name, # 根据键获取自定义字段名称:get_custom_field_name("customField8", 1) → "Excute Point"
is_config_initialized, # 检查配置是否已初始化
)始终在执行操作前使用或!
require_config()is_config_initialized()Session Startup (BẮT BUỘC)
会话启动(必须执行)
CRITICAL: Phải load config trước MỌI phiên làm việc mới!
Mỗi khi bắt đầu session mới hoặc khi skill được activate, PHẢI chạy đoạn code sau ĐẦU TIÊN trước khi làm bất kỳ thao tác nào khác:
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import load_session_config
from dotenv import load_dotenv
load_dotenv()
session = load_session_config()
if not session['ok']:
print(f'ERROR: {session[\"error\"]}')
print('Run init_config(project_id) to initialize!')
else:
print(f'Project: {session[\"project\"]} (ID: {session[\"project_id\"]})')
print(f'User: {session[\"user\"]} @ {session[\"instance\"]}')
print(f'Config updated: {session[\"updated_at\"]}')
print(f'Types: {session[\"types_count\"]}, Members: {session[\"members_count\"]}')
"Nếu → phải chạy trước.
Nếu → sẵn sàng sử dụng các tính năng.
ok=Falseinit_config(project_id)ok=True重要提示:每次新的工作会话前必须加载配置!
每次开始新会话或激活技能时,必须首先运行以下代码,然后才能执行任何其他操作:
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import load_session_config
from dotenv import load_dotenv
load_dotenv()
session = load_session_config()
if not session['ok']:
print(f'错误: {session[\"error\"]}')
print('请运行init_config(project_id)进行初始化!')
else:
print(f'项目: {session[\"project\"]} (ID: {session[\"project_id\"]})')
print(f'用户: {session[\"user\"]} @ {session[\"instance\"]}')
print(f'配置更新时间: {session[\"updated_at\"]}')
print(f'类型数量: {session[\"types_count\"]}, 成员数量: {session[\"members_count\"]}')
"如果 → 必须先运行。
如果 → 可以开始使用各项功能。
ok=Falseinit_config(project_id)ok=TrueInstructions
使用说明
CRITICAL: Always use package imports - NEVER write inline API calls!
- Load session config first - Phải chạy trước mỗi phiên làm việc
load_session_config() - Init config if needed - Nếu session config trả , chạy
ok=Falseinit_config(project_id) - Use package imports - All operations via clean imports
- Run with uv - Always from skill directory
uv run python - Load dotenv - Always call before API calls
load_dotenv() - Use config helpers - Dùng ,
get_type_id()thay vì hardcode IDsget_status_id() - Check permissions - Some operations require admin
- Handle pagination - Use for large datasets
paginate()
重要提示:始终使用包导入——绝不要编写内联API调用!
- 首先加载会话配置 - 每次工作会话前必须运行
load_session_config() - 必要时初始化配置 - 如果会话配置返回,运行
ok=Falseinit_config(project_id) - 使用包导入 - 所有操作通过规范的导入完成
- 使用uv运行 - 始终从技能目录使用
uv run python - 加载dotenv - 在API调用前始终调用
load_dotenv() - 使用配置辅助函数 - 使用、
get_type_id()替代硬编码IDget_status_id() - 检查权限 - 部分操作需要管理员权限
- 处理分页 - 对大型数据集使用
paginate()
⚠️ Important Notes
⚠️ 重要注意事项
Project identifier ≠ Project name!
python
undefined项目标识符 ≠ 项目名称!
python
undefined❌ WRONG - project name không phải identifier
❌ 错误 - 项目名称不是标识符
project = get_project('sol-proj-25001') # 404 Error!
project = get_project('sol-proj-25001') # 404 错误!
✅ CORRECT - tìm project trước để lấy đúng identifier hoặc ID
✅ 正确 - 先查找项目以获取正确的标识符或ID
for p in list_projects():
if 'sol-proj-25001' in p['name']:
project_id = p['id'] # ID số: 3
identifier = p['identifier'] # '008-mii-pb-mh008'
break
project = get_project(project_id) # Works!
OpenProject có 2 khái niệm:
- `name`: Tên hiển thị (VD: "sol-proj-25001")
- `identifier`: Slug URL (VD: "008-mii-pb-mh008")
Luôn dùng `list_projects()` để tìm đúng ID/identifier trước khi gọi `get_project()`.
---
**All `list_*` functions return generators, NOT lists!**
```pythonfor p in list_projects():
if 'sol-proj-25001' in p['name']:
project_id = p['id'] # 数字ID: 3
identifier = p['identifier'] # '008-mii-pb-mh008'
break
project = get_project(project_id) # 正常运行!
OpenProject有两个概念:
- `name`: 显示名称(例如:"sol-proj-25001")
- `identifier`: URL别名(例如:"008-mii-pb-mh008")
始终使用`list_projects()`查找正确的ID/标识符,再调用`get_project()`。
---
**所有`list_*`函数返回生成器,而非列表!**
```python❌ WRONG - generator has no len()
❌ 错误 - 生成器没有len()方法
entries = list_time_entries(filters=filters)
print(len(entries)) # TypeError!
entries = list_time_entries(filters=filters)
print(len(entries)) # 类型错误!
✅ CORRECT - convert to list first
✅ 正确 - 先转换为列表
entries = list(list_time_entries(filters=filters))
print(len(entries)) # Works!
This applies to: `list_projects`, `list_work_packages`, `list_time_entries`, `list_users`, `list_notifications`, `list_queries`, etc.
**Time entry `hours` field returns ISO 8601 duration, NOT a number!**
```pythonentries = list(list_time_entries(filters=filters))
print(len(entries)) # 正常运行!
这适用于:`list_projects`, `list_work_packages`, `list_time_entries`, `list_users`, `list_notifications`, `list_queries`等。
**工时记录的`hours`字段返回ISO 8601时长格式,而非数字!**
```python❌ WRONG - hours is 'PT1H30M45S', not 1.5
❌ 错误 - hours是'PT1H30M45S',不是1.5
hours = entry['hours']
total += hours # TypeError!
hours = entry['hours']
total += hours # 类型错误!
✅ CORRECT - use parse_duration()
✅ 正确 - 使用parse_duration()
from openproject_time import parse_duration
hours = parse_duration(entry['hours']) # 1.5125
total += hours # Works!
---
**Time entries: Filter theo Work Package**
```pythonfrom openproject_time import parse_duration
hours = parse_duration(entry['hours']) # 1.5125
total += hours # 正常运行!
---
**工时记录:按工作包筛选**
```python❌ WRONG - filter work_package không tồn tại
❌ 错误 - work_package筛选器不存在
filters = [{'work_package': {'operator': '=', 'values': ['123']}}]
filters = [{'work_package': {'operator': '=', 'values': ['123']}}]
✅ CORRECT - dùng entity_type + entity_id
✅ 正确 - 使用entity_type + entity_id
from openproject_time import get_work_package_time, get_work_packages_time
from openproject_time import get_work_package_time, get_work_packages_time
Cho 1 WP
单个工作包
entries = get_work_package_time(wp_id=675)
entries = get_work_package_time(wp_id=675)
Cho nhiều WPs (1 API call)
多个工作包(单次API调用)
result = get_work_packages_time(wp_ids=[675, 598, 577])
result = get_work_packages_time(wp_ids=[675, 598, 577])
Hoặc filter trực tiếp
或直接筛选
filters = [
{"entity_type": {"operator": "=", "values": ["WorkPackage"]}},
{"entity_id": {"operator": "=", "values": ["675"]}}
]
Filters hợp lệ: `entity_type`, `entity_id`, `project_id`, `user_id`, `spent_on`, `activity_id`, `ongoing`, `created_at`, `updated_at`.
---
**`get_work_packages_time()` returns Dict, NOT list!**
```pythonfilters = [
{"entity_type": {"operator": "=", "values": ["WorkPackage"]}},
{"entity_id": {"operator": "=", "values": ["675"]}}
]
有效的筛选器:`entity_type`, `entity_id`, `project_id`, `user_id`, `spent_on`, `activity_id`, `ongoing`, `created_at`, `updated_at`。
---
**`get_work_packages_time()`返回字典,而非列表!**
```python❌ WRONG - result is dict, not list
❌ 错误 - result是字典,不是列表
result = get_work_packages_time(wp_ids=[675, 598, 577])
for entry in result[:5]: # KeyError!
print(entry)
result = get_work_packages_time(wp_ids=[675, 598, 577])
for entry in result[:5]: # 键错误!
print(entry)
✅ CORRECT - iterate over dict items
✅ 正确 - 遍历字典项
result = get_work_packages_time(wp_ids=[675, 598, 577])
result = get_work_packages_time(wp_ids=[675, 598, 577])
result = {675: [entries...], 598: [entries...], 577: [entries...]}
result = {675: [entries...], 598: [entries...], 577: [entries...]}
for wp_id, entries in result.items():
for entry in entries:
hours = parse_duration(entry['hours'])
print(f'WP {wp_id}: {hours}h')
Return type: `Dict[int, List[dict]]` - key là WP ID, value là list time entries.
---
**`get_schema()` requires BOTH `project_id` AND `type_id`!**
```pythonfor wp_id, entries in result.items():
for entry in entries:
hours = parse_duration(entry['hours'])
print(f'工作包 {wp_id}: {hours}小时')
返回类型:`Dict[int, List[dict]]` - 键为工作包ID,值为工时记录列表。
---
**`get_schema()`需要同时提供`project_id`和`type_id`!**
```python❌ WRONG - missing type_id
❌ 错误 - 缺少type_id
schema = get_schema(project_id=3) # TypeError!
schema = get_schema(project_id=3) # 类型错误!
✅ CORRECT - provide both params
✅ 正确 - 提供两个参数
schema = get_schema(project_id=3, type_id=6) # type 6 = User Story
schema = get_schema(project_id=3, type_id=6) # 类型6 = 用户故事
Get custom field names
获取自定义字段名称
for key, val in schema.items():
if key.startswith('customField') and isinstance(val, dict):
print(f'{key}: {val.get("name")}')
for key, val in schema.items():
if key.startswith('customField') and isinstance(val, dict):
print(f'{key}: {val.get("name")}')
Output:
输出:
customField10: Research Point
customField10: Research Point
customField8: Excute Point
customField8: Excute Point
customField9: Verify Point
customField9: Verify Point
customField15: Review Point
customField15: Review Point
Common type IDs: `1` = Task, `6` = User Story, `10` = TechDebt. Use `list_types()` to get all.
---
**Custom fields are project/type specific!**
```python
常见类型ID:`1` = 任务,`6` = 用户故事,`10` = 技术债务。使用`list_types()`获取所有类型。
---
**自定义字段是项目/类型特定的!**
```pythonCustom fields vary by project and type
自定义字段因项目和类型而异
Always use get_schema() to discover field names
始终使用get_schema()发现字段名称
from openproject_work_packages import get_schema, list_work_packages
from openproject_work_packages import get_schema, list_work_packages
1. Get schema to know custom field mapping
1. 获取架构以了解自定义字段映射
schema = get_schema(project_id=3, type_id=6)
cf_names = {k: v.get('name') for k, v in schema.items()
if k.startswith('customField') and isinstance(v, dict)}
print(cf_names)
schema = get_schema(project_id=3, type_id=6)
cf_names = {k: v.get('name') for k, v in schema.items()
if k.startswith('customField') and isinstance(v, dict)}
print(cf_names)
{'customField10': 'Research Point', 'customField8': 'Excute Point', ...}
{'customField10': 'Research Point', 'customField8': 'Excute Point', ...}
2. Then access custom fields in work packages
2. 然后访问工作包中的自定义字段
for wp in list_work_packages(project_id=3):
research = wp.get('customField10') or 0
execute = wp.get('customField8') or 0
---
**`list_activities()` from openproject_time may return empty!**
Activities are often project-specific. Use work package activities instead:
```pythonfor wp in list_work_packages(project_id=3):
research = wp.get('customField10') or 0
execute = wp.get('customField8') or 0
---
**`list_activities()`来自openproject_time可能返回空值!**
活动通常是项目特定的。改用工作包活动:
```python❌ May return empty
❌ 可能返回空
from openproject_time import list_activities
activities = list(list_activities()) # []
from openproject_time import list_activities
activities = list(list_activities()) # []
✅ Use work package activities for comments/history
✅ 使用工作包活动获取评论/历史记录
from openproject_work_packages import list_activities
activities = list(list_activities(work_package_id=675))
undefinedfrom openproject_work_packages import list_activities
activities = list(list_activities(work_package_id=675))
undefinedRunning Scripts
运行脚本
IMPORTANT: Always run from skill directory with !
uv runbash
cd .claude/skills/openproject
uv run python -c "YOUR_CODE"重要提示:始终从技能目录使用运行!
uv runbash
cd .claude/skills/openproject
uv run python -c "YOUR_CODE"Script Template
脚本模板
python
from openproject_core import check_connection
from openproject_projects import list_projects
from dotenv import load_dotenv
load_dotenv() # Required!python
from openproject_core import check_connection
from openproject_projects import list_projects
from dotenv import load_dotenv
load_dotenv() # 必须调用!Your code here
你的代码
status = check_connection()
print(f"Connected as: {status['user']}")
undefinedstatus = check_connection()
print(f"当前登录用户: {status['user']}")
undefinedAvailable Packages
可用包
openproject_core
openproject_core
python
from openproject_core import (
# Connection
check_connection, # Verify API connection
OpenProjectClient, # HTTP client class
# Session (REQUIRED - call first each session!)
load_session_config, # Load & verify config for session
# Config (init once, use helpers)
init_config, # Init config: init_config(project_id)
load_config, # Load full config from YAML
refresh_config, # Refresh/update config
require_config, # Load config, raise if not init
is_config_initialized, # Check if config exists
get_project_id, # Get configured project ID
get_type_id, # Get type ID by name
get_status_id, # Get status ID by name
get_priority_id, # Get priority ID by name
get_version_id, # Get version ID by name
get_member_id, # Get user ID by member name (partial match)
get_member_name, # Get member name by user ID
get_custom_field_id, # Get custom field key by name
get_custom_field_name, # Get custom field name by key
print_config_summary, # Print human-readable config
# Helpers
build_filters, # Build filter JSON
build_sort, # Build sort JSON
paginate, # Auto-paginate results
extract_id_from_href, # Extract ID from HAL href
)python
from openproject_core import (
# 连接
check_connection, # 验证API连接
OpenProjectClient, # HTTP客户端类
# 会话(必须调用 - 每次会话首先调用!)
load_session_config, # 加载并验证会话配置
# 配置(初始化一次,使用辅助函数)
init_config, # 初始化配置: init_config(project_id)
load_config, # 从YAML加载完整配置
refresh_config, # 刷新/更新配置
require_config, # 加载配置,未初始化则抛出异常
is_config_initialized, # 检查配置是否存在
get_project_id, # 获取已配置的项目ID
get_type_id, # 根据名称获取类型ID
get_status_id, # 根据名称获取状态ID
get_priority_id, # 根据名称获取优先级ID
get_version_id, # 根据名称获取版本ID
get_member_id, # 根据成员名称(部分匹配)获取用户ID
get_member_name, # 根据用户ID获取成员名称
get_custom_field_id, # 根据名称获取自定义字段键
get_custom_field_name, # 根据键获取自定义字段名称
print_config_summary, # 打印易读的配置摘要
# 辅助函数
build_filters, # 构建筛选器JSON
build_sort, # 构建排序JSON
paginate, # 自动分页结果
extract_id_from_href, # 从HAL href中提取ID
)openproject_projects
openproject_projects
python
from openproject_projects import (
list_projects, # List all projects
get_project, # Get by ID or identifier
create_project, # Create new project
update_project, # Update project
delete_project, # Delete project
copy_project, # Copy project structure
get_versions, # Get project versions
get_categories, # Get project categories
get_types, # Get available types
toggle_favorite, # Star/unstar project
)python
from openproject_projects import (
list_projects, # 列出所有项目
get_project, # 根据ID或标识符获取项目
create_project, # 创建新项目
update_project, # 更新项目
delete_project, # 删除项目
copy_project, # 复制项目结构
get_versions, # 获取项目版本
get_categories, # 获取项目分类
get_types, # 获取可用类型
toggle_favorite, # 收藏/取消收藏项目
)openproject_work_packages
openproject_work_packages
python
from openproject_work_packages import (
list_work_packages, # List with filters
get_work_package, # Get by ID
create_work_package, # Create task/issue
update_work_package, # Update fields (auto-handles lockVersion)
delete_work_package, # Delete
get_schema, # Get form schema
list_activities, # Get comments/history
add_comment, # Add comment
list_relations, # Get relations
create_relation, # Create relation
delete_relation, # Delete relation
)python
from openproject_work_packages import (
list_work_packages, # 带筛选条件列出工作包
get_work_package, # 根据ID获取工作包
create_work_package, # 创建任务/问题
update_work_package, # 更新字段(自动处理lockVersion)
delete_work_package, # 删除工作包
get_schema, # 获取表单架构
list_activities, # 获取评论/历史记录
add_comment, # 添加评论
list_relations, # 获取关联关系
create_relation, # 创建关联关系
delete_relation, # 删除关联关系
)openproject_time
openproject_time
python
from openproject_time import (
list_time_entries, # List with filters (use entity_type+entity_id for WP)
get_time_entry, # Get by ID
create_time_entry, # Create entry
update_time_entry, # Update entry
delete_time_entry, # Delete entry
log_time, # Shortcut for create
list_activities, # Available activities
get_user_time_today, # User's today entries
get_work_package_time, # Single WP's time entries
get_work_packages_time,# Multiple WPs (1 API call)
parse_duration, # Parse ISO 8601 duration to hours
)python
from openproject_time import (
list_time_entries, # 带筛选条件列出工时记录(按工作包筛选需用entity_type+entity_id)
get_time_entry, # 根据ID获取工时记录
create_time_entry, # 创建工时记录
update_time_entry, # 更新工时记录
delete_time_entry, # 删除工时记录
log_time, # 创建工时记录的快捷方式
list_activities, # 获取可用活动类型
get_user_time_today, # 获取用户今日的工时记录
get_work_package_time, # 获取单个工作包的工时记录
get_work_packages_time,# 获取多个工作包的工时记录(单次API调用)
parse_duration, # 将ISO 8601时长解析为小时数
)openproject_users
openproject_users
python
from openproject_users import (
list_users, # List users
get_user, # Get by ID
get_current_user, # Get current user
create_user, # Create/invite user
update_user, # Update user
delete_user, # Delete user
lock_user, # Lock account
unlock_user, # Unlock account
list_groups, # List groups
get_group, # Get group
create_group, # Create group
add_member, # Add to group
remove_member, # Remove from group
list_memberships, # List project memberships
create_membership, # Add to project
delete_membership, # Remove from project
)python
from openproject_users import (
list_users, # 列出用户
get_user, # 根据ID获取用户
get_current_user, # 获取当前用户
create_user, # 创建/邀请用户
update_user, # 更新用户
delete_user, # 删除用户
lock_user, # 锁定账户
unlock_user, # 解锁账户
list_groups, # 列出群组
get_group, # 根据ID获取群组
create_group, # 创建群组
add_member, # 添加用户到群组
remove_member, # 从群组移除用户
list_memberships, # 列出项目成员
create_membership, # 添加用户到项目
delete_membership, # 从项目移除用户
)openproject_documents
openproject_documents
python
from openproject_documents import (
get_attachment, # Get attachment metadata
list_attachments, # List container attachments (NOT documents!)
download_attachment, # Download file
upload_attachment, # Upload file
delete_attachment, # Delete attachment
list_documents, # List all documents (read-only API)
get_document, # Get document
get_wiki_page, # Get wiki page
update_wiki_page, # Update wiki page
)python
from openproject_documents import (
get_attachment, # 获取附件元数据
list_attachments, # 列出容器的附件(不是文档!)
download_attachment, # 下载文件
upload_attachment, # 上传文件
delete_attachment, # 删除附件
list_documents, # 列出所有文档(API仅支持读取)
get_document, # 获取文档
get_wiki_page, # 获取维基页面
update_wiki_page, # 更新维基页面
)NOTE: Documents API is read-only. Create/delete via web UI only.
注意:文档API仅支持读取。创建/删除需通过网页界面操作。
undefinedundefinedopenproject_queries
openproject_queries
python
from openproject_queries import (
list_queries, # List saved queries
get_query, # Get query config
create_query, # Create query
update_query, # Update query
delete_query, # Delete query
star_query, # Add to favorites
unstar_query, # Remove from favorites
get_query_default, # Get default query
get_available_columns,# Get column options
)python
from openproject_queries import (
list_queries, # 列出已保存的查询
get_query, # 获取查询配置
create_query, # 创建查询
update_query, # 更新查询
delete_query, # 删除查询
star_query, # 添加到收藏
unstar_query, # 从收藏移除
get_query_default, # 获取默认查询
get_available_columns,# 获取列选项
)openproject_notifications
openproject_notifications
python
from openproject_notifications import (
list_notifications, # List all
get_notification, # Get by ID
mark_read, # Mark as read
mark_unread, # Mark as unread
mark_all_read, # Mark all read
get_unread_count, # Count unread
list_unread, # List unread only
list_by_reason, # Filter by reason
)python
from openproject_notifications import (
list_notifications, # 列出所有通知
get_notification, # 根据ID获取通知
mark_read, # 标记为已读
mark_unread, # 标记为未读
mark_all_read, # 标记所有为已读
get_unread_count, # 获取未读数量
list_unread, # 仅列出未读通知
list_by_reason, # 按原因筛选
)openproject_admin
openproject_admin
python
from openproject_admin import (
get_configuration, # System config
list_statuses, # All statuses
get_status, # Status details
list_open_statuses, # Open statuses only
list_closed_statuses, # Closed statuses only
list_priorities, # All priorities
get_priority, # Priority details
get_default_priority, # Default priority
list_types, # WP types
get_type, # Type details
list_project_types, # Project-specific types
list_roles, # All roles
get_role, # Role with permissions
)python
from openproject_admin import (
get_configuration, # 系统配置
list_statuses, # 所有状态
get_status, # 状态详情
list_open_statuses, # 仅未关闭状态
list_closed_statuses, # 仅已关闭状态
list_priorities, # 所有优先级
get_priority, # 优先级详情
get_default_priority, # 默认优先级
list_types, # 工作包类型
get_type, # 类型详情
list_project_types, # 项目特定类型
list_roles, # 所有角色
get_role, # 带权限的角色详情
)Examples
示例
Check Connection
检查连接
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import check_connection
from dotenv import load_dotenv
load_dotenv()
status = check_connection()
print(f'OK: {status[\"ok\"]}, User: {status[\"user\"]}')
"bash
cd .claude/skills/openproject
uv run python -c "
from openproject_core import check_connection
from dotenv import load_dotenv
load_dotenv()
status = check_connection()
print(f'连接状态: {status[\"ok\"]}, 用户: {status[\"user\"]}')
"List Projects
列出项目
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_projects import list_projects
from dotenv import load_dotenv
load_dotenv()
for p in list_projects():
print(f'{p[\"id\"]}: {p[\"name\"]}')
"bash
cd .claude/skills/openproject
uv run python -c "
from openproject_projects import list_projects
from dotenv import load_dotenv
load_dotenv()
for p in list_projects():
print(f'{p[\"id\"]}: {p[\"name\"]}')
"Create Work Package
创建工作包
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_work_packages import create_work_package
from dotenv import load_dotenv
load_dotenv()
wp = create_work_package(project_id=5, subject='New task', type_id=1)
print(f'Created: #{wp[\"id\"]}')
"bash
cd .claude/skills/openproject
uv run python -c "
from openproject_work_packages import create_work_package
from dotenv import load_dotenv
load_dotenv()
wp = create_work_package(project_id=5, subject='新任务', type_id=1)
print(f'已创建工作包: #{wp[\"id\"]}')
"Log Time
记录工时
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_time import log_time
from dotenv import load_dotenv
load_dotenv()
entry = log_time(work_package_id=123, hours=2.5, comment='Dev work')
print(f'Logged: {entry[\"id\"]}')
"bash
cd .claude/skills/openproject
uv run python -c "
from openproject_time import log_time
from dotenv import load_dotenv
load_dotenv()
entry = log_time(work_package_id=123, hours=2.5, comment='开发工作')
print(f'已记录工时: {entry[\"id\"]}')
"List Open Work Packages with Filters
列出未关闭的工作包(带筛选)
bash
cd .claude/skills/openproject
uv run python -c "
from openproject_work_packages import list_work_packages
from dotenv import load_dotenv
load_dotenv()bash
cd .claude/skills/openproject
uv run python -c "
from openproject_work_packages import list_work_packages
from dotenv import load_dotenv
load_dotenv()Filter: open status
筛选条件: 未关闭状态
filters = [{'status': {'operator': 'o', 'values': []}}]
for wp in list_work_packages(filters=filters):
print(f'#{wp["id"]}: {wp["subject"]}')
"
undefinedfilters = [{'status': {'operator': 'o', 'values': []}}]
for wp in list_work_packages(filters=filters):
print(f'#{wp["id"]}: {wp["subject"]}')
"
undefinedReference Documentation
参考文档
Each sub-skill has detailed documentation:
| Skill | SKILL.md | API Reference |
|---|---|---|
| Core | | |
| Projects | | |
| Work Packages | | |
| Time | | |
| Users | | |
| Documents | | |
| Queries | | |
| Notifications | | |
| Admin | | |
每个子技能都有详细文档:
| 技能 | SKILL.md 文件 | API参考 |
|---|---|---|
| Core | | |
| Projects | | |
| Work Packages | | |
| Time | | |
| Users | | |
| Documents | | |
| Queries | | |
| Notifications | | |
| Admin | | |
Full API Specification
完整API规范
Complete OpenAPI spec: (1.2MB)
spec.yml完整OpenAPI规范:(1.2MB)
spec.yml