| @@ -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 | |||
| @@ -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() | |||
| @@ -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): | |||
| @@ -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() | |||
| @@ -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/<int:node>") | |||
| def add(node): | |||
| @app.route("/add_node/<int: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/<int:node>/<int:operation>") | |||
| def rotate(node): | |||
| @app.route("/act_local_rotation/<int:node>/<int:operation>") | |||
| 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/<int:a>/<int:b>") | |||
| def cz(a, b): | |||
| @app.route("/act_cz/<int:a>/<int:b>") | |||
| 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") | |||
| @@ -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; | |||
| @@ -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); | |||
| @@ -5,7 +5,7 @@ | |||
| <meta charset="utf-8"> | |||
| <title>abp</title> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=1" /> | |||
| <link rel="stylesheet" href="main.css"> | |||
| <link rel="stylesheet" href="/static/main.css"> | |||
| </head> | |||
| <body> | |||
| @@ -19,8 +19,18 @@ | |||
| <img id="ball" src="data:image/png;base64,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"/ | |||
| style=display:none;> | |||
| <div id=test>Hello World</div> | |||
| <div id=infoholder class=hidden> | |||
| </div> | |||
| <div id=pallette> | |||
| <ul> | |||
| <li>add_qubit</li> | |||
| <li>delete_qubit</li> | |||
| <li>hadamard</li> | |||
| <li>cz</li> | |||
| <li>clear</li> | |||
| </ul> | |||
| </div> | |||
| </body> | |||
| </html> | |||