Contributing#
We welcome contributions to epub-utils
! This guide will help you get started with contributing to the project.
Getting Started#
Setting Up Development Environment#
Fork the Repository
Fork the
epub-utils
repository on GitHub to your own account.Clone Your Fork
git clone https://github.com/yourusername/epub-utils.git cd epub-utils
Set Up Development Environment
# Create virtual environment python -m venv dev-env source dev-env/bin/activate # On Windows: dev-env\Scripts\activate # Install in development mode pip install -e ".[dev]" # Or install dependencies manually pip install -e . pip install pytest black flake8 mypy sphinx
Project Structure#
epub-utils/
├── src/
│ └── epub_utils/
│ ├── __init__.py
│ ├── cli.py # Command-line interface
│ ├── document.py # Main Document class
│ ├── extractors.py # Content extraction logic
│ └── formatters.py # Output formatting
├── tests/
│ ├── __init__.py
│ ├── test_document.py
│ ├── test_cli.py
│ └── fixtures/ # Test EPUB files
├── docs/
│ ├── conf.py
│ ├── index.rst
│ └── ... # Documentation files
├── pyproject.toml
├── README.md
└── CHANGELOG.md
Development Workflow#
Branch Strategy#
main
branch: Stable, release-ready codedevelop
branch: Integration branch for featuresFeature branches:
feature/your-feature-name
Bug fix branches:
fix/issue-description
Making Changes#
Create a Feature Branch
git checkout -b feature/your-feature-name
Make Your Changes
Follow the coding standards outlined below.
Write Tests
All new features should include comprehensive tests.
Run Tests Locally
# Run all tests pytest # Run with coverage pytest --cov=epub_utils # Run specific test file pytest tests/test_document.py
Check Code Quality
# Format code black src/ tests/ # Check linting flake8 src/ tests/ # Type checking mypy src/
Update Documentation
If your changes affect the API or add new features, update the documentation.
Commit Your Changes
git add . git commit -m "Add: Brief description of your changes"
Push and Create Pull Request
git push origin feature/your-feature-name
Then create a pull request on GitHub.
Coding Standards#
Python Style Guide#
We follow PEP 8 with some modifications:
Line length: 88 characters (Black’s default)
String quotes: Use double quotes for strings
Import sorting: Use isort or similar tool
Docstrings: Use Google-style docstrings
Code Formatting#
We use Black for code formatting:
# Format all Python files
black src/ tests/
# Check formatting without making changes
black --check src/ tests/
Example of properly formatted code:
def extract_metadata(epub_path: str, format_type: str = "dict") -> dict:
"""Extract metadata from an EPUB file.
Args:
epub_path: Path to the EPUB file.
format_type: Output format ('dict', 'xml', 'json').
Returns:
Dictionary containing extracted metadata.
Raises:
FileNotFoundError: If the EPUB file doesn't exist.
ValueError: If format_type is not supported.
"""
if not os.path.exists(epub_path):
raise FileNotFoundError(f"EPUB file not found: {epub_path}")
if format_type not in ["dict", "xml", "json"]:
raise ValueError(f"Unsupported format: {format_type}")
# Implementation here...
return {}
Linting#
We use ruff for linting:
# Check for linting errors
make lint
Type Hints#
Use type hints for all function signatures:
from typing import List, Dict, Optional, Union
from pathlib import Path
def process_files(
file_paths: List[Union[str, Path]],
output_format: str = "table"
) -> Optional[Dict[str, any]]:
"""Process multiple EPUB files."""
pass
Documentation Standards#
Docstring Format#
Use Google-style docstrings:
def complex_function(param1: str, param2: int, param3: bool = False) -> dict:
"""Brief description of the function.
Longer description if needed. Explain the purpose, behavior,
and any important details about the function.
Args:
param1: Description of the first parameter.
param2: Description of the second parameter.
param3: Description of optional parameter. Defaults to False.
Returns:
Description of return value and its structure.
Raises:
ValueError: When param2 is negative.
FileNotFoundError: When the specified file doesn't exist.
Example:
Basic usage example:
>>> result = complex_function("test", 42)
>>> print(result["status"])
"success"
"""
pass
API Documentation#
When adding new classes or functions to the public API:
Add to __init__.py exports if appropriate
Update API reference documentation
Include usage examples in docstrings
Add to tutorials if it’s a major feature
RST Documentation#
When writing RST documentation:
Section Title
=============
Subsection
----------
Code examples:
.. code-block:: python
# Python code here
import epub_utils
Shell commands:
.. code-block:: bash
epub-utils info book.epub
Testing Guidelines#
Test Structure#
Unit tests: Test individual functions and methods
Integration tests: Test component interactions
End-to-end tests: Test complete workflows
Performance tests: Test with large files (optional)
Writing Tests#
Use pytest for all tests:
import pytest
from epub_utils import Document
from pathlib import Path
def test_document_with_invalid_file():
"""Test error handling with invalid file."""
with pytest.raises(FileNotFoundError):
Document("nonexistent.epub")
@pytest.mark.parametrize("format_type", ["dict", "xml", "json"])
def test_metadata_formats(doc_path, format_type):
"""Test different metadata formats."""
doc = Document(str(doc_path)
metadata = doc.get_metadata(format_type=format_type)
assert metadata is not None
Test Fixtures#
Create test EPUB files in tests/fixtures/
:
# tests/conftest.py
import pytest
from pathlib import Path
@pytest.fixture
def sample_epub():
"""Provide path to sample EPUB for testing."""
return Path(__file__).parent / "fixtures" / "sample.epub"
@pytest.fixture
def invalid_epub():
"""Provide path to invalid EPUB for error testing."""
return Path(__file__).parent / "fixtures" / "invalid.epub"
Running Tests#
# Run all tests
make test
# Run specific test file
pytest tests/test_document.py
Types of Contributions#
Bug Reports#
When reporting bugs:
Check existing issues first
Use the issue template if available
Provide minimal reproduction case
Include system information
**Bug Description**
Clear description of the bug.
**Steps to Reproduce**
1. Step one
2. Step two
3. Step three
**Expected Behavior**
What should happen.
**Actual Behavior**
What actually happens.
**Environment**
- epub-utils version:
- Python version:
- Operating system:
**Sample File**
Attach or link to EPUB file if relevant.
Feature Requests#
For new features:
Describe the use case clearly
Explain why it’s valuable to users
Suggest implementation approach if you have ideas
Consider backward compatibility
Documentation Improvements#
Documentation contributions are highly valued:
Fix typos and grammar errors
Improve clarity of explanations
Add more examples to existing docs
Create new tutorials for common use cases
Update outdated information
Code Contributions#
Areas where contributions are welcome:
Performance improvements
New output formats
Additional EPUB validation
Better error handling
CLI usability enhancements
Support for EPUB 3 features
Release Process#
Versioning#
We follow Semantic Versioning:
MAJOR: Incompatible API changes
MINOR: New functionality (backward compatible)
PATCH: Bug fixes (backward compatible)
Version format: MAJOR.MINOR.PATCH
(e.g., 1.2.3
)
Development versions may include additional identifiers:
- 1.2.3-dev
(development)
- 1.2.3rc1
(release candidate)