nat.observability.utils.dict_utils#

Attributes#

Classes#

KeyedLock

A lock manager that provides an asyncio-compatible lock for each unique key.

AsyncDictionary

An asyncio-safe dictionary.

AsyncSafeWeakKeyDictionary

An asyncio-safe, weakly-referenced dictionary.

Functions#

merge_dicts(→ dict)

Merge two dictionaries, prioritizing non-null values from the first dictionary.

Module Contents#

logger#
class KeyedLock#

A lock manager that provides an asyncio-compatible lock for each unique key.

This allows for fine-grained locking based on arbitrary keys, so that concurrent operations on different keys do not block each other.

Attributes:

_locks (AsyncDictionary): A dictionary to store locks per key.

Initialize the KeyedLock with an internal AsyncSafeWeakKeyDictionary to store locks per key.

_locks: AsyncDictionary#
async get_lock(key: Any) collections.abc.AsyncGenerator[None]#

Async context manager to acquire a lock for a specific key.

Args:

key (Any): The key to lock on.

Yields:

None: Control is yielded while the lock is held.

async delete(key: Any) None#

Remove the lock associated with the given key, if it exists.

Args:

key (Any): The key whose lock should be removed.

async clear() None#

Remove all locks managed by this KeyedLock instance.

class AsyncDictionary#

An asyncio-safe dictionary.

This class wraps a regular dictionary with an asyncio.Lock to ensure thread safety for concurrent async operations.

Attributes:

_dict (dict): A dictionary to store the key-value pairs. _lock (asyncio.Lock): A lock to synchronize access to the dictionary.

Initialize the AsyncDictionary with a regular dictionary and an asyncio.Lock.

_dict: dict#
_lock#
async get(key: Any, default: Any | None = None) Any | None#

Get the value associated with the given key, or return default if not found.

Args:

key (Any): The key to look up. default (Any | None, optional): The value to return if key is not found. Defaults to None.

Returns:

Any | None: The value associated with the key, or default.

async keys() list[Any]#

Get a list of all keys currently in the dictionary.

Returns:

list[Any]: A list of keys.

async values() list[Any]#

Get a list of all values currently in the dictionary.

Returns:

list[Any]: A list of values.

async set(key: Any, value: Any) None#

Set the value for the given key, overwriting any existing value.

Args:

key (Any): The key to set. value (Any): The value to associate with the key.

async set_strict(key: Any, value: Any) None#

Set the value for the given key only if the key does not already exist.

Args:

key (Any): The key to set. value (Any): The value to associate with the key.

Raises:

ValueError: If the key already exists in the dictionary.

async delete(key: Any) None#

Remove the value associated with the given key, if it exists.

Args:

key (Any): The key to remove.

async delete_strict(key: Any) None#

Remove the value associated with the given key, raising an error if the key does not exist.

Args:

key (Any): The key to remove.

Raises:

ValueError: If the key does not exist in the dictionary.

async clear() None#

Remove all items from the dictionary.

async items() dict[Any, Any]#

Get a copy of the dictionary’s items as a regular dict.

Returns:

dict[Any, Any]: A copy of the dictionary’s items.

class AsyncSafeWeakKeyDictionary#

Bases: AsyncDictionary

An asyncio-safe, weakly-referenced dictionary.

This class wraps a WeakKeyDictionary with an asyncio.Lock to ensure thread safety for concurrent async operations.

Attributes:

_dict (WeakKeyDictionary): A dictionary to store the key-value pairs. _lock (asyncio.Lock): A lock to synchronize access to the dictionary.

Initialize the AsyncSafeWeakKeyDictionary with a WeakKeyDictionary and an asyncio.Lock.

_dict: weakref.WeakKeyDictionary#
_lock#
merge_dicts(dict1: dict, dict2: dict) dict#

Merge two dictionaries, prioritizing non-null values from the first dictionary.

Args:

dict1 (dict): First dictionary (higher priority) dict2 (dict): Second dictionary (lower priority)

Returns:

dict: Merged dictionary with non-null values from dict1 taking precedence