Skip to content

Commit cb26de0

Browse files
Convert Deepnote file to Jupyter notebook
Signed-off-by: Andy Jakubowski <[email protected]>
1 parent 07bb549 commit cb26de0

File tree

7 files changed

+100
-37
lines changed

7 files changed

+100
-37
lines changed

.yarnrc.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
nodeLinker: node-modules
2+
npmScopes:
3+
deepnote:
4+
npmRegistryServer: 'https://npm.pkg.github.com'
5+
npmAlwaysAuth: true
6+
npmAuthToken: '${GITHUB_TOKEN}'

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,15 @@
5858
"watch:labextension": "jupyter labextension watch ."
5959
},
6060
"dependencies": {
61-
"@deepnote/blocks": "file:/Users/work/repos/deepnote/deepnote/packages/blocks",
61+
"@deepnote/blocks": "^1.0.0",
6262
"@jupyterlab/application": "^4.0.0",
6363
"@jupyterlab/coreutils": "^6.0.0",
6464
"@jupyterlab/notebook": "^4.4.7",
6565
"@jupyterlab/services": "^7.0.0",
6666
"@jupyterlab/settingregistry": "^4.0.0",
6767
"@lumino/widgets": "^2.7.1",
68+
"@types/lodash": "^4.17.20",
69+
"lodash": "^4.17.21",
6870
"yaml": "^2.8.1",
6971
"zod": "^4.1.11"
7072
},
Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,47 @@
1-
import { convertCellTypeToJupyter } from './deepnote-convert/convert-cell-type-to-jupyter';
2-
import { DeepnoteFileBlock } from './deepnote-convert/deepnote-file-schema';
1+
import {
2+
createMarkdown,
3+
createPythonCode,
4+
DeepnoteBlock
5+
} from '@deepnote/blocks';
6+
import _cloneDeep from 'lodash/cloneDeep';
37
import { ICodeCell, IMarkdownCell } from '@jupyterlab/nbformat';
8+
import { convertDeepnoteBlockTypeToJupyter } from './convert-deepnote-block-type-to-jupyter';
9+
10+
export function convertDeepnoteBlockToJupyterCell(block: DeepnoteBlock) {
11+
const blockCopy = _cloneDeep(block);
12+
const jupyterCellMetadata = { ...blockCopy.metadata, cell_id: blockCopy.id };
13+
const jupyterCellType = convertDeepnoteBlockTypeToJupyter(blockCopy.type);
414

5-
export function convertDeepnoteBlockToJupyterCell(
6-
block: DeepnoteFileBlock
7-
): ICodeCell | IMarkdownCell {
8-
const jupyterCellType = convertCellTypeToJupyter(block.type);
915
if (jupyterCellType === 'code') {
10-
return {
16+
const blockOutputs = blockCopy.outputs ?? [];
17+
18+
if (Array.isArray(blockOutputs)) {
19+
blockOutputs.forEach(output => {
20+
delete output.truncated;
21+
});
22+
}
23+
24+
const source = createPythonCode(blockCopy);
25+
26+
const jupyterCell: ICodeCell = {
1127
cell_type: 'code',
12-
source: block.content || '',
13-
metadata: {},
14-
outputs: block.outputs || [],
15-
execution_count: block.executionCount || null
16-
};
17-
} else if (jupyterCellType === 'markdown') {
18-
return {
19-
cell_type: 'markdown',
20-
source: block.content || '',
21-
metadata: {}
28+
metadata: jupyterCellMetadata,
29+
execution_count:
30+
blockCopy.executionCount !== undefined
31+
? blockCopy.executionCount
32+
: null,
33+
outputs: blockOutputs,
34+
source
2235
};
36+
return jupyterCell;
2337
} else {
24-
// For unsupported block types, return a markdown cell indicating it's unsupported
25-
return {
38+
// Markdown cell
39+
const source = createMarkdown(blockCopy);
40+
const jupyterCell: IMarkdownCell = {
2641
cell_type: 'markdown',
27-
source: `# Unsupported block type: ${block.type}\n`,
28-
metadata: {}
42+
metadata: {},
43+
source
2944
};
45+
return jupyterCell;
3046
}
3147
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export function convertDeepnoteBlockTypeToJupyter(blockType: string) {
2+
switch (blockType) {
3+
case 'big-number':
4+
case 'code':
5+
case 'sql':
6+
case 'notebook-function':
7+
case 'input-text':
8+
case 'input-checkbox':
9+
case 'input-textarea':
10+
case 'input-file':
11+
case 'input-select':
12+
case 'input-date-range':
13+
case 'input-date':
14+
case 'input-slider':
15+
case 'visualization':
16+
return 'code';
17+
18+
case 'markdown':
19+
case 'text-cell-h1':
20+
case 'text-cell-h3':
21+
case 'text-cell-h2':
22+
case 'text-cell-p':
23+
case 'text-cell-bullet':
24+
case 'text-cell-todo':
25+
case 'text-cell-callout':
26+
case 'image':
27+
case 'button':
28+
case 'separator':
29+
default:
30+
return 'markdown';
31+
}
32+
}

src/transform-deepnote-yaml-to-notebook-content.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { IDeepnoteNotebookContent } from './types';
22
import { blankCodeCell, blankDeepnoteNotebookContent } from './fallback-data';
33
import { deserializeDeepnoteFile } from '@deepnote/blocks';
4+
import { convertDeepnoteBlockToJupyterCell } from './convert-deepnote-block-to-jupyter-cell';
45

56
export async function transformDeepnoteYamlToNotebookContent(
67
yamlString: string
@@ -22,7 +23,14 @@ export async function transformDeepnoteYamlToNotebookContent(
2223
};
2324
}
2425

25-
return blankDeepnoteNotebookContent;
26+
const cells = selectedNotebook.blocks.map(
27+
convertDeepnoteBlockToJupyterCell
28+
);
29+
30+
return {
31+
...blankDeepnoteNotebookContent,
32+
cells
33+
};
2634
} catch (error) {
2735
console.error('Failed to deserialize Deepnote file:', error);
2836
throw new Error('Failed to transform Deepnote YAML to notebook content.');

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { INotebookContent, INotebookMetadata } from '@jupyterlab/nbformat';
2-
import { DeepnoteFile } from './deepnote-convert/deepnote-file-schema';
2+
import type { DeepnoteFile } from '@deepnote/blocks';
33

44
export interface IDeepnoteNotebookMetadata extends INotebookMetadata {
55
deepnote: {

yarn.lock

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,14 +1577,12 @@ __metadata:
15771577
languageName: node
15781578
linkType: hard
15791579

1580-
"@deepnote/blocks@file:/Users/work/repos/deepnote/deepnote/packages/blocks::locator=jupyterlab-deepnote%40workspace%3A.":
1580+
"@deepnote/blocks@npm:^1.0.0":
15811581
version: 1.0.0
1582-
resolution: "@deepnote/blocks@file:/Users/work/repos/deepnote/deepnote/packages/blocks#/Users/work/repos/deepnote/deepnote/packages/blocks::hash=193053&locator=jupyterlab-deepnote%40workspace%3A."
1582+
resolution: "@deepnote/blocks@npm:1.0.0::__archiveUrl=https%3A%2F%2Fnpm.pkg.github.com%2Fdownload%2F%40deepnote%2Fblocks%2F1.0.0%2Fbbad3593046ed93df89035400c7e7d85a4742494"
15831583
dependencies:
15841584
ts-dedent: ^2.2.0
1585-
yaml: ^2.8.1
1586-
zod: ^4.1.12
1587-
checksum: d47ee3fe23825c2f3012c50cd87216a4099d0abb07a46de67c50650943448baf624c3ec93e9a4fc6626995c9fae33d3fc3500e37e3044d99c9660887ea88e2de
1585+
checksum: 69339b4c5d5b1da33c0deb248714b1aa151f9e80f623ba3a5b16669273fd0516db6c811b59c8cec3add16506e5bcf4b87c944744aa7d7761682139d3c556a06f
15881586
languageName: node
15891587
linkType: hard
15901588

@@ -3277,6 +3275,13 @@ __metadata:
32773275
languageName: node
32783276
linkType: hard
32793277

3278+
"@types/lodash@npm:^4.17.20":
3279+
version: 4.17.20
3280+
resolution: "@types/lodash@npm:4.17.20"
3281+
checksum: dc7bb4653514dd91117a4c4cec2c37e2b5a163d7643445e4757d76a360fabe064422ec7a42dde7450c5e7e0e7e678d5e6eae6d2a919abcddf581d81e63e63839
3282+
languageName: node
3283+
linkType: hard
3284+
32803285
"@types/minimist@npm:^1.2.2":
32813286
version: 1.2.5
32823287
resolution: "@types/minimist@npm:1.2.5"
@@ -6805,7 +6810,7 @@ __metadata:
68056810
version: 0.0.0-use.local
68066811
resolution: "jupyterlab-deepnote@workspace:."
68076812
dependencies:
6808-
"@deepnote/blocks": "file:/Users/work/repos/deepnote/deepnote/packages/blocks"
6813+
"@deepnote/blocks": ^1.0.0
68096814
"@jupyterlab/application": ^4.0.0
68106815
"@jupyterlab/builder": ^4.0.0
68116816
"@jupyterlab/coreutils": ^6.0.0
@@ -6816,6 +6821,7 @@ __metadata:
68166821
"@lumino/widgets": ^2.7.1
68176822
"@types/jest": ^29.2.0
68186823
"@types/json-schema": ^7.0.11
6824+
"@types/lodash": ^4.17.20
68196825
"@types/react": ^18.0.26
68206826
"@types/react-addons-linked-state-mixin": ^0.14.22
68216827
"@typescript-eslint/eslint-plugin": ^6.1.0
@@ -6825,6 +6831,7 @@ __metadata:
68256831
eslint-config-prettier: ^8.8.0
68266832
eslint-plugin-prettier: ^5.0.0
68276833
jest: ^29.2.0
6834+
lodash: ^4.17.21
68286835
mkdirp: ^1.0.3
68296836
npm-run-all2: ^7.0.1
68306837
prettier: ^3.0.0
@@ -9842,10 +9849,3 @@ __metadata:
98429849
checksum: 022d59f85ebe054835fbcdc96a93c01479a64321104f846cb5644812c91e00d17ae3479f823956ec9b04e4351dd32841e1f12c567e81bc43f6e21ef5cc02ce3c
98439850
languageName: node
98449851
linkType: hard
9845-
9846-
"zod@npm:^4.1.12":
9847-
version: 4.1.12
9848-
resolution: "zod@npm:4.1.12"
9849-
checksum: 91174acc7d2ca5572ad522643474ddd60640cf6877b5d76e5d583eb25e3c4072c6f5eb92ab94f231ec5ce61c6acdfc3e0166de45fb1005b1ea54986b026b765f
9850-
languageName: node
9851-
linkType: hard

0 commit comments

Comments
 (0)