def node_link_data(G, attrs=None):
    multigraph = G.is_multigraph()
    # Allow 'attrs' to keep default values.
    if attrs is None:
        attrs = _attrs
    else:
        attrs.update({k: v for (k, v) in _attrs.items() if k not in attrs})
    name = attrs['name']
    source = attrs['source']
    target = attrs['target']
    links = attrs['link']
    # Allow 'key' to be omitted from attrs if the graph is not a multigraph.
    key = None if not multigraph else attrs['key']
    if len(set([source, target, key])) < 3:
        raise nx.NetworkXError('Attribute names are not unique.')
    mapping = dict(zip(G, count()))
    data = {}
    data['directed'] = G.is_directed()
    data['multigraph'] = multigraph
    data['graph'] = G.graph
    data['nodes'] = [dict(chain(G.node[n].items(), [(name, n)])) for n in G]
    if multigraph:
        data[links] = [
            dict(chain(d.items(),
                       [(source, mapping[u]), (target, mapping[v]), (key, k)]))
            for u, v, k, d in G.edges(keys=True, data=True)]
    else:
        data[links] = [
            dict(chain(d.items(),
                       [(source, mapping[u]), (target, mapping[v])]))
            for u, v, d in G.edges(data=True)]
    return data
Return data in node-link format that is suitable for JSON serialization
dataset/ETHPy150Open networkx/networkx/networkx/readwrite/json_graph/node_link.py/node_link_data