Run python script using existing ipython kernel without console - console

I can run a python script from a bash shell like so:
>> python script.py
I can also start an iPython kernel and connect multiple iPython consoles to the same kernel like so:
>> ipython kernel
...
To connect another client to this kernel, use:
--existing kernel-8987.json
then, for as many consoles as I would like, I execute
>> jupyter console --existing kernel-8987.json
However, what I would like to do is start a kernel, but then run scripts without opening a console. I'd like to do something like this:
>> ipython --existing kernel-8987.json script.py
Is this possible to do this somehow?

Extending on the other answer and use the %run magic command1, it's possible to do this (which works for multiple-line scripts):
$ jupyter console --simple-prompt --existing kernel-8987.json <<< '%run script.py'
or (on Windows where <<< doesn't work)
> echo %run script.py | jupyter console --simple-prompt --existing kernel-8987.json
Unfortunately, this method still prints some redundant prompt (In[1]:) on the console.
Alternatively, using Python API: (create a script to execute this Python code) (on my machine, this method is much faster)
from jupyter_client.manager import KernelManager
manager=KernelManager(connection_file="full path to connection file.json")
manager.load_connection_file()
manager.client().execute("commands to execute")
The commands to execute might span multiple lines, or have the form %run file.py.
There's also silent=True, store_history=False as parameters to execute().
The full path to the connection file can be found as
Path(jupyter_core.paths.jupyter_runtime_dir()) / "kernel-8987.json", or
jupyter_client.connect.find_connection_file("kernel-8987.json") (find file with specific name), or
jupyter_client.connect.find_connection_file() (find the latest file)
See also jupyter-client documentation.
Disclaimer: Some of the code are taken from jupyter-vim plugin, and manager.load_connection_file and connect.find_connection_file appears to be undocumented.
1: As mentioned in the documentation, the file is executed in a new namespace unless you use -i.

It seems that jupyter has this functionality already built in.
$ jupyter run --existing kernel-8987.json script.py
I don't know if this was a feature addition since the OP, or if I was really stupid and didn't RTFM.
$ jupyter run --help
Run Jupyter kernel code.
Options
=======
...
--existing=<CUnicode>
Connect to an already running kernel
Default: ''
Equivalent to: [--JupyterConsoleApp.existing]
The other answers will run the code in the existing kernel, but still open a console in the process. The run subcommand does exactly what I requested: runs the code without opening an interactive console.

% jupyter console --version
6.2.0
I can exec one-liners from a file like this:
% jupyter console --simple-prompt --existing kernel-8987.json < script.py

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.

Can I run a jupyter notebook with an R kernel from a jupyter notebook with a python kernel?

I have some R code to update a database stored in update_db.ipynb. When I try to %run update_db.ipynb from a jupyter notebook with a python kernel, I get an error
File "<ipython-input-8-815efb9473c5>", line 14
city_weather <- function(start,end,airports){
^
SyntaxError: invalid syntax
Looks like it thinks that update_db.ipynb is written in python. Can I specify which kernel to use when I use %run?
Your error is not due to the kernel selected. Your command %run is made to run python only, but it has to be a script, not a notebook. You can check in details the ipython magic commands
For your use case I would suggest to install both python and R kernel in jupyter. Then you can use the magic cell command %%R to select to run R kernel for a cell inside the python notebook. Source :this great article on jupyter - tip 19
Other solution is to put your R code in an R script, and then execute it from a jupyter notebook. For this you can run a bash command from a jupyter notebook that will execute the script
!R path/to/script.r

Way to get jupyter server root directory

Consider following:
$ cd /home/mydir
$ jupyter notebook --port=8888
In plain English, I am running jupyter server from /home/mydir directory.
Is there a simple way to get this directory from within a notebook regardless if it's a R notebook or a Python notebook or whatever? Maybe there is some magic command or variable?
NOTE: getwd() is not an answer as it returns directory of a current notebook but not the jupyter server root.
I have a similar problem and found your post, although I don't see a viable solution yet. Eventually I did found a solution, although it works only because I only care about Linux and I only care about Python. The solution is this magic line:
J_ROOT = os.readlink('/proc/%s/cwd' % os.environ['JPY_PARENT_PID'])
(I put it in a module in my PYTHONPATH so that I can easily use it in any Python notebook.) See if it is good for you.
Remember that your iPtyhon is just a Python module, so you can execute any valid Python code in a cell. So, if you started your notebook and haven't executed any directory changes in your code, you should be able to retrieve your cwd with the following in a cell:
import os
os.getcwd()
But furthermore, you can execute shell commands in cells, so you can retrieve other information in the cell. For example:
!which jupyter
should give you the path to your jupyter executable.
Which then leads you to running something like:
!jupyter --paths
which should give you something similar to:
​
config:
/Users/yourdir/.jupyter
/usr/local/etc/jupyter
/etc/jupyter
data:
/Users/yourdir/Library/Jupyter
/usr/local/share/jupyter
/usr/share/jupyter
runtime:
/Users/yourdir/Library/Jupyter/runtime
Frankly I'm surprised that all this time later there is still no built-in way to do this. I have used Isaac To's solution on Linux but recently had to make a jupyter notebook portable to Windows as well. Simply using os.getcwd() is fragile because a cell using it to set your JUPYTER_ROOT_DIRECTORY can potentially be called again, after you have changed your working directory.
Here is what I came up with:
try:
JUPYTER_ROOT_DIRECTORY
except NameError:
JUPYTER_ROOT_DIRECTORY = os.getcwd()
I put it in one of the first couple cells with the initial import statements. If the cell gets called again, it will not re-set the variable value because the variable exists and does not throw an exception.
It should be noted that unlike Isaac To's solution it sets the value to the directory the current .ipynb was run from, which is not necessarily the same directory as the top-level dir the user can access in the left hand file pane.
My suggestion is to use an intuitive approach.
Create a new folder within the Jupyter environment with a very unique name, for example, T246813579.
You can now locate the Jupyter working path by searching in your file explorer. For example, you can use the Windows Explorer in order to locate your new folder.
The expected result should look something like this:
C:\Users\my_user_name\JupyterHome\T246813579
The answer from #Isaac works well for Linux, but not all systems have /proc. For a solution that works on macOS and Linux, we can use shell commands, taking advantage of the ! shell assignment syntax in Jupyter:
import os
JPY_ROOT = ! lsof -a -p {os.environ['JPY_PARENT_PID']} -d cwd -F n | tail -1 | cut -c 2-
JPY_ROOT = JPY_ROOT[0]
print(JPY_ROOT) # prints Jupyter's dir
Explanation:
Get the process ID (pid) of the current jupyter instance with os.environ['JPY_PARENT_PID']
Call lsof to list the process's open files, keeping only the current working dir (cwd)
Parse the output of lsof using tail and cut to keep just the directory name we want
The ! command returns a list, here having only one element
Alternate Version
To save the os import, we could also use shell commands to get the PID. We could also do the subsequent string wrangling in python, rather than calling tail and cut from the shell, as:
JPY_ROOT = ! lsof -a -p $(printenv | grep JPY_PARENT_PID | cut -d '=' -f 2) -d cwd -F n
JPY_ROOT = JPY_ROOT[2][1:]

Send line to console in Notepad++

Is there a way to execute commands line-by-line written in NPP editor in a console.
I have already looked at the following plugins, but they seem to execute a line or chunk of code as a standalone script (i.e. not interactive):
NPPExec;
NPPConsole;
This question is similar to this one:
Run selected line in notepad++ console
but in their case the code is being saved, executed, and stopped. But I would like an interactive console, i.e. it would bring up an instance of shell (or any other console), and I can send line-by-line code from NPP editor.
It sounds like you are looking for behaviour similar to IPython and the Jupyter Notebook or maybe just a regular debugger. I don't know of any plugin that can do that in Notepad++.
If interactive behaviour after initial execution will do (e.g. for inspection of variables), you can achieve that using the interactive flag -i in NppExec like this:
cd $(CURRENT_DIRECTORY)
python -u -i $(FILE_NAME)

How to enable and access debug logging for notebook and IPython kernel

I'm doing a small research on IPython kernel and trying to get debug logs out of it and see how it interacts with a notebook. Now it looks like the documentation and example configs shipped in my distribution is totally outdated.
The questions
Where the ipython kernel log files are located?
How can I enable DEBUG level logging in both jupyter notebook and ipython kernel?
What I've tried
Please read this section before giving links to the official docs
First I created profiles for both IPython and notebook with the following commands:
$ ipython profile create
$ jupyter notebook --generate-config
As expected three files where created:
.jupyter/jupyter_notebook_config.py
.ipython/profile_default/ipython_config.py
.ipython/profile_default/ipython_kernel_config.py
In these files I found similar commented fragments:
# Set the log level by value or name.
# c.Application.log_level = 0
I tried to uncomment it in the jupyter config. Instead of adding more details it totally disabled console output for the jupyter process. I also tried value 50 it has the same result, value DEBUG gave me Python error on start.
I also played with these values in ipython's configs but I wasn't able to find log files location.
In mail list command line option --log-level=DEBUG is mentioned and indeed it works for jupyter. But I really want to persist this setting in a profile and have debug info for the kernel too.
Config options NotebookApp.log_level and IPKernelApp.log_level also change nothing.
I believe that this kind of functionality is still on the wishlist:
https://github.com/ipython/ipython/issues/8570
But you could try something like this:
jupyter notebook --debug > log.file 2>&1
or
ipykernel kernel --debug > log.file 2>&1
You can also try to start ipython kernel without attached frontend with option --debug:
ipython kernel --debug
You can get lot of info about interaction between kernel and the forntend by setting c.Session.debug = True in jupyter_notebook_config.py.

Resources