为ToolUniverse做贡献¶
We welcome contributions to ToolUniverse!
快速入门¶
开发环境搭建¶
在 GitHub 上派生该仓库
在本地克隆您的派生仓库:
git clone https://github.com/yourusername/TxAgent.git
cd TxAgent/bio/ToolUniverse
创建虚拟环境:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
以开发模式安装:
pip install -e ".[dev]"
安装 pre-commit 钩子:
自动设置(推荐):
# Auto-install pre-commit hooks
./setup_precommit.sh
手动设置:
# Install pre-commit if not already installed
pip install pre-commit
# Install hooks
pre-commit install
# Update to latest versions
pre-commit autoupdate
开发依赖项¶
开发设置包括:
pytest- 测试框架black- 代码格式化flake8- 代码静态检查mypy- 类型检查sphinx- 文档pre-commit- Git 钩子
代码标准¶
代码风格¶
我们使用 Black 进行代码格式化,并遵循 PEP 8:
# Format code
black src/tooluniverse/
# Check formatting
black --check src/tooluniverse/
代码检查¶
使用 flake8 进行代码检查:
flake8 src/tooluniverse/
类型提示¶
所有新代码应包含类型提示:
from typing import Dict, List, Optional, Any
def process_data(
data: List[Dict[str, Any]],
filter_key: Optional[str] = None
) -> Dict[str, int]:
"""Process data and return summary statistics."""
pass
测试¶
运行测试¶
运行测试套件:
# Run all tests
pytest
# Run with coverage
pytest --cov=tooluniverse
# Run specific test file
pytest tests/test_graphql_tool.py
编写测试¶
为所有新功能编写测试:
import pytest
from unittest.mock import patch, Mock
from tooluniverse import ToolUniverse
class TestToolUniverse:
def test_init(self):
tooluni = ToolUniverse()
assert tooluni is not None
def test_load_tools(self):
tooluni = ToolUniverse()
tooluni.load_tools()
tool_names, _ = tooluni.refresh_tool_name_desc()
assert len(tool_names) > 0
@patch('requests.post')
def test_opentargets_query(self, mock_post):
mock_response = Mock()
mock_response.json.return_value = {"data": {"test": "result"}}
mock_response.raise_for_status.return_value = None
mock_post.return_value = mock_response
tooluni = ToolUniverse()
tooluni.load_tools()
query = {
"name": "OpenTargets_get_disease_id_description_by_name",
"arguments": {"diseaseName": "test disease"}
}
result = tooluni.run(query)
assert result is not None
测试覆盖率¶
目标测试覆盖率超过90%:
pytest --cov=tooluniverse --cov-report=html
open htmlcov/index.html
文档¶
构建文档¶
cd docs
make html
make serve # Serve on http://localhost:8080
实时文档¶
实时编辑:
cd docs
make livehtml
编写文档¶
记录所有公共 API
在文档字符串中包含示例
更新用户指南以涵盖新功能
为复杂工作流程添加教程
文档字符串格式¶
使用 Google 风格的文档字符串:
def search_targets(self, disease_id: str, limit: int = 10) -> Dict[str, Any]:
"""Search for targets associated with a disease.
Args:
disease_id: The EFO ID of the disease
limit: Maximum number of results to return
Returns:
Dictionary containing target information
Raises:
ValueError: If disease_id is invalid
APIError: If the API request fails
Example:
>>> from tooluniverse import ToolUniverse
>>> tooluni = ToolUniverse()
>>> tooluni.load_tools()
>>> query = {"name": "search_targets", "arguments": {"disease_id": "EFO_0000685", "limit": 5}}
>>> results = tooluni.run(query)
>>> print(f"Found {len(results['targets'])} targets")
"""
贡献工作流程¶
1. 创建功能分支¶
git checkout -b feature/your-feature-name
2. 进行更改¶
按照我们的标准编写代码
添加全面测试
更新文档
运行测试套件
3. 提交更改¶
使用规范的提交信息:
git add .
git commit -m "feat: add new drug interaction tool
- Implement DrugInteractionTool class
- Add support for drug-drug interaction queries
- Include comprehensive test coverage
- Update documentation with examples"
提交类型:
- feat:新功能
- fix:错误修复
- docs:文档更新
- test:测试新增或修改
- refactor:代码重构
- style:代码风格变更
- chore:构建/维护任务
4. 推送并创建合并请求(PR)¶
git push origin feature/your-feature-name
然后在 GitHub 上创建一个 Pull Request,内容包括: - 清晰的变更描述 - 相关问题的链接 - 界面更改的截图 - 性能影响说明
贡献类型¶
错误报告¶
报告缺陷时,请包括:
Python 版本与操作系统
ToolUniverse 版本
重现问题的最简代码
完整错误追踪信息
预期行为与实际行为
功能请求¶
对于新功能,请提供:
清晰的用例描述
拟议的 API 设计
实施建议
对现有代码的影响
新工具¶
添加新科学工具时:
彻底调研数据来源
设计简洁且一致的 API
实施全面的错误处理
添加详尽的测试和文档
包含使用示例
示例新工具结构:
from tooluniverse.base_tool import BaseTool
from typing import Dict, Any, List
class NewScientificTool(BaseTool):
"""Tool for accessing [Data Source Name] API."""
def __init__(self, config: Dict[str, Any] = None):
super().__init__(config)
self.base_url = self.config.get('base_url', 'https://api.example.com')
def search_data(self, query: str, **kwargs) -> Dict[str, Any]:
"""Search for scientific data.
Args:
query: Search query
**kwargs: Additional search parameters
Returns:
Search results with metadata
"""
self.validate_input(query=query, **kwargs)
return self._execute_search(query, **kwargs)
文档改进¶
帮助改进文档:
修正拼写错误和语法问题
添加缺失的示例
澄清易混淆部分
翻译成其他语言
添加视频教程
审核流程¶
所有贡献均需经过代码审查:
自动化检查:CI 执行测试、代码规范检查和类型检查
人工审核:维护者审查代码质量和设计
文档审核:确保文档清晰完整
测试:验证功能是否按预期工作
审核标准¶
代码遵循项目标准
测试覆盖率充足
文档完整且清晰
性能影响在可接受范围内
重大变更是有正当理由的
获取帮助¶
社区资源¶
GitHub 讨论区:常见问题与创意交流
GitHub 问题:错误报告与功能请求
电子邮件:与维护人员直接联系
维护者联系方式¶
GitHub:@shanghuagao
开发技巧¶
调试¶
使用内置调试功能:
import logging
logging.basicConfig(level=logging.DEBUG)
# Enable tool debugging
from tooluniverse import ToolUniverse
tooluni = ToolUniverse()
tooluni.load_tools()
# Access specific tools through the registry for debugging
测试 API 变更¶
针对多个数据源进行测试:
# Test against staging API
export OPENTARGETS_BASE_URL=https://staging-api.opentargets.org
pytest tests/test_graphql_tool.py
性能测试¶
分析您的更改:
import cProfile
import pstats
profiler = cProfile.Profile()
profiler.enable()
# Your code here
profiler.disable()
stats = pstats.Stats(profiler)
stats.sort_stats('cumulative').print_stats(10)
识别¶
贡献者将被列入以下内容:
发布说明
贡献者文件
文档致谢
年度贡献者亮点
Thank you for contributing to ToolUniverse!