from flask import Flask, jsonify, request, render_template import numpy as np app = Flask(__name__) class Graph(object): nodes = set() # set of strings edges = dict() # (string,string) -> float def bellmann_ford(graph, node_a, node_b): """Calculate distance from node_a to node_b assuming no negative cycles.""" # weights from_a_to = {**[(node, np.inf) for node in graph.nodes]} from_a_to[node_a] = 0 # save path so we dont have to backtrace later path_from_a_to = {**[(node, []) for node in graph.nodes]} path_from_a_to[node_a] = [node_a] for i in range(len(graph.nodes)-1): for e in graph.edges: # because edges are not directed for (x,y) in [e,e[::-1]]: if from_a_to[x] + graph.edges[(x,y)] < from_a_to[y]: path_from_a_to[y] = path_from_a_to + [y] from_a_to[y] = from_a_to[x] + graph.edges[(x,y)] return path_from_a_to[node_b] graph = Graph() def error(message): return jsonify({"error": message}) def edges_to_json(edges): return_list = [] for e in edges: return_list.append({"start":e[0],"end":e[1],"weight":edges[e]}) return return_list @app.route('/api/nodes', methods=['GET']) def get_nodes(): return jsonify({'nodes': graph.nodes}) @app.route('/api/edges', methods=['GET']) def get_edges(): return jsonify({'edges': edges_to_json(graph.edges)}) @app.route('/api/nodes', methods=['POST']) def create_node(): if not request.json: return error("Request needs to be JSON."), 400 if 'name' not in request.json: return error("Name must be set."), 400 name = request.json['name'] if name == "": return error("Name cannot be empty."), 400 if name in graph.nodes: return error(f'Node with name "{name}" already exist.'), 400 graph.nodes.add(name) return jsonify(name), 201 @app.route('/api/edges', methods=['POST']) def create_edge(): if not request.json: return error("Request needs to be JSON."), 400 if 'start' not in request.json: return error("Start node must be set."), 400 if 'end' not in request.json: return error("End node must be set."), 400 if 'weight' not in request.json: return error("Edge weight must be set."), 400 start = request.json['start'] end = request.json['end'] weight = request.json['weight'] try: weight = float(weight) except ValueError: return error("Weight must be a number."), 400 if weight < 0: return error("Weight must be positive."), 400 if start == end: return error("Start and end node must be different."), 400 if start not in graph.nodes: return error("Start node does not exist."), 400 if end not in graph.nodes: return error("End node does not exist."), 400 if (start,end) in graph.edges or (end,start) in graph.edges: return error("Edge already exists."), 400 edge = {"start":start,"end":end, "weight": weight} graph.edges[(start,end)] = weight return jsonify(edge), 201 @app.route("/") def index(): return render_template("index.html", nodes=graph.nodes, edges=edges_to_json(graph.edges)) if __name__ == '__main__': app.run(host="127.0.0.1", debug=True, port=5000)