Contributing to Open Geodata API

We welcome contributions from the community! This guide will help you get started with contributing to Open Geodata API.

Ways to Contribute

πŸ› Bug Reports

Found a bug? Report it on our GitHub Issues page with detailed information.

✨ Feature Requests

Have an idea for a new feature? Create a feature request issue.

πŸ“ Documentation

Help improve our documentation, examples, or tutorials.

πŸ’» Code Contributions

Submit bug fixes, new features, or performance improvements.

πŸ§ͺ Testing

Help expand our test coverage or improve existing tests.

πŸ“š Examples

Create real-world examples and use cases.

Getting Started

Development Setup

  1. Fork the repository on GitHub

  2. Clone your fork:

git clone https://github.com/YOUR_USERNAME/open-geodata-api.git
cd open-geodata-api
  1. Create a virtual environment:

python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
  1. Install development dependencies:

pip install -e .[dev]
  1. Install pre-commit hooks:

pre-commit install
  1. Run tests to verify setup:

pytest

Development Workflow

  1. Create a feature branch:

git checkout -b feature/your-feature-name
  1. Make your changes following our coding standards

  2. Run tests:

pytest
pytest --cov=open_geodata_api  # With coverage
  1. Check code style:

black .
flake8
mypy open_geodata_api/
  1. Commit your changes:

git add .
git commit -m "feat: add your feature description"
  1. Push to your fork:

git push origin feature/your-feature-name
  1. Create a Pull Request on GitHub

Coding Standards

Code Style

We use Black for code formatting and flake8 for linting:

# Format code
black .

# Check style
flake8

# Type checking
mypy open_geodata_api/

Key Style Guidelines:

  • Use Black default formatting (88 character line length)

  • Follow PEP 8 naming conventions

  • Use type hints for all public functions

  • Write descriptive docstrings for all public APIs

  • Keep functions focused and single-purpose

Documentation Style

Docstring Format (Google style):

def search_items(collections, bbox=None, datetime=None):
    """Search for satellite data items.

    Args:
        collections: List of collection names to search
        bbox: Bounding box as [west, south, east, north]
        datetime: Date range as string or datetime objects

    Returns:
        STACItemCollection: Collection of found items

    Raises:
        ValueError: If collection names are invalid

    Example:
        >>> pc = ogapi.planetary_computer()
        >>> results = pc.search(['sentinel-2-l2a'], bbox=[-122, 47, -121, 48])
        >>> items = results.get_all_items()
    """

Comment Guidelines:

  • Use comments sparingly for complex logic

  • Prefer self-documenting code with clear variable names

  • Add TODO comments for future improvements

  • Use docstrings for all public functions and classes

Testing Guidelines

Test Structure

We use pytest for testing:

tests/
β”œβ”€β”€ conftest.py              # Shared fixtures
β”œβ”€β”€ test_clients.py          # Client class tests
β”œβ”€β”€ test_core.py             # Core STAC class tests
β”œβ”€β”€ test_utils.py            # Utility function tests
β”œβ”€β”€ test_integration.py      # Integration tests
└── fixtures/                # Test data
    β”œβ”€β”€ sample_item.json
    └── sample_collection.json

Writing Tests

Test Naming:

def test_search_returns_items():
    """Test that search returns expected items."""

def test_search_with_invalid_collection_raises_error():
    """Test error handling for invalid collections."""

Test Structure:

def test_feature_functionality():
    # Arrange
    client = create_test_client()
    expected_result = "expected_value"

    # Act
    result = client.some_method()

    # Assert
    assert result == expected_result

Mocking External APIs:

@patch('requests.post')
def test_search_calls_api_correctly(mock_post):
    mock_post.return_value.json.return_value = sample_response

    client = PlanetaryComputerCollections()
    result = client.search(['sentinel-2-l2a'])

    mock_post.assert_called_once()

Test Coverage

  • Aim for >90% test coverage

  • Test happy paths and error conditions

  • Include integration tests for complete workflows

  • Mock external API calls in unit tests

  • Use real API calls in integration tests (sparingly)

Run coverage reports:

pytest --cov=open_geodata_api --cov-report=html
open htmlcov/index.html  # View coverage report

