Source code for nv_dfm_core.api._node_id

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Any, Literal

from pydantic import BaseModel, field_validator
from typing_extensions import override


[docs] class NodeId(BaseModel, frozen=True): """ NodeId uniquely identifies a node in a Pipeline graph. The NodeId is used at the node itself. Other nodes use NodeRef, not NodeId, to reference this node. NodeRef is different from the NodeId in that it adds a possible `selector` to reference individual fields of the node's result. """ tag: Literal["@dfm-node"] = "@dfm-node" ident: int | str @field_validator("ident") @classmethod def validate_ident(cls, v: Any) -> Any: if isinstance(v, str) and not v.isidentifier(): raise ValueError(f"NodeId.ident '{v}' is not a valid identifier") return v @override def __str__(self) -> str: nid = f"%{self.ident}" if isinstance(self.ident, int) else f"#{self.ident}" return f"{nid}"
[docs] def to_ref(self, sel: int | str | None = None, issubs: bool | None = None): """ Create a NodeRef from a NodeId. If issubs is not provided, it is inferred from whether sel is an int or a str. For ints we assume a subscript like some_val[42] whereas for strings we assume a field selector like some_val.myname """ if not issubs: # if sel is None it doesn't really matter what issubs is, but # we use True as the default (e.g. in testing), so let's use True issubs = True if sel is None else isinstance(sel, int) return NodeRef(id=self, sel=sel, issubs=issubs)
[docs] def as_identifier(self) -> str: """Returns this node_id as a valid identifier""" if isinstance(self.ident, int): return f"node{self.ident}" else: assert self.ident.isidentifier(), ( f"Node ID {self.ident} is not a valid identifier" ) return self.ident
[docs] class NodeRef(BaseModel, frozen=True): """A NodeRef is used to identify (reference) a node in a pipeline when passing the output of a node as a parameter to another node. NodeRef is a tuple ['@dfmref', NodeId, Field]. The first element is a magic string that helps identifying a tuple as a node ref. The NodeID is the id of the referenced node. The optional Field is a field inside the node's result that should get passed as a parameter. If None, the whole result object is passed. But for example `op = OtherOp(name=['@dfmref', 42, 'filename'])` would only pass the 'filename' field of node 42's result.""" id: NodeId sel: int | str | None = None # if sel is a string, issubs=True is ref[sel] whereas issubs=False is ref.sel issubs: bool = True @override def __str__(self) -> str: selector = f".{self.sel}" if self.sel else "" return f"{str(self.id)}{selector}"
[docs] def make_auto_id(ident: int) -> NodeId: """Auto IDs are prefixed with %. Auto NodeIds are managed by PipelineBuildHelper. This function should only be used by users if they know what they are doing, otherwise there's a risk of naming conflict. Users should use the well_known_id variant below""" return NodeId(ident=ident)
[docs] def well_known_id(ident: int | str) -> NodeId: """Well-known IDs (user-defined IDs) are prefixed with #. The user should make sure that there is really only one node in a pipeline with this ID""" return NodeId(ident=ident if isinstance(ident, str) else f"wkid{ident}")