Yes, the SlicerWeb project has a lot of experimental parts and is not complete. I’ve been thinking for quite a while that it should be refactored and simplified. That said it does work well and could be the basis for this ‘singleton app’ feature and others. It probably looks more complex than it really is because I was trying to figure out how it needed to work while developing this version. The actual core is not that big and most of the rest would be better as plugins.
Considering that “singleton app” is a core feature, needed in many use cases, it would be much better to have it in the Slicer core.
What do you think about bringing base classes and maybe some stable request handlers (such as opening of an URL) to the Slicer core and leave the experimental and project-specific features in SlicerWeb and other extensions?
Or we could clean up Slicer Web and move out experimental things to other extension(s).
Yes, there’s a very small set of code in SlicerWeb that would enable the essential functionality. I agree it would be better in the core than in an extension so that people could rely on it being available. Let me try look into that and try a PR. It’s really just the one WebServer
scripted module.
Sounds great!
We could consider adding two request handlers to the Slicer core: one for opening an URL and another one for executing Python command and return the output. By default the server would be disabled, so it would not be a security risk.
Yes, I already have a repl
endpoint in the web server that accepts python code and returns the result. The first time the request is received the user gets a dialog to accept or not (along with an ‘always accept’ checkbox). We may want to make a separate preference for allowing this endpoint since it seems more risky than some of the others (but it’s super powerful too!).
It is definitely important to consider security implications before using this. I also recently added a certfile
option to support https.
I’ve pushed the DICOMweb import enhancements, which will be available in the Slicer Preview Release from tomorrow. Improvements include:
- fine-grained progress reporting during downloading of each series (not just when a series download is completed)
- avoid re-downloading of content already in the local DICOM database
- select loaded content in the DICOM browser when import is finished
- improved error handling (errors are displayed in a popup window)
While @pieper takes care of moving core parts of the web server to the Slicer core, you can already write a Python script that starts Slicer (if not started already) and uses the SlicerWeb extension to make it load an image via a web request.
@lassoan
I download the newest slicer 4.13.0-2021-11-9, I tested using the URL to open the slicer, but it took much longer time than before to download the data. Wonder if this is only me?
Confirmed when the file already existed in the slicer, it will not download again.
Good catch, thanks for reporting this. The download time got increased by the combination of detailed logging and increased progress reporting. On a test case, download time increased from 150sec to 244sec. I’ve updated the importer to only report warnings and errors during series download, which cut the download time to 68sec.
The fix will be included in the Slicer Preview Releases from tomorrow but you can apply the change to your local installation now (just modification of a single .py file).
I’ve been waiting for the update about the “singleton app”, any news?
The pull request to integrate the WebServer module into Slicer core is still under review:
You don’t need to wait for this to be merged. You can get the WebServer module files from that branch and copy them into your <SlicerInstallFolder>lib\Slicer-4.13\qt-scripted-modules
folder then start Slicer and open the WebServer module. It starts the web server automatically. Instead of the GUI, you can also start Slicer and start the WebServer module from the command line.
After this, you can make Slicer open a file by sending a command via Slicer’s REST API. For example, you can open a file by running these few lines from any Python environment:
import requests
import sys
filename=sys.argv[-1].replace('\\','/')
port = 2016
requests.post(url=f'http://localhost:{port}/slicer/repl', data='slicer.app.loadFiles([\''+filename+'\'])', timeout=15)
You can use Slicer’s Python interpreter to run this (unlike the full Slicer application, it starts up in a second) by copying the above script into a new ShowInSlicer
folder: <SlicerInstallFolder>/bin/Python/ShowInSlicer/__main__.py
(this creates a Python module that can be referred to by name instead of a full path). After this, you can execute this command in the terminal:
PythonSlicer.exe -m ShowInSlicer c:\tmp\CTChest.nrrd
It will open the specified file in the running Slicer instance.
After the WebServer module will be integrated into the Slicer core, I’ll add a Python script like the one above to the Slicer core, so it will not be necessary to mess with copying files. It could also make sense to add detection of the server to the script: if the server is not running then the script could start Slicer.
Can we upload more than 50 nifti files at a time with a link or can we upload a folder of these much nifti files through script in 3d slicer?
Yes, you can do this.
How to do that @pieper ? Is there is any script available? or we just need to pass a link with the prams which have the downloadable folder of these much files. Because I think we can’t pass it in link as folder is not considered as downloadable file.
please help.
The scripts @lassoan posted just above your post gives the formula, just repeat it for all your volumes. One note: the WebServer module is now is the Slicer release, so no need for special installation. Also the repl
endpoint has been renamed exec
. What this exec
endpoint allows is for external programs (e.g. python or shell scripts) to invoke the execution of python code in the Slicer application just as if it had been typed in the python console of the application or initiated by other GUI actions in the application. It’s a very powerful feature so you should be able to accomplish whatever you are trying to do.
If this isn’t clear, please post what specifically you are trying to accomplish and what tools you are using and maybe we can make more concrete suggestions.
Thank you @pieper . I will give it a try.
There have been even more improvements since this thread was started: you can use the slicerio Python package to conveniently open an image in Slicer bya simple Python call. slicerio launches Slicer with web server interface enabled and opens the file.
For example, after installing slicerio Python package, run this in any local Python environment to open an image in Slicer:
import slicerio.server
slicerio.server.file_load("https://github.com/rbumm/SlicerLungCTAnalyzer/releases/download/SampleData/LungCTAnalyzerChestCT.nrrd", slicer_executable="path/to/Slicer.exe")
See more information and examples here.
Thanks @lassoan. It is a great updated feature. But this is for a one file, can I open slicer 3d with a link which contains a folder of the files? Like how we are importing a single file or a directory in 3d slicer.
What is your end goal? Quickly view the 50 files one by one? Or view more (or all) at once?
Are those files in a local directory or a web server somewhere? If you show them one by one, how do you decide on the order?
Does the user need to do anything with them? For example, view one by one and approve or flag each? Maybe edit some segmentation results and submit the revised segmentation to a server?
Thanks for replying @lassoan , My folder which contains 50 NIFTI files is in my local repository. I mean in my app in cloud as .zip file.
when user click “label in slicer” then it will download zip and the zip will be extracted and will be in local downloads folder. (so can say the folder is in local directory).
There is a feature in the 3d slicer where I can take a file or a directory so I am trying to open 3d slicer and the directory should load.
I can open and place a file by cli command in subprocess, but giving error while putting folder in path.
The user want to label it and edit it to get obj file.
This use case is often implemented by simply sharing a dropbox or onedrive folder. The user drag-and-drops an image into the Slicer application window, segments it, and saves the result. Since segmentation typically takes tens of minutes, the 10-20 second task of loading and saving data usually does not justify doing any Python scripting to speed up things.
A more modern approach is to use MONAILabel for this. You can start a single MONAILabel server and many users can connect to it using the MONAILabel extension in 3D Slicer. MONAILabel automatically provides an image by a single click; the user can then segment the image (optionally MONAILabel may provide a default AI segmentation) and finally the user uploads the segmentation result by a single click.