Skip to content

Latest commit

 

History

History
367 lines (268 loc) · 8.61 KB

File metadata and controls

367 lines (268 loc) · 8.61 KB

Contributing to EVA

First off, thank you for considering contributing to EVA! It's people like you that make EVA such a great tool for the data science community.

Table of Contents

Code of Conduct

This project and everyone participating in it is governed by our commitment to providing a welcoming and inclusive environment. Please be respectful and constructive in all interactions.

Getting Started

Prerequisites

  • Python 3.8 or higher
  • Git
  • A GitHub account

Fork and Clone

  1. Fork the repository on GitHub
  2. Clone your fork locally:
    git clone https://github.com/YOUR_USERNAME/EVA.git
    cd EVA
  3. Add the upstream repository:
    git remote add upstream https://github.com/ORIGINAL_OWNER/EVA.git

Development Setup

Create Virtual Environment

# Create virtual environment
python -m venv .venv

# Activate it
# On Windows:
.venv\Scripts\activate
# On macOS/Linux:
source .venv/bin/activate

Install Dependencies

# Install runtime dependencies
pip install -r requirements.txt

# Install development dependencies
pip install -r requirements-dev.txt

# Install package in editable mode
pip install -e .

Install Pre-commit Hooks

pre-commit install

This ensures code quality checks run before each commit.

How to Contribute

Reporting Bugs

Before creating bug reports, please check existing issues to avoid duplicates.

When reporting a bug, include:

  • Clear title describing the issue
  • Steps to reproduce the behavior
  • Expected behavior vs actual behavior
  • Environment details (Python version, OS, EVA version)
  • Error messages or stack traces if applicable
  • Sample data (if possible and non-sensitive)

Suggesting Features

We love new ideas! When suggesting a feature:

  • Describe the problem you're trying to solve
  • Explain your proposed solution
  • Consider alternatives you've thought about
  • Provide use cases where this would be helpful

Contributing Code

  1. Find an issue to work on or create a new one
  2. Comment on the issue to let others know you're working on it
  3. Create a branch from main:
    git checkout -b feature/your-feature-name
    # or
    git checkout -b fix/issue-description
  4. Make your changes following our style guidelines
  5. Write tests for new functionality
  6. Run the test suite to ensure nothing is broken
  7. Submit a pull request

Style Guidelines

Python Code Style

We use the following tools to maintain code quality:

  • Black - Code formatting
  • isort - Import sorting
  • Flake8 - Linting
  • mypy - Type checking

Quick Formatting

# Format code
black eva tests

# Sort imports
isort eva tests

# Run linting
flake8 eva tests

# Type checking
mypy eva

Code Conventions

"""
Module docstring explaining the purpose.
"""

from typing import Dict, List, Optional, Any
import pandas as pd

from eva.models.core import AnalysisContext


class ExampleClass:
    """
    Class docstring with Google-style formatting.
    
    Attributes:
        name: Description of the attribute
        config: Configuration dictionary
    """
    
    def __init__(self, name: str, config: Optional[Dict[str, Any]] = None):
        """
        Initialize the class.
        
        Args:
            name: The name identifier
            config: Optional configuration
            
        Raises:
            ValueError: If name is empty
        """
        if not name:
            raise ValueError("Name cannot be empty")
        
        self.name = name
        self.config = config or {}
    
    def process_data(self, data: pd.DataFrame) -> Dict[str, Any]:
        """
        Process the input data.
        
        Args:
            data: Input DataFrame to process
            
        Returns:
            Dictionary containing processed results
        """
        # Implementation here
        return {"result": "value"}

Naming Conventions

Type Convention Example
Classes PascalCase AnalysisOrchestrator
Functions/Methods snake_case execute_pipeline
Variables snake_case analysis_context
Constants UPPER_SNAKE_CASE MAX_FILE_SIZE
Private methods _leading_underscore _validate_input

Docstrings

Use Google-style docstrings:

def function_with_docstring(param1: str, param2: int = 10) -> bool:
    """
    Short description of the function.
    
    Longer description if needed, explaining the function's
    behavior in more detail.
    
    Args:
        param1: Description of first parameter
        param2: Description of second parameter with default
        
    Returns:
        Description of return value
        
    Raises:
        ValueError: When param1 is empty
        TypeError: When param2 is not an integer
        
    Example:
        >>> result = function_with_docstring("test", 20)
        >>> print(result)
        True
    """
    pass

Testing

Running Tests

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=eva --cov-report=html --cov-report=term

# Run specific test file
pytest tests/test_orchestrator.py -v

# Run tests matching a pattern
pytest tests/ -k "test_csv" -v

# Run integration tests
python tests/run_integration_tests.py

Writing Tests

"""
Test module for ExampleClass.
"""

import pytest
import pandas as pd
from unittest.mock import Mock, patch

from eva.example import ExampleClass


class TestExampleClass:
    """Test suite for ExampleClass."""
    
    def setup_method(self):
        """Set up test fixtures."""
        self.instance = ExampleClass("test_name")
        self.sample_data = pd.DataFrame({"col1": [1, 2, 3]})
    
    def test_initialization_with_valid_name(self):
        """Test that initialization works with valid name."""
        instance = ExampleClass("valid_name")
        assert instance.name == "valid_name"
        assert instance.config == {}
    
    def test_initialization_with_empty_name_raises_error(self):
        """Test that empty name raises ValueError."""
        with pytest.raises(ValueError, match="cannot be empty"):
            ExampleClass("")
    
    def test_process_data_returns_expected_format(self):
        """Test that process_data returns correct format."""
        result = self.instance.process_data(self.sample_data)
        
        assert isinstance(result, dict)
        assert "result" in result
    
    @pytest.mark.parametrize("name,expected", [
        ("test", "test"),
        ("another", "another"),
    ])
    def test_initialization_with_various_names(self, name, expected):
        """Test initialization with various valid names."""
        instance = ExampleClass(name)
        assert instance.name == expected

Test File Naming

  • Unit tests: test_<module_name>.py
  • Integration tests: test_<feature>_integration.py
  • Fixtures: Place in tests/fixtures/

Pull Request Process

Before Submitting

  1. Update documentation if you've changed APIs
  2. Add tests for new functionality
  3. Run the full test suite and ensure it passes
  4. Run linting and fix any issues
  5. Update the CHANGELOG if applicable

PR Title Format

Use conventional commit format:

  • feat: Add new visualization type
  • fix: Resolve encoding issue in CSV reader
  • docs: Update API documentation
  • test: Add integration tests for orchestrator
  • refactor: Simplify agent base class

PR Description Template

## Description
Brief description of changes

## Type of Change
- [ ] Bug fix (non-breaking change fixing an issue)
- [ ] New feature (non-breaking change adding functionality)
- [ ] Breaking change (fix or feature causing existing functionality to change)
- [ ] Documentation update

## How Has This Been Tested?
Describe the tests you ran

## Checklist
- [ ] My code follows the style guidelines
- [ ] I have performed a self-review
- [ ] I have commented complex code
- [ ] I have updated documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests
- [ ] All tests pass locally

Review Process

  1. A maintainer will review your PR
  2. Address any feedback or requested changes
  3. Once approved, a maintainer will merge your PR

Questions?

Feel free to open an issue with the question label if you need help!


Thank you for contributing to EVA! 🎉