Thank you for your interest in contributing to FolioClient! This guide will help you get started with contributing to this Python library for interacting with FOLIO Platform APIs. These are guidelines to help make collaboration easier. They are not intended to be barriers to contribution—we just ask for good-faith efforts.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Testing
- Code Style
- Submitting Changes
- Reporting Issues
- Documentation
- Release Process
By participating in this project, you agree to abide by the FOLIO Community Code of Conduct. Please be respectful and constructive in all interactions with maintainers and other contributors.
- Python 3.10 or higher (Python 3.13 recommended)
- uv for dependency management
- Git for version control
- A FOLIO system for testing (optional, but recommended for comprehensive testing)
- You can use the community reference environments, but please be considerate of others
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/yourusername/FolioClient.git cd FolioClient - Add the upstream remote:
git remote add upstream https://github.com/FOLIO-FSE/FolioClient.git
# Install dependencies (including dev and docs)
uv sync --all-groups
# Install with JSON performance optimizations
uv sync --extra orjson-
Set up environment variables (if testing against a FOLIO system):
export FOLIO_URL="https://your-folio-instance.example.com" export FOLIO_TENANT="your_tenant" export FOLIO_USERNAME="your_username" export FOLIO_PASSWORD="your_password"
-
Create a
.envfile (optional, for local development):FOLIO_URL=https://your-folio-instance.example.com FOLIO_TENANT=your_tenant FOLIO_USERNAME=your_username FOLIO_PASSWORD=your_password GITHUB_TOKEN=your_github_token # For GitHub API tests
- Feature branches:
feature/description-of-feature - Bug fixes:
fix/description-of-bug - Documentation:
docs/description-of-update - Refactoring:
refactor/description-of-change
-
Create a new branch from
master:git checkout master git pull upstream master git checkout -b feature/your-feature-name
-
Make your changes following the code style guidelines below
-
Commit your changes with descriptive commit messages:
git add . git commit -m "Add feature: description of what you added"
-
Keep your branch up to date:
git fetch upstream git rebase upstream/master
-
Keep commits clean - Use meaningful commit messages and consider interactive rebase (
git rebase -i) to clean up your commit history before submitting
- Prefer the present tense ("Add feature" not "Added feature")
- Prefer the imperative mood ("Move cursor to..." not "Moves cursor to...")
- Limit the first line to 72 characters or less
- Reference issues and pull requests liberally after the first line
Examples:
Add async support for batch operations
- Implement async_batch_get method
- Add comprehensive async tests
- Update documentation with async examples
Fixes #123
# Run all tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=src/folioclient --cov-report=html
# Run specific test file
uv run pytest tests/test_folio_client.py
# Run tests with verbose output
uv run pytest -v
# Run async tests only
uv run pytest -k "async"We provide a limited set of integration tests to verify network functionality of FolioClient. These tests are not included in the standard pytest test run, and require additional configuration. By default they are run against the current community Okapi snapshot environment, Eureka snapshot environment, Eureka ECS snapshot environment, and the most recent Bugfest environment. You can specify a single environment from the available options:
snapshotsnapshot-2eureka(eureka snapshot)eureka-ecs(eureka snapshot ECS)snapshot-2-eureka(eureka backup snapshot)bugfest(currently Sunflower bugfest)
# Set up environment variables for integration testing
export FOLIO_SNAPSHOT_USERNAME=<snapshot_admin_usernae>
export FOLIO_SNAPSHOT_PASSWORD=<snapshot_admin_password>
export FOLIO_ECS_EUREKA_USERNAME=<eureka_ecs_snapshot_admin_username>
export FOLIO_ECS_EUREKA_PASSWORD=<eureka_ecs_snapshot_admin_password>
export FOLIO_BUGFEST_USERNAME=<bugfest_admin_username>
export FOLIO_BUGFEST_PASSWORD=<bugfest_admin_password>
# Run integration tests
uv run pytest --run-integration
# Run integration tests against snapshot only (others will be skipped)
uv run pytest --run-integration --integration-server snapshot- Location: Add tests to the
tests/directory - Naming: Test files should be named
test_*.py - Async tests: Use
@pytest.mark.asynciofor async test functions - Mocking: Use
unittest.mockfor mocking external dependencies - Coverage: Aim for high test coverage, especially for new features
Example test structure:
import pytest
from unittest.mock import Mock, patch
from folioclient import FolioClient
class TestFolioClient:
@patch.object(FolioClient, '_initial_ecs_check')
def test_feature_name(self, mock_ecs_check):
# Test implementation
pass
@pytest.mark.asyncio
async def test_async_feature(self):
# Async test implementation
passWe use Ruff for both linting and formatting:
# Check for linting issues
uv run ruff check
# Auto-fix linting issues
uv run ruff check --fix
# Format code
uv run ruff format
# Check formatting without applying
uv run ruff format --checkWe use mypy for static type checking:
# Run type checking
uv run mypy src/folioclient --ignore-missing-imports- Line length: Maximum 99 characters
- Import sorting: Use Ruff's import sorting
- Type hints: Add type hints for all function parameters and return values
- Docstrings: Use Google-style docstrings for all public methods
- Async/Sync patterns: Maintain parallel sync and async implementations where applicable
def folio_get(self, path: str, key: str | None = None, query: str = "",
query_params: dict = None) -> Any:
"""
Fetches data from FOLIO and returns it as a JSON object.
Args:
path: FOLIO API endpoint path
key: Key in JSON response that contains the array of results
query: CQL query string for filtering results
query_params: Additional query parameters for the request
Returns:
JSON response data, optionally filtered by key
Raises:
HTTPStatusError: If the HTTP request fails
FolioClientClosed: If the client has been closed
Example:
>>> client.folio_get("/users", "users", "username==admin")
"""- Update documentation if you've changed APIs or added features
- Add or update tests for your changes
- Ensure all tests pass and linting is clean
- Update the changelog if appropriate
- Submit a pull request with a clear description
## Description
Brief description of what this PR does.
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass (if applicable)
- [ ] New tests added for new functionality
## Checklist
- [ ] Code follows the project's style guidelines
- [ ] Self-review of code completed
- [ ] Code is commented, particularly in hard-to-understand areas
- [ ] Corresponding changes to documentation have been made
- [ ] Changes generate no new warnings- Automated checks must pass (GitHub Actions, linting, tests)
- At least one maintainer review is required
- Address feedback promptly and professionally
- Clean commit history - We use rebase and merge to maintain a linear history for all pull requests, so be sure your branch does not have conflicts with the main branch
When reporting bugs, please include:
- Python version and operating system
- FolioClient version
- FOLIO system version (if applicable)
- Minimal code example that reproduces the issue
- Full error traceback with any sensitive data removed/redacted
- Expected vs actual behavior
For feature requests, please include:
- Use case description - what problem does this solve?
- Proposed API - how should the feature work?
- Alternative solutions - what other approaches have you considered?
- FOLIO API documentation - links to relevant FOLIO API docs
For security-related issues, please do not open a public issue. Instead:
- Email the maintainers directly
- Include a detailed description of the vulnerability
- Provide steps to reproduce (if applicable)
- Allow reasonable time for response before disclosure
# Install documentation dependencies
uv sync --group docs
# Build documentation
cd docs
make html
# Serve documentation locally
make serve
# Open http://localhost:8000 in your browser
# Check for broken links
make linkcheck- API documentation: All public methods must have comprehensive docstrings
- Examples: Include working code examples in docstrings
- Type hints: All parameters and return values must be type-hinted
- Changelog: Update
CHANGELOG.mdfor user-facing changes
Note: This section is primarily for maintainers
We follow Semantic Versioning:
- Major (1.0.0): Breaking changes
- Minor (1.1.0): New features, backwards compatible
- Patch (1.1.1): Bug fixes, backwards compatible
- Pre-release
- (1.0.0b1): Beta versions
- (1.1.0a1): Alpha versions
- (1.1.0rc1): Release candidates
- Update version in
pyproject.toml - Update
CHANGELOG.md - Run full test suite, including integration tests
- Create release tag in GitHub
- Approve submit workflow to publish to pypi
- Update GitHub release notes
- GitHub Issues: For bugs, features, and questions
- GitHub Discussions: For general discussion and questions
- Documentation: Check the README and inline documentation first
- FOLIO Community: FOLIO Project for FOLIO-specific questions
Contributors will be recognized in:
- GitHub contributors list
- pyproject.toml project authors list
- Changelog acknowledgments
- Release notes (for significant contributions)
Thank you for contributing to FolioClient! Your efforts help make FOLIO integration easier for libraries worldwide. 🚀