emacs-jupyter / jupyter

An interface to communicate with Jupyter kernels.
GNU General Public License v3.0
928 stars 90 forks source link

No org-babel-execute function for jupyter-python #306

Closed cvanelteren closed 3 years ago

cvanelteren commented 3 years ago

I am trying to get ob-jupyter working under org-mode. Source code blocks keep returning No org-babel-execute function for jupyter-python after evaluating C-c C-c.

My config contains

(org-babel-do-load-languages
 'org-babel-load-languages
 '(
   (emacs-lisp . t)
   (python . t)
   (ipython . t)
   (jupyter . t)
   ))

example source block (from readme):

#+BEGIN_SRC jupyter-python :session py
x = 'foo'
y = 'bar'
x + ' ' + y
#+END_SRC

jupyter-server-list-kernels shows multiple active kernels @localhost:8888 image

I can connect to a repl but I would love to be able to run code directly from org, how do I achieve that?

timlod commented 3 years ago

Have you defined a :kernel <kernel-name> header-arg at the top of your file? If not, you will have to provide it - emacs-jupyter afaik requires both :session and :kernel to be defined to be available.

cvanelteren commented 3 years ago

Could you point me to the part in the readme where it states that? Applying the following yields the same error

:properties:
:header-kernel: python3
:end:
#+begin_src jupyter-python :kernel python3 :session py
print('hello')
#+end_src

Gives No org-babel-execute function for jupyter-python

timlod commented 3 years ago

The section org-mode source blocks specifies that each cell is based jointly on :kernel and :session - but I suppose there will always be a default kernel, so that's not the problem.

I think the problem then lies somewhere with the config - org-babel doesn't seem to recognize jupyter-python after all. First I'd try removing ipython from the load languages - the README states that there may be issues with having both jupyter and ipython active. If you check C-h-v RET org-babel-load-languages, is jupyter still last in the list?

cvanelteren commented 3 years ago

Hmm it is strange. The value is set correctly but I don't see the listing in the source-code. org-babel-load-languages gives

image

However the source code section doesn't list jupyter, is that normal?

org-babel-load-languages

``` (alist :tag "Babel Languages" :key-type (choice (const :tag "Awk" awk) (const :tag "C" C) (const :tag "R" R) (const :tag "Asymptote" asymptote) (const :tag "Calc" calc) (const :tag "Clojure" clojure) (const :tag "CSS" css) (const :tag "Ditaa" ditaa) (const :tag "Dot" dot) (const :tag "Ebnf2ps" ebnf2ps) (const :tag "Emacs Lisp" emacs-lisp) (const :tag "Forth" forth) (const :tag "Fortran" fortran) (const :tag "Gnuplot" gnuplot) (const :tag "Haskell" haskell) (const :tag "hledger" hledger) (const :tag "IO" io) (const :tag "J" J) (const :tag "Java" java) (const :tag "Javascript" js) (const :tag "LaTeX" latex) (const :tag "Ledger" ledger) (const :tag "Lilypond" lilypond) (const :tag "Lisp" lisp) (const :tag "Makefile" makefile) (const :tag "Maxima" maxima) (const :tag "Matlab" matlab) (const :tag "Mscgen" mscgen) (const :tag "Ocaml" ocaml) (const :tag "Octave" octave) (const :tag "Org" org) (const :tag "Perl" perl) (const :tag "Pico Lisp" picolisp) (const :tag "PlantUML" plantuml) (const :tag "Python" python) (const :tag "Ruby" ruby) (const :tag "Sass" sass) (const :tag "Scala" scala) (const :tag "Scheme" scheme) (const :tag "Screen" screen) (const :tag "Shell Script" shell) (const :tag "Shen" shen) (const :tag "Sql" sql) (const :tag "Sqlite" sqlite) (const :tag "Stan" stan) (const :tag "Vala" vala)) :value-type (boolean :tag "Activate" :value t)) custom-version ```

