Bagaimana cara mengubah Notebook IPython menjadi file Python melalui commandline?

258

Saya sedang melihat menggunakan file * .ipynb sebagai sumber kebenaran dan secara terprogram 'mengkompilasi' mereka menjadi file .py untuk pekerjaan / tugas terjadwal.

Satu-satunya cara saya mengerti untuk melakukan ini adalah melalui GUI. Apakah ada cara untuk melakukannya melalui command line?

Stefan Krawczyk
sumber
1
Apa yang Anda maksud dengan "sumber kebenaran"? Notebook IPython hanyalah file json. Anda dapat memuatnya dan memanipulasi sebagai kamus Python. Untuk kode sumber Anda harus iterasi inputkunci di mana cell_typesama dengan 'kode'. Lihatlah skema
theta
1
Yah saya ingin menyimpan .ipynb di repositori dan bukan file .py. Maka sebagai 'langkah membangun' saya akan mengonversi file .ipynb ke .py untuk penggunaan aktual oleh sistem otomatis. Anda benar, saya hanya bisa memuat json dan hanya menghasilkan sel-sel kode, tapi saya bertanya-tanya apakah ada sesuatu di luar sana yang melakukan itu untuk saya :)
Stefan Krawczyk
1
@StefanKrawczyk Bisakah Anda menandai aswer sebagai diterima? Saya akan merekomendasikan asnwer
wwwilliam

Jawaban:

413

Jika Anda tidak ingin membuat skrip Python setiap kali Anda simpan, atau Anda tidak ingin memulai ulang kernel IPython:

Di baris perintah , Anda dapat menggunakan nbconvert:

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

Sebagai sedikit peretasan, Anda bahkan dapat memanggil perintah di atas dalam notebook IPython dengan pra-pending !(digunakan untuk argumen baris perintah apa pun). Di dalam buku catatan:

!jupyter nbconvert --to script config_template.ipynb

Sebelum --to scriptitu menambahkan , pilihan itu --to pythonatau --to=python, tapi itu berganti nama dalam langkah menuju sistem notebook bahasa-agnostik.

wwwilliam
sumber
8
Jika Anda menginginkan satu setiap penyimpanan, di jupyterdalamnya Anda dapat memicu nbconvertmelalui kait sebelum atau sesudah penyimpanan: ContentsManager.pre_save_hookabd FileContentsManager.post_save_hook. Anda akan menambahkan kait pasca-simpanjupyter nbconvert --to script [notebook]
jaimedash
3
Apakah ada cara untuk melakukan yang sebaliknya yaitu mengkonversi dari skrip python ke notebook. Untuk mantan memiliki beberapa dokumen khusus yang diurai ke dalam sel?
Sujen Shah
3
konversikan semua notebook dalam folderjupyter nbconvert --to script /path/to/notebooks/*.ipynb
openwonk
8
Terima kasih, itu berhasil !, tetapi bagaimana jika saya tidak ingin # In[ ]:jenis barang di skrip, saya ingin itu menjadi bersih. Apakah ada cara untuk melakukan itu?
Rishabh Agrahari
1
@RishabhAgrahari periksa di sini, Anda dapat menyesuaikan lup jupyter-notebook.readthedocs.io/en/stable/extending/…
MichaelChirico
77

Jika Anda ingin mengonversi semua *.ipynbfile dari direktori saat ini ke skrip python, Anda dapat menjalankan perintah seperti ini:

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

Berikut ini adalah cara cepat dan kotor untuk mengekstrak kode dari V3 atau V4 ipynb tanpa menggunakan ipython. Itu tidak memeriksa jenis sel, dll.

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()
Valentas
sumber
1
Jawaban terbaik jika Anda tidak ingin menginstal alat Jupyter.
dacracot
1
Saya suka ini. Tapi saya tahu ketika saya mengunduh format .py dari notebook Jupyter, ia menggunakan ujung baris UNIX meskipun saya di windows. Untuk menghasilkan yang sama, tambahkan newlines='\n'argumen ketiga dalam panggilan file keluaran terbuka. (Python 3.x)
RufusVS
16

Mengikuti contoh sebelumnya tetapi dengan versi lib nbformat baru :

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'))
Spawnrider
sumber
Baris kode terakhir, fh.writelines (source.encode ('utf-8')) memberikan argumen 'TypeError: write () harus berupa str, bukan int' fh.writelines (source) bekerja.
BarryC
6

Anda dapat melakukan ini dari IPython API.

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)
justanr
sumber
4

Jupytext bagus untuk dimiliki dalam rantai alat Anda untuk konversi semacam itu. Ini memungkinkan tidak hanya konversi dari notebook ke skrip, tetapi Anda juga dapat kembali dari skrip ke notebook. Dan bahkan memiliki notebook yang diproduksi dalam bentuk yang dieksekusi.

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 
Wayne
sumber
Ternyata ada juga ipynb-py-convert, lihat di sini .
Wayne
'jupytext' tidak dikenali sebagai perintah internal atau eksternal, program yang dapat dijalankan, atau file batch. ???
Amine Chadi
Sudahkah Anda menginstalnya @AmineChadi. Lihat di sini untuk cara melakukannya. Jika Anda menggunakannya melalui notebook sebagai antarmuka baris perintah, Anda bisa menjalankannya %pip install jupytextdi notebook.
Wayne
3

Untuk mengonversi semua file format * .ipynb dalam direktori saat ini ke skrip python secara rekursif:

for i in *.ipynb **/*.ipynb; do 
    echo "$i"
    jupyter nbconvert  "$i" "$i"
done
Don Smythe
sumber
3
Saya harus menambahkan --to scriptargumen untuk menghindari output HTML default di Jupiter 4.4.0.
trojjer
0

Saya mempunyai masalah ini dan mencoba mencari solusinya secara online. Meskipun saya menemukan beberapa solusi, mereka masih memiliki beberapa masalah, misalnya, pembuatan Untitled.txtotomatis yang mengganggu ketika Anda memulai notebook baru dari dasbor.

Jadi akhirnya saya menulis solusi sendiri :

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

Untuk menggunakan skrip ini, Anda dapat menambahkannya ke ~/.jupyter/jupyter_notebook_config.py:)

Perhatikan bahwa Anda mungkin perlu me-restart notebook jupyter / lab agar bisa berfungsi.

Jiren Jin
sumber
0

Ada paket yang sangat bagus bernama nb_dev yang dirancang untuk membuat paket Python di Notebook Jupyter. Seperti nbconvert,itu dapat mengubah notebook menjadi file .py, tetapi lebih fleksibel dan kuat karena memiliki banyak fitur penulisan tambahan yang bagus untuk membantu Anda mengembangkan tes, dokumentasi, dan mendaftar paket pada PyPI. Ini dikembangkan oleh orang-orang fast.ai.

Ini memiliki sedikit kurva pembelajaran, tetapi dokumentasinya bagus dan tidak sulit secara keseluruhan.

John
sumber