Como converter um bloco de notas IPython em um arquivo Python via linha de comando?


258

Estou olhando para usar os arquivos * .ipynb como fonte da verdade e programaticamente 'compilando-os em arquivos .py para trabalhos / tarefas agendados.

A única maneira de entender isso é através da GUI. Existe uma maneira de fazê-lo via linha de comando?


1
O que você quer dizer com "fonte da verdade"? Os notebooks IPython são apenas arquivos json. Você pode carregá-los e manipular como dicionários Python. Para o código-fonte, você deve iterar inputchaves onde cell_typeé igual a 'código'. Dê uma olhada neste esquema
teta

1
Bem, eu quero armazenar o .ipynb em um repositório e não os arquivos .py. Então, como uma 'etapa de construção', eu converteria os arquivos .ipynb em .py para uso real pelo sistema automatizado. Você está certo, eu poderia apenas carregar o JSON e saída apenas as células de código, mas eu queria saber se havia algo lá fora, já que fez isso por mim :)
Stefan Krawczyk

1
@StefanKrawczyk Você pode marcar um aswer como aceito? Eu recomendaria wwwilliam's asnwer
pedram bashiri 13/01

Respostas:


413

Se você não deseja gerar um script Python toda vez que salvar, ou não deseja reiniciar o kernel do IPython:

Na linha de comando , você pode usar nbconvert:

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

Como um hack, você pode até chamar o comando acima em um bloco de notas IPython pré-pendente !(usado para qualquer argumento de linha de comando). Dentro de um notebook:

!jupyter nbconvert --to script config_template.ipynb

Antes de --to scriptser adicionada , a opção era --to pythonor --to=python, mas foi renomeada na mudança para um sistema de notebook independente de idioma.


8
Se você quiser salvar a cada vez, jupyterpoderá acioná nbconvert- lo através de ganchos pré ou pós-salvamento: ContentsManager.pre_save_hookabd FileContentsManager.post_save_hook. Você adicionaria um gancho pós-salvamentojupyter nbconvert --to script [notebook]
jaimedash 3/16

3
Existe uma maneira de fazer o inverso, ou seja, converter de um script python para um notebook. Por exemplo - tendo alguns documentos especializados que são analisados ​​em células?
precisa saber é o seguinte

3
converter todos os blocos de anotações em uma pastajupyter nbconvert --to script /path/to/notebooks/*.ipynb
openwonk

8
Obrigado, funciona !, mas e se eu não quiser o # In[ ]:tipo de coisa no script, quero que esteja limpo. Existe alguma maneira de fazer isso?
Rishabh Agrahari

1
@RishabhAgrahari confira aqui, você pode apenas personalizar o linter jupyter-notebook.readthedocs.io/en/stable/extending/...
MichaelChirico

77

Se você deseja converter todos os *.ipynbarquivos do diretório atual em script python, é possível executar o comando da seguinte maneira:

jupyter nbconvert --to script *.ipynb

19

Aqui está uma maneira rápida e suja de extrair o código do ipynb V3 ou V4 ​​sem usar o ipython. Não verifica os tipos de células, 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()

1
Melhor resposta se você não deseja instalar nenhuma das ferramentas Jupyter.
Dacracot 3/16

1
Eu gosto disso. Mas descobri que quando baixei o formato .py dos blocos de anotações Jupyter, ele usa terminações de linha UNIX, mesmo estando no Windows. Para gerar o mesmo, adicione newlines='\n'como um terceiro argumento na chamada de arquivo de saída aberta. (Python 3.x)
RufusVS

16

Seguindo o exemplo anterior, mas com a nova versão da 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'))

A última linha do código, fh.writelines (source.encode ('utf-8')) fornece o argumento 'TypeError: write () deve ser str, não int', mas funciona.
BarryC, 18/10/16

6

Você pode fazer isso a partir da 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)

4

É bom ter o Jupytext em seu conjunto de ferramentas para essas conversões. Ele permite não apenas a conversão de um bloco de anotações para um script, mas você também pode voltar do script para o bloco de anotações. E ainda tem esse notebook produzido na forma executada.

jupytext --to py notebook.ipynb                 # convert notebook.ipynb to a .py file
jupytext --to notebook notebook.py              # convert notebook.py to an .ipynb file with no outputs
jupytext --to notebook --execute notebook.py    # convert notebook.py to an .ipynb file and run it 

Aparentemente, também há ipynb-py-convert, veja aqui .
Wayne

'jupytext' não é reconhecido como um comando interno ou externo, programa operável ou arquivo em lote.
Amine Chadi 31/03

Você instalou o @AmineChadi. Veja aqui como fazer isso. Se você o estiver usando através de um notebook como sua interface de linha de comando, basta executar %pip install jupytextno seu notebook.
Wayne

3

Para converter todos os arquivos no formato * .ipynb no diretório atual em scripts python recursivamente:

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

3
Eu tive que adicionar o --to scriptargumento para evitar a saída HTML padrão no Jupiter 4.4.0.
precisa saber é o seguinte

0

Eu tive esse problema e tentei encontrar a solução online. Embora eu tenha encontrado algumas soluções, elas ainda têm alguns problemas, por exemplo, a Untitled.txtcriação automática irritante quando você inicia um novo notebook no painel.

Então, finalmente, eu escrevi minha própria solução :

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

Para usar esse script, você pode adicioná-lo a ~/.jupyter/jupyter_notebook_config.py:)

Observe que pode ser necessário reiniciar o notebook / laboratório jupyter para que ele funcione.


0

Existe um pacote muito bom chamado nb_dev, projetado para criar pacotes Python nos Jupyter Notebooks. Gostarnbconvert, ele pode transformar um notebook em um arquivo .py, mas é mais flexível e poderoso, pois possui muitos recursos adicionais de autoria para ajudá-lo a desenvolver testes, documentação e registrar pacotes no PyPI. Foi desenvolvido pelo pessoal da fast.ai.

Ele tem um pouco de curva de aprendizado, mas a documentação é boa e não é difícil no geral.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.