emacs-jupyter / jupyter

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

Working folder is wrong - not current directory #534

Open mankoff opened 2 months ago

mankoff commented 2 months ago

When I start a new kernel it's often in a working folder or directory from a previous run. For example, given,

#+BEGIN_SRC bash :exports both :results verbatim
pwd
#+END_SRC
: /home/kdm/tmp

I would expect the following new session to be in the same location, but it is rarely there.

#+BEGIN_SRC jupyter-python :exports both :session NEWSESSION
import xarray as xr
!pwd
#+END_SRC
: /home/kdm/projects/somewhere_else

How can I make new Jupyter sessions default to $(pwd)?

mankoff commented 2 months ago

Some more details...

In ~/.local/share/jupyter/runtime I have

nbserver-2253984.json
nbserver-2253984-open.html
kernel-bcf0dc65-81b1-4a74-9bc5-326a217396f9.json
kernel-bd9ff88d-d83f-4187-993c-9ccc5f8d741d.json

and many more kernel-*.json files.

I note that the nbserver-2253984.json file has a notebook_dir that points to the first place (after restarting emacs) where jupyter was run. All other kernels start there, until emacs is restarted.

mankoff commented 1 month ago

Looking into this a bit more... When I launch a kernel, it appears in the current directory. When I launch a new session on an existing kernel, it is in the old (original) directory. Is this the expected behavior? Is there some way to have sessions start in the current working directory of the Org file?

nnicandro commented 1 month ago

Kernels will be launched in the same directory as a notebook when it first launches so if you have a session /jpy::first which launches a notebook in some directory and then a second session /jpy::second, the second session will be in that same directory. Is your NEWSESSION a /jpy: based session or are you using just regular named sessions like first and second which do not launch a notebook and launch kernels directly? In this latter case, you should get kernels launching in the current directory as the Org file the source blocks are located in.

mankoff commented 1 month ago

No /kernel: or /kernel::, just :session foo and :session bar, different Org files in different folders.

If I don't specify a session, and just use

#+BEGIN_SRC jupyter-python :exports both :session NEW2
import os
print(os.getcwd())
#+END_SRC

I get an error: if: Need a valid session and a kernel to form a key

So I have this setting:

(setq org-babel-default-header-args:jupyter-python '((:session . "ds")
                                                    (:kernel . "ds")
                            ))

Now when I run the above Babel block (exactly as written, no jpy:/), results are:

#+RESULTS:
: /home/kdm/Desktop

If I open a new file in my home folder and run it,

#+BEGIN_SRC jupyter-python :exports both :session ELSEWHERE
import os
print(os.getcwd())
#+END_SRC

#+RESULTS:
: /home/kdm/Desktop

Note - new session, run from ~/, reports ~/Desktop.

But you are correct, each session does launch its own kernel. If I run jupyter-server-list-kernels I see:

http://localhost:8888
ds<1>             e1937ace-1342-4f0a-8e3d-33648131952f   a few seconds ago    idle       2
ds                83504539-f506-4e2c-b38c-c7f42ca3a2e2   a few seconds ago    idle       2
ds<2>             d80f103e-1b2d-44aa-8e85-578e7c7e49f9   a minute ago         idle       1
mankoff commented 1 month ago

Note - I've been using emacs-jupyter for a long time (>5 years?) and this is a relatively new behavior. Showed up sometime in the past six to nine months.

nnicandro commented 1 month ago

Oh I see. I was assuming that just having non-/jpy: sessions would use the zmq based kernel connections (as opposed to notebook based), but if you have jupyter-use-zmq set to nil then a local notebook will be used to launch kernels even with non-/jpy: sessions.

Can you evaluate the following code before launching your sessions. It should give the behavior you want. I'll have to think about if this is the right solution in general because it would mean having to do this for each language supported by Emacs-Jupyter.

(cl-defmethod jupyter-repl-after-init (&context (jupyter-lang python))
  (jupyter-eval (format "import os;os.chdir(\"%s\")" default-directory)))
mankoff commented 1 month ago

I have (setq jupyter-use-zmq nil) because of the ZMQ issues. #297.

Your proposed fix does work. Thank you.