Skip to content

Commit a9b7d5a

Browse files
committed
hooked in returning of kernelspecs
1 parent a570d5e commit a9b7d5a

6 files changed

Lines changed: 69 additions & 71 deletions

File tree

pythonFiles/PythonTools/ipythonServer.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ def _debug_write(out):
8080
sys.__stdout__.flush()
8181

8282

83-
def listKernelNames():
83+
def listKernelSpecs():
8484
"""Returns a dict mapping kernel names to resource directories."""
85-
return list(kernelSpecManager.find_kernel_specs().keys())
85+
return kernelSpecManager.get_all_specs()
8686

8787

8888
class IPythonExitException(Exception):
@@ -123,7 +123,7 @@ class iPythonSocketServer(object):
123123
"""Messages sent back as responses"""
124124
_PONG = to_bytes('PONG')
125125
_EXIT = to_bytes('EXIT')
126-
_LSTK = to_bytes('LSTK')
126+
_LSKS = to_bytes('LSKS')
127127
_EROR = to_bytes('EROR')
128128
_TEST = to_bytes('TEST')
129129

@@ -251,10 +251,10 @@ def _cmd_ping(self, id):
251251
def _cmd_lstk(self, id):
252252
"""List kernel specs"""
253253
_debug_write('Listing kernel specs')
254-
kernelspecs = json.dumps(listKernelNames())
254+
kernelspecs = json.dumps(listKernelSpecs())
255255
with self.send_lock:
256-
_debug_write('Replying with kernels = ' + kernelspecs)
257-
write_bytes(self.conn, iPythonSocketServer._LSTK)
256+
_debug_write('Replying with kernel Specs= ' + kernelspecs)
257+
write_bytes(self.conn, iPythonSocketServer._LSKS)
258258
write_string(self.conn, id)
259259
write_string(self.conn, kernelspecs)
260260

@@ -348,11 +348,11 @@ def flush(self):
348348
to_bytes('exit'): _cmd_exit,
349349
to_bytes('ping'): _cmd_ping,
350350
to_bytes('inpl'): _cmd_inpl,
351-
to_bytes('lstk'): _cmd_lstk,
351+
to_bytes('lsks'): _cmd_lstk,
352352
}
353353

354354
_COMMANDS_WITH_IDS = {
355-
to_bytes('lstk'): True,
355+
to_bytes('lsks'): True,
356356
to_bytes('ping'): True,
357357
}
358358

src/client/jupyter/jupyter_client/commands.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
export class Commands {
44
public static ExitCommandBytes: Buffer = new Buffer("exit");
55
public static PingBytes: Buffer = new Buffer("ping");
6-
public static ListKernelsBytes: Buffer = new Buffer("lstk");
6+
public static ListKernelSpecsBytes: Buffer = new Buffer("lsks");
77
}
88

99
export namespace ResponseCommands {
1010
export const Pong = 'PONG';
11-
export const ListKernels = 'LSTK';
11+
export const ListKernelsSpecs = 'LSKS';
1212
export const Error = 'EROR';
1313
}

