The two simplest approaches might be the methods “setColor” and “setColorScale” of NodePath–if I’m not much mistaken, the former replaces the current (vertex, I think?) colour of the object, while the latter treats the given colour as a scalar: the colour of the NodePath is multiplied by the given colour. These should allow for a basic form of colourising; the latter might be best used with greyscale diffuse maps, allowing for a wider range of colourisations (I’m not sure about the proper use of the former, I’m afraid).
For example, presume that you have a model named “cat.egg”, which has a single, greyscale texture:
np = loader.loadModel("cat")
np.reparentTo(render)
np.setColorScale(0, 1, 0, 1) # Make the cat green
This can, I think, be applied to separate sub-parts of a model; for example, if the “cat” model was composed of two sub-models named “paws” and “body”, we might do something like this:
np = loader.loadModel("cat")
np.reparentTo(render)
paws = np.find("**/paws")
np.setColorScale(0, 1, 0, 1) # Make the cat green...
paws.setColorScale(0, 0, 1, 1) # ...but make its paws blue.
There may, however, be caveats with this approach that I’m not aware of.
More advanced colourisations might be implemented using a custom shader. For example, you might use vertex colours to specify “regions” of colour, and set the colours to apply to those regions via shader inputs; the shader might then interpolate fragment colours based on the vertex colour and shader input.