Python: add custom nodegroup

hey sorry for the noob question but I don’t know how to do that:
So I have script, that creates a node group and within a couple boxmasks.
That works fine, but when I run the script it should add the nodegroup to the node tree, I can add an empty node group to the tree, but not my own. (It shows up in the add menu, so this works fine as well)
Here is my code:

width_min = 0.1
width_max = 0.3
height_min = 0.05
height_max = 0.15
tree = bpy.context.scene.node_tree

def makeNodes():
    nodeList = []

    masksGroup = bpy.data.node_groups.new('Mask_Group', 'CompositorNodeTree')
    masksOutputs = masksGroup.nodes.new('NodeGroupOutput')
    masksOutputs.location = (500,0)
    masksGroup.outputs.new('NodeSocketFloat','Mask')
    
    for i in range(15):
        node = masksGroup.nodes.new(type="CompositorNodeBoxMask")
        node.width = round(random.uniform(width_min,width_max),2)
        node.height = round(random.uniform(height_min,height_max),2)
               nodeList.append(node)
    linkNodes(nodeList,masksGroup)
 
    #here is my problem "Node type Mask_Group undefined"
    tree.nodes.new("Mask_Group")
    return nodeList

Do you have any idea?

Nodegroups are not Nodes. They are nodetrees, so using tree.nodes.new() won’t work.
For using Nodegroups, you need a *NodeGroup node, and set it to use the nodetree you want.
This is what you can do:

groupnode = tree.nodes.new('CompositorNodeGroup')
groupnode.node_tree = masksGroup # or bpy.data.node_groups['Mask_Group']

Or create a CompositorCustomNodeGroup (which will be a Node), with your node_tree inside.

1 Like

Thanks, works perfectly

Sorry to bump this, but it hurts a bit : NodeGroup are Nodes, which is its base class, they use NodeTree

A ‘ShaderNodeTree’ will be inside a ‘ShaderNodeGroup’ when used in a Material

>>> nodeTree = bpy.data.node_groups.new('MyNodeTree', 'ShaderNodeTree')
>>> type(nodeTree)
<class 'bpy.types.ShaderNodeTree'>

A Material now use a group of nodes, which use our ShaderNodeTree :

>>> type(bpy.data.materials['Test.000'].node_tree.nodes['MyGroup'])
<class 'bpy.types.ShaderNodeGroup'>

Finally :

>>> bpy.data.materials['Test.000'].node_tree.nodes['MyGroup'].node_tree
bpy.data.node_groups['MyNodeTree']

In the Shader Editor, a Material starts with a root ‘ShaderNodeTree’, which is not visible in bpy.data.node_groups (ref: source/blender/editors/space_node/node_edit.c) ; then you add Nodes to the Material ‘root ShaderNodeTree’, and a Node you add can be a NodeGroup, ie a Node that embed a NodeTree of other Nodes. So node_groups.new is a bit confusing, it should be named node_trees.new, and the ‘bpy.data’ branch should have been named as well ‘node_trees’.
Hope it helps.

Unfortunately, the nomenclature we have is not the best for such definitions. When I said ‘NodeGroups are not Nodes’, I was refering to the Nodetrees that are stored in bpy.data.node_groups (as data elements), commonly known as nodegroups.
On the other side, we have *NodeGroups (as classes), like the ‘ShaderNodeGroup’, that are container nodes; nodes that create an interface for nodetrees that can have an IO interface.
Note that this was a specific answer to a specific problem (trying to add a nodetree through the node api, rather than creating a ShaderNodeGroup and add a nodetree reference to it). This was not intended to be an extension of the Blender Documentation, for what I would use a more precise language.

It’s Ok, you already answered the question, it’s for future reading in order to avoid confusion (like I did myself). Thanks.