Thank you for your interest in contributing to MedCheck! We welcome contributions of all kinds, from bug reports and feature requests to code changes and documentation improvements.
Found a bug? We appreciate detailed bug reports. Please use our bug report template when opening an issue.
Have an idea for a new feature? Share it with us using the feature request template. We especially encourage:
- Requests for new data providers
- Suggestions for new LLM providers
- Pipeline improvements and enhancements
Code contributions are welcome! Whether it's a bug fix, feature implementation, or documentation update, we're happy to review your work.
Help us make MedCheck better documented. You can:
- Fix typos or clarify existing documentation
- Add examples and usage guides
- Improve API documentation
Please open an issue first to discuss your proposed changes with the maintainers. This helps us avoid duplicate work and ensures your changes align with the project's direction.
For small changes (typo fixes, minor documentation updates), you can skip this and go straight to a PR.
- Python 3.11+
- Git
- uv package manager
- Fork the repository on GitHub
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/MedCheck.git cd MedCheck - Install dependencies:
uv sync --all-extras
- Install pre-commit hooks:
pre-commit install
We maintain high code quality standards to ensure maintainability and reliability.
- Maximum 120 characters per line (enforced by Ruff)
- Type hints are required for all public functions and methods
- Use
from typing import ...orfrom collections.abc import ...for type annotations - Return types must be specified
- Google-style docstrings are required for all public functions, classes, and modules
- Include brief description, Args, Returns, and Raises sections
- Example:
def fetch_data(provider: str, query: str) -> dict: """Fetch medical data from the specified provider. Args: provider: Name of the data provider query: Search query for the data Returns: Dictionary containing the fetched data Raises: ValueError: If provider is not supported """
- Ruff is used for code formatting and linting:
uv run ruff check . uv run ruff format .
- MyPy is used for static type checking in strict mode:
uv run mypy src/medcheck --strict
Tests are required for all new features and bug fixes.
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=src/medcheck --cov-report=html
# Run specific test file
uv run pytest tests/test_providers.py
# Run tests matching a pattern
uv run pytest -k "test_llm"- Minimum coverage is 85% (
--cov-fail-under=85) - All new code must be covered by tests
- Aim for meaningful tests, not just coverage targets
- Create a feature branch from
main:git checkout -b feat/my-feature
- Make your changes and commit them (see commit message format below)
- Ensure all tests pass:
uv run pytest
- Ensure linting passes:
uv run ruff check . - Ensure type checking passes:
uv run mypy src/medcheck --strict
- Push to your fork and open a pull request
Use conventional commit format:
feat:- A new featurefix:- A bug fixdocs:- Documentation changesrefactor:- Code refactoring without behavior changestest:- Adding or updating testschore:- Build, CI, or dependency updates
Example: feat: add support for FHIR data provider
- Link related issues: "Fixes #123" or "Closes #456"
- Clear description of changes
- At least one maintainer review is required
- All CI checks must pass
- Code coverage must not decrease
To add a new data provider for medical data sources:
-
Create a new file in
src/medcheck/providers/:# src/medcheck/providers/my_provider.py from medcheck.providers.base import DataProvider class MyDataProvider(DataProvider): """Provider for my medical data source.""" name = "my_provider" async def fetch(self, query: str) -> dict: """Fetch data from the provider.""" pass
-
Implement the
DataProviderinterface:- Implement required abstract methods
- Add proper error handling
- Include rate limiting if needed
-
Register URL patterns in the router:
# src/medcheck/providers/__init__.py url_patterns = [ # ... existing patterns ("my-provider", MyDataProvider), ]
-
Add comprehensive tests:
# tests/test_providers/test_my_provider.py import pytest from medcheck.providers.my_provider import MyDataProvider @pytest.mark.asyncio async def test_fetch(): provider = MyDataProvider() result = await provider.fetch("test query") assert result is not None
To add a new LLM provider for language model integration:
-
Create a new file in
src/medcheck/llm/:# src/medcheck/llm/my_llm.py from medcheck.llm.base import LLMProvider class MyLLMProvider(LLMProvider): """LLM provider for my model.""" name = "my_llm" async def generate(self, prompt: str) -> str: """Generate response from the LLM.""" pass
-
Implement the
LLMProviderinterface:- Implement required abstract methods
- Add proper error handling and retries
- Implement streaming if supported
-
Add environment variable for API key:
import os api_key = os.getenv("MY_LLM_API_KEY")
-
Register the provider:
# src/medcheck/llm/__init__.py from medcheck.llm.my_llm import MyLLMProvider
-
Add comprehensive tests:
# tests/test_llm/test_my_llm.py import pytest from medcheck.llm.my_llm import MyLLMProvider @pytest.mark.asyncio async def test_generate(): provider = MyLLMProvider() response = await provider.generate("test prompt") assert response is not None
By contributing to MedCheck, you agree that your contributions will be licensed under the Apache License 2.0. See the LICENSE file for details.
If you have questions about contributing, feel free to open an issue or reach out to the maintainers. We're here to help!
Happy coding!