@deepnote/convert 1.2.1 → 1.4.0

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.
package/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # @deepnote/convert
2
2
 
3
- Convert Jupyter Notebook files (`.ipynb`) to Deepnote project files (`.deepnote`).
3
+ Bidirectional converter between Jupyter Notebook files (`.ipynb`) and Deepnote project files (`.deepnote`) with lossless roundtrip support.
4
+
5
+ ```bash
6
+ # Convert a Jupyter notebook to a Deepnote project
7
+ npx @deepnote/convert notebook.ipynb
8
+
9
+ # Convert a Deepnote project to Jupyter notebooks
10
+ npx @deepnote/convert project.deepnote
11
+ ```
4
12
 
5
13
  ## Installation
6
14
 
@@ -10,9 +18,11 @@ npm install -g @deepnote/convert
10
18
 
11
19
  ## CLI Usage
12
20
 
13
- The package provides a `deepnote-convert` command-line tool for converting Jupyter notebooks to Deepnote format.
21
+ The package provides a `deepnote-convert` command-line tool for bidirectional conversion between Jupyter and Deepnote formats.
22
+
23
+ ### Convert Jupyter → Deepnote
14
24
 
15
- ### Convert a Single Notebook
25
+ #### Convert a Single Notebook
16
26
 
17
27
  Convert a single `.ipynb` file to a `.deepnote` file:
18
28
 
@@ -22,7 +32,7 @@ deepnote-convert path/to/notebook.ipynb
22
32
 
23
33
  This will create a `notebook.deepnote` file in the current directory.
24
34
 
25
- ### Convert a Directory of Notebooks
35
+ #### Convert a Directory of Notebooks
26
36
 
27
37
  Convert all `.ipynb` files in a directory to a single `.deepnote` project:
28
38
 
@@ -32,6 +42,16 @@ deepnote-convert path/to/notebooks/
32
42
 
33
43
  This will create a `notebooks.deepnote` file in the current directory containing all notebooks from the directory.
34
44
 
45
+ ### Convert Deepnote → Jupyter
46
+
47
+ Convert a `.deepnote` file to Jupyter notebooks:
48
+
49
+ ```bash
50
+ deepnote-convert path/to/project.deepnote
51
+ ```
52
+
53
+ This will create a `project/` directory containing separate `.ipynb` files for each notebook in the Deepnote project.
54
+
35
55
  ### Options
36
56
 
37
57
  #### `--projectName <name>`
