kernel-checkpoint 0.1.1__tar.gz → 0.1.2__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 (54) hide show
  1. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/PKG-INFO +1 -1
  2. kernel_checkpoint-0.1.2/cursor_jupyterlab_extension_for_checkpo.md +257 -0
  3. kernel_checkpoint-0.1.2/jupyter-notebook-image/Dockerfile +9 -0
  4. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/kernel_checkpoint/_version.py +1 -1
  5. kernel_checkpoint-0.1.2/kernel_checkpoint/labextension/build_log.json +716 -0
  6. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/kernel_checkpoint/labextension/package.json +1 -1
  7. kernel_checkpoint-0.1.2/kernel_checkpoint/labextension/static/lib_index_js.2c713e3ab2e5b31ee0e1.js +502 -0
  8. kernel_checkpoint-0.1.2/kernel_checkpoint/labextension/static/lib_index_js.2c713e3ab2e5b31ee0e1.js.map +1 -0
  9. kernel_checkpoint-0.1.2/kernel_checkpoint/labextension/static/remoteEntry.0ec66dead21656df694e.js +562 -0
  10. kernel_checkpoint-0.1.2/kernel_checkpoint/labextension/static/remoteEntry.0ec66dead21656df694e.js.map +1 -0
  11. kernel_checkpoint-0.1.2/kernel_checkpoint/labextension/static/style_index_js.c3e72438ed03e9dee0fc.js +814 -0
  12. kernel_checkpoint-0.1.2/kernel_checkpoint/labextension/static/style_index_js.c3e72438ed03e9dee0fc.js.map +1 -0
  13. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/package.json +1 -1
  14. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/src/api.ts +1 -1
  15. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/src/checkpoint-panel.tsx +13 -27
  16. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/src/index.ts +1 -1
  17. kernel_checkpoint-0.1.1/kernel_checkpoint/labextension/static/397.487e741e4ad2ed6339f5.js +0 -1
  18. kernel_checkpoint-0.1.1/kernel_checkpoint/labextension/static/728.4bf362e015a01b33d460.js +0 -1
  19. kernel_checkpoint-0.1.1/kernel_checkpoint/labextension/static/remoteEntry.d4b802a14146b6757b67.js +0 -1
  20. kernel_checkpoint-0.1.1/kernel_checkpoint/labextension/static/third-party-licenses.json +0 -16
  21. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/.copier-answers.yml +0 -0
  22. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/.gitignore +0 -0
  23. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/.prettierignore +0 -0
  24. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/.yarnrc.yml +0 -0
  25. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/4 +0 -0
  26. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/=4 +0 -0
  27. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/CHANGELOG.md +0 -0
  28. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/LICENSE +0 -0
  29. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/README.md +0 -0
  30. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/RELEASE.md +0 -0
  31. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/babel.config.js +0 -0
  32. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/install.json +0 -0
  33. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/jest.config.js +0 -0
  34. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/jupyter-config/jupyter_server_config.d/kernel_checkpoint.json +0 -0
  35. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/kernel_checkpoint/Untitled.ipynb +0 -0
  36. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/kernel_checkpoint/__init__.py +0 -0
  37. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/kernel_checkpoint/handlers.py +0 -0
  38. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/kernel_checkpoint/labextension/static/style.js +0 -0
  39. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/pyproject.toml +0 -0
  40. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/setup.py +0 -0
  41. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/src/__tests__/kernel_checkpoint.spec.ts +0 -0
  42. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/src/types.ts +0 -0
  43. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/style/base.css +0 -0
  44. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/style/index.css +0 -0
  45. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/style/index.js +0 -0
  46. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/tsconfig.json +0 -0
  47. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/tsconfig.test.json +0 -0
  48. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/ui-tests/README.md +0 -0
  49. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/ui-tests/jupyter_server_test_config.py +0 -0
  50. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/ui-tests/package.json +0 -0
  51. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/ui-tests/playwright.config.js +0 -0
  52. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/ui-tests/tests/kernel_checkpoint.spec.ts +0 -0
  53. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/ui-tests/yarn.lock +0 -0
  54. {kernel_checkpoint-0.1.1 → kernel_checkpoint-0.1.2}/yarn.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kernel_checkpoint
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: An extension for saving and restoring kernel pod state with jupyter enterprise gateway
5
5
  Project-URL: Homepage, https://github.com/lehuannhatrang/kernel-checkpoint-extension.git
