Save ipython notebook as script programmatically - jupyter-notebook

The excellent ipython notebook has a handy --script command line flag that automatically saves a copy of the notebook as a .py script file (removing any header and markdown cells). Is there a way to switch this feature on from inside the notebook itself after the notebook is opened? Apparently, this option is not accessible to the %config magic.
Is there a way to have a cell that does this conversion? Is there any command-line tool I could use to do the conversion, and just have that in a shell command run from the notebook? (It seems that nbconvert does not output to .py.)
The reason I ask is that I have a git repository of notebooks, and I need to make sure the .py files are kept up to date when users change the notebooks themselves because the .py files are used to create c++ code from the contents of the notebooks. But I can't rely on users to set the --script flag because they'll always forget. (And I include myself in that group of users.)

Better yet (at least for my purposes): ipython respects local copies of the ipython_notebook_config.py file. So I can just add
c = get_config()
c.NotebookManager.save_script = True
to such a file in my notebook directory. Apparently, ipython first reads ~/.ipython/profile_default/ipython_notebook_config.py, and then reads the local copy of that file. So it's safe to use without worrying about demolishing the user settings.
This was not at all clear to me from the documentation, but I just tried it and it worked.

Oh. My mistake. nbconvert can handle conversions to script. So I can do something like this:
!ipython nbconvert --to python MyNB.ipynb
Of course, this line will get saved to the script, which means the script will try to re-save the notebook to itself every time it's executed. That's a bit circular, and I can imagine it could cause problems with some of my more outlandish hacks. Instead, we can ensure that it's only run from ipython by wrapping it as follows:
try :
if(__IPYTHON__) :
!ipython nbconvert --to python MyNB.ipynb
except NameError :
pass
Note that the conversion process will automatically convert the ! syntax to something that is acceptable to plain python. This is apparently not the case with the --script conversion. So the extra-safe way to do this is
try :
if(__IPYTHON__) :
get_ipython().system(u'ipython nbconvert --to python MyNB.ipynb')
except NameError :
pass

Related

I want to run magic command % somefile.py inside a jupyter notebook. However, this program requires variables from the main script

To clarify, somfile.py needs variables that are generated from main.ipynb. So, when I simply do %run somefile.py I get this error:
NameError: name 'viewer' is not defined
This viewer is defined in the main code above. However, now if I use %load somefile.py and THEN run it, it works fine. But, the whole point of me doing this is to not show the users of my script, the nitty gritty details. I am preparing this for some students.
The documentation of the magic command %run covers use of the -i option to "run the file in IPython’s namespace instead of an empty one." You want to add that flag to your %run command:
viewer = "something"
%run -i my_script.py
It applies to notebook kernel namespace as IPython was incorporated into the IPython notebook, which became the Jupyter notebook project later.

How do I have my Jupyter notebook server run arbitrary Python code before running notebook code?

I'm trying to replicate the functionality of the code editor on a platform I was previously using called Odoo.sh. The platform would let me create a .ipynb notebook, but in the cells I could reference pre-set variables which required no boilerplate code inside of the notebook. Extremely convenient.
If you're familiar with Odoo, it was like having odoo-bin shell be implicitly run before executing any of the cells inside the notebook. It was wonderful to work with, but Odoo.sh is proprietary, so I'm trying to replicate the same functionality on my local machine.
A minimal example of what I'm going for here would be to have the following python code run before executing any of my .ipynb notebook file's cells.
example_value = False
def example_func():
global example_value
example_value = True
example_func()
So that inside of any notebook's cells I could simply run something like example_value and get an output of True.
In the case of Odoo.sh it almost seemed like there was a special custom kernel set up that was nothing more than a regular Python 3 kernel with some initialization code. This may be exactly what was going on, but I don't know enough about how Jupyter works to know for myself. How do I replicate this functionality?
I figured it out! You need to create a custom kernel, but for this use case you can just reuse the default IPython kernel and just pass some variables into the user namespace.
First, create a Python file for your kernel. Let's use test_kernel.py. Here are the contents:
from ipykernel.ipkernel import IPythonKernel
from ipykernel.kernelapp import IPKernelApp
if __name__ == "__main__":
example_value = False
def example_func():
global example_value
example_value = True
example_func()
IPKernelApp.launch_instance(
kernel_class=IPythonKernel,
user_ns={"example_value": example_value})
See how the arbitrary code from the question is run before launching the kernel instance. Using the user_ns argument, we can pass arbitrary data to the user environment.
To get our kernel up and running we need to make a test directory and then a test/kernel.json file. It will have these contents:
{
"argv": ["python", "-m", "test_kernel", "-f", "{connection_file}"],
"display_name": "Test"
}
Let's install that bad boy. Run jupyter kernelspec install --user test. In that command, test is the name of the directory we created. The --user argument makes Jupyter install the kernel only for the current user. You don't have to use it if you don't want to.
Now we should be good to go! Start things up with jupyter notebook and you will see your new kernel is available to use when using notebooks. And check it out, we can see the variable we passed into the namespace:
Last of all, be sure to note that in order for this to work your test_kernel.py file will need to be somewhere where Python can import it. I'm not an expert on this, but from a bit of Googling I took this to mean that the directory containing the file should either be the current working directory or be in your PYTHONPATH.

