Logdict module

With this simple class and its slice-ability you can do great things:

>>> l = LogDict(a=1, b=2)
>>> list(l.items())
[('a', 1), ('b', 2)]
>>> l['c'] = 3
>>> l['b'] = 999
>>> list(l.items())
[('a', 1), ('b', 999), ('c', 3)]
>>> l.log
[('a', 1), ('b', 2), ('c', 3), ('b', 999)]
>>> l2 = l.slice(('c', 3), None) # to the end
>>> l2.log
[('c', 3), ('b', 999)]
>>> list(l2.items())
[('c', 3), ('b', 999)]

Continuing from above, you can save the LogDict log to file:

>>> l2.save('my.log')

A powerful additional feature is the append-only file (AOF) logging that enables storing changes continuously to disk.

>>> l = LogDict.load('my.log', logging=True)
>>> list(l.items())
[('c', 3), ('b', 999)]
>>> l['x'] = 123 # immediately persisted to disk

LogDict class with JSON log storage format and simple versioning.

class logdict.LogDict(*args, **kwargs)[source]

Map-like object with append-only-file logging for persistence.

All set and delete operations are written to append-only log and saved either real-time or upon request in line-based JSON format. Special version key and slice() can be used to implement versioning.

See collections.abc.MutableMapping for interface details.

Returns:

A class instance.

Return type:

LogDict

endLogging() None[source]

End AOF logging.

Does nothing if already closed, so safe to call multiple times.

classmethod load(filename: str, logging: bool = False) LogDict[source]

Create a LogDict, init from file and optionally start logging.

Parameters:
  • filename (str) – Filename, read into object if exists

  • logging (bool) – Set to True to have append-only file log, or to False to explicitly save() contents.

Returns:

A new object

Return type:

LogDict

save(filename: str) None[source]

Save log to file.

Use create() to restore from a saved log.

Parameters:

filename (str) – File to write to

slice(start: Optional[Tuple[Any, Any]] = None, end: Optional[Tuple[Any, Any]] = None) LogDict[source]

Create a new LogDict from a slice of operations log.

As all mutations are logged, you can easily use key changes as markers to construct a partial LogDict. Just specify beginning and end (or None to use log start/end). Deleting non-existing nodes is automatically skipped.

Parameters:
  • start (tuple) – A (key,value) pair for set, (key,) for del or None

  • end (tuple) – A (key,value) pair for set, (key,) for del or None

Returns:

A copy with slice of the log and appropriate content.

Return type:

LogDict

startLogging(filename: str) None[source]

Start AOF logging.

Does nothing if already logging, so safe to call multiple times.

Parameters:

filename (str) – File to write to