Pull Request Process

Pull Request Guidelines

Before Submitting:

  • βœ… All tests pass

  • βœ… Code follows style guidelines

  • βœ… Documentation is updated

  • βœ… CHANGELOG.md is updated (for significant changes)

  • βœ… Commit messages follow convention

PR Description Template:

## Description
Brief description of changes made.

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update

## Testing
- [ ] Added tests for new functionality
- [ ] All existing tests pass
- [ ] Manual testing completed

## Checklist
- [ ] Code follows style guidelines
- [ ] Documentation updated
- [ ] Self-review completed

Commit Message Convention

We follow Conventional Commits:

<type>(<scope>): <description>

[optional body]

[optional footer]

Types: - feat: New feature - fix: Bug fix - docs: Documentation changes - style: Code style changes (formatting, etc.) - refactor: Code refactoring - test: Adding or updating tests - chore: Maintenance tasks

Examples:

feat(core): add support for asset filtering

fix(cli): resolve URL encoding issue in download command

docs(examples): add real-world agricultural monitoring example

test(utils): increase coverage for download functions

Review Process

What We Look For:

  • βœ… Functionality: Does the code work as intended?

  • βœ… Testing: Are there adequate tests?

  • βœ… Documentation: Is the change properly documented?

  • βœ… Style: Does it follow our coding standards?

  • βœ… Performance: Any performance implications?

  • βœ… Breaking Changes: Are they necessary and documented?

Review Timeline: - Initial response: Within 1-2 weeks - Code review: Depends on complexity - Merge: After approval and CI passes

Release Process

Versioning

We follow Semantic Versioning (SemVer):

  • MAJOR (X.0.0): Breaking changes

  • MINOR (0.X.0): New features, backwards compatible

  • PATCH (0.0.X): Bug fixes, backwards compatible

Release Workflow

  1. Create release branch: release/vX.Y.Z

  2. Update version in __init__.py

  3. Update CHANGELOG.md

  4. Run full test suite

  5. Create release PR

  6. Tag release after merge

  7. Publish to PyPI (automated)

Community Guidelines

Code of Conduct

We follow the Contributor Covenant Code of Conduct:

  • Be respectful and inclusive

  • Be collaborative and helpful

  • Be patient with newcomers

  • Focus on the project goals

  • Respect different perspectives

Communication

Preferred Channels: - GitHub Issues: Bug reports, feature requests - GitHub Discussions: Questions, sharing ideas - Pull Requests: Code review and discussion

Response Expectations: - We aim to respond to issues within a week - Complex issues may take longer to resolve - Community contributions help everyone

Getting Recognition

Contributors Hall of Fame

All contributors are recognized in:

  • README.md: Contributors section

  • Documentation: Acknowledgments page

  • Release Notes: Major contribution highlights

Recognition Levels: - Contributor: Any merged PR - Regular Contributor: Multiple significant PRs - Core Contributor: Ongoing significant contributions - Maintainer: Trusted with repository access

Becoming a Maintainer

Path to Maintainer Status:

  1. Consistent Contributions: Regular, high-quality PRs

  2. Community Involvement: Helping others, reviewing PRs

  3. Domain Expertise: Deep understanding of codebase

  4. Reliability: Following through on commitments

  5. Leadership: Guiding project direction

Maintainer Responsibilities: - Review and merge pull requests - Triage issues and discussions - Guide project roadmap - Mentor new contributors - Maintain code quality standards

Resources for Contributors

Learning Resources: - Python packaging guide - Pytest documentation - STAC specification

Development Tools: - Black code formatter - Flake8 linter - MyPy type checker - Pre-commit hooks

Project Resources: - GitHub Repository: https://github.com/Mirjan-Ali-Sha/open-geodata-api - Documentation: https://open-geodata-api.readthedocs.io - PyPI Package: https://pypi.org/project/open-geodata-api - Examples Repository: https://github.com/Mirjan-Ali-Sha/open-geodata-api-examples

Thank you for contributing to Open Geodata API! Your contributions help make satellite data more accessible to everyone. πŸŒπŸ›°οΈ