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.
Files changed (46) hide show
  1. akernel-0.3.0/.github/workflows/main.yml +48 -0
  2. akernel-0.3.0/.pre-commit-config.yaml +7 -0
  3. {akernel-0.1.1 → akernel-0.3.0}/PKG-INFO +32 -24
  4. {akernel-0.1.1 → akernel-0.3.0}/README.md +23 -6
  5. {akernel-0.1.1 → akernel-0.3.0}/binder/postBuild +1 -0
  6. akernel-0.3.0/examples/concurrency.ipynb +127 -0
  7. {akernel-0.1.1 → akernel-0.3.0}/examples/reactivity.ipynb +1 -1
  8. akernel-0.3.0/plugins/akernel_task/LICENSE +21 -0
  9. akernel-0.3.0/plugins/akernel_task/README.md +3 -0
  10. akernel-0.3.0/plugins/akernel_task/fps_akernel_task/__init__.py +6 -0
  11. akernel-0.3.0/plugins/akernel_task/fps_akernel_task/akernel_task.py +49 -0
  12. akernel-0.3.0/plugins/akernel_task/fps_akernel_task/main.py +14 -0
  13. akernel-0.3.0/plugins/akernel_task/pyproject.toml +32 -0
  14. {akernel-0.1.1 → akernel-0.3.0}/pyproject.toml +21 -12
  15. akernel-0.3.0/src/akernel/__init__.py +6 -0
  16. akernel-0.3.0/src/akernel/akernel.py +140 -0
  17. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/cache.py +4 -5
  18. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/code.py +27 -28
  19. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/comm/comm.py +17 -18
  20. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/comm/manager.py +6 -5
  21. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/connect.py +7 -7
  22. akernel-0.3.0/src/akernel/display/__init__.py +0 -0
  23. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/display/display.py +3 -2
  24. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/execution.py +10 -8
  25. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/kernel.py +147 -99
  26. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/kernelspec.py +3 -4
  27. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/message.py +41 -51
  28. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/traceback.py +6 -7
  29. {akernel-0.1.1/akernel → akernel-0.3.0}/tests/conftest.py +5 -4
  30. {akernel-0.1.1/akernel → akernel-0.3.0}/tests/test_execution.py +5 -3
  31. {akernel-0.1.1/akernel → akernel-0.3.0}/tests/test_kernel.py +8 -15
  32. {akernel-0.1.1/akernel → akernel-0.3.0}/tests/test_react_code.py +1 -3
  33. akernel-0.1.1/.github/workflows/main.yml +0 -57
  34. akernel-0.1.1/akernel/__init__.py +0 -1
  35. akernel-0.1.1/akernel/akernel.py +0 -38
  36. {akernel-0.1.1 → akernel-0.3.0}/LICENSE +0 -0
  37. {akernel-0.1.1 → akernel-0.3.0}/MANIFEST.in +0 -0
  38. {akernel-0.1.1 → akernel-0.3.0}/binder/environment.yml +0 -0
  39. /akernel-0.1.1/akernel/IPython/core/__init__.py → /akernel-0.3.0/plugins/akernel_task/fps_akernel_task/py.typed +0 -0
  40. {akernel-0.1.1 → akernel-0.3.0}/share/jupyter/kernels/akernel/kernel.json +0 -0
  41. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/IPython/__init__.py +0 -0
  42. {akernel-0.1.1/akernel/display → akernel-0.3.0/src/akernel/IPython/core}/__init__.py +0 -0
  43. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/IPython/core/getipython.py +0 -0
  44. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/IPython/core/interactiveshell.py +0 -0
  45. {akernel-0.1.1 → akernel-0.3.0/src}/akernel/comm/__init__.py +0 -0
  46. {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
@@ -0,0 +1,7 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.11.13
4
+ hooks:
5
+ - id: ruff-check
6
+ args: [--fix, --show-fixes]
7
+ - id: ruff-format
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: akernel
3
- Version: 0.1.1
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.8
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>=0.5.3
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: test
31
- Requires-Dist: black; extra == 'test'
32
- Requires-Dist: ipyx>=0.1.7; extra == 'test'
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
  [![Build Status](https://github.com/davidbrochart/akernel/workflows/CI/badge.svg)](https://github.com/davidbrochart/akernel/actions)
@@ -45,7 +36,8 @@ Description-Content-Type: text/markdown
45
36
 
46
37
  # akernel
47
38
 
48
- An asynchronous Python Jupyter kernel, with different flavors:
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 (async)
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
- akernel now also supports reactive programming, although it is still experimental!
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
- ### Asynchronous execution
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
- An asynchronous Python Jupyter kernel, with different flavors:
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 (async)
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
- akernel now also supports reactive programming, although it is still experimental!
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
- ### Asynchronous execution
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
@@ -1,4 +1,5 @@
1
1
  #!/bin/bash
2
2
 
3
3
  python -m pip install -e .
4
+ akernel install
4
5
  akernel install react
@@ -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
+ }
@@ -257,7 +257,7 @@
257
257
  "kernelspec": {
258
258
  "display_name": "Python 3 (akernel-react)",
259
259
  "language": "python",
260
- "name": "akernel"
260
+ "name": "akernel-react"
261
261
  },
262
262
  "language_info": {
263
263
  "file_extension": ".py",
@@ -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,3 @@
1
+ # fps-akernel-task
2
+
3
+ An FPS plugin for the kernel task API.
@@ -0,0 +1,6 @@
1
+ import importlib.metadata
2
+
3
+ try:
4
+ __version__ = importlib.metadata.version("fps_akernel_task")
5
+ except importlib.metadata.PackageNotFoundError:
6
+ __version__ = "unknown"
@@ -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
- dynamic = ["version"]
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.8"
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.5.3",
28
+ "gast >=0.6.0, <0.7.0",
31
29
  "comm >=0.1.3,<1",
32
30
  ]
33
31
 
34
- [project.optional-dependencies]
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 }
@@ -0,0 +1,6 @@
1
+ import importlib.metadata
2
+
3
+ try:
4
+ __version__ = importlib.metadata.version("akernel")
5
+ except importlib.metadata.PackageNotFoundError:
6
+ __version__ = "unknown"