Closed almarklein closed 3 years ago
This is almost done, I think. The internals were refactored a bit, making those changes somewhat hard to read. I think the most important part for feedback is the API - have a look at the new example.
One thing I had not thought of is that if two different users work on the same deployed Dash app, since overlay
is a global variable there will be unwanted cross-talking between sessions. One possible way to alleviate this would be to have another component member of the VolumeSlicer
class which could be an user-id Input
field, and then overlay
would instead be a dict with the different user ids as keys... What do you think?
Good point ... I had overlooked that! Do you mean that each user must type their name into the input field?
Perhaps Dash or Flask provides a session id of some sorts?
edit: a ServerSideStore (which would not convert an ndarray to lists) would be handy here :)
Perhaps Dash or Flask provides a session id of some sorts?
I just saw https://dash.plotly.com/sharing-data-between-callbacks Example 4: User-Based Session Data on the Server
Also see https://dash.plotly.com/live-updates for the case where app.layout
is a function (which I just learned about while browsing the doc ;-)
Thanks Emma, that seems like the way to go, except perhaps use an in-memory cache instead of a file system cache.
I started on this approach, but I'm having second thoughts about it. A server-side cache to store 3D numpy arrays could easily cost considerable amounts of memory. A cache like that would have parameters like timeouts and max memory to prevent the server from going out of memory. In general, web server applications have a trade-off between protecting against malicious use and also keeping the app working for other users. Normally the margin between these two ends is large, but with data as large as this, that margin feels quite narrow ...
This can be a deliberate choice that would be fine for certain applications - if a user chooses to - but maybe we should not make it part of the default functionality ... Instead, I plan on looking into a more generic approach to add traces to the figure, so the user can (must :) ) decide where to store the data.
Ok, I eventually went with a client-side store to store the layout data, plus a method to easily create that data. I tried to make is more generic, but that made the application code (of the user) quite a bit more complex.
This is ready for review again.
Closes #17
Implements:
set_overlay()
to set/update mask data.set_overlay_colormap()
to allow specifying how the mask is rendered.slicer.trigger
) that a callback can output to to force an update (an purge the cache).