LiteBox
Containers for finding Python objects by attribute. Backed by SQLite.
pip install litebox
Usage
from litebox import LiteBox
tb = LiteBox(
[{'num': 1, 'size': 1000, 'shape': 'square'}], # provide a collection of objects or dicts
{'size': int, 'shape': str}) # specify attributes to store
tb.find('size >= 1000 and shape == "square"') # find by attribute value
The objects can be anything - class, dataclass, namedtuple, dict, string, int, etc.
LiteBox supports add(), add_many(), update(), and remove(); see API below.
Nested attributes
You can define a function to access nested or derived attributes.
from litebox import LiteBox
objs = [
{'num': 1, 'nested': {'a': 2, 'b': 3}},
{'num': 2, 'nested': {'a': 4, 'b': 5}}
]
def nested_attr(obj):
return obj['nested']['a']
# Build LiteBox, run find
tb = LiteBox(objs, {nested_attr: int})
tb.find('nested_attr == 2') # returns obj 1
How it works
When you do: LiteBox(list_of_objects, on={'size': int, 'shape': string}) or PandasBox(...)
A SQLite table is created with 3 columns:
- size
- shape
- Python object reference
On find(), a query will run to find the matching objects.
Only the relevant attributes of the object are copied into the table. The rest of the object remains in memory.
An ideal use case is when you have "heavy" objects containing images / audio / large texts, plus some small metadata fields that you want to find by. Just make a LiteBox on the metadata, and use it to find the object without needing to serialize / deserialize the heavy stuff.
LiteBox is especially good when finding by < and >. If you only need ==, consider
HashBox -- it is based on dict lookups which are faster in that case.
API
Init
LiteBox(
objs: Optional[Iterable[Any]] = None,
on: Optional[Dict[str, Any]] = None,
index: Optional[List[ Union[Tuple[str], str]]] = None
)
Creates a LiteBox.
objsis optional. It can be any container of class, dataclass, dict, or namedtuple objects.onis required. It specifies the attributes and types to index. The allowed types are float, int, bool, and str.indexspecifies the indices to create on the SQLite table. If unspecified, a single-column index is made on each attribute.
The index parameter is the key to getting good performance. A multi-column index can often speed up find()
operations. index=[('a', 'b', 'c'), 'd'] will create a multi-column index on (a, b, c) and a single-column index
on d. Conversely, some columns such as those containing only a few different values may perform better without an
index.
See SQLite index documentation for more insights.
find()
find(where: Optional[str]) -> List finds objects matching the query string in where.
Examples:
tb.find('b == True and string == "okay"')tb.find('(x == 0 and y >= 1000.0) or x == 9')lb.find('x is null')
If where is unspecified, all objects in the container are returned.
Consult the syntax for SQLite queries as needed.
add(), add_many()
add(obj:Any)
add_many(objs:Iterable[Any])
The add() method adds a single object. If you have many objects, it is much faster to add_many() than it is to
call add() on each one.
If an added object is missing an attribute, the object will still be added. The missing attribute will be given a
None value.
update()
update(self, obj: Any) updates attributes of a single object in the index.
It's just a shorthand for remove() and then add().
If you change an object's attributes without calling update(), the LiteBox will be out of sync and
return stale results. Consider implementing a setattr listener on your object to update LiteBox when your objects
change.
remove()
remove(self, obj: Any) removes an object.
Container methods
You can do the usual container things:
- Length:
len(tb) - Contains:
obj in tb - Iteration:
for obj in tb: ...
Performance
See examples for performance tests.
Metadata
Release files for litebox 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| litebox-0.2.0.tar.gz | 7.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| litebox-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.9 kB
Release files / litebox-0.2.0.tar.gz
| Download URL | litebox-0.2.0.tar.gz |
|---|---|
| Size | 7.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b7fdd4cb1cb1bdfd9338eb8dc7c66c5584c34250ec0ea2736556f3f53d12be0c
|
|
BLAKE2b-256 checksum How to use checksums |
0a71f5cc2d13a41db4f16c2158655ae39e613dcec8698924a38a8604dc4fb79e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.13 CPython/3.9.7 Linux/5.15.55-1-MANJARO
|
Release files / litebox-0.2.0-py3-none-any.whl
| Download URL | litebox-0.2.0-py3-none-any.whl |
|---|---|
| Size | 7.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c89340cd37809b267e04b8539b5bf8f8d61d8f6dfaf663e1a4418eae094ea5a8
|
|
BLAKE2b-256 checksum How to use checksums |
23ac98468d21c86b7531520e45e4df25386e1045f48e3d6984f42d2a135c4879
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.13 CPython/3.9.7 Linux/5.15.55-1-MANJARO
|
Security for litebox 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.