Contributing to ToolUniverse#
We welcome contributions to ToolUniverse!
Getting Started#
Development Setup#
Fork the repository on GitHub
Clone your fork locally:
git clone https://github.com/yourusername/ToolUniverse.git
cd ToolUniverse
Create a virtual environment:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
Install in development mode:
python -m pip install -e ".[dev]"
Install pre-commit hooks:
Automatic Setup (Recommended):
# Auto-install pre-commit hooks
./setup_precommit.sh
Manual Setup:
# Install pre-commit if not already installed
python -m pip install pre-commit
# Install hooks
pre-commit install
# Update to latest versions
pre-commit autoupdate
Development Dependencies#
The development setup includes:
pytest- Testing frameworkruff- Code formatting and lintingsphinx- Documentationpre-commit- Git hooks
Code Standards#
Code Style#
We use Ruff for code formatting and linting:
# Format code
ruff format src/tooluniverse/ tests/
# Check formatting
ruff format --check src/tooluniverse/ tests/
Linting#
Use Ruff for linting:
ruff check src/tooluniverse/ tests/
Type Hints#
All new code should include type hints:
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
Testing#
Running Tests#
Run the test suite:
# Run the default fast test suite
pytest
# Run with coverage
pytest --cov=tooluniverse
# Run specific test file
pytest tests/unit/test_tooluniverse_core_methods.py
# Run integration tests when needed
pytest tests/integration
Writing Tests#
Write tests for all new functionality:
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
Test Coverage#
Aim for >90% test coverage:
pytest --cov=tooluniverse --cov-report=html
open htmlcov/index.html
Documentation#
Building Documentation#
cd docs
make html
make serve # Serve on http://localhost:8080
Live Documentation#
For live editing:
cd docs
make livehtml
Writing Documentation#
Document all public APIs
Include examples in docstrings
Update user guides for new features
Add tutorials for complex workflows
Docstring Format#
Use Google-style docstrings:
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")
"""
Contributing Workflow#
1. Create a Feature Branch#
git checkout -b feature/your-feature-name
2. Make Changes#
Write code following our standards
Add comprehensive tests
Update documentation
Run the test suite
3. Commit Changes#
Use conventional commit messages:
git add src/tooluniverse/specific_file.py tests/unit/specific_test.py
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"
Commit Types:
- feat: New features
- fix: Bug fixes
- docs: Documentation updates
- test: Test additions or modifications
- refactor: Code refactoring
- style: Code style changes
- chore: Build/maintenance tasks
4. Push and Create PR#
git push origin feature/your-feature-name
Then create a Pull Request on GitHub with: - Clear description of changes - Link to related issues - Screenshots for UI changes - Performance impact notes
Types of Contributions#
Bug Reports#
When reporting bugs, include:
Python version and OS
ToolUniverse version
Minimal code to reproduce
Full error traceback
Expected vs actual behavior
Feature Requests#
For new features, provide:
Clear use case description
Proposed API design
Implementation suggestions
Impact on existing code
New Tools#
When adding new scientific tools:
Research the data source thoroughly
Design a clean, consistent API
Implement comprehensive error handling
Add extensive tests and documentation
Include usage examples
Example new tool structure:
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)
Documentation Improvements#
Help improve documentation by:
Fixing typos and grammar
Adding missing examples
Clarifying confusing sections
Translating to other languages
Adding video tutorials
Review Process#
All contributions go through code review:
Automated Checks: CI runs tests, linting, and type checking
Manual Review: Maintainers review code quality and design
Documentation Review: Ensure docs are clear and complete
Testing: Verify functionality works as expected
Review Criteria#
Code follows project standards
Tests provide adequate coverage
Documentation is complete and clear
Performance impact is acceptable
Breaking changes are justified
Getting Help#
Community Resources#
GitHub Discussions: General questions and ideas
GitHub Issues: Bug reports and feature requests
Email: Direct contact with maintainers
Maintainer Contact#
Shanghua Gao: shanghuagao@gmail.com
GitHub: @shanghuagao
Development Tips#
Debugging#
Use the built-in debugging features:
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
Testing API Changes#
Test against multiple data sources:
# Test against staging API
export OPENTARGETS_BASE_URL=https://staging-api.opentargets.org
pytest tests/integration
Performance Testing#
Profile your changes:
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)
Recognition#
Contributors are recognized in:
Release notes
Contributors file
Documentation acknowledgments
Annual contributor highlights
Thank you for contributing to ToolUniverse!