/
ipython.py
115 lines (93 loc) · 2.79 KB
/
ipython.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
from IPython.nbformat.current import reads_json
from IPython.nbconvert.exporters import HTMLExporter
import json
import hashlib
import memcache
import traceback
import logging
import StringIO
import subprocess
import os
import sys
if __name__ != "__main__":
connection = memcache.Client([
"notebook-cache.l0s8m9.0001.use1.cache.amazonaws.com"])
def python_to_notebook(source_code):
"""
Converts this Python file into a notebook.
"""
return json.dumps({
"metadata": { "name": "" },
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [ {
"cells": [ {
"cell_type": "code",
"collapsed": False,
"input": source_code.split("\n"),
"language": "python",
"metadata": {},
"outputs": []
} ],
"metadata": {}
} ]
})
def render_to_html(json_as_string):
"""
Renders the given Notebook node as HTML.
"""
import os
os.environ["HOME"] = "/home/git"
# Return if not yet ready.
if not json_as_string:
return
# Attempt to read a cached value.
key = hashlib.sha1(json_as_string).hexdigest()
try:
value = connection.get(key)
if type(value) not in (str, unicode):
raise ValueError("Invalid cache response.")
except Exception:
logging.exception("Unable to read fragment.")
else:
if value:
logging.info("Cache HIT.")
return value.decode("utf-8")
else:
logging.info("Cache MISS.")
# Render the notebook.
logging.info("About to render externally.")
process = subprocess.Popen(["/usr/bin/env", "python", "ipython.py"],
cwd = os.path.dirname(__file__),
stdin = subprocess.PIPE,
stdout = subprocess.PIPE)
logging.info("About to render externally.")
html = process.communicate(json_as_string)[0].decode("utf-8")
logging.info("Rendering complete.")
if html == "":
return None
# Saved the cached value.
try:
connection.set(key, html)
except Exception:
logging.exception("Unable to cache fragment.")
return html
def main():
"""
Render STDIN as a notebook.
"""
exporter = HTMLExporter()
json_as_string = sys.stdin.read().decode("utf-8")
try:
notebook_node = reads_json(json_as_string)
except Exception:
logging.exception("Unable to parse JSON.")
html, _ = exporter.from_notebook_node(notebook_node)
sys.stderr.write("JSON was {:,} byte(s); html is {:,} byte(s).\n".format(
len(json_as_string), len(html)
))
sys.stdout.write(html.encode("utf-8"))
sys.stderr.flush()
sys.stdout.flush()
if __name__ == '__main__':
main()