-
Notifications
You must be signed in to change notification settings - Fork 526
Expand file tree
/
Copy pathpatches.ts
More file actions
48 lines (43 loc) · 1.64 KB
/
Copy pathpatches.ts
File metadata and controls
48 lines (43 loc) · 1.64 KB
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
import {HOME_FOLDER, SERVICE_WORKER_PATH} from './constants';
export enum MessageTag {
MATPLOTLIB_IMG = 'MATPLOTLIB_SHOW_IMG',
NEIGHBORHOOD_SIGNAL = '[NEIGHBORHOOD]',
INPUT_PROMPT = '[INPUT_PROMPT]',
INPUT_FAILED = '[INPUT_FAILED]',
}
export const TEARDOWN_CODE = `from pythonlab_setup import teardown_pythonlab
teardown_pythonlab('/${HOME_FOLDER}')
`;
export const SETUP_CODE = `from pythonlab_setup import setup_pythonlab
setup_pythonlab('${MessageTag.MATPLOTLIB_IMG}')
`;
// The two functions below are used to patch the input function in Python.
// When the user calls input() or readline from stdin in Python, we intercept
// the call and send a get request to our service worker, which in turn sends a
// message to the main thread that we are awaiting input. The main thread then
// sends a message back to the service worker, which becomes the result of the get request.
export const patchInputCode = (id: number) => `
import sys, builtins
import pythonlab_input
def get_input(prompt=""):
print(f'${MessageTag.INPUT_PROMPT}{prompt}')
return pythonlab_input.getInput("${id}", prompt)
builtins.input = get_input
sys.stdin.readline = lambda: pythonlab_input.getInput("${id}", "")
`;
export const pythonlabInputModule = {
getInput: (id: string, prompt: string) => {
const request = new XMLHttpRequest();
// Synchronous request to be intercepted by service worker
request.open(
'GET',
`${SERVICE_WORKER_PATH}?id=${id}&prompt=${encodeURIComponent(prompt)}`,
false
);
request.send(null);
if (request.status !== 200) {
throw new Error(MessageTag.INPUT_FAILED);
}
return request.responseText;
},
};