Skip to content

Commit d481a6e

Browse files
bugfix for get_obj_uri for dict objects + utility functions in RgbaColor
1 parent bd1143a commit d481a6e

5 files changed

Lines changed: 100 additions & 11 deletions

File tree

energyml-utils/example/attic/misc_test.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
from energyml.utils.epc_utils import get_dor_uris_from_obj
1+
import json
2+
3+
from energyml.utils.epc_utils import as_dor, get_dor_uris_from_obj
24
from energyml.utils.introspection import get_obj_uri, search_attribute_matching_type_with_path
35
from energyml.utils.serialization import (
6+
serialize_json,
47
serialize_xml,
58
read_energyml_xml_str,
69
read_energyml_xml_file,
@@ -25,8 +28,20 @@ def test_as_uri(xml_path: str):
2528
print("=" * 40)
2629
for p, o in search_attribute_matching_type_with_path(obj, "DataObjectreference"):
2730
print(f"{p}: {o} ({get_obj_uri(o)})\n")
31+
32+
33+
def test_serialize_dor(xml_path: str):
34+
obj = read_energyml_xml_file(xml_path)
35+
dor = as_dor(obj)
36+
print(dor)
37+
json_dict = json.loads(serialize_json(dor))
38+
print(json_dict)
39+
40+
print(get_obj_uri(json_dict))
2841

2942

3043
if __name__ == "__main__":
3144
# test_as_uri("rc/ContinuousProperty_1d34249c-4c4f-4705-870e-b5dea9c0d78e.xml")
32-
test_as_uri("rc/DiscreteProperty.xml")
45+
# test_as_uri("rc/DiscreteProperty.xml")
46+
test_serialize_dor("rc/DiscreteProperty.xml")
47+

energyml-utils/src/energyml/utils/data/helper.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,15 @@ def to_uint8(self) -> Tuple[int, int, int, int]:
19521952
int(round(self.b * 255)),
19531953
int(round(self.a * 255)),
19541954
)
1955+
1956+
def to_hex(self) -> str:
1957+
"""Return color as a hex string, e.g. '#RRGGBBAA'."""
1958+
return "#{:02X}{:02X}{:02X}{:02X}".format(*self.to_uint8())
1959+
1960+
def to_hex_argb(self) -> str:
1961+
"""Return color as a hex string in ARGB order, e.g. '#AARRGGBB'."""
1962+
r, g, b, a = self.to_uint8()
1963+
return "#{:02X}{:02X}{:02X}{:02X}".format(a, r, g, b)
19551964

