Skip to content

Commit cfe234c

Browse files
committed
Fix metadata serialization
1 parent f064ec6 commit cfe234c

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

src/mdio/core/v1/_serializer.py

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,41 @@ def make_coordinate(
4444
dimensions: list[NamedDimension | str],
4545
data_type: ScalarType | StructuredType,
4646
long_name: str = None,
47-
metadata: list[AllUnits | UserAttributes] | None = None,
47+
metadata: list[AllUnits | UserAttributes] | dict[str, Any] | None = None,
4848
) -> Coordinate:
4949
"""Create a Coordinate with the given name, dimensions, data_type, and metadata."""
50-
coordinate_dict = {
51-
"name": name,
52-
"longName": long_name,
53-
"dimensions": dimensions,
54-
"dataType": data_type,
55-
"metadata": metadata,
56-
}
57-
return Coordinate(**coordinate_dict)
50+
# Build metadata list of AllUnits or UserAttributes to satisfy Coordinate.schema
51+
coord_meta_list: list[AllUnits | UserAttributes] | None = None
52+
if metadata is not None:
53+
items: list[AllUnits | UserAttributes] = []
54+
# single dict input
55+
if isinstance(metadata, dict):
56+
if "unitsV1" in metadata:
57+
items.append(AllUnits(**{"unitsV1": metadata["unitsV1"]}))
58+
if "attributes" in metadata:
59+
items.append(UserAttributes(**{"attributes": metadata["attributes"]}))
60+
# list input may contain dict or model instances
61+
elif isinstance(metadata, list):
62+
for md in metadata:
63+
if isinstance(md, AllUnits) or isinstance(md, UserAttributes):
64+
items.append(md)
65+
elif isinstance(md, dict):
66+
if "unitsV1" in md:
67+
items.append(AllUnits(**{"unitsV1": md["unitsV1"]}))
68+
if "attributes" in md:
69+
items.append(UserAttributes(**{"attributes": md["attributes"]}))
70+
else:
71+
raise TypeError(f"Unsupported metadata element type for coordinate: {type(md)}")
72+
else:
73+
raise TypeError(f"Unsupported metadata type for coordinate: {type(metadata)}")
74+
coord_meta_list = items or None
75+
return Coordinate(
76+
name=name,
77+
longName=long_name,
78+
dimensions=dimensions,
79+
dataType=data_type,
80+
metadata=coord_meta_list,
81+
)
5882

5983

6084
def make_variable( # noqa: PLR0913 PLR0912
@@ -115,7 +139,12 @@ def _to_serializable(val: object) -> dict[str, Any] | object:
115139
var_metadata = VariableMetadata(**converted_dict)
116140

117141
elif isinstance(metadata, VariableMetadata):
118-
var_metadata = metadata
142+
# Flatten any single-element list fields in metadata
143+
md = metadata.model_dump(by_alias=True, exclude_none=True)
144+
for key, value in list(md.items()):
145+
if isinstance(value, list) and len(value) == 1:
146+
md[key] = value[0]
147+
var_metadata = VariableMetadata(**md)
119148

120149
else:
121150
msg = f"Unsupported metadata type: {type(metadata)}"

0 commit comments

Comments
 (0)