Open Wildcarde opened 4 years ago
Adding an option to specify the token to use would be a good idea and should be easy enough --- would you like to send a patch?
If you don't actually need any interaction from Python, nor do you need to serve volumes from Python, and merely want to put neuroglancer into a specific state, you can construct a neuroglancer.ViewerState object, then convert it to a URL via neuroglancer.to_url.
As far as "attaching to a running Neuroglancer instance", do you specifically want to control the single web browser from multiple Python (or other) processes simultaneously, and/or have the state shared between multiple Python processes, or is it merely about avoiding having to copy in the correct URL each time you restart the Python process? In general I agree this would be useful and there are various options for how it could be done, but it might take a bit of work depending on what is desired.
Adding an option to specify the token to use would be a good idea and should be easy enough --- would you like to send a patch?
This I may be able to scratch together and send over I'll send over a patch if I get it working.
do you specifically want to control the single web browser from multiple Python (or other) processes simultaneously, and/or have the state shared between multiple Python processes, or is it merely about avoiding having to copy in the correct URL each time you restart the Python process?
Kinda both? But for different reasons.
I'd like to be able to put nglancer instances behind a reverse proxy (https://github.com/jupyterhub/configurable-http-proxy and traefik being the current candidates) so that we can have separate viewer instances for different stages of a pipeline with their own layers, sessions, and users.
The other side is, it would be great to be able to launch an nglancer instance in an initial configuration state (ie, something like this: https://github.com/Wildcarde/nglancer-frame/blob/master/neuroglancer/nglancer-launcher.py) and be able to attach to that nglancer instance to have a python process provide additional inputs, either because they are hacking on it with a jupyter notebook, or an automate process is launching a container for an additional layer and needs to programatically add mapping to that new layer into the viewer.
A quick follow-up question: is there a way to instruct neuroglancer to
stage the urls differently? Ie, move the token to the root of the tree and
have the smaller url bits as sub branches past that instead of
host/v/
^/v/<token>
to (.*)/v/<token>
. With this tiny change, I am able to use construct URLs for use with jupyter-server-proxy.This seems to slightly miss what I'm asking here. There is a set of urls supplied as part of the neuroglancer application:
INFO_PATH_REGEX = r'^/neuroglancer/info/(?P<token>[^/]+)$'
DATA_PATH_REGEX = r'^/neuroglancer/(?P<data_format>[^/]+)/(?P<token>[^/]+)/(?P<scale_key>[^/]+)/(?P<start_x>[0-9]+),(?P<end_x>[0-9]+)/(?P<start_y>[0-9]+),(?P<end_y>[0-9]+)/(?P<start_z>[0-9]+),(?P<end_z>[0-9]+)$'
SKELETON_PATH_REGEX = r'^/neuroglancer/skeleton/(?P<key>[^/]+)/(?P<object_id>[0-9]+)$'
MESH_PATH_REGEX = r'^/neuroglancer/mesh/(?P<key>[^/]+)/(?P<object_id>[0-9]+)$'
STATIC_PATH_REGEX = r'^/v/(?P<viewer_token>[^/]+)/(?P<path>(?:[a-zA-Z0-9_\-][a-zA-Z0-9_\-.]*)?)$'
All of these append the key at or near the end making it impossible to put an arbitrary reverse proxy in front of this tool without knowing the key value; either a button has to be presented that has the correct token already included in the url or the user needs to know the token and paste it into the url in order to use the tool. Both defeating the base of the question. I need to be able to spin up a neuroglancer that will self register behind a configurable proxy as something like <session hash>/viewerX
and have the user need nothing to exist past that point in order to land on the neuroglancer interface. If I was just putting an apache proxy infront of a single viewer object, doing the work to make a fixed token entry and using rewrite engine while not particularly easy to get working would probably work. But as we are trying to integrate this into a pipeline where researchers will be using it to review data at different stages in the overall process that doesn't work here.
I can see that the current URL syntax makes the proxy configuration more complicated than necessary. I'm not opposed to changing it to something that is better. I imagine a change might break some existing users' reverse proxy configurations, but if there is a clear improvement I think that cost is reasonable.
If you want to implement something better, I don't think it would be much work.
I thought I should update this, while I'm hoping to do the updates to make controlling the token possible from inside python we are currently examining working around the URL structuring in an alternate way by loading the relevant information into a key/value store and having the wrapper application reconstruct the urls directly.
@Wildcarde and I are working on the same project. We found a solution to the first question using a programmable proxy and a key/value store, i.e. we did not have to modify any neuroglancer code.
For the second question (creating a python viewer object from an already running neuroglancer instance) it is looking like we will need to modify the neuroglancer python code directly. The need has narrowed slightly so this might be easier to solve than the original request.
To give some context to the problem we are facing: we are running a flask (python) service where users can request a link to view their data in neuroglancer. When they make a request, we create a neuroglancer.viewer.Viewer()
instance, load in the volumes the user requested, modify the viewer state to the specifications the user requested and then return the viewer link. This is all working great, but the issue is: what if the user wants to modify the existing viewer state, add new volumes, etc. in a jupyter notebook (common use case).
One way I can think of to approach this is to add optional parameters specifying the address and port of the tornado server on which the existing viewer is already registered, along with the viewer token when making the Viewer()
object. Then some sort of API would need to be created for communicating with the tornado server to update the viewer state. I am interested to hear from those who have worked on the python interface to neuroglancer on whether this seems like a viable approach.
First question /request: In a docker framework I'm building out as a combination quick data review tool and development platofrm we are launching a neuroglancer object using python with the
neuroglancer.Viewer()
command and then spinning to keep the process alive so that we can do some initial setup. While I'm guessing this isn't the only way to do this, I couldn't find a way to spin up a free standing neuroglancer instance and pre-load the configuration settings we want. However I'm working to put this all behind an apache proxy to give the end user a simple plane to talk to and can't control the token used to secure neuroglancer on startup so I can't put a simple reverse proxy layer in front of it. This appears to be due to the fact that instantiating a viewer object immediately has side effects before you can tune what you want. My current plan is to put a configurable proxy (https://github.com/jupyterhub/configurable-http-proxy) in front of the neuroglancer instance and use the run time token generation to populate that but i'd like to avoid the hop if possible. I need this conf proxy for volumes anyway but it would still be helpful to control this for smaller setups. If you could just enable passingtoken=
into the__init__
process that would fix this for our use case. I've included a copy of our neuroglancer launcher shim below.Second question: Is it possible to attach to a running neuroglancer instance from a remote location, I've got the approach where you instance a neuroglancer viewer object and feed configurations into it working and that works fine if you are doing that from inside a notebook or just spin locking it like we do below. But I'd like to be able to spin up a free standing neuroglancer instance, and then attach to it form a jupyternotebook to use as a hackable development interface. I'm hoping to have a new more capable push up soon to https://github.com/Wildcarde/nglancer-frame that demonstrates at least some of what we are thinking about in this direction.
in dev version of the launcher:
edit: sorry about the empty notification email, hit enter early.