Skip to content

Commit

Permalink
deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Feb 15, 2024
0 parents commit 8ba772d
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 0 deletions.
Binary file added dist/spycy_aneeshdurg-0.0.3-py3-none-any.whl
Binary file not shown.
Binary file added dist/spycy_aneeshdurg-0.0.3.tar.gz
Binary file not shown.
60 changes: 60 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!doctype html>
<html>
<title>sPyCy browser demo</title>
<head>
<script src="https://cdn.jsdelivr.net/pyodide/v0.23.0/full/pyodide.js"></script>
<script src="./static/script.js"></script>
<script type="text/javascript">
window.addEventListener("DOMContentLoaded", (event) => {
main();
});
</script>
<link rel="stylesheet" type="text/css" href="./static/style.css">
</head>
<body>
<h1> sPyCy browser demo </h1>
<p> Input openCypher queries and use `ctrl + enter` to execute them! </p>
<p> This project is <a href="https://github.com/aneeshdurg/spycy">open source</a>! </p>
<details>
<summary> Sample Queries </summary>
<code>
<ul>
<li> Create nodes with ids 1 to 5:
<ul>
<li> UNWIND range(1, 5) AS id CREATE (n:Node {id: id}) </li>
</ul>
</li>
<li> Return all nodes:
<ul>
<li> MATCH (n:Node) RETURN n, properties(n) </li>
</ul>
</li>
<li> Return nodes with id > 3:
<ul>
<li> MATCH (n:Node) WHERE n.id > 3 RETURN n, properties(n) </li>
</ul>
</li>
<li> Create a relationship between nodes with even and odd ids:
<ul>
<li> MATCH (n: Node) WHERE n.id % 2 = 0 CREATE (n)-[:EVEN]->(m:Node {id: n.id + 1}) </li>
</ul>
</li>
<li> Return all relationships:
<ul>
<li> MATCH (n:Node)-[r]->(m) RETURN n.id, r, m.id </li>
</ul>
</li>
</ul>
</code>
</details>
<div class="content">
<div id="preload" class="preload">
<code id="progress"></code>
</div>
<div id="loaded" style="display: none;">
<div id="notebook"></div>
</div>
</div>
</body>
</html>

174 changes: 174 additions & 0 deletions static/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
function render_table(output, table) {
if (table.length == 0) {
output.innerHTML = "<i>empty table</i>"
return;
}

const output_table = document.createElement('table');
const heading_row = document.createElement('tr');

const row0 = table[0];
const table_headings = []
for (let key of Object.getOwnPropertyNames(row0)){
const heading = document.createElement('th');
heading.innerText = key;
heading_row.appendChild(heading);
table_headings.push(key);
}
output_table.appendChild(heading_row);

for (let row of table) {
const content_row = document.createElement('tr');
for (let key of table_headings) {
const element = document.createElement('td');
const data = row[key];
element.innerText = JSON.stringify(data);
content_row.appendChild(element);
}
output_table.appendChild(content_row);
}

output.appendChild(output_table);
}

async function eval_cell(input, output) {
output.innerHTML = "";

window.stderr = []
try {
await pyodide.runPython(`
try:
exe.exec(${JSON.stringify(input.value)})
result = exe.table_to_json()
except Exception as e:
print(e, file=sys.stderr)
raise Exception from e
`);
const output_table = JSON.parse(pyodide.globals.get('result'))
render_table(output, output_table)
} catch (e){
const summary = document.createElement('summary');
if (window.stderr.length) {
for (let msg of window.stderr) {
const error_msg = document.createElement('p');
error_msg.className = "errormsg";
error_msg.innerText = msg;
summary.appendChild(error_msg);
}
} else {
const error_msg = document.createElement('p');
error_msg.className = "errormsg";
error_msg.innerText = "UNKNOWN EXECUTION ERROR";
summary.appendChild(error_msg);
}

const details = document.createElement('details');
const errors = document.createElement('code');
errors.innerText = e;
details.appendChild(errors);

output.appendChild(summary);
output.appendChild(details);
}
}

function create_cell(container) {
const input = document.createElement("textarea");
input.className = "cellinput";
const run = document.createElement("button");
run.innerText = "run"
const output = document.createElement("div");
const cell = document.createElement("div");
const count = container.childElementCount;
cell.id = "cell" + container.childElementCount;

cell.addEventListener('focus', () => {
input.focus();
});

const evaluate = async () => {
await eval_cell(input, output);
const nextid = count + 1;
const next_el = document.getElementById("cell" + nextid);
if (next_el) {
next_el.focus();
} else {
create_cell(container);
}
};
input.addEventListener('keydown', async (event) => {
if (event.key === "Enter" && event.ctrlKey) {
evaluate();
}
});
run.addEventListener('click', evaluate);

cell.appendChild(input);
cell.appendChild(document.createElement("br"));
cell.appendChild(run);
cell.appendChild(document.createElement("br"));
cell.appendChild(document.createElement("br"));
cell.appendChild(output);
cell.appendChild(document.createElement("br"));
cell.appendChild(document.createElement("br"));
container.appendChild(cell);
input.focus();
container.scrollTop = container.scrollHeight;
}

function setup_notebook() {
notebook = document.getElementById("notebook");
create_cell(notebook, 0);
}

async function main(){
const progress = document.getElementById("progress");
progress.innerHTML += "Initializing pyodide<br>"

let pyodide = await loadPyodide();
progress.innerHTML += "Installing micropip<br>"
await pyodide.loadPackage('micropip');
progress.innerHTML += "Installed micropip<br>"

window.stderr = [];
console.warn = (x) => {
window.stderr.push(x);
};

const originalConsoleLog = console.log;
console.log = (s) => {
progress.innerText += "<pyodide>: " + s + "\n";
};

await pyodide.runPython(`
import sys
import js
preload = js.document.getElementById("preload")
loaded_env = js.document.getElementById("loaded")
progress = js.document.getElementById("progress")
exe = None
result = None
import micropip
async def main():
global exe
progress.innerHTML += "Initializing python environment<br>"
progress.innerHTML += "Installing spycy (may take a few minutes)<br>"
await micropip.install("./dist/spycy_aneeshdurg-0.0.2-py3-none-any.whl", deps=True)
progress.innerHTML += "Installed spycy<br>"
progress.innerHTML += "READY!<br>"
import spycy
from spycy.spycy import CypherExecutor
exe = CypherExecutor()
preload.style = "display:none;"
loaded_env.style.display = ""
main()
`);

console.log = originalConsoleLog;

window.pyodide = pyodide;

setup_notebook();
}
34 changes: 34 additions & 0 deletions static/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.content {
position: absolute;
border: 1px solid;
padding: 1em;
height: 80%;
width: 95%;
margin-left: 1%;
overflow: auto;
}

.preload {
background: black;
color: white;
padding: 1em;
}

.cellinput {
width: 100%;
}

.errormsg {
font-family: monospaced;
background: #f7da79;
padding: 0.25em;
}

th {
background: #bbbbbb;
padding: 0.25em;
}

td {
padding: 0.25em;
}
1 change: 1 addition & 0 deletions version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6af86391ffdc5f7ef5ab2662caf2984d072fc910

0 comments on commit 8ba772d

Please sign in to comment.