-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make interactive mode work on macOS #298
Comments
Any news on this issue? We'd like to create a LLM agent for pyimagej, but this prevent me from having both a chatbot and imagej interface. |
Yes! Just yesterday I completed my draft implementation of Python support for Jaunch, the native launcher I've been working on to replace the current ImageJ Launcher. If you launch Python via Jaunch instead of the normal We still need to update PyImageJ to remove the "no interactive mode on macOS" fail-fast check, though. And of course, Jaunch is not yet released, so all this is quite "bleeding edge" for the moment. But there is hope. @oeway Do you think launching via Jaunch would be sufficient for you? Or do you need everything work via the standard One other idea to make interactive mode work from standard import code; code.interact(local=locals()) or import IPython
IPython.embed() and then in the main Python program, start the AppKit loop. So the main program's thread becomes blocked, but meanwhile there is a Python REPL running on another thread. I haven't tried it yet though, so it may or may not work... |
Hi, @ctrueden This sounds great! Great that you made it work with Jaunch. Please let me know how I can try it. I am trying to make this hypha service for imagej work: https://gist.github.com/oeway/4fb456ab1d700e802d76a98e88370359 (the same one as we worked during our last hackathon in loci). This script launches imagej and expose some python function to a remote hypha server (similar to imagej http server plugin). Here we specifically want the user to be able to see the GUI and operate together with the remote request. But I could not get it to work with mac. I just tried GUI mode and it crashes:
If I set to headless, it looks like running, but still got stuck somehow. Maybe related to my JVM? No idea. I would be happy to try Jaunch, could you let me know how I can get the imagej gui together with this python script? |
This issue has been mentioned on Image.sc Forum. There might be relevant details there: https://forum.image.sc/t/fiji-friends-weekly-dev-update-thread/103718/32 |
Currently, macOS users are unable to use
interactive
mode with PyImageJ. See issue #23 for more details on getting the ImageJ GUI to work on macOS. Work on this issue resulted in thegui
mode for PyImageJ macOS users. While the GUI does work for macOS users, they unfortunately loose access to the REPL (unlike Linux and Windows users). This is because on macOS the Java AWT GUI must poll the interface for clicks and other input using Apple's AppKit framework (accessible viaPyObcTools
from Python). This is done via anNSRunLoop
which blocks the console. In Python land this is done withAppHelper.runConsoleEventLoop()
frompyobjc
.Here is a quick breakdown of my conclusions thus far in investigating this issue:
pyimagej
,scijava
andjpype
. Trying to start and control the JVM andAppHelper
event loop from Python doesn't work.AppHelper.runConsoleEventLoop()
and the associated Objective-C code checks if its in the main thread or not. This means that any viable approaches here will likely involve sacrificing the main thread to Apple.concurrent.futures
module is just a high level API for thethreading
module. It doesn't offer any solutions here.installInterrupt=True
flag withAppHelper.runConsoleEventLoop()
doesn't help here.asyncio
doesn't work (I also tried withinstallInterrupt=True
).multiprocessing
module and starting a new process works...but of course the two processes can't share data easily. You can make a shared memory map and share data but this seems like it would require extensive rework. I didn't try this. Also,appose
could make this work nicely for us as well.The latest approach I've seen and have tried (it didn't work but I could have been doing it wrong) is using AppKit's dispatch mechanism. The credit for this idea goes to this stackoverflow post where the user retsigam wanted to interact with the Bluetooth stack (which needed to run a console event loop) without locking up the REPL. This seemed like as close as I was going to get to finding an analogous problem in the wild. This solution relies on the
libdispatch
which is also known as Grand Central Dispatch.Digging a little further
pyobjc
added bindings forlibdispatch
in version 4.1. See this issue. Also in that issue is another user who is trying to resolve the console event loop block by starting theAppHelper.runCopnsoleEventLoop()
in a separate thread. Wayne solved this by using the dispatch mechanism documented here. This made think that using the dispatch mechanism was a viable approach here.The text was updated successfully, but these errors were encountered: