Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/readwrite/json_graph/node_link.py: 18%

44 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-10-20 07:00 +0000

1from itertools import chain, count 

2 

3import networkx as nx 

4 

5__all__ = ["node_link_data", "node_link_graph"] 

6 

7 

8_attrs = { 

9 "source": "source", 

10 "target": "target", 

11 "name": "id", 

12 "key": "key", 

13 "link": "links", 

14} 

15 

16 

17def _to_tuple(x): 

18 """Converts lists to tuples, including nested lists. 

19 

20 All other non-list inputs are passed through unmodified. This function is 

21 intended to be used to convert potentially nested lists from json files 

22 into valid nodes. 

23 

24 Examples 

25 -------- 

26 >>> _to_tuple([1, 2, [3, 4]]) 

27 (1, 2, (3, 4)) 

28 """ 

29 if not isinstance(x, (tuple, list)): 

30 return x 

31 return tuple(map(_to_tuple, x)) 

32 

33 

34def node_link_data( 

35 G, 

36 *, 

37 source="source", 

38 target="target", 

39 name="id", 

40 key="key", 

41 link="links", 

42): 

43 """Returns data in node-link format that is suitable for JSON serialization 

44 and use in JavaScript documents. 

45 

46 Parameters 

47 ---------- 

48 G : NetworkX graph 

49 source : string 

50 A string that provides the 'source' attribute name for storing NetworkX-internal graph data. 

51 target : string 

52 A string that provides the 'target' attribute name for storing NetworkX-internal graph data. 

53 name : string 

54 A string that provides the 'name' attribute name for storing NetworkX-internal graph data. 

55 key : string 

56 A string that provides the 'key' attribute name for storing NetworkX-internal graph data. 

57 link : string 

58 A string that provides the 'link' attribute name for storing NetworkX-internal graph data. 

59 

60 Returns 

61 ------- 

62 data : dict 

63 A dictionary with node-link formatted data. 

64 

65 Raises 

66 ------ 

67 NetworkXError 

68 If the values of 'source', 'target' and 'key' are not unique. 

69 

70 Examples 

71 -------- 

72 >>> G = nx.Graph([("A", "B")]) 

73 >>> data1 = nx.node_link_data(G) 

74 >>> data1 

75 {'directed': False, 'multigraph': False, 'graph': {}, 'nodes': [{'id': 'A'}, {'id': 'B'}], 'links': [{'source': 'A', 'target': 'B'}]} 

76 

77 To serialize with JSON 

78 

79 >>> import json 

80 >>> s1 = json.dumps(data1) 

81 >>> s1 

82 '{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": "A"}, {"id": "B"}], "links": [{"source": "A", "target": "B"}]}' 

83 

84 A graph can also be serialized by passing `node_link_data` as an encoder function. The two methods are equivalent. 

85 

86 >>> s1 = json.dumps(G, default=nx.node_link_data) 

87 >>> s1 

88 '{"directed": false, "multigraph": false, "graph": {}, "nodes": [{"id": "A"}, {"id": "B"}], "links": [{"source": "A", "target": "B"}]}' 

89 

90 The attribute names for storing NetworkX-internal graph data can 

91 be specified as keyword options. 

92 

93 >>> H = nx.gn_graph(2) 

94 >>> data2 = nx.node_link_data(H, link="edges", source="from", target="to") 

95 >>> data2 

96 {'directed': True, 'multigraph': False, 'graph': {}, 'nodes': [{'id': 0}, {'id': 1}], 'edges': [{'from': 1, 'to': 0}]} 

97 

98 Notes 

99 ----- 

100 Graph, node, and link attributes are stored in this format. Note that 

101 attribute keys will be converted to strings in order to comply with JSON. 

102 

103 Attribute 'key' is only used for multigraphs. 

104 

105 To use `node_link_data` in conjunction with `node_link_graph`, 

106 the keyword names for the attributes must match. 

107 

108 

109 See Also 

110 -------- 

111 node_link_graph, adjacency_data, tree_data 

112 """ 

113 multigraph = G.is_multigraph() 

114 

115 # Allow 'key' to be omitted from attrs if the graph is not a multigraph. 

116 key = None if not multigraph else key 

117 if len({source, target, key}) < 3: 

118 raise nx.NetworkXError("Attribute names are not unique.") 