src/client/jupyter/jupyter_client/ipythonAdapter.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class iPythonAdapter extends SocketCallbackHandler {
1313
constructor(socketServer: SocketServer) {
1414
super(socketServer);
1515
this.registerCommandHandler(ResponseCommands.Pong, this.onPong.bind(this));
16-
this.registerCommandHandler(ResponseCommands.ListKernels, this.onKernelsListed.bind(this));
16+
this.registerCommandHandler(ResponseCommands.ListKernelsSpecs, this.onKernelsListed.bind(this));
1717
this.registerCommandHandler(ResponseCommands.Error, this.onError.bind(this));
1818
this.idDispenser = new IdDispenser();
1919
}
@@ -53,9 +53,9 @@ export class iPythonAdapter extends SocketCallbackHandler {
5353
this.idDispenser.Free(parseInt(id));
5454
}
5555

56-
public listKernels(): Promise<string[]> {
57-
const [def, id] = this.createId<string[]>();
58-
this.SendRawCommand(Commands.ListKernelsBytes);
56+
public listKernelSpecs(): Promise<any> {
57+
const [def, id] = this.createId<any>();
58+
this.SendRawCommand(Commands.ListKernelSpecsBytes);
5959
this.stream.WriteString(id);
6060
return def.promise;
6161
}
@@ -70,7 +70,7 @@ export class iPythonAdapter extends SocketCallbackHandler {
7070
const def = this.pendingCommands.get(id);
7171
this.releaseId(id);
7272

73-
let kernelList: string[];
73+
let kernelList: any;
7474
try {
7575
kernelList = JSON.parse(kernels)
7676
}

src/client/jupyter/jupyter_client/jupyterClient.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as child_process from 'child_process';
44
import * as path from 'path';
55
import * as vscode from 'vscode';
66
import { createDeferred, Deferred } from '../../common/helpers';
7+
import { KernelspecMetadata, Kernelspec } from '../contracts';
78

89
export class JupyterClient {
910
constructor(private outputChannel: vscode.OutputChannel) {
@@ -12,9 +13,17 @@ export class JupyterClient {
1213
private process: child_process.ChildProcess;
1314
private socketServer: SocketServer;
1415
private ipythonAdapter: iPythonAdapter;
16+
17+
private startDef: Deferred<any>;
1518
public start(): Promise<any> {
19+
if (this.startDef) {
20+
return this.startDef.promise;
21+
}
22+
23+
this.startDef = createDeferred<any>();
1624
const pyFile = path.join(__dirname, '..', '..', '..', '..', 'pythonFiles', 'PythonTools', 'ipythonServer.py');
17-
return this.startSocketServer().then(port => {
25+
26+
this.startSocketServer().then(port => {
1827
const def = createDeferred<any>();
1928
const newEnv = { "DEBUG_DJAYAMANNE_IPYTHON": "1" };
2029
Object.assign(newEnv, process.env);
@@ -68,13 +77,23 @@ export class JupyterClient {
6877
}
6978

7079
return def.promise;
80+
}).then(() => {
81+
this.startDef.resolve();
82+
}).catch(reason => {
83+
this.startDef.reject(reason);
7184
});
85+
86+
return this.startDef.promise;
7287
}
7388
private startSocketServer(): Promise<number> {
7489
this.socketServer = new SocketServer();
7590
this.ipythonAdapter = new iPythonAdapter(this.socketServer);
7691
return this.socketServer.Start();
7792
}
93+
94+
public getAllKernelSpecs(): Promise<{ [key: string]: Kernelspec }> {
95+
return this.start().then(() => this.ipythonAdapter.listKernelSpecs());
96+
}
7897
}
7998

8099

src/client/jupyter/kernel-manager.ts

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
import * as child_process from 'child_process';
33
import * as os from 'os';
44
import * as vscode from 'vscode';
5-
import {Kernel} from './kernel';
6-
import {WSKernel} from './ws-kernel';
7-
import {ZMQKernel} from './zmq-kernel';
8-
import {launchSpec} from 'spawnteract';
9-
import {KernelspecMetadata, Kernelspec} from './contracts';
10-
import {Commands, Documentation} from '../common/constants';
11-
import {EventEmitter} from 'events';
12-
import {PythonSettings} from '../common/configSettings';
13-
import {formatErrorForLogging} from '../common/utils';
14-
import {JmpModuleLoadError} from '../common/errors';
15-
5+
import { Kernel } from './kernel';
6+
import { WSKernel } from './ws-kernel';
7+
import { ZMQKernel } from './zmq-kernel';
8+
import { launchSpec } from 'spawnteract';
9+
import { KernelspecMetadata, Kernelspec } from './contracts';
10+
import { Commands, Documentation } from '../common/constants';
11+
import { EventEmitter } from 'events';
12+
import { PythonSettings } from '../common/configSettings';
13+
import { formatErrorForLogging } from '../common/utils';
14+
import { JmpModuleLoadError } from '../common/errors';
15+
import { JupyterClient } from './jupyter_client/jupyterClient';
1616
// Todo: Refactor the error handling and displaying of messages
1717

1818
const pythonSettings = PythonSettings.getInstance();
@@ -21,7 +21,7 @@ export class KernelManagerImpl extends EventEmitter {
2121
private _runningKernels: Map<string, Kernel>;
2222
private _kernelSpecs: { [key: string]: Kernelspec };
2323
private disposables: vscode.Disposable[];
24-
constructor(private outputChannel: vscode.OutputChannel) {
24+
constructor(private outputChannel: vscode.OutputChannel, private jupyterClient: JupyterClient) {
2525
super();
2626
this.disposables = [];
2727
this._runningKernels = new Map<string, Kernel>();
@@ -221,29 +221,6 @@ export class KernelManagerImpl extends EventEmitter {
221221
}
222222

223223
public getKernelSpecsFromJupyter(): Promise<any> {
224-
const jupyter = 'jupyter kernelspec list --json --log-level=CRITICAL';
225-
const ipython = 'ipython kernelspec list --json --log-level=CRITICAL';
226-
return this.getKernelSpecsFrom(jupyter).catch(jupyterError => {
227-
return this.getKernelSpecsFrom(ipython);
228-
});
229-
}
230-
231-
public getKernelSpecsFrom(command: string): Promise<any> {
232-
const options = {
233-
killSignal: 'SIGINT'
234-
};
235-
return new Promise<any>((resolve, reject) => {
236-
return child_process.exec(command, options, (err, stdout, stderr) => {
237-
if (err) {
238-
return reject(err);
239-
}
240-
try {
241-
const kernelSpecs = JSON.parse(stdout).kernelspecs;
242-
resolve(kernelSpecs);
243-
} catch (err) {
244-
return reject(err);
245-
}
246-
});
247-
});
224+
return this.jupyterClient.getAllKernelSpecs();
248225
}
249226
}

src/client/jupyter/main.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ export class Jupyter extends vscode.Disposable {
2727
this.registerKernelCommands();
2828
}
2929
activate(state) {
30-
this.kernelManager = new KernelManagerImpl(this.outputChannel);
30+
const m = new main.JupyterClient(this.outputChannel);
31+
m.start();
32+
this.kernelManager = new KernelManagerImpl(this.outputChannel, m);
3133
this.disposables.push(this.kernelManager);
3234
this.disposables.push(vscode.window.onDidChangeActiveTextEditor(this.onEditorChanged.bind(this)));
3335
this.codeLensProvider = new JupyterCodeLensProvider();
@@ -79,25 +81,25 @@ export class Jupyter extends vscode.Disposable {
7981
this.status.setActiveKernel(this.kernel ? this.kernel.kernelSpec : null);
8082
}
8183
executeCode(code: string, language: string): Promise<any> {
82-
const m = new main.JupyterClient(this.outputChannel);
83-
m.start();
84-
return Promise.resolve();
85-
// telemetryHelper.sendTelemetryEvent(telemetryContracts.Jupyter.Usage);
84+
// const m = new main.JupyterClient(this.outputChannel);
85+
// m.start();
86+
// return Promise.resolve();
87+
telemetryHelper.sendTelemetryEvent(telemetryContracts.Jupyter.Usage);
8688

87-
// if (this.kernel && this.kernel.kernelSpec.language === language) {
88-
// return this.executeAndDisplay(this.kernel, code);
89-
// }
90-
// return this.kernelManager.startKernelFor(language)
91-
// .then(kernel => {
92-
// if (kernel) {
93-
// this.onKernelChanged(kernel);
94-
// return this.executeAndDisplay(kernel, code);
95-
// }
96-
// }).catch(reason => {
97-
// const message = typeof reason === 'string' ? reason : reason.message;
98-
// vscode.window.showErrorMessage(message);
99-
// this.outputChannel.appendLine(formatErrorForLogging(reason));
100-
// });
89+
if (this.kernel && this.kernel.kernelSpec.language === language) {
90+
return this.executeAndDisplay(this.kernel, code);
91+
}
92+
return this.kernelManager.startKernelFor(language)
93+
.then(kernel => {
94+
if (kernel) {
95+
this.onKernelChanged(kernel);
96+
return this.executeAndDisplay(kernel, code);
97+
}
98+
}).catch(reason => {
99+
const message = typeof reason === 'string' ? reason : reason.message;
100+
vscode.window.showErrorMessage(message);
101+
this.outputChannel.appendLine(formatErrorForLogging(reason));
102+
});
101103
}
102104
private executeAndDisplay(kernel: Kernel, code: string) {
103105
return this.executeCodeInKernel(kernel, code).then(result => {

0 commit comments

Comments
 (0)