Skip to content

Persistent dictionary

asab.pdict.PersistentDict ¤

Bases: dict

The persistent dictionary works as the regular Python dictionary but the content of the dictionary is stored in the file. You cat think of a PersistentDict as a simple key-value store. It is not optimized for a frequent access. This class provides common dict interface.

Example
class MyApplication(asab.Application):
        async def main(self):
                pdict = asab.PersistentDict('./pdict.bin')
                pdict.load()
                counter = pdict['counter'] = pdict.setdefault('counter', 0) + 1
                print("Executed for {} times".format(counter))
                pdict.store()
                self.stop()

Warning

You must explicitly `load()` and `store()` content of the dictionary!

Warning

You can only store objects in the persistent dictionary that are serializable.
Source code in asab/pdict.py
class PersistentDict(dict):
	"""
	The persistent dictionary works as the regular Python dictionary but the content of the dictionary is stored in the file.
	You cat think of a `PersistentDict` as a simple [key-value store](https://en.wikipedia.org/wiki/Key-value_database).
	It is not optimized for a frequent access. This class provides common `dict` interface.

	Example:
		```python
		class MyApplication(asab.Application):
			async def main(self):
				pdict = asab.PersistentDict('./pdict.bin')
				pdict.load()
				counter = pdict['counter'] = pdict.setdefault('counter', 0) + 1
				print("Executed for {} times".format(counter))
				pdict.store()
				self.stop()
		```

	!!! warning
		You must explicitly `load()` and `store()` content of the dictionary!

	!!! warning
		You can only store objects in the persistent dictionary that are serializable.
	"""

	def __init__(self, path: str):
		"""Initialize persistent dictionary.

		Args:
			path (str): Path for the dictionary file.
		"""
		super().__init__()
		# Create directory, if needed
		dirname = os.path.dirname(path)
		if not os.path.isdir(dirname):
			os.makedirs(dirname)

		self._path = path

	def __delitem__(self, key):
		super().__delitem__(key)
		with shelve.open(self._path) as d:
			del d[key]

	def load(self) -> None:
		"""
		Load content of file as dictionary.
		"""
		with shelve.open(self._path) as d:
			for key, value in d.items():
				self[key] = value

	def store(self) -> None:
		"""
		Store content of persistent dictionary to a file.
		"""

		with shelve.open(self._path) as d:
			for key, value in self.items():
				d[key] = value

	def update(self, other={}, **kwds) -> None:
		"""
		Update persistent dictionary from mapping or iterable.

		Examples:
			```python
				>>> pdict.update({'foo': 'bar', 'moo': 'buzz'})
				>>> pdict.update(foo='bar', moo='buzz')
				>>> pdict.update([('foo','bar'),('moo','buzz')])
			```

		Args:
			other: Dictionary or iterable of 2-tuples of the form (key, value) to be updated.
		"""

		if isinstance(other, collections.abc.Mapping):
			for key in other:
				self[key] = other[key]
		elif hasattr(other, "keys"):
			for key in other.keys():
				self[key] = other[key]
		else:
			for key, value in other:
				self[key] = value

		for key, value in kwds.items():
			self[key] = value

__init__(path) ¤

Initialize persistent dictionary.

Parameters:

Name Type Description Default
path str

Path for the dictionary file.

required
Source code in asab/pdict.py
def __init__(self, path: str):
	"""Initialize persistent dictionary.

	Args:
		path (str): Path for the dictionary file.
	"""
	super().__init__()
	# Create directory, if needed
	dirname = os.path.dirname(path)
	if not os.path.isdir(dirname):
		os.makedirs(dirname)

	self._path = path

load() ¤

Load content of file as dictionary.

Source code in asab/pdict.py
def load(self) -> None:
	"""
	Load content of file as dictionary.
	"""
	with shelve.open(self._path) as d:
		for key, value in d.items():
			self[key] = value

store() ¤

Store content of persistent dictionary to a file.

Source code in asab/pdict.py
def store(self) -> None:
	"""
	Store content of persistent dictionary to a file.
	"""

	with shelve.open(self._path) as d:
		for key, value in self.items():
			d[key] = value

update(other={}, **kwds) ¤

Update persistent dictionary from mapping or iterable.

Examples:

        >>> pdict.update({'foo': 'bar', 'moo': 'buzz'})
        >>> pdict.update(foo='bar', moo='buzz')
        >>> pdict.update([('foo','bar'),('moo','buzz')])

Parameters:

Name Type Description Default
other

Dictionary or iterable of 2-tuples of the form (key, value) to be updated.

{}
Source code in asab/pdict.py
def update(self, other={}, **kwds) -> None:
	"""
	Update persistent dictionary from mapping or iterable.

	Examples:
		```python
			>>> pdict.update({'foo': 'bar', 'moo': 'buzz'})
			>>> pdict.update(foo='bar', moo='buzz')
			>>> pdict.update([('foo','bar'),('moo','buzz')])
		```

	Args:
		other: Dictionary or iterable of 2-tuples of the form (key, value) to be updated.
	"""

	if isinstance(other, collections.abc.Mapping):
		for key in other:
			self[key] = other[key]
	elif hasattr(other, "keys"):
		for key in other.keys():
			self[key] = other[key]
	else:
		for key, value in other:
			self[key] = value

	for key, value in kwds.items():
		self[key] = value