Skip to content

Commit 522a0c2

Browse files
committed
Replace pydot by graphviz
This is in an effort to support Python 3: pydot is not compatible with Python 3, while graphviz is.
1 parent b02c54c commit 522a0c2

File tree

2 files changed

+15
-20
lines changed

2 files changed

+15
-20
lines changed

netbox/extras/api/views.py

+14-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import pydot
1+
import graphviz
22
from rest_framework import generics
33
from rest_framework.views import APIView
44
import tempfile
@@ -49,32 +49,30 @@ def get(self, request, slug):
4949
tmap = get_object_or_404(TopologyMap, slug=slug)
5050

5151
# Construct the graph
52-
graph = pydot.Dot(graph_type='graph', ranksep='1')
52+
graph = graphviz.Graph()
53+
graph.graph_attr['ranksep'] = '1'
5354
for i, device_set in enumerate(tmap.device_sets):
5455

55-
subgraph = pydot.Subgraph('sg{}'.format(i), rank='same')
56+
subgraph = graphviz.Graph(name='sg{}'.format(i))
57+
subgraph.graph_attr['rank'] = 'same'
5658

5759
# Add a pseudonode for each device_set to enforce hierarchical layout
58-
subgraph.add_node(pydot.Node('set{}'.format(i), shape='none', width='0', label=''))
60+
subgraph.node('set{}'.format(i), label='', shape='none', width='0')
5961
if i:
60-
graph.add_edge(pydot.Edge('set{}'.format(i - 1), 'set{}'.format(i), style='invis'))
62+
graph.edge('set{}'.format(i - 1), 'set{}'.format(i), style='invis')
6163

6264
# Add each device to the graph
6365
devices = []
6466
for query in device_set.split(','):
6567
devices += Device.objects.filter(name__regex=query)
6668
for d in devices:
67-
node = pydot.Node(d.name)
68-
subgraph.add_node(node)
69+
subgraph.node(d.name)
6970

7071
# Add an invisible connection to each successive device in a set to enforce horizontal order
7172
for j in range(0, len(devices) - 1):
72-
edge = pydot.Edge(devices[j].name, devices[j + 1].name)
73-
# edge.set('style', 'invis') doesn't seem to work for some reason
74-
edge.set_style('invis')
75-
subgraph.add_edge(edge)
73+
subgraph.edge(devices[j].name, devices[j + 1].name, style='invis')
7674

77-
graph.add_subgraph(subgraph)
75+
graph.subgraph(subgraph)
7876

7977
# Compile list of all devices
8078
device_superset = Q()
@@ -87,17 +85,14 @@ def get(self, request, slug):
8785
connections = InterfaceConnection.objects.filter(interface_a__device__in=devices,
8886
interface_b__device__in=devices)
8987
for c in connections:
90-
edge = pydot.Edge(c.interface_a.device.name, c.interface_b.device.name)
91-
graph.add_edge(edge)
88+
graph.edge(c.interface_a.device.name, c.interface_b.device.name)
9289

93-
# Write the image to disk and return
94-
topo_file = tempfile.NamedTemporaryFile()
90+
# Get the image data and return
9591
try:
96-
graph.write(topo_file.name, format='png')
92+
topo_data = graph.pipe(format='png')
9793
except:
9894
return HttpResponse("There was an error generating the requested graph. Ensure that the GraphViz "
9995
"executables have been installed correctly.")
100-
response = HttpResponse(FileWrapper(topo_file), content_type='image/png')
101-
topo_file.close()
96+
response = HttpResponse(topo_data, content_type='image/png')
10297

10398
return response

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ django-filter==0.13.0
55
django-rest-swagger==0.3.7
66
django-tables2==1.2.1
77
djangorestframework==3.3.3
8+
graphviz==0.4.10
89
Markdown==2.6.6
910
ncclient==0.4.7
1011
netaddr==0.7.18
1112
paramiko==2.0.0
1213
psycopg2==2.6.1
1314
py-gfm==0.1.3
1415
pycrypto==2.6.1
15-
pydot==1.0.2
1616
sqlparse==0.1.19
1717
xmltodict==0.10.2

0 commit comments

Comments
 (0)