aiida.orm.nodes package¶
Module with Node sub classes for data and processes.
Submodules¶
Package for node ORM classes.
- class aiida.orm.nodes.node.Node(backend: Optional[StorageBackend] = None, user: Optional[aiida.orm.users.User] = None, computer: Optional[aiida.orm.computers.Computer] = None, **kwargs: Any)[source]¶
Bases:
aiida.orm.entities.Entity
[BackendNode
],aiida.orm.nodes.repository.NodeRepositoryMixin
,aiida.orm.entities.EntityAttributesMixin
,aiida.orm.entities.EntityExtrasMixin
Base class for all nodes in AiiDA.
Stores attributes starting with an underscore.
Caches files and attributes before the first save, and saves everything only on store(). After the call to store(), attributes cannot be changed.
Only after storing (or upon loading from uuid) extras can be modified and in this case they are directly set on the db.
In the plugin, also set the _plugin_type_string, to be set in the DB in the ‘type’ field.
- Collection¶
alias of
aiida.orm.nodes.node.NodeCollection
- __abstractmethods__ = frozenset({})¶
- __annotations__ = {'_HASH_EXTRA_KEY': <class 'str'>, '_VALID_CACHE_KEY': <class 'str'>, '_hash_ignored_attributes': typing.Tuple[str, ...], '_incoming_cache': typing.Union[typing.List[aiida.orm.utils.links.LinkTriple], NoneType], '_logger': typing.Union[logging.Logger, NoneType], '_plugin_type_string': typing.ClassVar[str], '_query_type_string': typing.ClassVar[str], '_updatable_attributes': typing.Tuple[str, ...]}¶
- __deepcopy__(memo)[source]¶
Deep copying a Node is not supported in general, but only for the Data sub class.
- __eq__(other: Any) bool [source]¶
Fallback equality comparison by uuid (can be overwritten by specific types)
- __init__(backend: Optional[StorageBackend] = None, user: Optional[aiida.orm.users.User] = None, computer: Optional[aiida.orm.computers.Computer] = None, **kwargs: Any) None [source]¶
- Parameters
backend_entity – the backend model supporting this entity
- __module__ = 'aiida.orm.nodes.node'¶
- __orig_bases__ = (aiida.orm.entities.Entity[ForwardRef('BackendNode')], <class 'aiida.orm.nodes.repository.NodeRepositoryMixin'>, <class 'aiida.orm.entities.EntityAttributesMixin'>, <class 'aiida.orm.entities.EntityExtrasMixin'>)¶
- __parameters__ = ()¶
- _abc_impl = <_abc_data object>¶
- _add_incoming_cache(source: aiida.orm.nodes.node.Node, link_type: aiida.common.links.LinkType, link_label: str) None [source]¶
Add an incoming link to the cache.
- Parameters
source – the node from which the link is coming
link_type – the link type
link_label – the link label
- Raises
aiida.common.UniquenessError – if the given link triple already exists in the cache
- _add_outputs_from_cache(cache_node: aiida.orm.nodes.node.Node) None [source]¶
Replicate the output links and nodes from the cached node onto this node.
- _cachable = False¶
- _get_hash(ignore_errors: bool = True, **kwargs: Any) Optional[str] [source]¶
Return the hash for this node based on its attributes.
This will always work, even before storing.
- Parameters
ignore_errors – return
None
onaiida.common.exceptions.HashingError
(logging the exception)
- _get_objects_to_hash() List[Any] [source]¶
Return a list of objects which should be included in the hash.
- _get_same_node() Optional[aiida.orm.nodes.node.Node] [source]¶
Returns a stored node from which the current Node can be cached or None if it does not exist
If a node is returned it is a valid cache, meaning its _aiida_hash extra matches self.get_hash(). If there are multiple valid matches, the first one is returned. If no matches are found, None is returned.
- Returns
a stored Node instance with the same hash as this code or None
Note: this should be only called on stored nodes, or internally from .store() since it first calls clean_value() on the attributes to normalise them.
- _incoming_cache: Optional[List[aiida.orm.utils.links.LinkTriple]] = None¶
- _iter_all_same_nodes(allow_before_store=False) Iterator[aiida.orm.nodes.node.Node] [source]¶
Returns an iterator of all same nodes.
Note: this should be only called on stored nodes, or internally from .store() since it first calls clean_value() on the attributes to normalise them.
- _logger: Optional[logging.Logger] = <Logger aiida.orm.nodes.node.Node (REPORT)>¶
- _storable = False¶
- _store(with_transaction: bool = True, clean: bool = True) aiida.orm.nodes.node.Node [source]¶
Store the node in the database while saving its attributes and repository directory.
- Parameters
with_transaction – if False, do not use a transaction because the caller will already have opened one.
clean – boolean, if True, will clean the attributes and extras before attempting to store
- _store_from_cache(cache_node: aiida.orm.nodes.node.Node, with_transaction: bool) None [source]¶
Store this node from an existing cache node.
Note
With the current implementation of the backend repository, which automatically deduplicates the content that it contains, we do not have to copy the contents of the source node. Since the content should be exactly equal, the repository will already contain it and there is nothing to copy. We simply replace the current
repository
instance with a clone of that of the source node, which does not actually copy any files.
- _unstorable_message = 'only Data, WorkflowNode, CalculationNode or their subclasses can be stored'¶
- _validate() bool [source]¶
Validate information stored in Node object.
For the
Node
base class, this check is always valid. Subclasses can override this method to perform additional checks and should usually callsuper()._validate()
first!This method is called automatically before storing the node in the DB. Therefore, use
get_attribute()
and similar methods that automatically read either from the DB or from the internal attribute cache.
- add_comment(content: str, user: Optional[aiida.orm.users.User] = None) aiida.orm.comments.Comment [source]¶
Add a new comment.
- Parameters
content – string with comment
user – the user to associate with the comment, will use default if not supplied
- Returns
the newly created comment
- add_incoming(source: aiida.orm.nodes.node.Node, link_type: aiida.common.links.LinkType, link_label: str) None [source]¶
Add a link of the given type from a given node to ourself.
- Parameters
source – the node from which the link is coming
link_type – the link type
link_label – the link label
- Raises
TypeError – if source is not a Node instance or link_type is not a LinkType enum
ValueError – if the proposed link is invalid
- class_node_type = ''¶
- property computer: Optional[aiida.orm.computers.Computer]¶
Return the computer of this node.
- property ctime: datetime.datetime¶
Return the node ctime.
- Returns
the ctime
- get_all_same_nodes() List[aiida.orm.nodes.node.Node] [source]¶
Return a list of stored nodes which match the type and hash of the current node.
All returned nodes are valid caches, meaning their _aiida_hash extra matches self.get_hash().
Note: this can be called only after storing a Node (since at store time attributes will be cleaned with clean_value and the hash should become idempotent to the action of serialization/deserialization)
- get_cache_source() Optional[str] [source]¶
Return the UUID of the node that was used in creating this node from the cache, or None if it was not cached.
- Returns
source node UUID or None
- get_comment(identifier: int) aiida.orm.comments.Comment [source]¶
Return a comment corresponding to the given identifier.
- Parameters
identifier – the comment pk
- Raises
aiida.common.NotExistent – if the comment with the given id does not exist
aiida.common.MultipleObjectsError – if the id cannot be uniquely resolved to a comment
- Returns
the comment
- get_comments() List[aiida.orm.comments.Comment] [source]¶
Return a sorted list of comments for this node.
- Returns
the list of comments, sorted by pk
- get_description() str [source]¶
Return a string with a description of the node.
- Returns
a description string
- get_hash(ignore_errors: bool = True, **kwargs: Any) Optional[str] [source]¶
Return the hash for this node based on its attributes.
- Parameters
ignore_errors – return
None
onaiida.common.exceptions.HashingError
(logging the exception)
- get_incoming(node_class: Optional[Type[aiida.orm.nodes.node.Node]] = None, link_type: Union[aiida.common.links.LinkType, Sequence[aiida.common.links.LinkType]] = (), link_label_filter: Optional[str] = None, only_uuid: bool = False) aiida.orm.utils.links.LinkManager [source]¶
Return a list of link triples that are (directly) incoming into this node.
- Parameters
node_class – If specified, should be a class or tuple of classes, and it filters only elements of that specific type (or a subclass of ‘type’)
link_type – If specified should be a string or tuple to get the inputs of this link type, if None then returns all inputs of all link types.
link_label_filter – filters the incoming nodes by its link label. Here wildcards (% and _) can be passed in link label filter as we are using “like” in QB.
only_uuid – project only the node UUID instead of the instance onto the NodeTriple.node entries
- get_outgoing(node_class: Optional[Type[aiida.orm.nodes.node.Node]] = None, link_type: Union[aiida.common.links.LinkType, Sequence[aiida.common.links.LinkType]] = (), link_label_filter: Optional[str] = None, only_uuid: bool = False) aiida.orm.utils.links.LinkManager [source]¶
Return a list of link triples that are (directly) outgoing of this node.
- Parameters
node_class – If specified, should be a class or tuple of classes, and it filters only elements of that specific type (or a subclass of ‘type’)
link_type – If specified should be a string or tuple to get the inputs of this link type, if None then returns all outputs of all link types.
link_label_filter – filters the outgoing nodes by its link label. Here wildcards (% and _) can be passed in link label filter as we are using “like” in QB.
only_uuid – project only the node UUID instead of the instance onto the NodeTriple.node entries
- get_stored_link_triples(node_class: Optional[Type[aiida.orm.nodes.node.Node]] = None, link_type: Union[aiida.common.links.LinkType, Sequence[aiida.common.links.LinkType]] = (), link_label_filter: Optional[str] = None, link_direction: str = 'incoming', only_uuid: bool = False) List[aiida.orm.utils.links.LinkTriple] [source]¶
Return the list of stored link triples directly incoming to or outgoing of this node.
Note this will only return link triples that are stored in the database. Anything in the cache is ignored.
- Parameters
node_class – If specified, should be a class, and it filters only elements of that (subclass of) type
link_type – Only get inputs of this link type, if empty tuple then returns all inputs of all link types.
link_label_filter – filters the incoming nodes by its link label. This should be a regex statement as one would pass directly to a QueryBuilder filter statement with the ‘like’ operation.
link_direction – incoming or outgoing to get the incoming or outgoing links, respectively.
only_uuid – project only the node UUID instead of the instance onto the NodeTriple.node entries
- has_cached_links() bool [source]¶
Feturn whether there are unstored incoming links in the cache.
- Returns
boolean, True when there are links in the incoming cache, False otherwise
- initialize() None [source]¶
Initialize internal variables for the backend node
This needs to be called explicitly in each specific subclass implementation of the init.
- property is_created_from_cache: bool¶
Return whether this node was created from a cached node.
- Returns
boolean, True if the node was created by cloning a cached node, False otherwise
- property is_valid_cache: bool¶
Hook to exclude certain
Node
classes from being considered a valid cache.The base class assumes that all node instances are valid to cache from, unless the
_VALID_CACHE_KEY
extra has been set toFalse
explicitly. Subclasses can override this property with more specific logic, but should probably also consider the value returned by this base class.
- property logger: Optional[logging.Logger]¶
Return the logger configured for this Node.
- Returns
Logger object
- property mtime: datetime.datetime¶
Return the node mtime.
- Returns
the mtime
- objects¶
A class that, when used as a decorator, works as if the two decorators @property and @classmethod where applied together (i.e., the object works as a property, both for the Class and for any of its instance; and is called with the class cls rather than with the instance as its first argument).
- remove_comment(identifier: int) None [source]¶
Delete an existing comment.
- Parameters
identifier – the comment pk
- property repository_metadata: Dict[str, Any]¶
Return the node repository metadata.
- Returns
the repository metadata
- store(with_transaction: bool = True) aiida.orm.nodes.node.Node [source]¶
Store the node in the database while saving its attributes and repository directory.
After being called attributes cannot be changed anymore! Instead, extras can be changed only AFTER calling this store() function.
- Note
After successful storage, those links that are in the cache, and for which also the parent node is already stored, will be automatically stored. The others will remain unstored.
- Parameters
with_transaction – if False, do not use a transaction because the caller will already have opened one.
- store_all(with_transaction: bool = True) aiida.orm.nodes.node.Node [source]¶
Store the node, together with all input links.
Unstored nodes from cached incoming linkswill also be stored.
- Parameters
with_transaction – if False, do not use a transaction because the caller will already have opened one.
- update_comment(identifier: int, content: str) None [source]¶
Update the content of an existing comment.
- Parameters
identifier – the comment pk
content – the new comment content
- Raises
aiida.common.NotExistent – if the comment with the given id does not exist
aiida.common.MultipleObjectsError – if the id cannot be uniquely resolved to a comment
- property user: aiida.orm.users.User¶
Return the user of this node.
- validate_incoming(source: aiida.orm.nodes.node.Node, link_type: aiida.common.links.LinkType, link_label: str) None [source]¶
Validate adding a link of the given type from a given node to ourself.
This function will first validate the types of the inputs, followed by the node and link types and validate whether in principle a link of that type between the nodes of these types is allowed.
Subsequently, the validity of the “degree” of the proposed link is validated, which means validating the number of links of the given type from the given node type is allowed.
- Parameters
source – the node from which the link is coming
link_type – the link type
link_label – the link label
- Raises
TypeError – if source is not a Node instance or link_type is not a LinkType enum
ValueError – if the proposed link is invalid
- validate_outgoing(target: aiida.orm.nodes.node.Node, link_type: aiida.common.links.LinkType, link_label: str) None [source]¶
Validate adding a link of the given type from ourself to a given node.
The validity of the triple (source, link, target) should be validated in the validate_incoming call. This method will be called afterwards and can be overriden by subclasses to add additional checks that are specific to that subclass.
- Parameters
target – the node to which the link is going
link_type – the link type
link_label – the link label
- Raises
TypeError – if target is not a Node instance or link_type is not a LinkType enum
ValueError – if the proposed link is invalid
- validate_storability() None [source]¶
Verify that the current node is allowed to be stored.
- Raises
aiida.common.exceptions.StoringNotAllowed – if the node does not match all requirements for storing
- verify_are_parents_stored() None [source]¶
Verify that all parent nodes are already stored.
- Raises
aiida.common.ModificationNotAllowed – if one of the source nodes of incoming links is not stored.
- class aiida.orm.nodes.node.NodeCollection(entity_class: Type[aiida.orm.entities.EntityType], backend: Optional[StorageBackend] = None)[source]¶
Bases:
aiida.orm.entities.Collection
[aiida.orm.nodes.node.NodeType
],Generic
[aiida.orm.nodes.node.NodeType
]The collection of nodes.
- __abstractmethods__ = frozenset({})¶
- __module__ = 'aiida.orm.nodes.node'¶
- __orig_bases__ = (aiida.orm.entities.Collection[~NodeType], typing.Generic[~NodeType])¶
- __parameters__ = (~NodeType,)¶
- _abc_impl = <_abc_data object>¶
- static _entity_base_cls() Type[aiida.orm.nodes.node.Node] [source]¶
The allowed entity class or subclasses thereof.
- delete(pk: int) None [source]¶
Delete a Node from the collection with the given id
- Parameters
pk – the node id
- iter_repo_keys(filters: Optional[dict] = None, subclassing: bool = True, batch_size: int = 100) Iterator[str] [source]¶
Iterate over all repository object keys for this
Node
classNote
keys will not be deduplicated, wrap in a
set
to achieve this- Parameters
filters – Filters for the node query
subclassing – Whether to include subclasses of the given class
batch_size – The number of nodes to fetch data for at once
Interface to the file repository of a node instance.
- class aiida.orm.nodes.repository.NodeRepositoryMixin[source]¶
Bases:
object
Interface to the file repository of a node instance.
This is the compatibility layer between the Node class and the Repository class. The repository in principle has no concept of immutability, so it is implemented here. Any mutating operations will raise a ModificationNotAllowed exception if the node is stored. Otherwise the operation is just forwarded to the repository instance.
The repository instance keeps an internal mapping of the file hierarchy that it maintains, starting from an empty hierarchy if the instance was constructed normally, or from a specific hierarchy if reconstructred through the
Repository.from_serialized
classmethod. This is only the case for stored nodes, because unstored nodes do not have any files yet when they are constructed. Once the node get’s stored, the repository is asked to serialize its metadata contents which is then stored in therepository_metadata
attribute of the node in the database. This layer explicitly does not update the metadata of the node on a mutation action. The reason is that for stored nodes these actions are anyway forbidden and for unstored nodes, the final metadata will be stored in one go, once the node is stored, so there is no need to keep updating the node metadata intermediately. Note that this does mean thatrepository_metadata
does not give accurate information as long as the node is not yet stored.- __dict__ = mappingproxy({'__module__': 'aiida.orm.nodes.repository', '__doc__': "Interface to the file repository of a node instance.\n\n This is the compatibility layer between the `Node` class and the `Repository` class. The repository in principle has\n no concept of immutability, so it is implemented here. Any mutating operations will raise a `ModificationNotAllowed`\n exception if the node is stored. Otherwise the operation is just forwarded to the repository instance.\n\n The repository instance keeps an internal mapping of the file hierarchy that it maintains, starting from an empty\n hierarchy if the instance was constructed normally, or from a specific hierarchy if reconstructred through the\n ``Repository.from_serialized`` classmethod. This is only the case for stored nodes, because unstored nodes do not\n have any files yet when they are constructed. Once the node get's stored, the repository is asked to serialize its\n metadata contents which is then stored in the ``repository_metadata`` attribute of the node in the database. This\n layer explicitly does not update the metadata of the node on a mutation action. The reason is that for stored nodes\n these actions are anyway forbidden and for unstored nodes, the final metadata will be stored in one go, once the\n node is stored, so there is no need to keep updating the node metadata intermediately. Note that this does mean that\n ``repository_metadata`` does not give accurate information as long as the node is not yet stored.\n ", '_repository_instance': None, '_update_repository_metadata': <function NodeRepositoryMixin._update_repository_metadata>, '_repository': <property object>, 'repository_serialize': <function NodeRepositoryMixin.repository_serialize>, 'check_mutability': <function NodeRepositoryMixin.check_mutability>, 'list_objects': <function NodeRepositoryMixin.list_objects>, 'list_object_names': <function NodeRepositoryMixin.list_object_names>, 'open': <function NodeRepositoryMixin.open>, 'get_object': <function NodeRepositoryMixin.get_object>, 'get_object_content': <function NodeRepositoryMixin.get_object_content>, 'put_object_from_filelike': <function NodeRepositoryMixin.put_object_from_filelike>, 'put_object_from_file': <function NodeRepositoryMixin.put_object_from_file>, 'put_object_from_tree': <function NodeRepositoryMixin.put_object_from_tree>, 'walk': <function NodeRepositoryMixin.walk>, 'glob': <function NodeRepositoryMixin.glob>, 'copy_tree': <function NodeRepositoryMixin.copy_tree>, 'delete_object': <function NodeRepositoryMixin.delete_object>, 'erase': <function NodeRepositoryMixin.erase>, '__dict__': <attribute '__dict__' of 'NodeRepositoryMixin' objects>, '__weakref__': <attribute '__weakref__' of 'NodeRepositoryMixin' objects>, '__annotations__': {}})¶
- __module__ = 'aiida.orm.nodes.repository'¶
- __weakref__¶
list of weak references to the object (if defined)
- property _repository: aiida.repository.repository.Repository¶
Return the repository instance, lazily constructing it if necessary.
Note
this property is protected because a node’s repository should not be accessed outside of its scope.
- Returns
the file repository instance.
- _repository_instance = None¶
- _update_repository_metadata()[source]¶
Refresh the repository metadata of the node if it is stored and the decorated method returns successfully.
- check_mutability()[source]¶
Check if the node is mutable.
- Raises
ModificationNotAllowed – when the node is stored and therefore immutable.
- copy_tree(target: Union[str, pathlib.Path], path: Optional[Union[str, pathlib.PurePosixPath]] = None) None [source]¶
Copy the contents of the entire node repository to another location on the local file system.
- Parameters
target – absolute path of the directory where to copy the contents to.
path – optional relative path whose contents to copy.
- delete_object(path: str)[source]¶
Delete the object from the repository.
- Parameters
key – fully qualified identifier for the object within the repository.
- Raises
TypeError – if the path is not a string and relative path.
FileNotFoundError – if the file does not exist.
IsADirectoryError – if the object is a directory and not a file.
OSError – if the file could not be deleted.
ModificationNotAllowed – when the node is stored and therefore immutable.
- erase()[source]¶
Delete all objects from the repository.
- Raises
ModificationNotAllowed – when the node is stored and therefore immutable.
- get_object(path: Optional[Union[str, pathlib.PurePosixPath]] = None) aiida.repository.common.File [source]¶
Return the object at the given path.
- Parameters
path – the relative path where to store the object in the repository.
- Returns
the File representing the object located at the given relative path.
- Raises
TypeError – if the path is not a string or
Path
, or is an absolute path.FileNotFoundError – if no object exists for the given path.
- get_object_content(path: str, mode='r') Union[str, bytes] [source]¶
Return the content of a object identified by key.
- Parameters
key – fully qualified identifier for the object within the repository.
- Raises
TypeError – if the path is not a string and relative path.
FileNotFoundError – if the file does not exist.
IsADirectoryError – if the object is a directory and not a file.
OSError – if the file could not be opened.
- glob() Iterable[pathlib.PurePosixPath] [source]¶
Yield a recursive list of all paths (files and directories).
- list_object_names(path: Optional[str] = None) List[str] [source]¶
Return a sorted list of the object names contained in this repository, optionally in the given sub directory.
- Parameters
path – the relative path where to store the object in the repository.
- Returns
a list of File named tuples representing the objects present in directory with the given key.
- Raises
TypeError – if the path is not a string and relative path.
FileNotFoundError – if no object exists for the given path.
NotADirectoryError – if the object at the given path is not a directory.
- list_objects(path: Optional[str] = None) List[aiida.repository.common.File] [source]¶
Return a list of the objects contained in this repository sorted by name, optionally in given sub directory.
- Parameters
path – the relative path where to store the object in the repository.
- Returns
a list of File named tuples representing the objects present in directory with the given key.
- Raises
TypeError – if the path is not a string and relative path.
FileNotFoundError – if no object exists for the given path.
NotADirectoryError – if the object at the given path is not a directory.
- open(path: str, mode='r') Iterator[BinaryIO] [source]¶
Open a file handle to an object stored under the given key.
Note
this should only be used to open a handle to read an existing file. To write a new file use the method
put_object_from_filelike
instead.- Parameters
path – the relative path of the object within the repository.
- Returns
yield a byte stream object.
- Raises
TypeError – if the path is not a string and relative path.
FileNotFoundError – if the file does not exist.
IsADirectoryError – if the object is a directory and not a file.
OSError – if the file could not be opened.
- put_object_from_file(filepath: str, path: str)[source]¶
Store a new object under path with contents of the file located at filepath on the local file system.
- Parameters
filepath – absolute path of file whose contents to copy to the repository
path – the relative path where to store the object in the repository.
- Raises
TypeError – if the path is not a string and relative path, or the handle is not a byte stream.
ModificationNotAllowed – when the node is stored and therefore immutable.
- put_object_from_filelike(handle: _io.BufferedReader, path: str)[source]¶
Store the byte contents of a file in the repository.
- Parameters
handle – filelike object with the byte content to be stored.
path – the relative path where to store the object in the repository.
- Raises
TypeError – if the path is not a string and relative path.
ModificationNotAllowed – when the node is stored and therefore immutable.
- put_object_from_tree(filepath: str, path: Optional[str] = None)[source]¶
Store the entire contents of filepath on the local file system in the repository with under given path.
- Parameters
filepath – absolute path of the directory whose contents to copy to the repository.
path – the relative path where to store the objects in the repository.
- Raises
TypeError – if the path is not a string and relative path.
ModificationNotAllowed – when the node is stored and therefore immutable.
- repository_serialize() Dict [source]¶
Serialize the metadata of the repository content into a JSON-serializable format.
- Returns
dictionary with the content metadata.
- walk(path: Optional[Union[str, pathlib.PurePosixPath]] = None) Iterable[Tuple[pathlib.PurePosixPath, List[str], List[str]]] [source]¶
Walk over the directories and files contained within this repository.
Note
the order of the dirname and filename lists that are returned is not necessarily sorted. This is in line with the
os.walk
implementation where the order depends on the underlying file system used.- Parameters
path – the relative path of the directory within the repository whose contents to walk.
- Returns
tuples of root, dirnames and filenames just like
os.walk
, with the exception that the root path is always relative with respect to the repository root, instead of an absolute path and it is an instance ofpathlib.PurePosixPath
instead of a normal string