1from typing
import Any, Dict, Type, TypeVar, List
3from ids_peak_common.datatypes.metadata_key
import MetadataKey
10 from typing
import get_origin, get_args
12 expected_type = key.type
13 origin = get_origin(expected_type)
16 inner_type = get_args(expected_type)[0]
18 actual_origin = type(value)
19 if not actual_origin
is origin:
20 raise InvalidCastException(
21 f
"Value for key '{key.string_value}' must be of type {origin.__name__}, "
22 f
"got {actual_origin.__name__}"
26 if not isinstance(v, inner_type):
27 raise InvalidCastException(
28 f
"Inner value for key '{key.string_value}' must be of type {inner_type.__name__}, "
29 f
"got {type(v).__name__} (value={v})"
32 elif not isinstance(value, expected_type):
33 raise InvalidCastException(
34 f
"Value for key '{key.string_value}' must be of type {expected_type.__name__}, "
35 f
"got {type(value).__name__}"
42 A type-safe container for metadata key-value pairs.
44 This class provides a flexible mechanism for storing and retrieving metadata:
45 - Arbitrary runtime keys (string string_values).
46 - Strongly typed keys defined in a schema.
48 Values are stored in a Python dictionary but accessed with additional
49 safety checks to ensure type correctness.
54 metadata.set_value_by_key(MetadataKey.DEVICE_FRAME_ID, 1)
55 print(metadata.get_value_by_key(MetadataKey.DEVICE_FRAME_ID)) # outputs: 1
56 print(metadata.has_entry_by_key(MetadataKey.DEVICE_FRAME_ID)) # outputs: True
58 @ingroup ids_peak_common_python_types
63 @brief Initialize an empty metadata container."""
69 Store a value using a string-based key.
71 @param key: Runtime string string_value.
72 @param value: Value to store.
74 self.
_data[key] = value
79 Check if a string key is present in the metadata.
81 @param key: The metadata key.
82 @return True if the key exists, False otherwise.
84 return key
in self.
_data
89 Retrieve a value by string key, returning None if not found.
91 @param key: The metadata key.
92 @return The stored value if found, otherwise None.
94 return self.
_data.get(key,
None)
99 Retrieve the value for a key and validate that it is of the expected type.
101 @param expected_type: The expected type of the stored value.
102 @param key: The metadata key.
103 @exception OutOfRangeException: If the key does not exist.
104 @exception InvalidCastException: If the stored type does not match.
105 @return The stored value cast to the expected type.
107 if key
not in self.
_data:
108 raise OutOfRangeException(f
"There is no value named '{key}'")
110 value = self.
_data[key]
111 if not isinstance(value, expected_type):
112 raise InvalidCastException(
113 f
"Value for key '{key}' is of type {type(value).__name__}, "
114 f
"expected {expected_type.__name__}"
121 Store a value using a strongly typed metadata key.
123 @param key: A MetadataKey object containing key name and expected type.
124 @param value: The value to store.
125 @exception InvalidCastException: If the value type does not match the trait type.
129 self.
_data[key.string_value] = value
134 Check if a strongly typed metadata key is present and matches the expected type.
136 @param key: A MetadataKey object.
137 @return True if the key exists and type matches, False otherwise.
139 if key.string_value
not in self.
_data:
142 from typing
import get_origin, get_args
144 expected_type = key.type
145 origin = get_origin(expected_type)
146 args = get_args(expected_type)
148 if (origin
is list)
and args:
149 element_type = args[0]
150 return all(isinstance(v, element_type)
for v
in self.
_data[key.string_value])
152 return isinstance(self.
_data[key.string_value], key.type)
157 Retrieve the value of a strongly typed metadata key.
159 @param key: A MetadataKey object.
160 @exception OutOfRangeException: If the key does not exist.
161 @exception InvalidCastException: If the type does not match.
162 @return The stored value.
164 if key.string_value
not in self.
_data:
165 raise OutOfRangeException(f
"Key '{key.string_value}' not found")
167 value = self.
_data[key.string_value]
174 Returns a list of metadata key names.
176 @return A list of metadata key names
178 return list(self.
_data.keys())
183 Check if two metadata are equal.
185 @param other: Another Metadata object
187 @return True if metadata are equal, False otherwise
189 if isinstance(other, Metadata):
190 return self.
_data == other._data
196 Check if two metadata are not equal.
198 @param other: Another metadata object
200 @return True if metadata are not equal, False otherwise
202 return not self.
__eq__(other)
207 Return a human-readable string of metadata keys and values.
210 { "DeviceFrameID": 42, "DeviceTimestamp": 1695472000, "custom_data": "xyz" }
212 items = [f
'"{k}": {v!r}' for k, v
in self.
_data.items()]
214 return f
"( {', '.join(items)} )"
219 Return an unambiguous string of the Metadata object.
221 return f
"{self.__class__.__name__}{str(self)}"