Skip to content

Commit 1df9328

Browse files
authored
Merge pull request nteract#1023 from rgbkrk/conda-main-kernels
feat(conda): detect conda environments with ipykernels
2 parents 59e3f3a + 80580aa commit 1df9328

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"redux-observable": "^0.12.0",
5757
"rxjs": "^5.0.0-rc.1",
5858
"shell-env": "^0.2.0",
59+
"spawn-rx": "^2.0.3",
5960
"spawnteract": "^2.2.0",
6061
"uuid": "^2.0.3",
6162
"yargs": "^6.0.0"

src/main/kernels.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Rx from 'rxjs/Rx';
2+
3+
import {
4+
spawn,
5+
} from 'spawn-rx';
6+
7+
const path = require('path');
8+
9+
// TODO: Check for sys.prefix/share/jupyter/kernels/*/kernel.json
10+
/**
11+
* ipyKernelTryObservable check for existence of ipykernel in an env
12+
* @param {Object} env [description]
13+
* @return {[type]} [description]
14+
*/
15+
export function ipyKernelTryObservable(env) {
16+
const executable = path.join(env.prefix, 'bin', 'python');
17+
return spawn(executable, ['-m', 'ipykernel', '--version'], { split: true })
18+
.filter(x => x.source && x.source === 'stdout')
19+
.mapTo(env)
20+
.catch(err => Rx.Observable.empty());
21+
}
22+
23+
export function condaInfoObservable() {
24+
return spawn('conda', ['info', '--json'])
25+
.map(info => JSON.parse(info));
26+
}
27+
28+
export function condaEnvsObservable(condaInfo$) {
29+
return condaInfo$.map(info => {
30+
const envs = info.envs.map(env => ({ name: path.basename(env), prefix: env }));
31+
envs.push({ name: 'root', prefix: info.root_prefix });
32+
return envs;
33+
})
34+
.map(envs => envs.map(ipyKernelTryObservable))
35+
.mergeAll()
36+
.mergeAll()
37+
.toArray();
38+
}
39+
40+
export function createKernelSpecsFromEnvs(envs) {
41+
const displayPrefix = 'Python'; // Or R
42+
const languageKey = 'py'; // or r
43+
44+
// TODO: Handle Windows & Conda
45+
const languageExe = 'bin/python';
46+
const jupyterBin = 'bin/jupyter';
47+
48+
const langEnvs = {};
49+
50+
for (const env of envs) {
51+
const base = env.prefix;
52+
const exePath = path.join(base, languageExe);
53+
const envName = env.name;
54+
const name = `conda-env-${envName}-${languageKey}`;
55+
langEnvs[name] = {
56+
display_name: `${displayPrefix} [conda env:${envName}]`,
57+
// TODO: Support default R kernel
58+
argv: [exePath, '-m', 'ipykernel', '-f', '{connection_file}'],
59+
language: 'python',
60+
// TODO: Provide resource_dir
61+
};
62+
}
63+
return langEnvs;
64+
}
65+
66+
export function condaKernelsObservable() {
67+
return condaEnvsObservable(condaInfoObservable())
68+
.map(createKernelSpecsFromEnvs);
69+
}

0 commit comments

Comments
 (0)