Skip to content

Commit 3ae303f

Browse files
Start/stop the IPykernel process
1 parent fa01353 commit 3ae303f

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"deno.enable": true
3+
}

packages/python-runtime-agent/deno.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
},
1616
"imports": {
1717
"@runt/lib": "jsr:@runt/lib@^0.6.2",
18-
"@runt/schema": "jsr:@runt/schema@^0.6.2"
18+
"@runt/schema": "jsr:@runt/schema@^0.6.2",
19+
"@std/path": "jsr:@std/path@^1.1.1"
1920
},
2021
"tasks": {
2122
"test": "deno test --allow-all",

packages/python-runtime-agent/src/python-runtime-agent.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import {
2+
createLogger,
23
createRuntimeConfig,
34
RuntimeAgent,
5+
type RuntimeAgentOptions,
46
type RuntimeConfig,
57
} from "@runt/lib";
8+
import * as path from "@std/path";
69

710
export class PythonRuntimeAgent extends RuntimeAgent {
11+
private kernel: Deno.ChildProcess | null = null;
12+
private logger = createLogger("python-runtime-agent");
813
constructor(args: string[] = Deno.args) {
914
let config: RuntimeConfig;
1015
try {
@@ -36,6 +41,54 @@ export class PythonRuntimeAgent extends RuntimeAgent {
3641
Deno.exit(1);
3742
}
3843

39-
super(config, config.capabilities, {});
44+
super(config, config.capabilities, {
45+
onStartup: (environmentOptions) => this.onStartup(environmentOptions),
46+
onShutdown: () => this.onShutdown(),
47+
});
48+
}
49+
50+
private async onStartup(
51+
options: RuntimeAgentOptions["environmentOptions"],
52+
): Promise<void> {
53+
if (options.runtimeEnvExternallyManaged) {
54+
const pythonPath = options.runtimePythonPath ?? "python3";
55+
const tempDir = await Deno.makeTempDir({ prefix: "anode-kernel" });
56+
const connPath = path.join(tempDir, "conn.json");
57+
const args = ["-m", "ipykernel_launcher", "-f", connPath];
58+
try {
59+
const command = new Deno.Command(pythonPath, {
60+
args,
61+
});
62+
this.logger.debug("Starting kernel", {
63+
python: pythonPath,
64+
args,
65+
});
66+
this.kernel = command.spawn();
67+
this.logger.info("Kernel started", { pid: this.kernel.pid });
68+
} finally {
69+
Deno.removeSync(tempDir, { recursive: true });
70+
}
71+
} else {
72+
throw new Error("Not yet implemented");
73+
}
74+
}
75+
76+
private async onShutdown(): Promise<void> {
77+
if (this.kernel) {
78+
this.logger.info("Shutting down kernel", { pid: this.kernel.pid });
79+
try {
80+
this.kernel.kill();
81+
const status = (await this.kernel.status).code;
82+
this.logger.info("Kernel shutdown", {
83+
pid: this.kernel.pid,
84+
status,
85+
});
86+
} catch (error) {
87+
this.logger.error("Error shutting down kernel", {
88+
pid: this.kernel.pid,
89+
error: error instanceof Error ? error.message : String(error),
90+
});
91+
}
92+
}
4093
}
4194
}

0 commit comments

Comments
 (0)