-
Notifications
You must be signed in to change notification settings - Fork 6
/
lnsetup.py
176 lines (147 loc) · 6.09 KB
/
lnsetup.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import os, os.path, shutil, json
try:
import IPython
from notebook import notebookapp
from IPython.terminal.ipapp import TerminalIPythonApp
from jupyter_client import kernelspec
from traitlets.config import Config
except:
print("Warning: Failed to load IPython/Jupyter. Some features disabled.")
import lamb
# note: can't import this from any other module.
from lamb import utils, types, meta, lang, tree_mini, parsing, magics, combinators
from lamb.tree_mini import Tree
def inject_into_ipython():
try:
ip = get_ipython()
# inject the module names
ip.user_ns["lamb"] = lamb
ip.user_ns["utils"] = lamb.utils
ip.user_ns["types"] = lamb.types
ip.user_ns["meta"] = lamb.meta
ip.user_ns["lang"] = lamb.lang
ip.user_ns["parsing"] = lamb.parsing
ip.user_ns["display"] = lamb.display
ip.user_ns["combinators"] = lamb.combinators
# inject some convenience functions
ip.user_ns["reload_lamb"] = reload_lamb
ip.user_ns["Tree"] = lamb.tree_mini.Tree
ip.user_ns["MiniLatex"] = lamb.utils.MiniLatex
ip.user_ns["ltx_print"] = lamb.utils.ltx_print
ip.user_ns["te"] = lamb.meta.te
ip.user_ns["tp"] = lamb.meta.tp
except:
print("Failed to inject lambda notebook variables into the ipython kernel namespace")
raise
def reload_lamb():
# should this reload the magics?
import imp
imp.reload(lamb.utils)
imp.reload(lamb.types)
imp.reload(lamb.meta)
imp.reload(lamb.lang)
imp.reload(lamb.parsing)
imp.reload(lamb.display)
imp.reload(lamb.combinators)
lamb.reload_all = reload_lamb
inject_into_ipython()
def ipython_setup():
lamb.reload_all = reload_lamb
inject_into_ipython()
def install_notebooks(nb_path, package_nb_path, force=False):
copy_nbs = False
#TODO: this is kind of hacky
if nb_path[0] == "~":
nb_path = os.path.expanduser(nb_path)
if not os.path.exists(nb_path):
os.makedirs(nb_path)
copy_nbs = True
if copy_nbs and not os.path.exists(package_nb_path):
print("Path not found for notebooks to install: '%s'" % package_nb_path, flush=True)
copy_nbs = False
if package_nb_path and (copy_nbs or force):
errors = []
print("Attempting to copy installation notebooks from '%s' to '%s'" % (package_nb_path, nb_path), flush=True)
names = os.listdir(package_nb_path)
for name in names:
srcname = os.path.join(package_nb_path, name)
destname = os.path.join(nb_path, name)
if os.path.exists(destname):
pass # never overwrite anything
try:
if os.path.islink(srcname):
pass # ignore symlinks
elif os.path.isdir(srcname):
shutil.copytree(srcname, destname)
else:
shutil.copy2(srcname, destname)
except OSError as why:
errors.append((srcname, destname, str(why)))
# catch the Error from the recursive copytree so that we can
# continue with other files
except shutil.Error as err:
errors.extend(err.args[0])
if errors:
raise shutil.Error(errors)
kernelspec_str = """{
"argv": ["python3", "-m", "IPython.kernel",
"-f", "{connection_file}", "%s"],
"display_name": "Lambda Notebook (Python 3)",
"language": "python"
}"""
kernelspec_json = {
"argv": ["python3", "-m", "IPython.kernel", "-f", "{connection_file}"],
"display_name": "Lambda Notebook (Python 3)",
"language": "python"
}
def install_kernelspec(kernel_dir, lib_dir):
if lib_dir:
# TODO: won't override an installed copy of lamb in site-packages (e.g. in the app), fix this
injection_path_opt = "--IPKernelApp.exec_lines=[\"import sys; sys.path.append(\\\"%s\\\"); import lamb.lnsetup; lamb.lnsetup.ipython_setup()\"]" % lib_dir
else:
injection_path_opt = "--IPKernelApp.exec_lines=[\"import lamb.lnsetup; lamb.lnsetup.ipython_setup()\"]"
k_json = kernelspec_json.copy()
k_json["argv"].append(injection_path_opt)
k_json_filename = os.path.join(kernel_dir, "kernel.json")
with open(k_json_filename, 'w') as k_json_file:
json.dump(k_json, k_json_file, sort_keys=True, indent=4)
kernelspec.install_kernel_spec(kernel_dir, user=True, replace=True)
def launch_lambda_console(args, lib_dir=None, kernel_dir=None):
if kernel_dir is None:
kernel_dir = os.path.join(lib_dir, "kernel/lambda-notebook")
install_kernelspec(kernel_dir, lib_dir)
c = Config()
# no idea why this doesn't work, but it doesn't...
#c.IPythonConsoleApp.kernel_name="lambda-notebook"
c.InteractiveShellApp.exec_lines=["import sys; sys.path.append(\"%s\"); import lamb.lnsetup; lamb.lnsetup.ipython_setup()" % lib_dir]
app = TerminalIPythonApp.instance(config=c)
app.initialize(argv=args[1:])
app.start()
def launch_lambda_notebook(args, nb_path=None, lib_dir=None, package_nb_path=None, kernel_dir=None):
# originally based on branded notebook recipe here: https://gist.github.com/timo/1497850
# that recipe is for a much earlier version of IPython, so the method is quite a bit different now
if kernel_dir is None:
kernel_dir = os.path.join(lib_dir, "kernel/lambda-notebook")
# ensure that the lambda-notebook kernelspec is installed
install_kernelspec(kernel_dir, lib_dir)
c = Config()
if nb_path is None:
nb_path = os.path.expanduser("~/Documents/lambda_notebook/")
if nb_path[0] == "~":
raise Error("Unable to locate home directory")
#TODO: need something more general here
if not os.path.exists(nb_path):
try:
install_notebooks(nb_path, package_nb_path, force=False)
except shutil.Error as err:
print(err)
#os.makedirs(nb_path)
c.NotebookApp.notebook_dir = nb_path
app = notebookapp.NotebookApp(config=c)
app.initialize(args[1:])
try:
app.start()
except KeyboardInterrupt:
pass
finally:
pass