@@ -46,36 +66,57 @@ If not specified, the project name will default to the filename (without extensi
46
66
 
47
67
  #### `-o, --outputPath <path>`
48
68
 
49
- Specify where to save the output `.deepnote` file:
69
+ Specify where to save the output file(s):
50
70
 
51
71
  ```bash
52
- # Save to a specific file
72
+ # For Jupyter → Deepnote: Save to a specific file
53
73
  deepnote-convert notebook.ipynb -o output/project.deepnote
54
74
 
55
- # Save to a directory (filename will be auto-generated)
75
+ # For Jupyter → Deepnote: Save to a directory (filename will be auto-generated)
56
76
  deepnote-convert notebook.ipynb -o output/
77
+
78
+ # For Deepnote → Jupyter: Specify output directory for notebooks
79
+ deepnote-convert project.deepnote -o output/jupyter-notebooks/
57
80
  ```
58
81
 
59
- If not specified, the output file will be saved in the current directory.
82
+ If not specified:
83
+
84
+ - For Jupyter → Deepnote: Output file will be saved in the current directory
85
+ - For Deepnote → Jupyter: A directory will be created using the `.deepnote` filename (e.g., `project.deepnote` → `project/`)
60
86
 
61
87
  ### Examples
62
88
 
63
89
  ```bash
64
- # Convert a single notebook with custom name
90
+ # Jupyter → Deepnote: Convert a single notebook with custom name
65
91
  deepnote-convert titanic.ipynb --projectName "Titanic Analysis"
66
92
 
67
- # Convert all notebooks in a directory
93
+ # Jupyter → Deepnote: Convert all notebooks in a directory
68
94
  deepnote-convert ./analysis --projectName "Data Science Project" -o ./output
69
95
 
70
- # Convert multiple notebooks from a folder
96
+ # Jupyter → Deepnote: Convert multiple notebooks from a folder
71
97
  deepnote-convert ~/notebooks/ml-experiments -o ~/projects/
98
+
99
+ # Deepnote → Jupyter: Convert a Deepnote project to Jupyter notebooks
100
+ deepnote-convert my-project.deepnote
101
+
102
+ # Deepnote → Jupyter: Specify output directory
103
+ deepnote-convert my-project.deepnote -o ./jupyter-notebooks/
72
104
  ```
73
105
 
106
+ ### Lossless Roundtrip Conversion
107
+
108
+ The converter supports lossless roundtrip conversions:
109
+
110
+ - **Deepnote → Jupyter → Deepnote**: Preserves all Deepnote-specific metadata in Jupyter cell metadata, enabling faithful reconstruction of the original notebook's structure and metadata (note: serialization formatting or key ordering may differ)
111
+ - **Jupyter → Deepnote → Jupyter**: Preserves original Jupyter content while adding Deepnote metadata
112
+
113
+ This is achieved by storing Deepnote-specific metadata as flat `deepnote_*` keys directly on Jupyter notebook metadata (e.g., `deepnote_notebook_id`, `deepnote_execution_mode`) and cell metadata (e.g., `deepnote_cell_type`, `deepnote_sorting_key`, `deepnote_source`).
114
+
74
115
  ## Programmatic Usage
75
116
 
76
- You can also use the conversion function programmatically in your Node.js or TypeScript applications.
117
+ You can also use the conversion functions programmatically in your Node.js or TypeScript applications.
77
118
 
78
- ### Basic Usage
119
+ ### Jupyter → Deepnote
79
120
 
80
121
  ```typescript
81
122
  import { convertIpynbFilesToDeepnoteFile } from "@deepnote/convert";
@@ -86,6 +127,45 @@ await convertIpynbFilesToDeepnoteFile(["path/to/notebook.ipynb"], {
86
127
  });
87
128
  ```
88
129
 
130
+ ### Deepnote → Jupyter
131
+
132
+ #### File-based Conversion
133
+
134
+ For automatic file I/O (reading and writing files):
135
+
136
+ ```typescript
137
+ import { convertDeepnoteFileToJupyter } from "@deepnote/convert";
138
+
139
+ await convertDeepnoteFileToJupyter("path/to/project.deepnote", {
140
+ outputDir: "./jupyter-notebooks",
141
+ });
142
+ ```
143
+
144
+ #### Pure Conversion (No File I/O)
145
+
146
+ For programmatic use with in-memory data:
147
+
148
+ ```typescript
149
+ import fs from "node:fs/promises";
150
+ import { deserializeDeepnoteFile } from "@deepnote/blocks";
151
+ import { convertDeepnoteToJupyterNotebooks } from "@deepnote/convert";
152
+
153
+ // Read and deserialize the Deepnote file
154
+ const yamlContent = await fs.readFile("project.deepnote", "utf-8");
155
+ const deepnoteFile = deserializeDeepnoteFile(yamlContent);
156
+
157
+ // Convert to Jupyter notebooks (pure function, no I/O)
158
+ const notebooks = convertDeepnoteToJupyterNotebooks(deepnoteFile);
159
+
160
+ // Now you can work with the notebooks in memory
161
+ for (const { filename, notebook } of notebooks) {
162
+ console.log(`${filename}: ${notebook.cells.length} cells`);
163
+
164
+ // Or save them yourself
165
+ await fs.writeFile(filename, JSON.stringify(notebook, null, 2));
166
+ }
167
+ ```
168
+
89
169
  ## License
90
170
 
91
171
  Apache-2.0
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as convertIpynbFilesToDeepnoteFile } from "./src-n1bYyJ74.js";
2
+ import { a as convertDeepnoteFileToJupyterFiles, t as convertIpynbFilesToDeepnoteFile } from "./src-DgOsAHcf.js";
3
3
  import { cli } from "cleye";
4
4
  import fs from "node:fs/promises";
5
5
  import { basename, extname, resolve } from "node:path";
@@ -60,7 +60,19 @@ async function convert(options) {
60
60
  throw error;
61
61
  }
62
62
  }
63
- if (ext === ".deepnote") throw new Error("The .deepnote format is not supported for conversion yet.");
63
+ if (ext === ".deepnote") {
64
+ const spinner = ora("Converting Deepnote project to Jupyter Notebooks...").start();
65
+ try {
66
+ const outputDirName = basename(absolutePath, ext);
67
+ const outputDir = customOutputPath ? resolve(cwd, customOutputPath) : resolve(cwd, outputDirName);
68
+ await convertDeepnoteFileToJupyterFiles(absolutePath, { outputDir });
69
+ spinner.succeed(`Jupyter Notebooks have been saved to ${chalk.bold(outputDir)}`);
70
+ return outputDir;
71
+ } catch (error) {
72
+ spinner.fail("Conversion failed");
73
+ throw error;
74
+ }
75
+ }
64
76
  throw new Error("Unsupported file type. Please provide a .ipynb or .deepnote file.");
65
77
  }
66
78