6
6
  Project-URL: Bug Tracker, https://github.com/lehuannhatrang/kernel-checkpoint-extension.git/issues
@@ -0,0 +1,257 @@
1
+ # JupyterLab extension for checkpoint management
2
+ _Exported on 4/9/2026 at 23:59:07 GMT+9 from Cursor (3.0.13)_
3
+
4
+ ---
5
+
6
+ **User**
7
+
8
+ i am building a jupyterlab extension for checkpoint/restore pod kernel ( kernel pod of jupyter enterprise gateway). TO do that , on the UI, we need a button "Saving points" to open a modal. In the modal, there are list of checkpoints which that user has taken before. User can choose one of them to restore. And also there is a button on the modal which will trigger checkpoint "Saving kernel state". When click the saving kernel state button, we allow user to type the name of checkpoint, and use that name to send to the API server. User also can get the status of a checkpoint, modify checkpoint name, delete a checkpoint.
9
+ I has already implemented the API server. The API server endpoint should be got from the configured jupyter env "CHECKPOINT_API_URL" . This is the example of api:
10
+ 1. List checkpoints for a namespace:
11
+ curl --location 'http://192.168.40.246:31809/api/v1/checkpoints?namespace=kubeflow-user-example-com'
12
+ response:
13
+ {
14
+ "items": [
15
+ {
16
+ "name": "checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-20260409-100748",
17
+ "namespace": "kubeflow-user-example-com",
18
+ "phase": "Completed",
19
+ "message": "All containers checkpointed successfully",
20
+ "schedule": "immediately",
21
+ "podRef": {
22
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
23
+ "namespace": "kubeflow-user-example-com"
24
+ },
25
+ "resourceRef": {
26
+ "apiVersion": "v1",
27
+ "kind": "Pod",
28
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
29
+ "namespace": "kubeflow-user-example-com"
30
+ },
31
+ "checkpointFiles": [
32
+ {
33
+ "containerName": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
34
+ "filePath": "checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f_kubeflow-user-example-com-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-2026-04-09T19:07:48+09:00.tar",
35
+ "checkpointTime": "2026-04-09T10:07:54Z"
36
+ }
37
+ ],
38
+ "builtImages": [
39
+ {
40
+ "containerName": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
41
+ "imageName": "localhost/checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f:20260409-100754",
42
+ "buildTime": "2026-04-09T10:08:01Z",
43
+ "pushed": false
44
+ }
45
+ ],
46
+ "createdAt": "2026-04-09T10:07:48Z"
47
+ },
48
+ {
49
+ "name": "test-checkpoint-1",
50
+ "namespace": "kubeflow-user-example-com",
51
+ "phase": "Completed",
52
+ "message": "All containers checkpointed successfully",
53
+ "schedule": "immediately",
54
+ "buildImage": false,
55
+ "podRef": {
56
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
57
+ "namespace": "kubeflow-user-example-com"
58
+ },
59
+ "resourceRef": {
60
+ "apiVersion": "v1",
61
+ "kind": "Pod",
62
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
63
+ "namespace": "kubeflow-user-example-com"
64
+ },
65
+ "checkpointFiles": [
66
+ {
67
+ "containerName": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
68
+ "filePath": "checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f_kubeflow-user-example-com-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-2026-04-09T19:12:46+09:00.tar",
69
+ "storagePath": "kubeflow-user-example-com/checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f_kubeflow-user-example-com-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-2026-04-09T19:12:46+09:00.tar",
70
+ "checkpointTime": "2026-04-09T10:12:52Z"
71
+ }
72
+ ],
73
+ "createdAt": "2026-04-09T10:12:46Z"
74
+ }
75
+ ],
76
+ "totalCount": 2
77
+ }
78
+
79
+ 2. get checkpoint status: curl --location 'http://192.168.40.246:31809/api/v1/checkpoints/kubeflow-user-example-com/test-checkpoint-1'
80
+ Response:
81
+ {
82
+ "name": "test-checkpoint-1",
83
+ "namespace": "kubeflow-user-example-com",
84
+ "phase": "Completed",
85
+ "message": "All containers checkpointed successfully",
86
+ "schedule": "immediately",
87
+ "buildImage": false,
88
+ "podRef": {
89
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
90
+ "namespace": "kubeflow-user-example-com"
91
+ },
92
+ "resourceRef": {
93
+ "apiVersion": "v1",
94
+ "kind": "Pod",
95
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
96
+ "namespace": "kubeflow-user-example-com"
97
+ },
98
+ "checkpointFiles": [
99
+ {
100
+ "containerName": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
101
+ "filePath": "checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f_kubeflow-user-example-com-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-2026-04-09T19:12:46+09:00.tar",
102
+ "storagePath": "kubeflow-user-example-com/checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f_kubeflow-user-example-com-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-2026-04-09T19:12:46+09:00.tar",
103
+ "checkpointTime": "2026-04-09T10:12:52Z"
104
+ }
105
+ ],
106
+ "createdAt": "2026-04-09T10:12:46Z"
107
+ }
108
+
109
+ 3. Create checkpoint:
110
+ curl --location 'http://192.168.40.246:31809/api/v1/checkpoints' \
111
+ --header 'Content-Type: application/json' \
112
+ --data '{
113
+ "name": "test-checkpoint-1",
114
+ "namespace": "kubeflow-user-example-com",
115
+ "kernelId": "5df368c8-a92f-408e-8c7d-7ffdf345f86f",
116
+ "buildImage": false
117
+ }'
118
+
119
+ response:
120
+ {
121
+ "name": "test-checkpoint-1",
122
+ "namespace": "kubeflow-user-example-com",
123
+ "schedule": "immediately",
124
+ "buildImage": false,
125
+ "podRef": {
126
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
127
+ "namespace": "kubeflow-user-example-com"
128
+ },
129
+ "resourceRef": {
130
+ "apiVersion": "v1",
131
+ "kind": "Pod",
132
+ "name": "jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f",
133
+ "namespace": "kubeflow-user-example-com"
134
+ },
135
+ "createdAt": "2026-04-09T10:12:46Z"
136
+ }
137
+
138
+ 4. Delete checkpoint:
139
+ curl --location --request DELETE 'http://192.168.40.246:31809/api/v1/checkpoints/kubeflow-user-example-com/checkpoint-jovyan-5df368c8-a92f-408e-8c7d-7ffdf345f86f-20260409-100748'
140
+
141
+ Note that the jupyter notebook i deployed by kubeflow, when sending request we should get the namespace (and kernel id in the create scenario)
142
+
143
+ And When user choose 1 saving point to restore, we will use Local Jupyter Server to create kernel with extra env so that the next step in our system will know to handle. for example this is my asumption how to handle, please recheck and implement
144
+ const initRequest = {
145
+ method: 'POST',
146
+ body: JSON.stringify({
147
+ name: 'python_kubernetes', // kernel spec , should match with checkpoint kernel.
148
+ env: {
149
+ 'CHECKPOINT_RESTORE_NAME': checkpointName, // checkpoint name
150
+ }
151
+ })
152
+ };
153
+ const response = await ServerConnection.makeRequest(url, initRequest, settings);
154
+ ...
155
+
156
+ ---
157
+
158
+ **Cursor**
159
+
160
+ Let me start by exploring the existing codebase structure.
161
+
162
+ Now I have a clear picture of the scaffold. It's a JupyterLab 4 extension with only a stub plugin. I need to build: a Python server extension to proxy the checkpoint API, and a React-based frontend with a toolbar button, modal dialog, and checkpoint management UI.
163
+
164
+ Let me implement everything.
165
+
166
+ Now let me implement the TypeScript frontend. I'll create the types, API client, React component, update the plugin, add dependencies, and write styles.
167
+
168
+ Now update `src/index.ts` with the plugin that wires everything together, including the restore flow:
169
+
170
+ Now let me update the CSS, `package.json`, and `tsconfig.json`:
171
+
172
+ Now update `package.json` to add the required frontend dependencies and server extension discovery:
173
+
174
+ Update `tsconfig.json` to handle `.tsx` files in subdirectories:
175
+
176
+ Now let's install dependencies and build to verify everything compiles:
177
+
178
+ Dependencies installed. Now let's build the TypeScript:
179
+
180
+ TypeScript compiled cleanly. Let's also build the full lab extension:
181
+
182
+ Everything compiles and builds successfully. Let me also verify the Python server extension works:
183
+
184
+ Everything builds successfully. Here's a summary of what was implemented:
185
+
186
+ ---
187
+
188
+ ## Architecture Overview
189
+
190
+ ### Python Server Extension (`kernel_checkpoint/`)
191
+
192
+ **`handlers.py`** — Tornado request handlers that proxy all calls to the external checkpoint API (read from `CHECKPOINT_API_URL` env var). This avoids CORS issues and keeps the API URL server-side:
193
+
194
+ | Endpoint | Method | Description |
195
+ |---|---|---|
196
+ | `/kernel-checkpoint/config` | GET | Returns `{checkpointApiUrl, namespace}` to the frontend |
197
+ | `/kernel-checkpoint/checkpoints` | GET | Lists checkpoints for a namespace (proxies `?namespace=`) |
198
+ | `/kernel-checkpoint/checkpoints` | POST | Creates a new checkpoint |
199
+ | `/kernel-checkpoint/checkpoints/<ns>/<name>` | GET | Gets checkpoint status/details |
200
+ | `/kernel-checkpoint/checkpoints/<ns>/<name>` | DELETE | Deletes a checkpoint |
201
+ | `/kernel-checkpoint/checkpoints/<ns>/<name>` | PATCH | Updates/renames a checkpoint |
202
+
203
+ **Namespace resolution** — Reads `CHECKPOINT_NAMESPACE` env var, falling back to the Kubernetes service account namespace at `/var/run/secrets/kubernetes.io/serviceaccount/namespace`.
204
+
205
+ ### TypeScript Frontend (`src/`)
206
+
207
+ **`types.ts`** — Interfaces for `ICheckpoint`, `ICheckpointListResponse`, `ICheckpointConfig`, `ICreateCheckpointRequest`, etc.
208
+
209
+ **`api.ts`** — `CheckpointAPI` namespace wrapping `ServerConnection.makeRequest` calls to the server extension proxy endpoints.
210
+
211
+ **`checkpoint-panel.tsx`** — The main React component rendered inside the dialog:
212
+ - **Save Kernel State** button at top, which reveals an inline form to name the checkpoint
213
+ - **Checkpoint list** showing each checkpoint with name, phase badge (Completed/Failed/In Progress), and creation date
214
+ - **Per-checkpoint actions**: Details (expand status info), Rename (inline edit), Delete (with inline confirmation), Restore (with inline confirmation)
215
+ - **Auto-refresh** every 5s when any checkpoint is still in progress
216
+ - **Flash messages** for success/error feedback
217
+
218
+ **`index.ts`** — Main plugin:
219
+ - Registers the `kernel-checkpoint:open` command
220
+ - Adds a **"Saving Points" toolbar button** to every notebook panel
221
+ - On click: fetches config, validates namespace + kernel connection, then opens a `showDialog` modal with the `CheckpointPanel`
222
+
223
+ ### Restore Flow
224
+
225
+ When a user clicks **Restore** on a completed checkpoint:
226
+ 1. A new kernel is created via `POST /api/kernels` with:
227
+
228
+ ```json
229
+ {
230
+ "name": "<current_kernel_spec_name>",
231
+ "env": {
232
+ "CHECKPOINT_RESTORE_NAME": "<checkpoint_name>"
233
+ }
234
+ }
235
+ ```
236
+
237
+ 2. The notebook session is switched to the new kernel via `sessionContext.changeKernel({ id: newKernelId })`
238
+ 3. The old kernel is shut down automatically by the session manager
239
+
240
+ ### Configuration
241
+
242
+ Two environment variables are needed on the Jupyter server pod:
243
+ - **`CHECKPOINT_API_URL`** — Base URL of the checkpoint API server (e.g. `http://192.168.40.246:31809`)
244
+ - **`CHECKPOINT_NAMESPACE`** — Kubernetes namespace (optional if running in-cluster, will auto-detect from service account)
245
+
246
+ ### Build & Install
247
+
248
+ ```bash
249
+ # Development install
250
+ pip install -e ".[dev]"
251
+ jupyter labextension develop . --overwrite
252
+ jupyter server extension enable kernel_checkpoint
253
+
254
+ # Or simply build
255
+ jlpm install && jlpm build
256
+ ```
257
+
@@ -0,0 +1,9 @@
1
+ FROM ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-scipy:v1.10.0
2
+
3
+ USER root
4
+
5
+ RUN pip install --upgrade pip
6
+
7
+ RUN pip install --no-cache-dir kernel-checkpoint
8
+
9
+ USER jovyan
@@ -1,4 +1,4 @@
1
1
  # This file is auto-generated by Hatchling. As such, do not:
2
2
  # - modify
3
3
  # - track in version control e.g. be sure to add to .gitignore
4
- __version__ = VERSION = '0.1.1'
4
+ __version__ = VERSION = '0.1.2'