Currently, the pydantic models for nodes contain
- a generic attributes Dict:
|
attributes: Optional[Dict[str, Any]] = MetadataField( |
- and any actual node attributes are validated at the "root level", by overloading the Model, e.g. for BandsData:
|
class Model(KpointsData.Model): |
Some possible drawback of this are
-
conceptually, the pydantic model doesn't reflect the attribute location of the ORM objects (so, the attributes, are at root level).
-
When one serializes a node, you get duplication of the attributes at root level and also in the attributes dict, e.g.
> n = orm.Int(1)
> n.serialize()
{'pk': None,
'uuid': '2bec1c81-d452-4421-a7dd-7691e8c5133d',
'node_type': 'data.core.int.Int.',
...
'attributes': {'value': 1},
'value': 1}
For integers this does not look too bad, but for nodes with a lot of attributes (e.g. Calcjobs, BandsData), it gets quite messy.
-
(vaguely related) the new restapi GET and POST models are not consistent: one has to POST with attributes at root level, while when you GET a node, the attributes will be nested inside attributes dict.
An alternative solution would be to reflect the attribute structure also in the Pydantic models. So e.g. one could define something a separate AttributesModel that can be overloaded by children:
class Node(Entity['BackendNode', NodeCollection['Node']], metaclass=AbstractNodeMeta):
...
class AttributesModel(BaseModel):
"""Generic attributes with everything allowed."""
class Config:
extra = 'allow' # potentially 'forbid' might also make sense.
class Model(Entity.Model):
...
attributes: Optional['AttributesModel'] = MetadataField(...)
class StructureData(Node):
...
class AttributesModel(Node.AttributesModel):
"""Overload structure attributes."""
kinds: List[Dict[str, Any]]
sites: List[Dict[str, Any]]
cell: List[List[float]]
pbc: List[bool]
...
@edan-bainglass
Currently, the pydantic models for nodes contain
aiida-core/src/aiida/orm/nodes/node.py
Line 240 in d123ac2
aiida-core/src/aiida/orm/nodes/data/array/bands.py
Line 216 in d123ac2
Some possible drawback of this are
conceptually, the pydantic model doesn't reflect the attribute location of the ORM objects (so, the attributes, are at root level).
When one serializes a node, you get duplication of the attributes at root level and also in the attributes dict, e.g.
For integers this does not look too bad, but for nodes with a lot of attributes (e.g. Calcjobs, BandsData), it gets quite messy.
(vaguely related) the new restapi GET and POST models are not consistent: one has to POST with attributes at root level, while when you GET a node, the attributes will be nested inside
attributesdict.An alternative solution would be to reflect the attribute structure also in the Pydantic models. So e.g. one could define something a separate
AttributesModelthat can be overloaded by children:@edan-bainglass