gregsexton / ob-ipython

org-babel integration with Jupyter for evaluation of (Python by default) code blocks
737 stars 111 forks source link

How to get the json file into the :session argument #197

Closed inglada closed 5 years ago

inglada commented 5 years ago

Hi, Thanks for this great package. I have started using ob-ipython to do C++ using the xeus-c++ kernel. Right now, my workflow is not at all streamlined. My jupyter is installed using miniconda, so I have set

(setq python-shell-interpreter "/home/inglada/miniconda3/bin/python")

Then I start the kernel like this in a terminal:

./miniconda3/bin/jupyter kernel --kernel=xeus-cling-cpp17

Then I copy the

inglada commented 5 years ago

Sorry, something went wrong!

So the I copy the path to the json file generated by the command line kernel activation above and pass it as the session parameter to the code block:

#+BEGIN_SRC ipython :session :results output :session /run/user/1000/jupyter/kernel-74d79038-f07b-4f9f-b376-844ef8a760e6.json
#include <iostream>
std::cout << ++i << "\n";
#+END_SRC

This is not very practical when reopening the file after a kernel shutdown, since I have to manually update the json file path. How could I start a kernel and get the path to the json file into a variable that I can use as the session parameter for the code block?

Thank you.

dangirsh commented 5 years ago

Short story: org header definitions support elisp evaluation. This means you can save the kernel path to an emacs variable, and then evaluate it dynamically for the session argument.

Long story of my use-case:

In my case, there's a script that emits the path to a kernel file that I copy out of a local container (usually based on this). The fact that it's in a container is irrelevant to your question. I use the following code to execute that script and capture the kernel path it emits:

(setq container-jupyter-kernel
      (string-trim
       (shell-command-to-string "./copy-kernel-to-host.sh")))

Then, for any subtree where the ipython blocks should be run in that kernel, I use the following property header:

:PROPERTIES:
:header-args:ipython: :session (eval container-jupyter-kernel)
:END:

Of course, you can alternatively just add the :session header to a single code block:

#+BEGIN_SRC ipython :session (eval container-jupyter-kernel) 
%load_ext autoreload
%autoreload 2

import numpy
#...
#+END_SRC

Hope this helps!

inglada commented 5 years ago

Thanks!