Python's graphviz module

Doing this in dot is trivial
[dot]
strict digraph G
{
node[shape=ellipse];
NodeI → NodeII [label = “prop1”];
NodeIII → NodeI [label = “prop3”];
{rank=same; NodeII → NodeIII [label=“prop2”];}
}
[/dot]

ie:

strict digraph G
{
   node[shape=ellipse];
   NodeI -> NodeII [label = "prop1"];
   NodeIII -> NodeI [label = "prop3"];
   {rank=same; NodeII -> NodeIII [label="prop2"];}
}

But I’ve tried in vain to reproduce this result using the python syntax of the graphviz module.

This is as close as I could get using the graphviz module:

import graphviz as gv
dg = gv.Digraph('digraph experiment', comment='trying to get a triangular graph with named edges', filename='triangle.gv', engine='dot')
dg.node('1', 'Node I')
dg.node('2', 'Node II')
dg.node('3', 'Node III')
# dg.edges(['12', '13'])
dg.edge('1','2', label="relationI")
dg.edge('3', '1', label="relationIII", constraint='false')
dg.edge('2', '3', rank='same', label="relationII", constraint='false')
dg.view()

I can, of course, use python’s graphviz module to draw the graph from the dot source, like this:

dg = gv.Source(dotsourcestring, filename='triangle.gv', engine='dot')
dg.view()

but perhaps the assembled wise here can help me understand what I’m missing in the graphviz module to generate this simple graph?