I've previously written here about the vpython module that makes it easy to display program-driven 3D animations in a Jupyter notebook.
I'm now trying to extend the vpython module to function if the user is not running in a notebook, in response to requests from users. I detect whether you're running in a notebook and do two different things depending on the answer. If not in a notebook, I still use a browser for display, using the GlowScript library that calls on WebGL.
I use webbrowser.open('http://localhost:{}'.format(HTTP_PORT)) to open a browser window and start an HTTPServer, which sends to the browser an html file containing the JavaScript program that will receive instructions from the server to create or modify VPython objects and use those instructions to tell the GlowScript library what to do. The communcations between server and browser in the notebook case uses a websocket, and in the new option I create an autobahn.asyncio.websocket in the server. What I run into is that code that works in the notebook case fails in the new case, due to various complications. I can solve a subset of these problems at the cost of the others failing, no matter what subset I choose. It's a Whack-a-mole game.
To take just one example: In order that a user's simple one-line program "box()" display a 3D box, and since I have no programmatic indication that the end of the user's program has been reached, I have to run the websocket in a thread; otherwise there is nothing to signal to the vpython module that output needs to be sent to the browser. But if the websocket is in a thread, there are problems of handling event-driven function calls, because they count as being inside the thread, whereas user-program-driven function calls are not in a thread. Etc.
So my ill-formed question is this: Can someone summarize the Jupyter communications machinery in the context of my difficulty in doing something similar? For example, in the notebook case I don't see any difference in the behavior of user-driven function behavior and event-driven function behavior.
Bruce