commit 43ef16c10345923d239b6bf4204ae5063c0ef17e Author: Ugo Date: Fri Sep 6 16:20:17 2019 +0200 Backend with restapi diff --git a/main.py b/main.py new file mode 100644 index 0000000..8549fc2 --- /dev/null +++ b/main.py @@ -0,0 +1,107 @@ +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}) + + +@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': 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'] + 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 exists already."), 400 + try: + weight = float(weight) + except ValueError: + return error("Weight must be a number."), 400 + + edge = {(start,end): weight} + graph.edges[(start,end)] = weight + + return jsonify(edge), 201 + + +@app.route("/") +def index(): + return render_template("index.html", nodes=graph.nodes, edges=graph.edges) + + +if __name__ == '__main__': + app.run(host="127.0.0.1", debug=True, port=5000) diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..172f754 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,13 @@ + + + + + Assignment + + +

nodes: {{ nodes }}

+

edges: {{ edges }}

+
+ + +