akernel 0.1.1__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- akernel-0.3.0/.github/workflows/main.yml +48 -0
- akernel-0.3.0/.pre-commit-config.yaml +7 -0
- {akernel-0.1.1 → akernel-0.3.0}/PKG-INFO +32 -24
- {akernel-0.1.1 → akernel-0.3.0}/README.md +23 -6
- {akernel-0.1.1 → akernel-0.3.0}/binder/postBuild +1 -0
- akernel-0.3.0/examples/concurrency.ipynb +127 -0
- {akernel-0.1.1 → akernel-0.3.0}/examples/reactivity.ipynb +1 -1
- akernel-0.3.0/plugins/akernel_task/LICENSE +21 -0
- akernel-0.3.0/plugins/akernel_task/README.md +3 -0
- akernel-0.3.0/plugins/akernel_task/fps_akernel_task/__init__.py +6 -0
- akernel-0.3.0/plugins/akernel_task/fps_akernel_task/akernel_task.py +49 -0
- akernel-0.3.0/plugins/akernel_task/fps_akernel_task/main.py +14 -0
- akernel-0.3.0/plugins/akernel_task/pyproject.toml +32 -0
- {akernel-0.1.1 → akernel-0.3.0}/pyproject.toml +21 -12
- akernel-0.3.0/src/akernel/__init__.py +6 -0
- akernel-0.3.0/src/akernel/akernel.py +140 -0
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/cache.py +4 -5
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/code.py +27 -28
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/comm/comm.py +17 -18
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/comm/manager.py +6 -5
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/connect.py +7 -7
- akernel-0.3.0/src/akernel/display/__init__.py +0 -0
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/display/display.py +3 -2
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/execution.py +10 -8
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/kernel.py +147 -99
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/kernelspec.py +3 -4
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/message.py +41 -51
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/traceback.py +6 -7
- {akernel-0.1.1/akernel → akernel-0.3.0}/tests/conftest.py +5 -4
- {akernel-0.1.1/akernel → akernel-0.3.0}/tests/test_execution.py +5 -3
- {akernel-0.1.1/akernel → akernel-0.3.0}/tests/test_kernel.py +8 -15
- {akernel-0.1.1/akernel → akernel-0.3.0}/tests/test_react_code.py +1 -3
- akernel-0.1.1/.github/workflows/main.yml +0 -57
- akernel-0.1.1/akernel/__init__.py +0 -1
- akernel-0.1.1/akernel/akernel.py +0 -38
- {akernel-0.1.1 → akernel-0.3.0}/LICENSE +0 -0
- {akernel-0.1.1 → akernel-0.3.0}/MANIFEST.in +0 -0
- {akernel-0.1.1 → akernel-0.3.0}/binder/environment.yml +0 -0
- /akernel-0.1.1/akernel/IPython/core/__init__.py → /akernel-0.3.0/plugins/akernel_task/fps_akernel_task/py.typed +0 -0
- {akernel-0.1.1 → akernel-0.3.0}/share/jupyter/kernels/akernel/kernel.json +0 -0
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/IPython/__init__.py +0 -0
- {akernel-0.1.1/akernel/display → akernel-0.3.0/src/akernel/IPython/core}/__init__.py +0 -0
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/IPython/core/getipython.py +0 -0
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/IPython/core/interactiveshell.py +0 -0
- {akernel-0.1.1 → akernel-0.3.0/src}/akernel/comm/__init__.py +0 -0
- {akernel-0.1.1/akernel → akernel-0.3.0}/tests/test_async_code.py +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
defaults:
|
|
12
|
+
run:
|
|
13
|
+
shell: bash -l {0}
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
name: Test
|
|
18
|
+
runs-on: ${{ matrix.os }}
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: false
|
|
21
|
+
matrix:
|
|
22
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
23
|
+
python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13' ]
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Setup Python
|
|
30
|
+
uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: ${{ matrix.python-version }}
|
|
33
|
+
|
|
34
|
+
- name: Install akernel
|
|
35
|
+
run: |
|
|
36
|
+
pip install . --group test
|
|
37
|
+
|
|
38
|
+
- name: Check style and types
|
|
39
|
+
run: |
|
|
40
|
+
ruff check --show-fixes
|
|
41
|
+
ruff format --check
|
|
42
|
+
mypy src
|
|
43
|
+
|
|
44
|
+
- name: Run tests
|
|
45
|
+
run: |
|
|
46
|
+
akernel --help
|
|
47
|
+
test -f ${pythonLocation}/../share/jupyter/kernels/akernel/kernel.json
|
|
48
|
+
pytest -v --reruns 5
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: akernel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: An asynchronous Python Jupyter kernel
|
|
5
5
|
Project-URL: Homepage, https://github.com/davidbrochart/akernel
|
|
6
6
|
Author-email: David Brochart <david.brochart@gmail.com>
|
|
@@ -9,34 +9,25 @@ License-File: LICENSE
|
|
|
9
9
|
Keywords: jupyter
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Programming Language :: Python
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.9
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
17
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
17
18
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
18
|
-
Requires-Python: >=3.
|
|
19
|
-
Requires-Dist: click
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
20
|
Requires-Dist: colorama
|
|
21
21
|
Requires-Dist: comm<1,>=0.1.3
|
|
22
|
-
Requires-Dist: gast
|
|
22
|
+
Requires-Dist: gast<0.7.0,>=0.6.0
|
|
23
23
|
Requires-Dist: python-dateutil
|
|
24
|
-
Requires-Dist: pyzmq
|
|
25
|
-
Requires-Dist: typer>=0.4.0
|
|
26
24
|
Provides-Extra: cache
|
|
27
25
|
Requires-Dist: zict; extra == 'cache'
|
|
28
26
|
Provides-Extra: react
|
|
29
27
|
Requires-Dist: ipyx>=0.1.7; extra == 'react'
|
|
30
|
-
Provides-Extra:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist: kernel-driver>=0.0.7; extra == 'test'
|
|
34
|
-
Requires-Dist: mypy; extra == 'test'
|
|
35
|
-
Requires-Dist: pytest; extra == 'test'
|
|
36
|
-
Requires-Dist: pytest-asyncio; extra == 'test'
|
|
37
|
-
Requires-Dist: ruff; extra == 'test'
|
|
38
|
-
Requires-Dist: types-python-dateutil; extra == 'test'
|
|
39
|
-
Requires-Dist: zict; extra == 'test'
|
|
28
|
+
Provides-Extra: subprocess
|
|
29
|
+
Requires-Dist: typer>=0.4.0; extra == 'subprocess'
|
|
30
|
+
Requires-Dist: zmq-anyio<0.4.0,>=0.3.9; extra == 'subprocess'
|
|
40
31
|
Description-Content-Type: text/markdown
|
|
41
32
|
|
|
42
33
|
[](https://github.com/davidbrochart/akernel/actions)
|
|
@@ -45,7 +36,8 @@ Description-Content-Type: text/markdown
|
|
|
45
36
|
|
|
46
37
|
# akernel
|
|
47
38
|
|
|
48
|
-
|
|
39
|
+
A Python Jupyter kernel, with different flavors:
|
|
40
|
+
- concurrent cell execution,
|
|
49
41
|
- reactive programming,
|
|
50
42
|
- cell execution caching,
|
|
51
43
|
- multi-kernel emulation.
|
|
@@ -61,11 +53,12 @@ pip install akernel
|
|
|
61
53
|
You can parameterize akernel's execution mode:
|
|
62
54
|
|
|
63
55
|
```bash
|
|
64
|
-
akernel install # default (
|
|
56
|
+
akernel install # default (chained cell execution mode)
|
|
57
|
+
akernel install concurrent # concurrent cell execution mode
|
|
65
58
|
akernel install react # reactive programming mode
|
|
66
59
|
akernel install cache # cell execution caching mode
|
|
67
60
|
akernel install multi # multi-kernel emulation mode
|
|
68
|
-
akernel install cache-multi-react # you can combine several modes
|
|
61
|
+
akernel install cache-multi-react-concurrent # you can combine several modes
|
|
69
62
|
```
|
|
70
63
|
|
|
71
64
|
## Motivation
|
|
@@ -75,13 +68,28 @@ akernel install cache-multi-react # you can combine several modes
|
|
|
75
68
|
This means you can `await` at the top-level, outside of an async function. Unfortunately, this will still
|
|
76
69
|
block the kernel.
|
|
77
70
|
|
|
78
|
-
akernel changes this behavior by launching each cell in a task.
|
|
71
|
+
akernel changes this behavior by launching each cell in a task. By default, cell tasks are chained, which
|
|
72
|
+
means that a cell will start executing after the previous one is done. You might wonder, is it not the same
|
|
73
|
+
as ipykernel then? Well, not quite. In ipykernel, when an async cell is executing, it also blocks the
|
|
74
|
+
processing of
|
|
75
|
+
[Comm messages](https://jupyter-client.readthedocs.io/en/stable/messaging.html#custom-messages), which
|
|
76
|
+
prevents the kernel from interacting with e.g. JupyterLab widgets (see
|
|
77
|
+
[here](https://github.com/ipython/ipykernel/issues/646) and
|
|
78
|
+
[there](https://github.com/ipython/ipykernel/issues/696)). In akernel, it will not be the case.
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
If you want to go all the way and have cells execute concurrently, you can also do so (see below).
|
|
81
81
|
|
|
82
82
|
## Features
|
|
83
83
|
|
|
84
|
-
###
|
|
84
|
+
### Concurrent execution
|
|
85
|
+
|
|
86
|
+
First, set the concurrent execution mode in order to have async cells execute concurrently
|
|
87
|
+
(you could also do that at install-time with `akernel install concurrent`):
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
__unchain_execution__()
|
|
91
|
+
# __chain_execution__()
|
|
92
|
+
```
|
|
85
93
|
|
|
86
94
|
akernel allows for asynchronous code execution. What this means is that when used in a Jupyter
|
|
87
95
|
notebook, you can run cells concurrently if the code is cooperative. For instance, you can run a
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
# akernel
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
A Python Jupyter kernel, with different flavors:
|
|
8
|
+
- concurrent cell execution,
|
|
8
9
|
- reactive programming,
|
|
9
10
|
- cell execution caching,
|
|
10
11
|
- multi-kernel emulation.
|
|
@@ -20,11 +21,12 @@ pip install akernel
|
|
|
20
21
|
You can parameterize akernel's execution mode:
|
|
21
22
|
|
|
22
23
|
```bash
|
|
23
|
-
akernel install # default (
|
|
24
|
+
akernel install # default (chained cell execution mode)
|
|
25
|
+
akernel install concurrent # concurrent cell execution mode
|
|
24
26
|
akernel install react # reactive programming mode
|
|
25
27
|
akernel install cache # cell execution caching mode
|
|
26
28
|
akernel install multi # multi-kernel emulation mode
|
|
27
|
-
akernel install cache-multi-react # you can combine several modes
|
|
29
|
+
akernel install cache-multi-react-concurrent # you can combine several modes
|
|
28
30
|
```
|
|
29
31
|
|
|
30
32
|
## Motivation
|
|
@@ -34,13 +36,28 @@ akernel install cache-multi-react # you can combine several modes
|
|
|
34
36
|
This means you can `await` at the top-level, outside of an async function. Unfortunately, this will still
|
|
35
37
|
block the kernel.
|
|
36
38
|
|
|
37
|
-
akernel changes this behavior by launching each cell in a task.
|
|
39
|
+
akernel changes this behavior by launching each cell in a task. By default, cell tasks are chained, which
|
|
40
|
+
means that a cell will start executing after the previous one is done. You might wonder, is it not the same
|
|
41
|
+
as ipykernel then? Well, not quite. In ipykernel, when an async cell is executing, it also blocks the
|
|
42
|
+
processing of
|
|
43
|
+
[Comm messages](https://jupyter-client.readthedocs.io/en/stable/messaging.html#custom-messages), which
|
|
44
|
+
prevents the kernel from interacting with e.g. JupyterLab widgets (see
|
|
45
|
+
[here](https://github.com/ipython/ipykernel/issues/646) and
|
|
46
|
+
[there](https://github.com/ipython/ipykernel/issues/696)). In akernel, it will not be the case.
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
If you want to go all the way and have cells execute concurrently, you can also do so (see below).
|
|
40
49
|
|
|
41
50
|
## Features
|
|
42
51
|
|
|
43
|
-
###
|
|
52
|
+
### Concurrent execution
|
|
53
|
+
|
|
54
|
+
First, set the concurrent execution mode in order to have async cells execute concurrently
|
|
55
|
+
(you could also do that at install-time with `akernel install concurrent`):
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
__unchain_execution__()
|
|
59
|
+
# __chain_execution__()
|
|
60
|
+
```
|
|
44
61
|
|
|
45
62
|
akernel allows for asynchronous code execution. What this means is that when used in a Jupyter
|
|
46
63
|
notebook, you can run cells concurrently if the code is cooperative. For instance, you can run a
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"id": "1424909b-49ae-4f63-938c-c72cb3f84550",
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"source": [
|
|
8
|
+
"If you execute the three following for-loops, you can see that they are executed concurrently."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"cell_type": "code",
|
|
13
|
+
"execution_count": null,
|
|
14
|
+
"id": "97b4a9c1-6818-404d-9e4f-64569dd9351f",
|
|
15
|
+
"metadata": {},
|
|
16
|
+
"outputs": [],
|
|
17
|
+
"source": [
|
|
18
|
+
"__unchain_execution__()"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"cell_type": "code",
|
|
23
|
+
"execution_count": null,
|
|
24
|
+
"id": "073b08dd-d004-4f94-8522-bfa1002c9694",
|
|
25
|
+
"metadata": {},
|
|
26
|
+
"outputs": [],
|
|
27
|
+
"source": [
|
|
28
|
+
"for i in range(5):\n",
|
|
29
|
+
" await asyncio.sleep(1)\n",
|
|
30
|
+
" print(f\"{i=}\")"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"cell_type": "code",
|
|
35
|
+
"execution_count": null,
|
|
36
|
+
"id": "1ced9a54-9d08-4cb7-bd57-e68db9b1d7fb",
|
|
37
|
+
"metadata": {},
|
|
38
|
+
"outputs": [],
|
|
39
|
+
"source": [
|
|
40
|
+
"for j in range(5):\n",
|
|
41
|
+
" await asyncio.sleep(1)\n",
|
|
42
|
+
" print(f\"{j=}\")"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"cell_type": "code",
|
|
47
|
+
"execution_count": null,
|
|
48
|
+
"id": "98e994bb-caa2-45f7-b35d-a183facb1b72",
|
|
49
|
+
"metadata": {},
|
|
50
|
+
"outputs": [],
|
|
51
|
+
"source": [
|
|
52
|
+
"for k in range(5):\n",
|
|
53
|
+
" await asyncio.sleep(1)\n",
|
|
54
|
+
" print(f\"{k=}\")"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"cell_type": "markdown",
|
|
59
|
+
"id": "558b8d22-d221-4ea8-bc25-e261ea491b7d",
|
|
60
|
+
"metadata": {},
|
|
61
|
+
"source": [
|
|
62
|
+
"Now if you execute the three following for-loops, you can see that they are executed one after the other."
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"cell_type": "code",
|
|
67
|
+
"execution_count": null,
|
|
68
|
+
"id": "422c2851-f7c8-460c-9544-13c9c8ebfe0b",
|
|
69
|
+
"metadata": {},
|
|
70
|
+
"outputs": [],
|
|
71
|
+
"source": [
|
|
72
|
+
"__chain_execution__()"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"cell_type": "code",
|
|
77
|
+
"execution_count": null,
|
|
78
|
+
"id": "21b5428c-9fcf-4150-af59-635deab42833",
|
|
79
|
+
"metadata": {},
|
|
80
|
+
"outputs": [],
|
|
81
|
+
"source": [
|
|
82
|
+
"for i in range(5):\n",
|
|
83
|
+
" await asyncio.sleep(1)\n",
|
|
84
|
+
" print(f\"{i=}\")"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"cell_type": "code",
|
|
89
|
+
"execution_count": null,
|
|
90
|
+
"id": "5ee578b3-6b4d-4315-ab17-8c845d740b36",
|
|
91
|
+
"metadata": {},
|
|
92
|
+
"outputs": [],
|
|
93
|
+
"source": [
|
|
94
|
+
"for j in range(5):\n",
|
|
95
|
+
" await asyncio.sleep(1)\n",
|
|
96
|
+
" print(f\"{j=}\")"
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"cell_type": "code",
|
|
101
|
+
"execution_count": null,
|
|
102
|
+
"id": "16f0146a-fdf8-4fbe-bf37-63b2da2fe1e0",
|
|
103
|
+
"metadata": {},
|
|
104
|
+
"outputs": [],
|
|
105
|
+
"source": [
|
|
106
|
+
"for k in range(5):\n",
|
|
107
|
+
" await asyncio.sleep(1)\n",
|
|
108
|
+
" print(f\"{k=}\")"
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"metadata": {
|
|
113
|
+
"kernelspec": {
|
|
114
|
+
"display_name": "Python 3 (akernel)",
|
|
115
|
+
"language": "python",
|
|
116
|
+
"name": "akernel"
|
|
117
|
+
},
|
|
118
|
+
"language_info": {
|
|
119
|
+
"file_extension": ".py",
|
|
120
|
+
"mimetype": "text/x-python",
|
|
121
|
+
"name": "python",
|
|
122
|
+
"version": "3.11.4"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"nbformat": 4,
|
|
126
|
+
"nbformat_minor": 5
|
|
127
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 David Brochart
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from anyio import TASK_STATUS_IGNORED, create_task_group, sleep_forever
|
|
4
|
+
from anyio.abc import TaskStatus
|
|
5
|
+
from jupyverse_api.kernel import Kernel as _Kernel
|
|
6
|
+
|
|
7
|
+
from akernel.kernel import Kernel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AKernelTask(_Kernel):
|
|
11
|
+
def __init__(self, *args, **kwargs):
|
|
12
|
+
super().__init__()
|
|
13
|
+
|
|
14
|
+
async def start(self, *, task_status: TaskStatus[None] = TASK_STATUS_IGNORED) -> None:
|
|
15
|
+
async with (
|
|
16
|
+
create_task_group() as self.task_group,
|
|
17
|
+
self._to_shell_send_stream,
|
|
18
|
+
self._to_shell_receive_stream,
|
|
19
|
+
self._from_shell_send_stream,
|
|
20
|
+
self._from_shell_receive_stream,
|
|
21
|
+
self._to_control_send_stream,
|
|
22
|
+
self._to_control_receive_stream,
|
|
23
|
+
self._from_control_send_stream,
|
|
24
|
+
self._from_control_receive_stream,
|
|
25
|
+
self._to_stdin_send_stream,
|
|
26
|
+
self._to_stdin_receive_stream,
|
|
27
|
+
self._from_stdin_send_stream,
|
|
28
|
+
self._from_stdin_receive_stream,
|
|
29
|
+
self._from_iopub_send_stream,
|
|
30
|
+
self._from_iopub_receive_stream,
|
|
31
|
+
):
|
|
32
|
+
self.kernel = Kernel(
|
|
33
|
+
self._to_shell_receive_stream,
|
|
34
|
+
self._from_shell_send_stream,
|
|
35
|
+
self._to_control_receive_stream,
|
|
36
|
+
self._from_control_send_stream,
|
|
37
|
+
self._to_stdin_receive_stream,
|
|
38
|
+
self._from_stdin_send_stream,
|
|
39
|
+
self._from_iopub_send_stream,
|
|
40
|
+
)
|
|
41
|
+
self.task_group.start_soon(self.kernel.start)
|
|
42
|
+
task_status.started()
|
|
43
|
+
await sleep_forever()
|
|
44
|
+
|
|
45
|
+
async def stop(self) -> None:
|
|
46
|
+
self.task_group.cancel_scope.cancel()
|
|
47
|
+
|
|
48
|
+
async def interrupt(self) -> None:
|
|
49
|
+
pass
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from fps import Module
|
|
4
|
+
|
|
5
|
+
from jupyverse_api.kernel import KernelFactory
|
|
6
|
+
from jupyverse_api.kernels import Kernels
|
|
7
|
+
|
|
8
|
+
from .akernel_task import AKernelTask
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AKernelTaskModule(Module):
|
|
12
|
+
async def prepare(self) -> None:
|
|
13
|
+
kernels = await self.get(Kernels)
|
|
14
|
+
kernels.register_kernel_factory("akernel", KernelFactory(AKernelTask))
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "fps_akernel_task"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "An FPS plugin for the kernel task API"
|
|
9
|
+
keywords = ["jupyter", "server", "fastapi", "plugins"]
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"jupyverse-api >=0.10.0,<0.11.0",
|
|
13
|
+
"anyio",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[[project.authors]]
|
|
17
|
+
name = "David Brochart"
|
|
18
|
+
email = "david.brochart@gmail.com"
|
|
19
|
+
|
|
20
|
+
[project.readme]
|
|
21
|
+
file = "README.md"
|
|
22
|
+
content-type = "text/markdown"
|
|
23
|
+
|
|
24
|
+
[project.license]
|
|
25
|
+
text = "MIT"
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/davidbrochart/akernel"
|
|
29
|
+
|
|
30
|
+
[project.entry-points]
|
|
31
|
+
"fps.modules" = {akernel_task = "fps_akernel_task.main:AKernelTaskModule"}
|
|
32
|
+
"jupyverse.modules" = {akernel_task = "fps_akernel_task.main:AKernelTaskModule"}
|
|
@@ -4,46 +4,50 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "akernel"
|
|
7
|
-
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "An asynchronous Python Jupyter kernel"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
12
|
authors = [{name = "David Brochart", email = "david.brochart@gmail.com"}]
|
|
13
13
|
classifiers = [
|
|
14
14
|
"Development Status :: 4 - Beta",
|
|
15
15
|
"Programming Language :: Python",
|
|
16
|
-
"Programming Language :: Python :: 3.8",
|
|
17
16
|
"Programming Language :: Python :: 3.9",
|
|
18
17
|
"Programming Language :: Python :: 3.10",
|
|
19
18
|
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
20
21
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
21
22
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
22
23
|
]
|
|
23
24
|
keywords = [ "jupyter" ]
|
|
24
25
|
dependencies = [
|
|
25
|
-
"pyzmq",
|
|
26
|
-
"typer >=0.4.0",
|
|
27
|
-
"click",
|
|
28
26
|
"python-dateutil",
|
|
29
27
|
"colorama",
|
|
30
|
-
"gast >=0.
|
|
28
|
+
"gast >=0.6.0, <0.7.0",
|
|
31
29
|
"comm >=0.1.3,<1",
|
|
32
30
|
]
|
|
33
31
|
|
|
34
|
-
[
|
|
32
|
+
[dependency-groups]
|
|
35
33
|
test = [
|
|
36
34
|
"mypy",
|
|
37
35
|
"ruff",
|
|
38
|
-
"black",
|
|
39
36
|
"pytest",
|
|
40
37
|
"pytest-asyncio",
|
|
38
|
+
"pytest-rerunfailures",
|
|
41
39
|
"types-python-dateutil",
|
|
42
40
|
"kernel_driver >=0.0.7",
|
|
43
41
|
"ipyx >=0.1.7",
|
|
44
42
|
"zict",
|
|
45
43
|
]
|
|
46
44
|
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
subprocess = [
|
|
47
|
+
"zmq-anyio >=0.3.9,<0.4.0",
|
|
48
|
+
"typer >=0.4.0",
|
|
49
|
+
]
|
|
50
|
+
|
|
47
51
|
react = [
|
|
48
52
|
"ipyx >=0.1.7",
|
|
49
53
|
]
|
|
@@ -55,14 +59,19 @@ cache = [
|
|
|
55
59
|
[project.scripts]
|
|
56
60
|
akernel = "akernel.akernel:cli"
|
|
57
61
|
|
|
62
|
+
[tool.hatch.build.targets.wheel]
|
|
63
|
+
ignore-vcs = true
|
|
64
|
+
packages = ["src/akernel"]
|
|
65
|
+
|
|
58
66
|
[tool.hatch.build.targets.wheel.shared-data]
|
|
59
67
|
"share/jupyter/kernels/akernel/kernel.json" = "share/jupyter/kernels/akernel/kernel.json"
|
|
60
68
|
|
|
61
69
|
[project.urls]
|
|
62
70
|
Homepage = "https://github.com/davidbrochart/akernel"
|
|
63
71
|
|
|
64
|
-
[tool.hatch.version]
|
|
65
|
-
path = "akernel/__init__.py"
|
|
66
|
-
|
|
67
72
|
[tool.ruff]
|
|
68
73
|
line-length = 100
|
|
74
|
+
exclude = ["examples"]
|
|
75
|
+
|
|
76
|
+
[tool.uv.sources]
|
|
77
|
+
fps-akernel-task = { workspace = true }
|