Home¶
Overview¶
coola is a lightweight Python library to compare, hash and summarize complex and
nested data structures.
It provides simple, extensible functions that work on objects containing
PyTorch tensors,
NumPy arrays,
pandas/polars DataFrames, and other scientific
computing objects:
- Compare:
objects_are_equal,objects_are_allclose,assert_objects_equalandcomparecheck equality (exact or with a tolerance) and tell where two objects differ. - Hash:
hash_objectcomputes a deterministic hash of a nested object. - Summarize:
summarizecreates a short, readable description of a large structure for logs.
Quick Links:
Why coola?¶
Python's native equality operator (==) doesn't work well with complex nested structures
containing tensors, arrays, or DataFrames. You'll often encounter errors or unexpected behavior.
coola solves this with intuitive comparison functions:
Check exact equality:
>>> import numpy as np
>>> import torch
>>> from coola.equality import objects_are_equal
>>> data1 = {"torch": torch.ones(2, 3), "numpy": np.zeros((2, 3))}
>>> data2 = {"torch": torch.ones(2, 3), "numpy": np.zeros((2, 3))}
>>> objects_are_equal(data1, data2)
True
Compare with numerical tolerance:
>>> from coola.equality import objects_are_allclose
>>> data1 = {"value": 1.0}
>>> data2 = {"value": 1.0 + 1e-9}
>>> objects_are_allclose(data1, data2)
True
Assert equality in your tests, with the path of the difference:
>>> from coola.equality import assert_objects_equal
>>> actual = {"users": [{"id": 1, "score": 95}, {"id": 2, "score": 87}]}
>>> expected = {"users": [{"id": 1, "score": 95}, {"id": 2, "score": 88}]}
>>> assert_objects_equal(actual, expected)
Traceback (most recent call last):
...
AssertionError: objects are not equal at actual['users'][1]['score']
numbers are different:
actual : 87
expected : 88
assert_objects_allclose does the same with a tolerance.
Get the difference as data:
>>> from coola.equality import compare
>>> result = compare(actual, expected)
>>> result.equal
False
>>> result.path
('users', 1, 'score')
>>> print(result.reason)
numbers are different:
actual : 87
expected : 88
Hash and summarize:
>>> from coola.hashing import hash_object
>>> from coola.summary import summarize
>>> len(hash_object(actual))
64
>>> print(summarize(actual, max_depth=2))
<class 'dict'> (length=1)
(users): <class 'list'> (length=2)
(0): {'id': 1, 'score': 95}
(1): {'id': 2, 'score': 87}
compare(actual, expected) explains the first difference (its path and its reason), and
assert_objects_equal(actual, expected) raises an AssertionError with the same message.
See the user guide for detailed examples.
Features¶
coola provides a comprehensive set of utilities for working with complex data structures:
π Equality Comparison¶
Compare complex nested objects with support for multiple data types:
- Exact equality:
objects_are_equal()for strict comparison - Approximate equality:
objects_are_allclose()for numerical tolerance - Assertions for tests:
assert_objects_equal()andassert_objects_allclose()raise anAssertionErrorwith the path of the difference - Structured results:
compare()returns aComparisonResultwith the path and the reason - Extensible: Add custom equality testers for your own types
Supported types: JAX β’ NumPy β’ pandas β’ polars β’ PyArrow β’ pydantic β’ PyTorch β’ SciPy (sparse matrices and arrays) β’ xarray β’ Python built-ins (dict, list, tuple, set, etc.)
Learn more about supported types β
π Data Summarization¶
Generate human-readable summaries of nested data structures for debugging and logging:
- Configurable depth control
- Type-specific formatting
- Truncation for large collections
π Data Conversion¶
Transform data between different nested structures:
- Convert between list-of-dicts and dict-of-lists formats
- Useful for working with tabular data and different data representations
ποΈ Mapping Utilities¶
Work with nested dictionaries efficiently:
- Flatten nested dictionaries into flat key-value pairs
- Extract specific values from complex nested structures
- Filter dictionary keys based on patterns or criteria, rename keys and merge mappings
π Iteration¶
Traverse nested data structures systematically:
- Depth-first search (DFS) traversal for nested containers
- Breadth-first search (BFS) traversal for level-by-level processing
- Filter and extract specific types from heterogeneous collections
π Reduction¶
Compute statistics on sequences with flexible backends:
- Calculate min, max, mean, median, quantile, std on numeric sequences
- Support for multiple backends: native Python, NumPy, PyTorch
- Consistent API regardless of backend choice
#οΈβ£ Hashing¶
Compute stable hashes of nested objects:
- Hash dicts, lists, sets, dataclasses, pydantic models, arrays and data frames
- Independent of the insertion order of mappings and sets
- Extensible with custom hashers
π Identifiers¶
Generate unique identifiers: ULID, UUID (v5, v7), Snowflake, ObjectId, and checksummed and content-based identifiers.
πΎ Data Loading and Saving¶
Load and save JSON, pickle, text and PyTorch files with atomic writes, an overwrite policy and
optional durability (fsync).
π² Random Number Generators¶
Seed, save and restore the random number generators of random, NumPy and PyTorch in one call.
π§ Recursive Transformation and Validation¶
- Apply a function to every leaf of a nested structure
- Validate arguments with clear error messages
Learn more about transformation β Β· Learn more about validation β
π§© Registries and Factories¶
Build extensible components:
- Thread-safe
RegistryandTypeRegistry(lookup by Method Resolution Order, lazy loading of optional libraries) - Build any importable class or function from a configuration dictionary with
coola.factory
Learn more about registries β Β· Learn more about factories β
π§Ύ JSON Conversion¶
Convert nested data (dataclasses, sets, paths, arrays, tensors, pydantic models, ...) to JSON data
with to_jsonable, with a strict, extensible and cycle-safe conversion.
π’ Rounding¶
Round, floor or ceil numbers, NumPy arrays, PyTorch tensors, and pandas, polars and PyArrow data
with round_values.
π¨οΈ Display and Formatting¶
Build consistent __repr__/__str__ with display mixins, mask secrets, format sizes and durations,
and configure rich and colorlog output.
Learn more about display β Β· Learn more about formatting β
π§ͺ Testing and Utilities¶
pytest marks and fixtures to test code with optional dependencies, and helpers for imports, paths,
environment variables, caches and more.
Learn more about testing β Β· Learn more about utilities β
Contributing¶
Contributions are welcome! We appreciate bug fixes, feature additions, documentation improvements, and more. Please check the contributing guidelines for details on:
- Setting up the development environment
- Code style and testing requirements
- Submitting pull requests
Whether you're fixing a bug or proposing a new feature, please open an issue first to discuss your changes.
API Stability¶
Important: As
coola is under active development, its API is not yet stable and may
change between releases. We recommend pinning a specific version in your projectβs dependencies to
ensure consistent behavior.
License¶
coola is licensed under BSD 3-Clause "New" or "Revised" license available
in LICENSE
file.