/clj-python-trampoline

Open an NREPL session from an existing python process

Primary LanguageClojure

Motivation

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

Examples

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:
    clj -m clj-python-trampoline.resources --requirements > requirements.txt
    pip3 install -r requirements.txt
    
    clj -m clj-python-trampoline.resources --clj > clj.py
        
  2. Starting a REPL:

    i. from the command line:

    python3 clj.py
        

    ii. with nREPL:

    python3 clj.py -- -e "(require 'nrepl.cmdline) (future (nrepl.cmdline/-main))"
        

    iii. from blender, with nREPL and cider middleware:

    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\\\"]\"))"
        
  3. Connect to remote nREPL, and load python bindings:
    clj -m nrepl.cmdline -c -p $(cat .nrepl-port)
        
    (require '[libpython-clj.require :refer [require-python]]) ;; loads python shared library for us, calling our patched libpython-clj
    (require-python 'sys)
    (println sys/version)
        

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.