clj-python-trampoline icon indicating copy to clipboard operation
clj-python-trampoline copied to clipboard

Open an NREPL session from an existing python process

trafficstars
  • Motivation

I want to use libpython-clj from an already running python process, without needing any special python builds.

  • Examples

    [[https://github.com/tristanstraub/blender-clj-addon][blender-clj-addon]]

  • Running python with embedded nREPL

The following prepares and runs the python process (or application with embedded python) and bootstraps nREPL via a python script, passed via the command line.

  1. Preparing python environment:

    #+BEGIN_SRC sh clj -m clj-python-trampoline.resources --requirements > requirements.txt pip3 install -r requirements.txt

    clj -m clj-python-trampoline.resources --clj > clj.py #+END_SRC

  2. Starting a REPL:

    i. from the command line:

    #+BEGIN_SRC sh python3 clj.py #+END_SRC

    ii. with nREPL:

    #+BEGIN_SRC sh python3 clj.py -- -e "(require 'nrepl.cmdline) (future (nrepl.cmdline/-main))" #+END_SRC

    iii. from blender, with nREPL and cider middleware:

    #+BEGIN_SRC sh export CLASSPATH="$(clj -Sdeps '{:deps {nrepl {:mvn/version "0.7.0"} refactor-nrepl {:mvn/version "RELEASE"} cider/cider-nrepl {:mvn/version "RELEASE"}}}' -Spath)"

    blender -P clj.py -- -e "(require 'nrepl.cmdline) (future (nrepl.cmdline/-main "--middleware" "[\"refactor-nrepl.middleware/wrap-refactor\",\"cider.nrepl/cider-middleware\"]"))" #+END_SRC

  3. Connect to remote nREPL, and load python bindings:

    #+BEGIN_SRC sh clj -m nrepl.cmdline -c -p $(cat .nrepl-port) #+END_SRC

    #+BEGIN_SRC clojure (require '[libpython-clj.require :refer [require-python]]) ;; loads python shared library for us, calling our patched libpython-clj (require-python 'sys) (println sys/version) #+END_SRC

  • Assumptions

javabridge is installed with your local "pip3" command, which should be installing to the python environment that blender uses.

(Tested on Fedora 31)

  • Implementation
  • javabridge provides the python -> jvm connection.
  • libpython-clj is patched at runtime, to be able to use it from inside an existing python process. This patch is experimental and will certainly break something.