Thank you for your interest in contributing to EasyScrape! This document provides guidelines and instructions for contributing.
- Python 3.8 or higher
- Git
# Clone the repository
git clone https://github.com/doudol/easyscrape.git
cd easyscrape
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode with all dependencies
pip install -e ".[dev,all]"
# Install pre-commit hooks
pre-commit install
# Install Playwright browsers (for JS rendering tests)
playwright install chromium# Run all tests
pytest -v
# Run with coverage
pytest -v --cov=easyscrape --cov-report=html
# Run specific test file
pytest tests/test_core.py -v
# Run in parallel
pytest -v -n autoWe use the following tools for code quality:
# Check formatting
black --check easyscrape/ tests/
# Auto-format
black easyscrape/ tests/isort easyscrape/ tests/mypy easyscrape/bandit -r easyscrape/Pre-commit hooks run automatically on git commit. To run manually:
pre-commit run --all-files- Fork the repository
- Create a branch for your feature/fix:
git checkout -b feature/my-feature
- Make your changes with clear, descriptive commits
- Add tests for new functionality
- Run the test suite to ensure nothing is broken
- Update documentation if needed
- Submit a pull request with a clear description
- Tests pass (
pytest -v) - Code is formatted (
black --check) - Types check (
mypy easyscrape/) - Security check passes (
bandit -r easyscrape/) - Documentation updated (if applicable)
- CHANGELOG.md updated (if applicable)
Use Google-style docstrings:
def scrape(url: str, config: Optional[Config] = None) -> ScrapeResult:
"""Fetch a URL and return a result with extraction helpers.
Args:
url: The URL to fetch (must be http:// or https://)
config: Optional configuration object
Returns:
ScrapeResult with response data and extraction methods.
Raises:
InvalidURLError: If URL is invalid or blocked
Example:
>>> result = scrape("https://example.com")
>>> print(result.title())
'Example Domain'
"""All public APIs must have type hints:
from typing import Optional, List, Dict
def process(items: List[str], config: Optional[Config] = None) -> Dict[str, int]:
...- Use custom exceptions from
easyscrape.exceptions - Provide helpful error messages
- Don't catch and silence exceptions without logging
- All URLs must go through
validate_url()before fetching - Never use
eval()orexec() - Validate all file paths for traversal attacks
- Never log sensitive data (passwords, API keys)
Include:
- Python version
- EasyScrape version
- Operating system
- Minimal code to reproduce
- Expected vs actual behavior
- Full traceback (if applicable)
Include:
- Clear description of the feature
- Use case / motivation
- Example API (if applicable)
Open a GitHub issue with the question label.
Thank you for contributing!