Help test new exporter

That takes care of the error, thanks!

1 Like

Good to know! I’ll work on the rest of the stuff tonight.

The script I use for updating the other packages is here. It basically copies the newly updated module file in all further modules it’s used in.

This is awesome! Thanks for doing it.

I have an idea feature request. Sometimes I need to run notebooks as standalone binaries, to run debuggers or profilers on them. Right now, I achieve this by exporting the dependency notebooks and then manually copying the cells that I want to execute into a “main.swift” file in the SwiftPM package. This is pretty tedious.

This could be automated with a directive like “//executable: foo” that exports the cell into an executable product named “foo”! Then you can swift run foo or swift build foo in the exported package to use the executable.

2 Likes

That’s a great idea, I think it could be added to the current package. Do we need a different comment to mark those cells? Wouldn’t it be enough to export the cells that are being currently mark as //export? Or is this more like a one-off thing for specific cells to be tested?

The way it determines the package where it belongs to is based on filenames, right? I was planning to do it by checking whether the source is actually already used in all other potential packages.

I do think we need a separate comment, because it’s common for notebooks to mix things that should be exported as a library with things that only make sense to run in a binary.

For example, https://github.com/fastai/fastai_docs/blob/master/dev_swift/00_load_data.ipynb defines a “shell” method on String (which should be exported for others to use), and then immediately uses it in an example (which would be nice to be able to run as a standalone binary, but which isn’t useful for anyone else to import).

Not only should the binary cells be separate from the exported cells, but also it would be useful to be able to define separate binaries. For example, in the 00_load_data notebook, it would be convenient to do:

//executable: exampleShellCommand
print("/bin/ls".shell("-lh"))
//executable: printMNISTShape
let (xTrain, yTrain, xValid, yValid) = loadMNIST(path: mnistPath)
xTrain.shape

Then if you just want to test out the shell command, you can do swift run exampleShellCommand and if you just want to test out the MNIST shape, you can do swift run printMNISTShape.

1 Like

Yes, I didn’t have anything better than that.

@sgugger Please, try version 0.5.0 when you can - it should copy the exported notebook source to all other notebooks that depend on it. Let me know if something’s amiss!

1 Like

Thanks a lot, it’s confirmed working!

1 Like

This has just been added to version 0.6.0 of NotebookExport, so the following will generate a ls executable product inside the exported package:

//executable: ls
print("/bin/ls".shell("-lh"))

import clauses are automatically added to the executable source for the generated package and all %installed dependencies.

@marcrasi Please, let me know if it works for you!

I’m thinking about combining several cells in the same executable by using the same executable name in the comment. Would that be something useful to you?

3 Likes

I just tried it out! It works just how I was wanting, thanks!

I’m going through a period of less notebook use, so it might be a while until I use it “for real”. I’ll let you know how it goes when I do. Also I’ll make sure to tell people about it if I see anyone needing to export some executables from their notebooks :slight_smile:

One note: I think you forgot to tag the 0.6.0 version in GitHub, so

%install '.package(url: "https://github.com/latenitesoft/NotebookExport", from: "0.6.0")' NotebookExport`

doesn’t work. I was able to use it by writing .branch("master") instead of from: "0.6.0".

2 Likes

I totally did. Fixed now, thanks!

2 Likes