Contributing¶
Thanks for taking the time to contribute. This project aims to be small, sharp, and well-tested. PRs that keep that spirit are very welcome.
TL;DR¶
- Fork → branch → commit small, focused changes → add tests → open a PR
- Keep public API changes minimal and documented
- Tests should pass locally
- Use the CLI tool to test against a real WeFact environment
Development Setup¶
Installation¶
# Clone the repository
git clone https://github.com/zzinnovate/wefact-python.git
cd wefact-python
# Install with all development dependencies (CLI, testing, docs)
pip install -e ".[all]"
# Or install specific groups
pip install -e ".[cli]" # CLI testing tool only
pip install -e ".[dev]" # Testing tools only
pip install -e ".[docs]" # Documentation tools only
CLI Testing Tool¶
Test endpoints interactively against a real WeFact environment:
# Run the CLI tool
python -m wefact_cli
# Or after installation
wefact-test
The CLI provides: - Interactive API endpoint testing - Dummy data generation for testing - Nifty terminal UI - Environment variable management
See docs/guides/cli-tool.md for details.
Running Tests¶
# Run all tests
pytest
# Run with coverage (terminal report)
pytest --cov=wefact --cov-report=term-missing
# HTML coverage report (open htmlcov/index.html)
pytest --cov=wefact --cov-report=html
# Run specific test file
pytest tests/test_invoices.py
Building Documentation¶
# Serve docs locally with live reload
mkdocs serve
# Build static site
mkdocs build
Workflow¶
- Fork and clone:
git clone https://github.com/your-username/wefact-python.git cd wefact-python - Create a feature branch:
git checkout -b feat/short-slug - Make changes with tests. Put tests under
tests/. - Run the suite until green.
- Commit with a clear message:
git commit -m "feat(invoice): add mark_as_paid helper" - Push and open a PR against
main.
Code Style¶
- Small, composable functions - Keep functions focused on a single responsibility
- Explicit names - Method names should clearly describe what they do
- Align with WeFact API - Public methods match WeFact's controller/action pattern (e.g.,
list,show,create,edit,delete,mark_as_paid) - Use existing exceptions - Raise exceptions from
wefact.exceptions(e.g.,ValidationError,AuthenticationError,NotFoundError) - Use enums for readability - Provide enums in
wefact.enumsfor API values (e.g.,PricePeriod.MONTHLY,TaskStatus.IN_PROGRESS,PaymentMethod.IDEAL) instead of Dutch abbreviations - Avoid breaking changes - Maintain backward compatibility unless there's a compelling reason
Example with enums:
from wefact.enums import PricePeriod, TaskStatus
# Good - readable and IDE-friendly
product = client.products.create(
ProductName="Hosting",
PricePeriod=PricePeriod.MONTHLY
)
# Avoid - unclear abbreviations
product = client.products.create(
ProductName="Hosting",
PricePeriod='m' # What does 'm' mean?
)
Tests¶
- Add tests for all changes - New features and bug fixes require tests
- Mock API calls - Use
pytest-mockto mockrequests.postresponses - Cover happy path and edge cases - Include at least one success test and one failure/edge case
- Use fixtures - Leverage fixtures from
tests/conftest.py(e.g.,api_client,sample_invoice) - Test naming - Use descriptive names:
test_create_invoice,test_list_invoices_with_filters
Example test pattern:
def test_create_invoice(client, mocker):
mock_response = {'status': 'success', 'invoice': {'Identifier': 'INV10000'}}
mocker.patch('wefact.request.requests.post', return_value=type('R', (), {
'status_code': 200,
'json': staticmethod(lambda: mock_response)
})())
response = client.invoices.create(DebtorCode='DB10000', InvoiceLines=[...])
assert response['status'] == 'success'
Documentation¶
- Update docs when behavior or configuration changes
- Keep examples runnable - Code examples should work as-is
- Document new resources - Add to
docs/api/when adding new endpoints - Update CHANGELOG.md - Document all notable changes
Releasing (maintainers)¶
- Update
CHANGELOG.md. - Bump version in
pyproject.toml. - Tag and publish to PyPI.
Thank you for making the project better.