19561965
@staticmethod
19571966
def from_hsv(hsv_obj: Any) -> "RgbaColor":
@@ -2328,3 +2337,45 @@ def read_graphical_rendering_info(
23282337
# because it drives label text, not colour/size - handle separately if needed.
23292338

23302339
return result if found else None
2340+
2341+
# def numpy_dtype_to_resqml_22_type(dtype: np.dtype, is_external: bool = True) -> Optional[str]:
2342+
# import energyml.resqml.v2_2.resqmlv2
2343+
# # ======== resqml22
2344+
# # BooleanXmlArrayList
2345+
# # FloatingPointXmlArrayList
2346+
# # IntegerXmlArrayList
2347+
# # BooleanXmlArray
2348+
# # StringXmlArray
2349+
# # FloatingPointXmlArray
2350+
# # IntegerXmlArray
2351+
# # ======= common23
2352+
# # BooleanExternalArray
2353+
# # StringExternalArray
2354+
# # FloatingPointExternalArray
2355+
# # IntegerExternalArray
2356+
# # ======= common21
2357+
# # Point2DHdf5Array
2358+
# # Point2dHdf5Array
2359+
# # Point3DHdf5Array
2360+
# # Point3dHdf5Array
2361+
# # StringHdf5Array
2362+
# # BooleanHdf5Array
2363+
# # DoubleHdf5Array
2364+
# # IntegerHdf5Array
2365+
2366+
# suffix = "ExternalArray" if is_external else "XmlArray"
2367+
# if np.issubdtype(dtype, np.bool_):
2368+
2369+
2370+
2371+
2372+
# def numpy_to_resqml_array(np_array: np.ndarray, resqlm_version: str = "2.2") -> Any:
2373+
# """
2374+
# Convert a NumPy array to a RESQML array object (e.g. RealArray, IntegerArray).
2375+
2376+
# :param np_array: The input NumPy array to convert.
2377+
# :param resqlm_version: The target RESQML version (default "2.2").
2378+
# :return: A RESQML array object containing the data from the NumPy array.
2379+
# """
2380+
# dtype = np_array.dtype
2381+

energyml-utils/src/energyml/utils/introspection.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,11 +1330,11 @@ def get_obj_version(obj: Any) -> Optional[str]:
13301330
# )
13311331
if isinstance(obj, dict):
13321332
for k in obj.keys():
1333-
if re.match(r"object_version|version_string", k, re.IGNORECASE):
1333+
if re.match(r"object_?version|version_?string", k, re.IGNORECASE):
13341334
return obj[k]
13351335
elif re.match(r"citation", k, re.IGNORECASE) and isinstance(obj[k], dict):
13361336
for ck in obj[k].keys():
1337-
if re.match(r"version_string", ck, re.IGNORECASE):
1337+
if re.match(r"version_?string", ck, re.IGNORECASE):
13381338
return obj[k][ck]
13391339
pass
13401340
return None
@@ -1390,7 +1390,12 @@ def get_obj_pkg_pkgv_type_uuid_version(
13901390
:param obj:
13911391
:return:
13921392
"""
1393-
pkg: Optional[str] = get_class_pkg(obj)
1393+
pkg: Optional[str] = None
1394+
try:
1395+
pkg = get_class_pkg(obj)
1396+
except AttributeError:
1397+
# could occur if obj is a dict
1398+
pass
13941399
pkg_v: Optional[str] = get_class_pkg_version(obj)
13951400
obj_type: Optional[str] = get_object_type_for_file_path_from_class(obj)
13961401
obj_uuid = get_obj_uuid(obj)
@@ -1400,24 +1405,33 @@ def get_obj_pkg_pkgv_type_uuid_version(
14001405
try:
14011406
ct = get_object_attribute_no_verif(obj, "content_type")
14021407
except:
1403-
pass
1404-
1408+
try:
1409+
ct = get_object_attribute_no_verif(obj, "ContentType")
1410+
except:
1411+
pass
1412+
14051413
if ct is not None:
14061414
ct_match = parse_content_type(ct)
14071415
if ct_match is not None:
14081416
pkg = ct_match.group("domain")
14091417
pkg_v = ct_match.group("domainVersion")
14101418
obj_type = ct_match.group("type")
14111419
else:
1420+
qt = None
14121421
try:
14131422
qt = get_object_attribute_no_verif(obj, "qualified_type")
1423+
except:
1424+
try:
1425+
qt = get_object_attribute_no_verif(obj, "QualifiedType")
1426+
except:
1427+
pass
1428+
1429+
if qt is not None:
14141430
qt_match = parse_qualified_type(qt)
14151431
if qt_match is not None:
14161432
pkg = qt_match.group("domain")
14171433
pkg_v = qt_match.group("domainVersion")
14181434
obj_type = qt_match.group("type")
1419-
except:
1420-
pass
14211435

14221436
# flattening version
14231437
if pkg_v is not None:

energyml-utils/src/energyml/utils/manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ def get_class_pkg(cls):
183183
match = p.search(cls.__module__)
184184
return match.group("pkg") # type: ignore
185185
except AttributeError as e:
186-
logging.error(f"Exception to get class package for '{cls}'")
187-
logging.error(
186+
logging.debug(f"Exception to get class package for '{cls}'")
187+
logging.debug(
188188
f"Error getting package for {type(cls)} -- {cls}",
189189
exc_info=True,
190190
stack_info=True, # This shows the full call stack including caller

energyml-utils/tests/test_introspection.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
This module contains comprehensive tests for introspection utilities used to
77
inspect, manipulate, and extract information from Energyml objects.
88
"""
9+
import json
910
from dataclasses import dataclass
1011
from energyml.utils.epc_utils import MimeType, as_dor
12+
from energyml.utils.serialization import serialize_json
1113
import pytest
1214
from typing import Any
1315

@@ -761,6 +763,13 @@ def test_get_obj_uri(triangulated_set_no_version, fault_interpretation):
761763
uri_str_fi_dataspace
762764
== f"eml:///dataspace('/MyDataspace/')/resqml20.obj_FaultInterpretation(uuid={fault_interpretation.uuid},version='{fault_interpretation.object_version}')"
763765
)
766+
767+
uri_dict_dor = str(get_obj_uri(json.loads(serialize_json(as_dor(fault_interpretation)))))
768+
769+
assert (
770+
uri_dict_dor
771+
== f"eml:///resqml20.obj_FaultInterpretation(uuid={fault_interpretation.uuid},version='{fault_interpretation.object_version}')"
772+
)
764773

765774

766775
# =============================================================================

0 commit comments

Comments
 (0)