edit: for clarity, removing ipython gives the same error. edit2: I am using doom emacs 27.1

timlod commented 3 years ago

I believe that's the problem - that's clearly not the list you defined up top. You can try reconfiguring this in the scratch buffer, see if that solves it?

cvanelteren commented 3 years ago

I have looked at this and #251 but both suggestions don't do anything for me.

My env is activated an I can see both repls and servers running with jupyter.

You can try reconfiguring this in the scratch buffer, see if that solves it? Do you mean adding it manual to source? Isn't that what the config.elin essence does?

I am presuming now emacs-jupyter does not play nice with virtual envs like conda, are there any official instructions for getting this up and running?

Installing jupyter on my system python seems a bit odd.

cvanelteren commented 3 years ago

If it helps any

(shell-command "jupyter-available-kernelspecs") evaluates to 127. Perhaps the locate python functions are not looking for the jupyter in path?

timlod commented 3 years ago

About conda - it works for me, so that's not the problem. Did you fix (org-babel-load-languages)? Its value should be the exact list you pass in the config. jupyter-python ie. shouldn't even be on there (it isn't in my working config). You do need to install jupyter on the python that is the base python used in emacs. For my desktop, that is my anaconda base python.

About you seeing REPLs and servers running with jupyter - what do you mean here? How did you start those up - within emacs?

cvanelteren commented 3 years ago

I am not sure on how to fix the (org-babel-load-languages); jupyter is listed as a value to that variable

config.el

``` (org-babel-do-load-languages 'org-babel-load-languages '( (emacs-lisp . t) (python . t) (jupyter . t) ) ) ```

org-babel-load-languages

``` org-babel-load-languages is a variable defined in org.el. Value ((emacs-lisp . t) (python . t) (jupyter . t)) Original Value ((emacs-lisp . t)) Set Customize ```

With the repl I mean that I can run jupyter-run-repl and I will see my kernels that I have in jupyter and I can finally open it resulting in: image

Which shows that it sees conda, all good! In addition I could connect to a server repl, however, in org-mode it doesn't seem to see jupyter at all.

EDIT: as a counter question how come the jupyter-list-kernelspecs evaluate to 127? Shouldn't it output all the avaiable kernels?

timlod commented 3 years ago

I don't have a function/variable jupyter-list-kernelspecs - are you sure that's the one you mean? I assume you mean jupyter-available-kernelspecs. If I evaluate it in the scratch buffer it indeed lists all available kernels.

org-babel-load-languages now looks good - in the screenshot above it was not. Also good that jupyter in itself seems to work somehow. If you do jupyter-run-repl - does it list all your kernels?

cvanelteren commented 3 years ago

Yes that lists all the kernels I have installed.

image

kernels are also listed now:

image

timlod commented 3 years ago

OK, last thing to try before I'm at a loss: How and when do you load the jupyter package? I load it with use-package and make sure org has been loaded to correctly hook up org-babel and emacs-jupyter:

(use-package jupyter
  :demand t
  :after (:all org python))

Can you, in the scratch buffer, manually do (require 'ob-jupyter) after you opened an org buffer with a jupyter cell? Then refresh that buffer and see if you now have the package available.

cvanelteren commented 3 years ago

Ah now we are getting somewhere. If I run (require 'ob-jupyter) in a scratch buffer it give me error in process sentinel: Cannot open load file: no such file or directory, ob-jupyter-python

The wombo-combo that seem to produce at least some output now looks like

;;config.el
(require 'ob-python)
(use-package jupyter
  :demand t
  :after (:all org python)
)
)

Now syntax highlighting is also recognized (!)

timlod commented 3 years ago

Interesting. Why do you manually require ob-python? I don't think that's necessary. If (require 'ob-jupyter) doesn't work, try (require 'jupyter) first (after having loaded org) and then ob-jupyter.

cvanelteren commented 3 years ago

Few hours later and a reboot of emacs I can't seem to replicate the results I was having.

org-babel can't, for whatever reason, can't find emacs-jupyter, could it be that doom-emacs causes a large difference? I am coming from vim and as such am not sure exactly on whether this causes a problem. emacs-jupyter is installed to ~/.emacs.d/.local/straight/build-27.1/jupyter through M-x package install as per usual.

timlod commented 3 years ago

:/ sorry, I'm out of my depth now. It is possible it's an issue with doom-emacs interop. It would make sense to try and isolate the issue - get it working without doom and adding components. Obviously doom is a pretty big config so that may take a bit - but you'd learn a lot about emacs in the process :)

I would wager the actual problem lies with the order in which packages are installed and then loaded. There may be some problems in there with deferred package loading (where you have it installed but another package, ie. jupyter, relies on org-babel to be loaded) as well. Maybe someone else here knows more - hope you can get it working!

cvanelteren commented 3 years ago

I got it to work! This link helped me. The thought that doom was just a 'light' layer on top of emacs but the comments above here show that it may actually modify it a bit more than I thought it did.

adding (org +jupyter) to my init.el made it work immediately.

Thanks everyone for the help!

dmusican commented 2 years ago

I stumbled on this issue when I was trying to solve this problem as well. I'm using Doom Emacs, but I wanted to use the standard emacs-jupyter package rather than the customized config provided by the fix above.

Here's the problem, which took me days to find. Doom adds an advice on top of org-babel-do-load-languages which causes it to ignore the call to it. It's even in the Doom FAQ, in the section titled "Lazy load more than everything."

So I fixed it by removing the advice:

  (advice-remove #'org-babel-do-load-languages #'ignore)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((emacs-lisp . t) ;; Other languages
     (shell . t)
     (python . t)
     (jupyter . t))))

I'm sure there's supposed to be a better doom-y way of doing this involving autoloading something, but that's beyond my capabilities right now. Regardless, this seems to work great, and I'll wager this is exactly the problem @cvanelteren was having.

hwiorn commented 2 years ago

@dmusican If you want just doom-y way, try this. This will work in latest doom-emacs.

;;; Inside (use-package! org ...) clause.

  (after! (:and ob-async org-src)
    (dolist (lang '(rust C typescript julia)) ;; FIXME: Replace your prefer language for jupyter.
      (cl-pushnew (cons (format "jupyter-%s" lang) lang)
                  org-src-lang-modes :key #'car)))

  ;; Set some default header arguments for example.
  (setq org-babel-default-header-args:sh    '((:results . "output replace"))
        org-babel-default-header-args:bash  '((:results . "output replace"))
        org-babel-default-header-args:shell '((:results . "output replace"))
        org-babel-default-header-args:markdown '((:results . "output replace"))
        org-babel-default-header-args:jupyter-rust '((:results . "output replace")
                                                     (:kernel . "rust"))

IMPORTANT! You need to check Jupyter and Jupyter kernel first. If you don't have jupyter python module or any jupyter kernel matched, org-babel can't run the kernel. So it will keep saying No org-babel-execute function for jupyter-<lang>.

pip install jupyter # or jupyterlab
jupyter kernelspec list
NightMachinery commented 5 months ago

I get this error (No org-babel-execute function for jupyter-python) when I open emacs for the first time. Reloading an org-mode buffer fixes it. So the problem is some library not being loaded properly, I guess. I load these ones explicitly:

(require 'org-src)
(require 'ob-async)
(require 'jupyter)
(require 'jupyter-org-client)

What other libraries should I load?

NightMachinery commented 4 months ago

I solved my issue by doing all of these:

(require 'org-src)
(require 'ob-async)
(require 'ob-jupyter)
(require 'jupyter)
(require 'jupyter-org-client)

(after! (ob-jupyter)
  (org-babel-jupyter-aliases-from-kernelspecs))
thriveth commented 1 month ago

I am running vanilla Emacs and ran into the same problem. Running (org-babel-jupyter-aliases-from-kernelspecs) explicitly after loading Jupyter solved it for me. No idea why.