From f76b0d9595095da38aa952b75e6c6a9a4b034d7a Mon Sep 17 00:00:00 2001 From: Pete Shadbolt Date: Wed, 11 May 2016 18:07:20 +0100 Subject: [PATCH] Server / client architecture is looking good! --- abp/__init__.py | 1 + abp/client.py | 39 ++++++++++++++++++++++++++++++++ abp/graphstate.py | 6 ++--- examples/client.py | 15 +++++-------- server/server.py | 39 ++++++++++++++++++++------------ server/static/main.css | 29 +++++++++++++++++++++++- server/static/poll.js | 44 ------------------------------------- server/templates/index.html | 14 ++++++++++-- 8 files changed, 113 insertions(+), 74 deletions(-) create mode 100644 abp/client.py diff --git a/abp/__init__.py b/abp/__init__.py index a2258ac..3933731 100644 --- a/abp/__init__.py +++ b/abp/__init__.py @@ -1,3 +1,4 @@ # Alias some stuff to make imports cleaner from abp.graphstate import GraphState from abp.qi import CircuitModel +from abp.client import Client diff --git a/abp/client.py b/abp/client.py new file mode 100644 index 0000000..4c5b839 --- /dev/null +++ b/abp/client.py @@ -0,0 +1,39 @@ +import requests +import abp, json + +class Client(object): + def __init__(self, host="localhost", port=5000, clear=False): + self.session = requests.Session() + self.root = "http://{}:{}".format(host, port) + if clear: + self.clear() + + def get(self, endpoint): + url =self.root+endpoint + response = self.session.get(url) + assert response.status_code == 200 + return response.content + + def get_state(self): + response = self.get("/state") + output = abp.GraphState() + output.from_json(json.loads(response)) + return output + + def set_state(self, state): + return self.session.post(self.root+"/state", data=state.to_json()) + + def add_node(self, node): + return self.get("/add_node/{}".format(node)) + + def act_local_rotation(self, node, operation): + return self.get("/act_local_rotation/{}/{}".format(node, operation)) + + def act_cz(self, a, b): + return self.get("/act_cz/{}/{}".format(a, b)) + + def clear(self): + return self.get("/clear") + + def kill(self): + self.session.close() diff --git a/abp/graphstate.py b/abp/graphstate.py index 790de1c..6ba08cc 100644 --- a/abp/graphstate.py +++ b/abp/graphstate.py @@ -164,9 +164,9 @@ class GraphState(object): def from_json(self, data): """ Reconstruct from JSON """ self.__init__([]) - self.vops = data["nodes"] - self.meta = data["meta"] - self.ngbh = {key: set() for key in self.vops} + self.vops = {int(key): value for key, value in data["nodes"].items()} + self.meta = {int(key): value for key, value in data["meta"].items()} + self.ngbh = {int(key): set() for key in self.vops} self.add_edges(data["edges"]) def to_networkx(self): diff --git a/examples/client.py b/examples/client.py index 4008fe0..b1bd33b 100644 --- a/examples/client.py +++ b/examples/client.py @@ -1,15 +1,10 @@ import requests import abp, json +import time -s = requests.Session() -output = s.get("http://localhost:5000/state").content -s.post("http://localhost:5000/state", output).content +client = abp.Client() -s.get("http://localhost:5000/add/99") -s.get("http://localhost:5000/add/100") - -print s.get("http://localhost:5000/state").content - -s.get("http://localhost:5000/clear") -s.close() +client.add_node(0) +client.add_node(1) +print client.get_state() diff --git a/server/server.py b/server/server.py index 7ca3680..5635939 100644 --- a/server/server.py +++ b/server/server.py @@ -1,8 +1,13 @@ from flask import Flask, request, render_template, jsonify +from werkzeug.contrib.cache import SimpleCache import json import abp -graphstate = abp.GraphState() +#TODO: only send deltas + +#graphstate = abp.GraphState() +cache=SimpleCache() +cache.set("state", abp.GraphState()) app = Flask(__name__) @app.route("/") @@ -12,38 +17,44 @@ def index(): @app.route("/state", methods = ["GET", "POST"]) def state(): if request.method == "GET": - return jsonify(graphstate.to_json()) + return jsonify(cache.get("state").to_json()) elif request.method == "POST": + graphstate = abp.GraphState() graphstate.from_json(json.loads(request.data)) - return jsonify(graphstate.to_json()) + cache.set("state", graphstate) + return jsonify({"update": "ok"}) -@app.route("/add/") -def add(node): +@app.route("/add_node/") +def add_node(node): """ Add a node to the graph """ + graphstate = cache.get("state") graphstate.add_node(node) - return jsonify(graphstate.to_json()) + cache.set("state", graphstate) + return jsonify({"add_node": "okay"}) -@app.route("/rotate//") -def rotate(node): +@app.route("/act_local_rotation//") +def act_local_rotation(node): """ Add a node to the graph """ + # TODO: try to lookup the operation first graphstate.act_local_rotation(node, operation) - return jsonify(graphstate.to_json()) + return jsonify({"act_local_rotation": "okay"}) -@app.route("/cz//") -def cz(a, b): +@app.route("/act_cz//") +def act_cz(a, b): """ Add a node to the graph """ graphstate.act_cz(a, b) - return jsonify(graphstate.to_json()) + return jsonify({"act_cz": "okay"}) @app.route("/clear") def clear(): """ Clear the current state """ graphstate = abp.GraphState() - return jsonify({"clear": "ok"}) + cache.set("state", graphstate) + return jsonify({"clear": "okay"}) if __name__ == "__main__": - app.debug = True + app.debug = False app.run(host="0.0.0.0") diff --git a/server/static/main.css b/server/static/main.css index f1124cb..ff0f9a6 100644 --- a/server/static/main.css +++ b/server/static/main.css @@ -1,10 +1,37 @@ html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; font-family: "courier new"; } #infoholder { - background: black; color:white; padding: 5px; margin:0px; position: absolute; top:5px; left:5px; font-family:"courier new"; text-align: center; font-size:10pt; + background: black; + color:white; + padding: 5px; + margin:0px; + position: absolute; + top:5px; + left:5px; + font-family:"courier new"; + text-align: center; + font-size:10pt; height:15px; border-radius:3px; } +#pallette { + background-color: black; + /*border-radius:3px;*/ + color:white; + padding: 10px; + font-family:"courier new"; + position: absolute; + top: 10px; + right: 10px; + font-size: 9pt; +} + +ul { + list-style-type: none; + padding: 0px; + margin: 0px; +} + .visible { visibility: visible; opacity: 1; diff --git a/server/static/poll.js b/server/static/poll.js index 4122b85..139597f 100644 --- a/server/static/poll.js +++ b/server/static/poll.js @@ -1,46 +1,2 @@ -var url = "ws://localhost:8000/"; -function doConnect() { - websocket = new WebSocket(url); - websocket.onopen = onOpen; - websocket.onclose = onClose; - websocket.onmessage = onMessage; - websocket.onerror = onError; -} -function onOpen(evt) { - writeToScreen("connected\n"); - doSend("Hello from the browser"); -} - -function onClose(evt) { - writeToScreen("disconnected\n"); -} - -function onMessage(evt) { - writeToScreen("response: " + evt.data + '\n'); -} - -function onError(evt) { - writeToScreen('error: ' + evt.data + '\n'); - websocket.close(); -} - -function doSend(message) { - writeToScreen("sent: " + message + '\n'); - websocket.send(message); -} - -function writeToScreen(message) { - console.log(message); -} - -function init() { - doConnect(); -} - -function doDisconnect() { - websocket.close(); -} - -window.addEventListener("load", init, false); diff --git a/server/templates/index.html b/server/templates/index.html index 2e84832..b0e75e4 100644 --- a/server/templates/index.html +++ b/server/templates/index.html @@ -5,7 +5,7 @@ abp - + @@ -19,8 +19,18 @@ -
Hello World
+ +
+
    +
  • add_qubit
  • +
  • delete_qubit
  • +
  • hadamard
  • +
  • cz
  • +
  • clear
  • +
+
+