web-dev-qa-db-fra.com

Comment convertir un ordinateur portable IPython en un fichier Python via la ligne de commande?

Je cherche à utiliser les fichiers *. Ipynb comme source de vérité et à les "compiler" par programme dans des fichiers .py pour des travaux/tâches planifiés.

La seule façon que je comprends de faire cela est via l'interface graphique. Est-il possible de le faire via la ligne de commande?

193
Stefan Krawczyk

Si vous ne souhaitez pas générer un script Python à chaque fois que vous enregistrez, ou si vous ne souhaitez pas redémarrer le noyau IPython:

Sur la ligne de commande , vous pouvez utiliser nbconvert :

$ jupyter nbconvert --to script [YOUR_NOTEBOOK].ipynb

, vous pouvez même appeler la commande ci-dessus dans un cahier IPython par -pending ! (utilisé pour tout argument de ligne de commande). Dans un cahier:

!jupyter nbconvert --to script config_template.ipynb

Avant --to script était ajouté , l'option était --to python ou --to=python, mais c'était renommé dans le mouvement vers une langue agnostique système de cahier.

329
wwwilliam

Si vous voulez convertir tous les fichiers *.ipynb du répertoire actuel en script python, vous pouvez exécuter la commande comme suit:

jupyter nbconvert --to script *.ipynb
45
Břetislav Hájek

Voici un moyen simple et rapide d’extraire le code d’ipynb V3 ou V4 ​​sans utiliser ipython. Il ne vérifie pas les types de cellules, etc.

import sys,json

f = open(sys.argv[1], 'r') #input.ipynb
j = json.load(f)
of = open(sys.argv[2], 'w') #output.py
if j["nbformat"] >=4:
        for i,cell in enumerate(j["cells"]):
                of.write("#cell "+str(i)+"\n")
                for line in cell["source"]:
                        of.write(line)
                of.write('\n\n')
else:
        for i,cell in enumerate(j["worksheets"][0]["cells"]):
                of.write("#cell "+str(i)+"\n")
                for line in cell["input"]:
                        of.write(line)
                of.write('\n\n')

of.close()
17
Valentas

En suivant l’exemple précédent mais avec le nouvelle version de nbformat lib:

import nbformat
from nbconvert import PythonExporter

def convertNotebook(notebookPath, modulePath):

  with open(notebookPath) as fh:
    nb = nbformat.reads(fh.read(), nbformat.NO_CONVERT)

  exporter = PythonExporter()
  source, meta = exporter.from_notebook_node(nb)

  with open(modulePath, 'w+') as fh:
    fh.writelines(source.encode('utf-8'))
13
Spawnrider

@ La dernière ligne de code de Spawnrider,

fh.writelines(source.encode('utf-8'))

donne 'TypeError: write () l'argument doit être str, pas int'

fh.writelines(source) 

fonctionne bien.

8
BarryC

Vous pouvez le faire à partir de l'API IPython.

from IPython.nbformat import current as nbformat
from IPython.nbconvert import PythonExporter

filepath = 'path/to/my_notebook.ipynb'
export_path = 'path/to/my_notebook.py'

with open(filepath) as fh:
    nb = nbformat.reads_json(fh.read())

exporter = PythonExporter()

# source is a Tuple of python source code
# meta contains metadata
source, meta = exporter.from_notebook_node(nb)

with open(export_path, 'w+') as fh:
    fh.writelines(source)
6
justanr

Pour convertir tous les fichiers au format * .ipynb du répertoire en cours en python scripts récursivement:

for i in *.ipynb **/*.ipynb; do 
    echo "$i"
    jupyter nbconvert  "$i" "$i"
done
4
Don Smythe

J'ai eu ce problème et j'ai essayé de trouver la solution en ligne. Bien que j'ai trouvé des solutions, certains problèmes subsistent, par exemple, la gênante Untitled.txt création automatique lorsque vous démarrez un nouveau bloc-notes à partir du tableau de bord.

Donc finalement j'ai écrit ma propre solution :

import io
import os
import re
from nbconvert.exporters.script import ScriptExporter
from notebook.utils import to_api_path


def script_post_save(model, os_path, contents_manager, **kwargs):
    """Save a copy of notebook to the corresponding language source script.

    For example, when you save a `foo.ipynb` file, a corresponding `foo.py`
    python script will also be saved in the same directory.

    However, existing config files I found online (including the one written in
    the official documentation), will also create an `Untitile.txt` file when
    you create a new notebook, even if you have not pressed the "save" button.
    This is annoying because we usually will rename the notebook with a more
    meaningful name later, and now we have to rename the generated script file,
    too!

    Therefore we make a change here to filter out the newly created notebooks
    by checking their names. For a notebook which has not been given a name,
    i.e., its name is `Untitled.*`, the corresponding source script will not be
    saved. Note that the behavior also applies even if you manually save an
    "Untitled" notebook. The rationale is that we usually do not want to save
    scripts with the useless "Untitled" names.
    """
    # only process for notebooks
    if model["type"] != "notebook":
        return

    script_exporter = ScriptExporter(parent=contents_manager)
    base, __ = os.path.splitext(os_path)

    # do nothing if the notebook name ends with `Untitled[0-9]*`
    regex = re.compile(r"Untitled[0-9]*$")
    if regex.search(base):
        return

    script, resources = script_exporter.from_filename(os_path)
    script_fname = base + resources.get('output_extension', '.txt')

    log = contents_manager.log
    log.info("Saving script at /%s",
             to_api_path(script_fname, contents_manager.root_dir))

    with io.open(script_fname, "w", encoding="utf-8") as f:
        f.write(script)

c.FileContentsManager.post_save_hook = script_post_save

Pour utiliser ce script, vous pouvez l'ajouter à ~/.jupyter/jupyter_notebook_config.py :)

Notez que vous devrez peut-être redémarrer le cahier/laboratoire jupyter pour que cela fonctionne.

0
Jiren Jin