How can i edit jupyter notebook from terminal without opening web browser?

How can I edit my jupyter notebook in terminal.
I just don't like to open jupyter notebook in web browser.
I google out but every answer is related to how can we open notebook from terminal directly.
I'd suggest looking at Jupytext's ability to do command line conversions back-and-forth from the notebook json structure to a python script (or markdown). If you already have the backbone of a notebook (.ipynb) file, you can convert it to .py script using jupytext --to py notebook.ipynb. That makes a text file that is easy to edit in your favorite terminal based text editor. The json in the .ipynb files is not as easy to edit directly.
Then when you are done editing, you can convert the .py script form back to a notebook with something like jupytext --to notebook notebook.py. Optionally, you can even execute it without opening a browser by adding --execute. I have an example conversion-and-execution command in use here.

workaround for missing --script in ipython notebook 3.0.0-dev

I've been using automaticall saved scripts beside .ipynb files as a convenient way to write modules using ipython notebook. I updated to the head version today, and it seems the --script functionality has been removed.
Is there a way to obtain that functionality (automatically on save) with the latest ipython?
Running ipython notebook gives me a message telling me that it's been removed, and suggests doing
ipython nbconvert --to python [notebook]
To make that work automaticaly, I'd have to trigger it on each save - is there an easy way to achieve that?
Not really a workaround, but the --script functionality was still present in release 2.3.0 (if you're running from a live git repo, you can checkout tag 'rel-2.3.0').

Cannot import .py file to ipython notebook

With apologies in advance for the "I can't get it to work" question: How should I load a .py file into ipython notebook? I want to convert python code to notebooks (first simple scripts and later scripts that include nbconvert directives embedded as comments-- see bottom of the linked file.)
Perhaps I'm doing it wrong, but perhaps there's something wrong with my set-up. When I drag a .py file to the Notebook's file list, I get the message
Invalid file type: Uploaded notebooks must be .ipynb files.
I even tried changing the extension to .ipynb (keeping the python script unmodified); reasonably enough, I got an error:
Error loading notebook: Bad request
Any idea what's going wrong?
System information: I'm on OS X (10.8, Mountain Lion), using Firefox 28.0 and Anaconda 1.9.2 (x86_64), which supplies python 2.7.6 and ipython 2.0. Anaconda is not on the default PATH; I add it in a bash session from which I then launch notebook with ipython notebook, and I'm able to open and edit .ipynb files normally in the browser.
But I do get some curious behavior:
When exporting from notebook as a .py file, I don't get the control comments documented here but a simpler format, without version number:
# coding: utf-8
# In[ ]:
print "This is a slide"
## Top-level title
### Second-level heading
#### Third-level heading
# This is some `markdown` text.
#
# And some more here.
Any idea what's going on here?
The same format is generated by ipython nbconvert. However, if I start the notebook server with ipython notebook --script (which exports the notebook as a python script every time it is saved), the result contains the nbconvert directives we need to convert back to a notebook!
I had the same problem.
This post helped:
How to load/edit/run/save text files (.py) into an IPython notebook cell?
Basically, we just have to use the following command in the cell. And the .py file has to be in the same directory.
%load filename.py
I'm not sure why notebook doesn't support this natively, but I've concluded that the answer is: It can't be done from the command line or notebook GUI.
Control comments like <markdowncell> can only be interpreted by accessing notebook's API through python, as shown by #CliffordVienna in this answer to my related question.
import IPython.nbformat.current as nbf
nb = nbf.read(open('test.py', 'r'), 'py')
nbf.write(nb, open('test.ipynb', 'w'), 'ipynb')
Edit: The above method does not work with the current version (v4) of the Notebook API, so I have added this self-answer to show how it's done.
If you only need to import a local file, first use:
sys.path.append(os.getcwd())
to place the .pynb file's directory in sys.path, and then import the local file.

Resources