119 data = { 

120 "directed": G.is_directed(), 

121 "multigraph": multigraph, 

122 "graph": G.graph, 

123 "nodes": [{**G.nodes[n], name: n} for n in G], 

124 } 

125 if multigraph: 

126 data[link] = [ 

127 {**d, source: u, target: v, key: k} 

128 for u, v, k, d in G.edges(keys=True, data=True) 

129 ] 

130 else: 

131 data[link] = [{**d, source: u, target: v} for u, v, d in G.edges(data=True)] 

132 return data 

133 

134 

135@nx._dispatch(graphs=None) 

136def node_link_graph( 

137 data, 

138 directed=False, 

139 multigraph=True, 

140 *, 

141 source="source", 

142 target="target", 

143 name="id", 

144 key="key", 

145 link="links", 

146): 

147 """Returns graph from node-link data format. 

148 Useful for de-serialization from JSON. 

149 

150 Parameters 

151 ---------- 

152 data : dict 

153 node-link formatted graph data 

154 

155 directed : bool 

156 If True, and direction not specified in data, return a directed graph. 

157 

158 multigraph : bool 

159 If True, and multigraph not specified in data, return a multigraph. 

160 

161 source : string 

162 A string that provides the 'source' attribute name for storing NetworkX-internal graph data. 

163 target : string 

164 A string that provides the 'target' attribute name for storing NetworkX-internal graph data. 

165 name : string 

166 A string that provides the 'name' attribute name for storing NetworkX-internal graph data. 

167 key : string 

168 A string that provides the 'key' attribute name for storing NetworkX-internal graph data. 

169 link : string 

170 A string that provides the 'link' attribute name for storing NetworkX-internal graph data. 

171 

172 Returns 

173 ------- 

174 G : NetworkX graph 

175 A NetworkX graph object 

176 

177 Examples 

178 -------- 

179 

180 Create data in node-link format by converting a graph. 

181 

182 >>> G = nx.Graph([('A', 'B')]) 

183 >>> data = nx.node_link_data(G) 

184 >>> data 

185 {'directed': False, 'multigraph': False, 'graph': {}, 'nodes': [{'id': 'A'}, {'id': 'B'}], 'links': [{'source': 'A', 'target': 'B'}]} 

186 

187 Revert data in node-link format to a graph. 

188 

189 >>> H = nx.node_link_graph(data) 

190 >>> print(H.edges) 

191 [('A', 'B')] 

192 

193 To serialize and deserialize a graph with JSON, 

194 

195 >>> import json 

196 >>> d = json.dumps(node_link_data(G)) 

197 >>> H = node_link_graph(json.loads(d)) 

198 >>> print(G.edges, H.edges) 

199 [('A', 'B')] [('A', 'B')] 

200 

201 

202 Notes 

203 ----- 

204 Attribute 'key' is only used for multigraphs. 

205 

206 To use `node_link_data` in conjunction with `node_link_graph`, 

207 the keyword names for the attributes must match. 

208 

209 See Also 

210 -------- 

211 node_link_data, adjacency_data, tree_data 

212 """ 

213 multigraph = data.get("multigraph", multigraph) 

214 directed = data.get("directed", directed) 

215 if multigraph: 

216 graph = nx.MultiGraph() 

217 else: 

218 graph = nx.Graph() 

219 if directed: 

220 graph = graph.to_directed() 

221 

222 # Allow 'key' to be omitted from attrs if the graph is not a multigraph. 

223 key = None if not multigraph else key 

224 graph.graph = data.get("graph", {}) 

225 c = count() 

226 for d in data["nodes"]: 

227 node = _to_tuple(d.get(name, next(c))) 

228 nodedata = {str(k): v for k, v in d.items() if k != name} 

229 graph.add_node(node, **nodedata) 

230 for d in data[link]: 

231 src = tuple(d[source]) if isinstance(d[source], list) else d[source] 

232 tgt = tuple(d[target]) if isinstance(d[target], list) else d[target] 

233 if not multigraph: 

234 edgedata = {str(k): v for k, v in d.items() if k != source and k != target} 

235 graph.add_edge(src, tgt, **edgedata) 

236 else: 

237 ky = d.get(key, None) 

238 edgedata = { 

239 str(k): v 

240 for k, v in d.items() 

241 if k != source and k != target and k != key 

242 } 

243 graph.add_edge(src, tgt, ky, **edgedata) 

244 return graph