Metadata-Version: 2.4
Name: jupyter-kernel-cli
Version: 0.1.1
Summary: Agent-friendly CLI and Python API for talking to existing Jupyter kernels.
Home-page: https://github.com/hruskamiro/jupyter-kernel-client
Author: Miroslav Hruska
Author-email: hruska.miro@gmail.com
License: MIT
Project-URL: Homepage, https://github.com/hruskamiro/jupyter-kernel-client
Project-URL: Repository, https://github.com/hruskamiro/jupyter-kernel-client
Project-URL: Issues, https://github.com/hruskamiro/jupyter-kernel-client/issues
Keywords: jupyter,kernel,cli,automation,agent
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: jupyter-client>=7.0
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# jupyter-kernel-client

`jk` is a small command-line tool and Python library for **executing code in an existing Jupyter kernel**.

It is designed for scripts and AI agents that need a **stable, machine-readable way to inspect or modify a live Python session**.

## Intended Use Case

You are working in an IPython console, Spyder console, notebook kernel, or other Jupyter-backed Python session. **The session already has important state loaded:** imports, data frames, models, helper functions, configuration, intermediate results, and whatever else you have built up interactively.

**Instead of asking an AI agent to recreate that state from scratch, give it access to the existing kernel.** Export or copy the kernel connection information, tell the agent to use `jk`, and let it inspect variables, run experiments, evaluate expressions, and return structured output from the same live Python process you are using.

The workflow is:

1. **Work normally** in an IPython, Spyder, notebook, or other Jupyter-backed console.
2. **Load the state you care about:** data, objects, functions, imports, models, and intermediate results.
3. **Copy the active kernel connection info**, for example with `%connect_info`.
4. **Give that connection info to Codex or another agent.**
5. **Tell the agent to use `jk`** to connect to that exact kernel.
6. **Let the agent inspect and experiment** with `jk exec`, `jk eval`, `jk get`, and `jk vars`.

This is useful when the hard part is **not writing code from a blank environment**, but **exploring and manipulating the state that already exists in a live session**.

## Install

Recommended:

```bash
pipx install jupyter-kernel-cli
```

Other install paths:

```bash
pipx install git+https://github.com/hruskamiro/jupyter-kernel-client.git
pipx upgrade jupyter-kernel-cli
pipx install --force .
python -m pip install -e ".[dev]"
```

Check:

```bash
jk --help
```

## Usage

Common commands:

```bash
jk kernels
jk kernels --probe
jk exec -f /path/to/kernel.json "x = 41"
jk eval -f /path/to/kernel.json "x + 1"
jk get -f /path/to/kernel.json x
jk vars -f /path/to/kernel.json --json
jk interrupt -f /path/to/kernel.json --json
jk demo -f /path/to/kernel.json --json
```

Use **JSON for agents** and stdin for larger generated code:

```bash
cat <<'PY' | jk exec -f /path/to/kernel.json --json --stdin
import pandas as pd

summary = {
    "variables": sorted(name for name in globals() if not name.startswith("_")),
    "answer": 6 * 7,
}
summary
PY
```

Other supported forms:

```bash
jk exec -f /path/to/kernel.json --file script.py
jk -f /path/to/kernel.json --json eval "x + 1"
export JK_CONNECTION_FILE=/path/to/kernel.json
jk eval "df.shape"
```

If execution times out, the code may still be running in the kernel. Send an
interrupt request separately:

```bash
jk exec -f /path/to/kernel.json --timeout 5 --json "long_running_call()"
jk interrupt -f /path/to/kernel.json --json
```

The JSON response includes status, stdout, stderr, rich display outputs, final `text/plain` result, parsed Python literal when possible, traceback details, elapsed time, timeout state, and message id.

## Using `jk` from Codex

Give Codex the **active kernel connection information** and tell it to use `jk`,
the locally installed **jupyter-kernel-client CLI**, to connect to that exact
kernel.

For Codex, the clearest instruction is usually to run `jk` **outside the command
sandbox**. This gives `jk` direct access to the local Jupyter kernel sockets
while the rest of the session can remain workspace-sandboxed.

You can copy the connection information from `%connect_info`. For integration
with the Spyder IDE, use
[`spyder-copy-current`](https://github.com/hruskamiro/spyder-copy-current) and
press `Ctrl+Alt+K` in Spyder to copy the current console's connection
information or a complete agent-ready prompt.

For example:

```text
Connect to this exact Jupyter kernel using jk, the locally installed
jupyter-kernel-client CLI. Run jk outside the command sandbox if approval is
needed. Inspect the available variables, run small experiments there, and report
the results.

<paste the kernel connection information here>
```

Useful checks if it does not work:

1. Make sure `jk` is installed and visible with `command -v jk`.
2. Pass the connection file explicitly with `jk -f /path/to/kernel.json ...`.
3. Make sure the installed `jk` environment has `jupyter-client`.

**Approving `jk` allows arbitrary code execution in the connected Jupyter
kernel.** Treat this as execution access to that live Python session.

## JSON Contract

Successful JSON responses include:

```json
{
  "status": "ok",
  "ok": true,
  "execution_count": 12,
  "stdout": "",
  "stderr": "",
  "outputs": [],
  "result_text": "42",
  "result_python": 42,
  "ename": null,
  "evalue": null,
  "traceback": [],
  "elapsed_seconds": 0.01,
  "timed_out": false,
  "msg_id": "..."
}
```

Exit codes:

```text
0    kernel execution succeeded
1    kernel execution raised an error
2    client or argument error
124  client timed out waiting for the kernel or interrupt reply
```

Timeouts only stop the client wait. Timed-out execution may continue in the
kernel until it finishes or is interrupted. `jk interrupt` sends a Jupyter
`interrupt_request` on the control channel; for Python kernels this is the
normal KeyboardInterrupt-style path. It is not a process kill, so native
extensions or blocking system calls may not stop immediately.

## Python API

```python
from jupyter_kernel_client import eval_expression, interrupt_kernel

response = eval_expression("/path/to/kernel.json", "x + 1")
if response.ok:
    print(response.result_python)

interrupt = interrupt_kernel("/path/to/kernel.json")
print(interrupt.status)
```

## License

MIT.
