Thank you for your interest in contributing to MLCLI! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Pull Request Process
- Coding Standards
- Testing
- Documentation
This project adheres to a Code of Conduct. By participating, you are expected to uphold this code.
- Fork the repository on GitHub
- Clone your fork locally
- Set up the development environment
- Create a branch for your changes
- Make your changes
- Submit a pull request
# Clone your fork
git clone https://github.com/YOUR_USERNAME/mlcli.git
cd mlcli
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit installfeature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test additions or modifications
Example: feature/add-lightgbm-trainer
Follow the Conventional Commits specification:
type(scope): description
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentationstyle: Formattingrefactor: Code restructuringtest: Testschore: Maintenance
Example:
feat(trainers): add LightGBM trainer support
- Implement LightGBMTrainer class
- Add configuration schema
- Include example config file
- Update documentation for any new features
- Add tests for new functionality
- Ensure all tests pass:
pytest - Update CHANGELOG.md
- Request review from maintainers
- Code follows project style guidelines
- Tests added/updated
- Documentation updated
- CHANGELOG.md updated
- All CI checks pass
- Follow PEP 8
- Use type hints for function signatures
- Maximum line length: 100 characters
- Use docstrings for all public functions/classes
from typing import Dict, Optional, Any
import numpy as np
def process_data(
data: np.ndarray,
config: Dict[str, Any],
normalize: bool = True,
*,
verbose: Optional[int] = None,
) -> np.ndarray:
"""
Process input data according to configuration.
Args:
data: Input array of shape (n_samples, n_features)
config: Processing configuration dictionary
normalize: Whether to normalize the data
verbose: Verbosity level (0=silent, 1=progress, 2=debug)
Returns:
Processed data array
Raises:
ValueError: If data is empty or config is invalid
Example:
>>> data = np.array([[1, 2], [3, 4]])
>>> result = process_data(data, {"scale": True})
"""
if data.size == 0:
raise ValueError("Data cannot be empty")
# Implementation
return processed_data- Create
mlcli/trainers/your_trainer.py - Inherit from
BaseTrainer - Implement required methods:
__init__trainpredictevaluatesaveload
- Register in
mlcli/trainers/__init__.py - Add example config in
examples/configs/ - Add tests in
tests/trainers/ - Update documentation
# Run all tests
pytest
# Run with coverage
pytest --cov=mlcli --cov-report=html
# Run specific test file
pytest tests/test_trainers.py
# Run specific test
pytest tests/test_trainers.py::test_rf_trainerimport pytest
from mlcli.trainers import RFTrainer
class TestRFTrainer:
@pytest.fixture
def trainer(self):
return RFTrainer(config={"params": {"n_estimators": 10}})
def test_train(self, trainer, sample_data):
X, y = sample_data
trainer.train(X, y)
assert trainer.model is not None
def test_predict(self, trainer, sample_data):
X, y = sample_data
trainer.train(X, y)
predictions = trainer.predict(X)
assert len(predictions) == len(y)- Use Markdown for documentation
- Include code examples
- Keep README.md updated
- Add docstrings to all public APIs
cd docs
pip install -r requirements.txt
mkdocs serve- Open an issue for bugs or feature requests
- Start a discussion for questions
- Check existing issues before creating new ones
Thank you for contributing! 🎉