forked from NUS-ALSET/lambda-nbconvert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
131 lines (97 loc) · 3.49 KB
/
main.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
import os
import sys
import ast
import tempfile
CURRENT_DIR = os.getcwd()
BUILD_DIR = os.path.join(os.getcwd(), "build", "code")
sys.path.append(CURRENT_DIR)
sys.path.append(BUILD_DIR)
os.environ['PYTHONPATH'] = os.environ['PYTHONPATH'] + ":" + CURRENT_DIR + ":" + BUILD_DIR
import logging
import nbformat
from nbconvert.preprocessors import ExecutePreprocessor
from io import StringIO
import json
import base64
from timeit import default_timer as timer
logger = logging.getLogger(__name__)
def return_result_json():
os.chdir('/tmp')
if(os.path.isfile('results.json')):
result_file_reader = open('results.json','r')
result_file = result_file_reader.read()
return result_file
def base64_decode_and_persist(filename, contents):
os.chdir('/tmp')
decoded = base64.b64decode(contents)
with open(filename, 'wb') as outfile:
outfile.write(decoded)
def save_files_to_temp_dir(files):
print(type(files))
for key in files:
print("Processing file: " + key)
base64_decode_and_persist(key, files[key])
def execute_notebook(source):
"""
:param source: Jupyter Notebook
:return: Result of the notebook invocation
"""
logger.debug("Executing notebook")
in_memory_source = StringIO(source)
nb = nbformat.read(in_memory_source, as_version=4)
logger.debug("Launching kernels")
ep = ExecutePreprocessor(timeout=600, kernel_name='python3', allow_errors=True)
ep.preprocess(nb, {'metadata': {'path': '/tmp/'}})
ex = StringIO()
nbformat.write(nb, ex)
logger.debug("Returning results")
return ex.getvalue()
homepage = ""
with open('index.html') as f:
homepage=f.read()
def populate_cors(response):
response['headers']['Access-Control-Allow-Origin'] = os.environ.get('CORS_DOMAIN', '*')
response['headers']['Access-Control-Allow-Headers'] = os.environ.get('CORS_HEADERS', 'Content-Type, Authorization, X-Amz-Date, X-Api-Key, X-Amz-Security-Token')
response['headers']['Access-Control-Allow-Methods'] = os.environ.get('CORS_METHODS', 'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT')
def handler(event, context):
cors_enabled = os.environ.get('ENABLE_CORS', 'false') == 'true'
if event['httpMethod'] == 'GET':
response = {
"statusCode": 200,
"body": homepage,
"headers": {
'Content-Type': 'text/html',
}
}
return response
elif event['httpMethod'] == 'OPTIONS' and cors_enabled:
response = {
"statusCode": 200,
"body": None,
"headers": {
'Content-Type': 'application/json',
}
}
populate_cors(response)
return response
else:
request_body = json.loads(event["body"])
notebook_source = request_body['notebook']
attached_files = request_body['files'] if 'files' in request_body else {}
save_files_to_temp_dir(attached_files)
start = timer()
result = execute_notebook(json.dumps(notebook_source))
result = json.loads(result)
exec_result = return_result_json()
end = timer()
duration = end - start
response = {
"statusCode": 200,
"body": json.dumps({"duration": duration,"ipynb": result, "result": exec_result}),
"headers": {
'Content-Type': 'application/json',
}
}
if cors_enabled:
populate_cors(response)
return response