IDS peak ICV v1.2.0
Loading...
Searching...
No Matches
metadata.py
Go to the documentation of this file.
1from typing import Any, Dict, Type, TypeVar, List
2
3from ids_peak_common.datatypes.metadata_key import MetadataKey
4from ids_peak_common.exceptions import OutOfRangeException, InvalidCastException
5
6T = TypeVar("T")
7
8
9class Metadata:
10 """!
11 @brief
12 A type-safe container for metadata key-value pairs.
13
14 This class provides a flexible mechanism for storing and retrieving metadata:
15 - Arbitrary runtime keys (string string_values).
16 - Strongly typed keys defined in a schema.
17
18 Values are stored in a Python dictionary but accessed with additional
19 safety checks to ensure type correctness.
20
21 Example usage::
22
23 metadata = Metadata()
24 metadata.set_value_by_key(MetadataKey.DEVICE_FRAME_ID, 1)
25 print(metadata.get_value_by_key(MetadataKey.DEVICE_FRAME_ID)) # outputs: 1
26 print(metadata.has_entry_by_key(MetadataKey.DEVICE_FRAME_ID)) # outputs: True
27
28 @ingroup ids_peak_common_python_types
29 """
30
31 def __init__(self) -> None:
32 """!
33 @brief Initialize an empty metadata container."""
34 self._data: Dict[str, Any] = {}
35
36 def set_value_by_name(self, key: str, value: Any) -> None:
37 """!
38 @brief
39 Store a value using a string-based key.
40
41 @param key: Runtime string string_value.
42 @param value: Value to store.
43 """
44 self._data[key] = value
45
46 def has_entry_by_name(self, key: str) -> bool:
47 """!
48 @brief
49 Check if a string key is present in the metadata.
50
51 @param key: The metadata key.
52 @return True if the key exists, False otherwise.
53 """
54 return key in self._data
55
56 def try_get_value_by_name(self, key: str) -> Any:
57 """!
58 @brief
59 Retrieve a value by string key, returning None if not found.
60
61 @param key: The metadata key.
62 @return The stored value if found, otherwise None.
63 """
64 return self._data.get(key, None)
65
66 def get_value_by_name(self, expected_type: Type[T], key: str) -> T:
67 """!
68 @brief
69 Retrieve the value for a key and validate that it is of the expected type.
70
71 @param expected_type: The expected type of the stored value.
72 @param key: The metadata key.
73 @exception OutOfRangeException: If the key does not exist.
74 @exception InvalidCastException: If the stored type does not match.
75 @return The stored value cast to the expected type.
76 """
77 if key not in self._data:
78 raise OutOfRangeException(f"There is no value named '{key}'")
79
80 value = self._data[key]
81 if not isinstance(value, expected_type):
83 f"Value for key '{key}' is of type {type(value).__name__}, "
84 f"expected {expected_type.__name__}"
85 )
86 return value
87
88 def set_value_by_key(self, key: MetadataKey, value: Any) -> None:
89 """!
90 @brief
91 Store a value using a strongly typed metadata key.
92
93 @param key: A MetadataKey object containing key name and expected type.
94 @param value: The value to store.
95 @exception InvalidCastException: If the value type does not match the trait type.
96 """
97 if not isinstance(value, key.type):
99 f"Value for key '{key.string_value}' must be of type {key.type.__name__}, "
100 f"got {type(value).__name__}"
101 )
102 self._data[key.string_value] = value
103
104 def has_entry_by_key(self, key: MetadataKey) -> bool:
105 """!
106 @brief
107 Check if a strongly typed metadata key is present and matches the expected type.
108
109 @param key: A MetadataKey object.
110 @return True if the key exists and type matches, False otherwise.
111 """
112 if key.string_value not in self._data:
113 return False
114 return isinstance(self._data[key.string_value], key.type)
115
116 def get_value_by_key(self, key: MetadataKey) -> Any:
117 """!
118 @brief
119 Retrieve the value of a strongly typed metadata key.
120
121 @param key: A MetadataKey object.
122 @exception OutOfRangeException: If the key does not exist.
123 @exception InvalidCastException: If the type does not match.
124 @return The stored value.
125 """
126 if key.string_value not in self._data:
127 raise OutOfRangeException(f"Key '{key.string_value}' not found")
128
129 value = self._data[key.string_value]
130 if not isinstance(value, key.type):
132 f"Value for key '{key.string_value}' is of type {type(value).__name__}, "
133 f"expected {key.type.__name__}"
134 )
135 return value
136
137 def get_key_names(self) -> List[str]:
138 """!
139 @brief
140 Returns a list of metadata key names.
141
142 @return A list of metadata key names
143 """
144 return list(self._data.keys())
145
146 def __eq__(self, other: Any) -> bool:
147 """!
148 @brief
149 Check if two metadata are equal.
150
151 @param other: Another Metadata object
152
153 @return True if metadata are equal, False otherwise
154 """
155 if isinstance(other, Metadata):
156 return self._data == other._data
157 return False
158
159 def __ne__(self, other: Any) -> bool:
160 """!
161 @brief
162 Check if two metadata are not equal.
163
164 @param other: Another metadata object
165
166 @return True if metadata are not equal, False otherwise
167 """
168 return not self.__eq__(other)
169
170 def __str__(self) -> str:
171 """!
172 @brief
173 Return a human-readable string of metadata keys and values.
174
175 Example:
176 { "DeviceFrameID": 42, "DeviceTimestamp": 1695472000, "custom_data": "xyz" }
177 """
178 items = [f'"{k}": {v!r}' for k, v in self._data.items()]
179
180 return f"( {', '.join(items)} )"
181
182 def __repr__(self) -> str:
183 """!
184 @brief
185 Return an unambiguous string of the Metadata object.
186 """
187 return f"{self.__class__.__name__}{str(self)}"
A type-safe container for metadata key-value pairs.
Definition metadata.py:9
bool has_entry_by_key(self, MetadataKey key)
Check if a strongly typed metadata key is present and matches the expected type.
Definition metadata.py:104
List[str] get_key_names(self)
Returns a list of metadata key names.
Definition metadata.py:137
bool has_entry_by_name(self, str key)
Check if a string key is present in the metadata.
Definition metadata.py:46
Any get_value_by_key(self, MetadataKey key)
Retrieve the value of a strongly typed metadata key.
Definition metadata.py:116
T get_value_by_name(self, Type[T] expected_type, str key)
Retrieve the value for a key and validate that it is of the expected type.
Definition metadata.py:66
None set_value_by_name(self, str key, Any value)
Store a value using a string-based key.
Definition metadata.py:36
None set_value_by_key(self, MetadataKey key, Any value)
Store a value using a strongly typed metadata key.
Definition metadata.py:88
Any try_get_value_by_name(self, str key)
Retrieve a value by string key, returning None if not found.
Definition metadata.py:56
bool __ne__(self, Any other)
Check if two metadata are not equal.
Definition metadata.py:159
None __init__(self)
Initialize an empty metadata container.
Definition metadata.py:31
str __str__(self)
Return a human-readable string of metadata keys and values.
Definition metadata.py:170
str __repr__(self)
Return an unambiguous string of the Metadata object.
Definition metadata.py:182
bool __eq__(self, Any other)
Check if two metadata are equal.
Definition metadata.py:146
Thrown when a cast to an incompatible type is attempted.
Definition exceptions.py:53
Thrown when a parameter is outside the valid range.
Definition exceptions.py:79