plexora 0.0.1__tar.gz → 0.0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. {plexora-0.0.1/plexora.egg-info → plexora-0.0.7}/PKG-INFO +384 -341
  2. {plexora-0.0.1 → plexora-0.0.7}/README.md +58 -17
  3. plexora-0.0.7/plexora/__init__.py +262 -0
  4. plexora-0.0.7/plexora/_resources.py +236 -0
  5. {plexora-0.0.1 → plexora-0.0.7}/plexora/api/__init__.py +11 -0
  6. {plexora-0.0.1 → plexora-0.0.7}/plexora/api/dataset.py +255 -14
  7. {plexora-0.0.1 → plexora-0.0.7}/plexora/api/plugin.py +120 -1
  8. plexora-0.0.7/plexora/askpass.py +157 -0
  9. plexora-0.0.7/plexora/cli.py +1650 -0
  10. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/vendor_bundle.js +1 -1
  11. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/css/import.css +55 -104
  12. plexora-0.0.7/plexora/client/src/css/main.css +3576 -0
  13. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/css/openProject.css +15 -3
  14. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/css/quickView.css +46 -2
  15. plexora-0.0.7/plexora/client/src/css/settings.css +1030 -0
  16. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/css/tokens.css +13 -0
  17. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/css/viewer.css +134 -12
  18. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/main.js +153 -3
  19. plexora-0.0.7/plexora/client/src/js/services/appRouter.js +438 -0
  20. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/appStatus.js +31 -2
  21. plexora-0.0.7/plexora/client/src/js/services/browsePicker.js +126 -0
  22. plexora-0.0.7/plexora/client/src/js/services/connectionModal.js +785 -0
  23. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/dataLayer.js +7 -13
  24. plexora-0.0.7/plexora/client/src/js/services/dataLocation.js +764 -0
  25. plexora-0.0.7/plexora/client/src/js/services/fileLocation.js +704 -0
  26. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/importFormValidation.js +107 -2
  27. plexora-0.0.7/plexora/client/src/js/services/keyboardShortcuts.js +222 -0
  28. plexora-0.0.7/plexora/client/src/js/services/logTerminal.js +126 -0
  29. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/numericData.js +28 -0
  30. plexora-0.0.7/plexora/client/src/js/services/pageBoot.js +103 -0
  31. plexora-0.0.7/plexora/client/src/js/services/pathPicker.js +886 -0
  32. plexora-0.0.7/plexora/client/src/js/services/placePicker.js +244 -0
  33. plexora-0.0.7/plexora/client/src/js/services/remoteGlobe.js +633 -0
  34. plexora-0.0.7/plexora/client/src/js/services/remoteState.js +533 -0
  35. plexora-0.0.7/plexora/client/src/js/services/resourceRouting.js +206 -0
  36. plexora-0.0.7/plexora/client/src/js/services/resourceStatus.js +418 -0
  37. plexora-0.0.7/plexora/client/src/js/services/sessionExpiry.js +338 -0
  38. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/channelList.js +69 -27
  39. plexora-0.0.7/plexora/client/src/js/views/channelNamesUpload.js +906 -0
  40. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/colorSwatchPicker.js +11 -7
  41. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/dataSourceField.js +35 -5
  42. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/imageViewer.js +11 -7
  43. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/navbarControls.js +14 -32
  44. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/openProjectPage.js +1 -9
  45. plexora-0.0.7/plexora/client/src/js/views/popoverPortal.js +89 -0
  46. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/projectEdit.js +227 -20
  47. plexora-0.0.7/plexora/client/src/js/views/quickViewLanding.js +202 -0
  48. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/requirementsModal.js +26 -7
  49. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/searchableSelect.js +11 -8
  50. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/segmentationProgress.js +5 -0
  51. plexora-0.0.7/plexora/client/src/js/views/segmentationWait.js +296 -0
  52. plexora-0.0.7/plexora/client/src/js/views/settingsPage.js +1233 -0
  53. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/toolLoader.js +231 -2
  54. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/viewerControls.js +165 -27
  55. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/viewerManager.js +11 -2
  56. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/viewerSidebar.js +154 -19
  57. plexora-0.0.7/plexora/client/templates/_fragment.html +34 -0
  58. plexora-0.0.7/plexora/client/templates/base.html +379 -0
  59. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/templates/index.html +69 -23
  60. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/templates/open_project.html +96 -96
  61. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/templates/project_columns.html +3 -3
  62. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/templates/project_edit.html +220 -196
  63. plexora-0.0.7/plexora/client/templates/settings.html +545 -0
  64. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/templates/upload.html +47 -3
  65. plexora-0.0.7/plexora/connect.py +1890 -0
  66. {plexora-0.0.1 → plexora-0.0.7}/plexora/datasource.py +22 -0
  67. {plexora-0.0.1 → plexora-0.0.7}/plexora/jupyter.py +313 -20
  68. plexora-0.0.7/plexora/nodes.py +730 -0
  69. {plexora-0.0.1 → plexora-0.0.7}/plexora/notebook_env.py +366 -232
  70. {plexora-0.0.1 → plexora-0.0.7}/plexora/paths.py +517 -486
  71. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/__init__.py +105 -100
  72. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/server/values.py +4 -1
  73. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerFigureBridge.js +92 -133
  74. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerRoiBridge.js +13 -10
  75. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/__init__.py +38 -2
  76. plexora-0.0.7/plexora/plugins/figure_builder/server/compose.py +825 -0
  77. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/export.py +280 -20
  78. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/pixels.py +110 -6
  79. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/render.py +58 -7
  80. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/schema.py +377 -37
  81. plexora-0.0.7/plexora/plugins/figure_builder/server/shapegeom.py +189 -0
  82. plexora-0.0.7/plexora/plugins/figure_builder/server/strokegeom.py +337 -0
  83. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/textmetrics.py +2 -2
  84. plexora-0.0.7/plexora/plugins/figure_builder/static/figureActions.js +659 -0
  85. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureBuilderApi.js +15 -3
  86. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureCanvas.js +1303 -174
  87. plexora-0.0.7/plexora/plugins/figure_builder/static/figureChoiceField.js +386 -0
  88. plexora-0.0.7/plexora/plugins/figure_builder/static/figureColorField.js +294 -0
  89. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureContextBar.js +500 -426
  90. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureContextMenu.js +19 -3
  91. plexora-0.0.7/plexora/plugins/figure_builder/static/figureImagePanel.js +1558 -0
  92. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureLibrary.js +13 -9
  93. plexora-0.0.7/plexora/plugins/figure_builder/static/figureLineDefs.js +142 -0
  94. plexora-0.0.7/plexora/plugins/figure_builder/static/figureLinePanel.js +445 -0
  95. plexora-0.0.7/plexora/plugins/figure_builder/static/figurePanelCompositor.js +157 -0
  96. plexora-0.0.7/plexora/plugins/figure_builder/static/figurePointEditor.js +575 -0
  97. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureQuickEdit.js +391 -99
  98. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureRichText.js +46 -1
  99. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureSceneSnapshot.js +12 -7
  100. plexora-0.0.7/plexora/plugins/figure_builder/static/figureSchema.js +466 -0
  101. plexora-0.0.7/plexora/plugins/figure_builder/static/figureShapeDefs.js +235 -0
  102. plexora-0.0.7/plexora/plugins/figure_builder/static/figureShapeDrawing.js +288 -0
  103. plexora-0.0.7/plexora/plugins/figure_builder/static/figureShapeGeometry.js +546 -0
  104. plexora-0.0.7/plexora/plugins/figure_builder/static/figureShapePanel.js +404 -0
  105. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureSidebarController.js +52 -14
  106. plexora-0.0.7/plexora/plugins/figure_builder/static/figureStrokeGeometry.js +323 -0
  107. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureTextEditor.js +65 -1
  108. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureTextPanel.js +18 -3
  109. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureViewOptions.js +15 -9
  110. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureWorkspace.js +626 -192
  111. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figure_builder.css +2367 -336
  112. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/templates/figure_builder/library.html +10 -1
  113. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/templates/figure_builder/workspace.html +27 -27
  114. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/templates/figure_builder/workspace_body.html +132 -41
  115. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/__init__.py +5 -1
  116. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/server/model.py +37 -39
  117. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/server/routes.py +29 -29
  118. plexora-0.0.7/plexora/plugins/gating/server/tableops.py +138 -0
  119. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/static/csvGatingList.js +7 -5
  120. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/static/gatingApi.js +67 -49
  121. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/__init__.py +100 -95
  122. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/mapping.py +5 -1
  123. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/routes.py +69 -62
  124. plexora-0.0.7/plexora/plugins/roi/server/tableops.py +138 -0
  125. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roiApi.js +15 -0
  126. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roiFigureBridge.js +8 -13
  127. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/adapters/inspection.py +31 -0
  128. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/centroid_tiles.py +32 -3
  129. plexora-0.0.7/plexora/server/models/data_migration.py +307 -0
  130. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/data_model.py +2379 -1659
  131. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/database_model.py +18 -0
  132. plexora-0.0.7/plexora/server/models/nodes.py +312 -0
  133. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/project.py +150 -1
  134. plexora-0.0.7/plexora/server/models/recipes.py +495 -0
  135. plexora-0.0.7/plexora/server/models/remote_sessions.py +707 -0
  136. plexora-0.0.7/plexora/server/models/remotes.py +267 -0
  137. plexora-0.0.7/plexora/server/models/secret_store.py +51 -0
  138. plexora-0.0.7/plexora/server/node/api.py +1138 -0
  139. plexora-0.0.7/plexora/server/node/app.py +508 -0
  140. plexora-0.0.7/plexora/server/node/resources.py +600 -0
  141. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/plugins.py +27 -0
  142. plexora-0.0.7/plexora/server/providers/__init__.py +185 -0
  143. plexora-0.0.7/plexora/server/providers/base.py +340 -0
  144. plexora-0.0.7/plexora/server/providers/http.py +453 -0
  145. plexora-0.0.7/plexora/server/providers/local.py +356 -0
  146. plexora-0.0.7/plexora/server/providers/node.py +542 -0
  147. plexora-0.0.7/plexora/server/providers/operations.py +139 -0
  148. plexora-0.0.7/plexora/server/providers/wire.py +131 -0
  149. plexora-0.0.7/plexora/server/routes/browse_routes.py +281 -0
  150. plexora-0.0.7/plexora/server/routes/data_routes.py +664 -0
  151. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/routes/import_routes.py +393 -34
  152. plexora-0.0.7/plexora/server/routes/page_routes.py +280 -0
  153. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/routes/project_routes.py +158 -5
  154. plexora-0.0.7/plexora/server/routes/quick_view_routes.py +127 -0
  155. plexora-0.0.7/plexora/server/routes/settings_routes.py +1059 -0
  156. plexora-0.0.7/plexora/server/routes/transfer_routes.py +198 -0
  157. plexora-0.0.7/plexora/server/utils/channel_file.py +272 -0
  158. plexora-0.0.7/plexora/server/utils/dir_listing.py +144 -0
  159. plexora-0.0.7/plexora/server/utils/file_transfer.py +192 -0
  160. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/native_dialog.py +33 -2
  161. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/segmentation_pyramid.py +131 -6
  162. {plexora-0.0.1 → plexora-0.0.7}/plexora/server_cli.py +6 -1
  163. {plexora-0.0.1 → plexora-0.0.7/plexora.egg-info}/PKG-INFO +384 -341
  164. {plexora-0.0.1 → plexora-0.0.7}/plexora.egg-info/SOURCES.txt +101 -1
  165. {plexora-0.0.1 → plexora-0.0.7}/plexora.egg-info/requires.txt +2 -0
  166. {plexora-0.0.1 → plexora-0.0.7}/pyproject.toml +15 -1
  167. {plexora-0.0.1 → plexora-0.0.7}/setup.cfg +4 -4
  168. plexora-0.0.7/tests/test_app_router.py +69 -0
  169. plexora-0.0.7/tests/test_app_shell.py +222 -0
  170. plexora-0.0.7/tests/test_auth_token.py +107 -0
  171. plexora-0.0.7/tests/test_browse_routes.py +430 -0
  172. {plexora-0.0.1 → plexora-0.0.7}/tests/test_cell_mode_control.py +50 -2
  173. plexora-0.0.7/tests/test_channel_names_modal.py +303 -0
  174. plexora-0.0.7/tests/test_channel_names_upload.py +362 -0
  175. plexora-0.0.7/tests/test_channel_rename_state.py +244 -0
  176. plexora-0.0.7/tests/test_cli.py +951 -0
  177. plexora-0.0.7/tests/test_column_classifier_css.py +110 -0
  178. plexora-0.0.7/tests/test_connect.py +1335 -0
  179. plexora-0.0.7/tests/test_connection_modal.py +273 -0
  180. plexora-0.0.7/tests/test_data_location.py +416 -0
  181. plexora-0.0.7/tests/test_file_location.py +232 -0
  182. plexora-0.0.7/tests/test_file_transfer_node.py +267 -0
  183. plexora-0.0.7/tests/test_hd_slider_domain.py +75 -0
  184. {plexora-0.0.1 → plexora-0.0.7}/tests/test_jupyter_viewer.py +172 -13
  185. plexora-0.0.7/tests/test_mask_without_table.py +78 -0
  186. plexora-0.0.7/tests/test_nav_shortcuts.py +45 -0
  187. plexora-0.0.7/tests/test_node_direct_routing.py +210 -0
  188. plexora-0.0.7/tests/test_node_disconnect.py +218 -0
  189. plexora-0.0.7/tests/test_node_dynamic.py +581 -0
  190. plexora-0.0.7/tests/test_node_image.py +712 -0
  191. plexora-0.0.7/tests/test_node_routes.py +552 -0
  192. plexora-0.0.7/tests/test_node_table.py +414 -0
  193. plexora-0.0.7/tests/test_node_warm_and_cache.py +338 -0
  194. plexora-0.0.7/tests/test_notebook_env.py +411 -0
  195. {plexora-0.0.1 → plexora-0.0.7}/tests/test_notebook_mode.py +10 -1
  196. plexora-0.0.7/tests/test_path_picker.py +252 -0
  197. {plexora-0.0.1 → plexora-0.0.7}/tests/test_plugin_boundary.py +2 -1
  198. {plexora-0.0.1 → plexora-0.0.7}/tests/test_plugins.py +122 -2
  199. plexora-0.0.7/tests/test_popover_portal.py +141 -0
  200. {plexora-0.0.1 → plexora-0.0.7}/tests/test_quick_view_routes.py +73 -0
  201. plexora-0.0.7/tests/test_recipes.py +308 -0
  202. plexora-0.0.7/tests/test_reconnect.py +295 -0
  203. plexora-0.0.7/tests/test_remote_connect.py +874 -0
  204. plexora-0.0.7/tests/test_remote_globe.py +295 -0
  205. plexora-0.0.7/tests/test_remote_health.py +329 -0
  206. plexora-0.0.7/tests/test_remote_state.py +190 -0
  207. plexora-0.0.7/tests/test_resource_status_banner.py +94 -0
  208. {plexora-0.0.1 → plexora-0.0.7}/tests/test_segmentation_mapping.py +121 -4
  209. {plexora-0.0.1 → plexora-0.0.7}/tests/test_segmentation_pyramid.py +197 -0
  210. plexora-0.0.7/tests/test_segmentation_wait.py +154 -0
  211. plexora-0.0.7/tests/test_session_expiry.py +169 -0
  212. plexora-0.0.7/tests/test_session_walltime.py +372 -0
  213. plexora-0.0.7/tests/test_settings_page.py +357 -0
  214. plexora-0.0.7/tests/test_settings_remotes_page.py +321 -0
  215. plexora-0.0.7/tests/test_tile_url.py +42 -0
  216. {plexora-0.0.1 → plexora-0.0.7}/tests/test_tool_cards.py +52 -0
  217. plexora-0.0.7/tests/test_transfer_routes.py +179 -0
  218. plexora-0.0.7/tests/test_unreachable_node.py +393 -0
  219. plexora-0.0.7/tests/test_view_menu.py +155 -0
  220. plexora-0.0.1/plexora/__init__.py +0 -129
  221. plexora-0.0.1/plexora/cli.py +0 -777
  222. plexora-0.0.1/plexora/client/src/css/main.css +0 -903
  223. plexora-0.0.1/plexora/client/src/js/services/browsePicker.js +0 -73
  224. plexora-0.0.1/plexora/client/src/js/views/quickViewLanding.js +0 -136
  225. plexora-0.0.1/plexora/client/templates/base.html +0 -212
  226. plexora-0.0.1/plexora/connect.py +0 -528
  227. plexora-0.0.1/plexora/plugins/figure_builder/server/compose.py +0 -365
  228. plexora-0.0.1/plexora/plugins/figure_builder/static/figureActions.js +0 -363
  229. plexora-0.0.1/plexora/plugins/figure_builder/static/figureSchema.js +0 -218
  230. plexora-0.0.1/plexora/server/routes/browse_routes.py +0 -41
  231. plexora-0.0.1/plexora/server/routes/data_routes.py +0 -294
  232. plexora-0.0.1/plexora/server/routes/page_routes.py +0 -139
  233. plexora-0.0.1/plexora/server/routes/quick_view_routes.py +0 -62
  234. plexora-0.0.1/tests/test_browse_routes.py +0 -97
  235. plexora-0.0.1/tests/test_cli.py +0 -443
  236. plexora-0.0.1/tests/test_connect.py +0 -371
  237. plexora-0.0.1/tests/test_notebook_env.py +0 -238
  238. {plexora-0.0.1 → plexora-0.0.7}/LICENSE +0 -0
  239. {plexora-0.0.1 → plexora-0.0.7}/MANIFEST.in +0 -0
  240. {plexora-0.0.1 → plexora-0.0.7}/plexora/__main__.py +0 -0
  241. {plexora-0.0.1 → plexora-0.0.7}/plexora/_url.py +0 -0
  242. {plexora-0.0.1 → plexora-0.0.7}/plexora/api/http.py +0 -0
  243. {plexora-0.0.1 → plexora-0.0.7}/plexora/api/store.py +0 -0
  244. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/354_bundle.js +0 -0
  245. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/354_bundle.js.LICENSE.txt +0 -0
  246. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/418_bundle.js +0 -0
  247. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/418_bundle.js.LICENSE.txt +0 -0
  248. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/693b935cb1f907814be9c6199a68c217.svg +0 -0
  249. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/713c134ff47cd328a5b711526f151082.svg +0 -0
  250. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/770_bundle.js +0 -0
  251. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/ff743f408972e0e96ca9153ed5ae4c83.svg +0 -0
  252. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/dist/vendor_bundle.js.LICENSE.txt +0 -0
  253. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/LICENSE.txt +0 -0
  254. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/canvas-overlay-hd.js +0 -0
  255. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/changelog.txt +0 -0
  256. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/.gitattributes +0 -0
  257. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/LICENSE.txt +0 -0
  258. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/Toolbar.png +0 -0
  259. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/fullpage.psd +0 -0
  260. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/home.psd +0 -0
  261. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/next.psd +0 -0
  262. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/previous.psd +0 -0
  263. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateleft.psd +0 -0
  264. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateright.psd +0 -0
  265. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/zoom.psd +0 -0
  266. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/README.md +0 -0
  267. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_grouphover.png +0 -0
  268. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_hover.png +0 -0
  269. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_pressed.png +0 -0
  270. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_rest.png +0 -0
  271. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_grouphover.png +0 -0
  272. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_hover.png +0 -0
  273. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_pressed.png +0 -0
  274. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_rest.png +0 -0
  275. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_grouphover.png +0 -0
  276. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_hover.png +0 -0
  277. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_pressed.png +0 -0
  278. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_rest.png +0 -0
  279. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_grouphover.png +0 -0
  280. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_hover.png +0 -0
  281. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_pressed.png +0 -0
  282. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_rest.png +0 -0
  283. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_grouphover.png +0 -0
  284. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_hover.png +0 -0
  285. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_pressed.png +0 -0
  286. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_rest.png +0 -0
  287. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_grouphover.png +0 -0
  288. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_hover.png +0 -0
  289. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_pressed.png +0 -0
  290. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_rest.png +0 -0
  291. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_grouphover.png +0 -0
  292. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_hover.png +0 -0
  293. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_pressed.png +0 -0
  294. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_rest.png +0 -0
  295. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_grouphover.png +0 -0
  296. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_hover.png +0 -0
  297. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_pressed.png +0 -0
  298. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_rest.png +0 -0
  299. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/external/openseadragon-bin-2.4.0/openseadragon-scalebar.js +0 -0
  300. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/img/apple-touch-icon.png +0 -0
  301. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/img/favicon.ico +0 -0
  302. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/img/logo.ai +0 -0
  303. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/img/logo.svg +0 -0
  304. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/img/logo_with_text.ai +0 -0
  305. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/img/logo_with_text.svg +0 -0
  306. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/pluginRegistry.js +0 -0
  307. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/datasetContext.js +0 -0
  308. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/glRenderer.js +0 -0
  309. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/passVariablesToFrontend.js +0 -0
  310. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/services/simpleEventHandler.js +0 -0
  311. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/vendor.js +0 -0
  312. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/columnClassifier.js +0 -0
  313. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/coordinateField.js +0 -0
  314. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/miniMap.js +0 -0
  315. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/rainbow.js +0 -0
  316. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/views/rgbImageViewer.js +0 -0
  317. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/js/workers/tileDecoder.js +0 -0
  318. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/shaders/frag.glsl +0 -0
  319. {plexora-0.0.1 → plexora-0.0.7}/plexora/client/src/shaders/vert.glsl +0 -0
  320. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/__init__.py +0 -0
  321. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/server/__init__.py +0 -0
  322. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/server/routes.py +0 -0
  323. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/server/state.py +0 -0
  324. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/server/variables.py +0 -0
  325. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerApi.js +0 -0
  326. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerColors.js +0 -0
  327. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerContinuous.js +0 -0
  328. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerLegend.js +0 -0
  329. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerSidebarController.js +0 -0
  330. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cellExplorerState.js +0 -0
  331. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/static/cell_explorer.css +0 -0
  332. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/cell_explorer/templates/cell_explorer/panel.html +0 -0
  333. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/__init__.py +0 -0
  334. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/export_jobs.py +0 -0
  335. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/operations.py +0 -0
  336. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/provenance.py +0 -0
  337. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/repository.py +0 -0
  338. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/routes.py +0 -0
  339. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/server/sources.py +0 -0
  340. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureCaptureBoxes.js +0 -0
  341. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureCaptureDock.js +0 -0
  342. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureCaptureTool.js +0 -0
  343. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureConfirm.js +0 -0
  344. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureDocumentState.js +0 -0
  345. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/figure_builder/static/figureExportUi.js +0 -0
  346. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/server/__init__.py +0 -0
  347. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/server/anndata_gates.py +0 -0
  348. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/server/database.py +0 -0
  349. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/static/gating.css +0 -0
  350. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/static/gatingSidebarController.js +0 -0
  351. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/templates/gating/legacy.html +0 -0
  352. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/gating/templates/gating/panel.html +0 -0
  353. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/__init__.py +0 -0
  354. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/adapters.py +0 -0
  355. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/geojson.py +0 -0
  356. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/geometry.py +0 -0
  357. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/operations.py +0 -0
  358. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/repository.py +0 -0
  359. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/server/schema.py +0 -0
  360. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roi.css +0 -0
  361. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roiGeometry.js +0 -0
  362. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roiRenderer.js +0 -0
  363. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roiSidebarController.js +0 -0
  364. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roiState.js +0 -0
  365. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/static/roiTools.js +0 -0
  366. {plexora-0.0.1 → plexora-0.0.7}/plexora/plugins/roi/templates/roi/panel.html +0 -0
  367. {plexora-0.0.1 → plexora-0.0.7}/plexora/proxy.py +0 -0
  368. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/adapters/__init__.py +0 -0
  369. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/adapters/anndata_adapter.py +0 -0
  370. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/adapters/base.py +0 -0
  371. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/adapters/classify.py +0 -0
  372. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/adapters/csv_adapter.py +0 -0
  373. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/models/adapters/spatialdata_adapter.py +0 -0
  374. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/routes/system_routes.py +0 -0
  375. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/routes/tool_routes.py +0 -0
  376. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/addHEColumns.py +0 -0
  377. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/fast_png.py +0 -0
  378. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/fullConversion.py +0 -0
  379. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/pre_normalization.py +0 -0
  380. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/smallestenclosingcircle.py +0 -0
  381. {plexora-0.0.1 → plexora-0.0.7}/plexora/server/utils/tiffsurgeon.py +0 -0
  382. {plexora-0.0.1 → plexora-0.0.7}/plexora/test.py +0 -0
  383. {plexora-0.0.1 → plexora-0.0.7}/plexora.egg-info/dependency_links.txt +0 -0
  384. {plexora-0.0.1 → plexora-0.0.7}/plexora.egg-info/entry_points.txt +0 -0
  385. {plexora-0.0.1 → plexora-0.0.7}/plexora.egg-info/top_level.txt +0 -0
  386. {plexora-0.0.1 → plexora-0.0.7}/tests/test_anndata_adapter.py +0 -0
  387. {plexora-0.0.1 → plexora-0.0.7}/tests/test_api_dataset.py +0 -0
  388. {plexora-0.0.1 → plexora-0.0.7}/tests/test_api_store.py +0 -0
  389. {plexora-0.0.1 → plexora-0.0.7}/tests/test_cell_color_layer.py +0 -0
  390. {plexora-0.0.1 → plexora-0.0.7}/tests/test_centroid_tiles.py +0 -0
  391. {plexora-0.0.1 → plexora-0.0.7}/tests/test_channel_overview.py +0 -0
  392. {plexora-0.0.1 → plexora-0.0.7}/tests/test_classify_columns.py +0 -0
  393. {plexora-0.0.1 → plexora-0.0.7}/tests/test_config_store.py +0 -0
  394. {plexora-0.0.1 → plexora-0.0.7}/tests/test_csv_adapter.py +0 -0
  395. {plexora-0.0.1 → plexora-0.0.7}/tests/test_database_model.py +0 -0
  396. {plexora-0.0.1 → plexora-0.0.7}/tests/test_datalayer_requests.py +0 -0
  397. {plexora-0.0.1 → plexora-0.0.7}/tests/test_derive_anndata_channel_names.py +0 -0
  398. {plexora-0.0.1 → plexora-0.0.7}/tests/test_detect_data_type.py +0 -0
  399. {plexora-0.0.1 → plexora-0.0.7}/tests/test_icon_names.py +0 -0
  400. {plexora-0.0.1 → plexora-0.0.7}/tests/test_label_outlines.py +0 -0
  401. {plexora-0.0.1 → plexora-0.0.7}/tests/test_label_tile_lifecycle.py +0 -0
  402. {plexora-0.0.1 → plexora-0.0.7}/tests/test_marker_split.py +0 -0
  403. {plexora-0.0.1 → plexora-0.0.7}/tests/test_metadata_columns.py +0 -0
  404. {plexora-0.0.1 → plexora-0.0.7}/tests/test_mini_map.py +0 -0
  405. {plexora-0.0.1 → plexora-0.0.7}/tests/test_optional_segmentation.py +0 -0
  406. {plexora-0.0.1 → plexora-0.0.7}/tests/test_page_assets.py +0 -0
  407. {plexora-0.0.1 → plexora-0.0.7}/tests/test_page_routes.py +0 -0
  408. {plexora-0.0.1 → plexora-0.0.7}/tests/test_paths.py +0 -0
  409. {plexora-0.0.1 → plexora-0.0.7}/tests/test_plugin_css_boundary.py +0 -0
  410. {plexora-0.0.1 → plexora-0.0.7}/tests/test_project_edit_routes.py +0 -0
  411. {plexora-0.0.1 → plexora-0.0.7}/tests/test_project_record.py +0 -0
  412. {plexora-0.0.1 → plexora-0.0.7}/tests/test_refresh_dataset.py +0 -0
  413. {plexora-0.0.1 → plexora-0.0.7}/tests/test_register_anndata_datasource.py +0 -0
  414. {plexora-0.0.1 → plexora-0.0.7}/tests/test_register_image_datasource.py +0 -0
  415. {plexora-0.0.1 → plexora-0.0.7}/tests/test_rename_channels.py +0 -0
  416. {plexora-0.0.1 → plexora-0.0.7}/tests/test_requirements_routes.py +0 -0
  417. {plexora-0.0.1 → plexora-0.0.7}/tests/test_segmentation_mode_routes.py +0 -0
  418. {plexora-0.0.1 → plexora-0.0.7}/tests/test_shared_roots.py +0 -0
  419. {plexora-0.0.1 → plexora-0.0.7}/tests/test_spatialdata_adapter.py +0 -0
  420. {plexora-0.0.1 → plexora-0.0.7}/tests/test_tool_assets.py +0 -0
  421. {plexora-0.0.1 → plexora-0.0.7}/tests/test_tool_coexistence.py +0 -0
  422. {plexora-0.0.1 → plexora-0.0.7}/tests/test_tool_switching.py +0 -0
  423. {plexora-0.0.1 → plexora-0.0.7}/tests/test_url_helpers.py +0 -0
@@ -1,341 +1,384 @@
1
- Metadata-Version: 2.4
2
- Name: plexora
3
- Version: 0.0.1
4
- Summary: OpenSeadragon-based cellular image viewing and analysis tool.
5
- License-Expression: LicenseRef-Plexora-Academic-1.0
6
- Requires-Python: <3.14,>=3.12
7
- Description-Content-Type: text/markdown
8
- License-File: LICENSE
9
- Requires-Dist: anndata>=0.10
10
- Requires-Dist: Flask>=3.1
11
- Requires-Dist: h5py>=3.16.0
12
- Requires-Dist: imagecodecs
13
- Requires-Dist: itsdangerous>=2.2
14
- Requires-Dist: Jinja2>=3.1
15
- Requires-Dist: numpy>=2.0
16
- Requires-Dist: ome-types>=0.6.3
17
- Requires-Dist: orjson>=3.11
18
- Requires-Dist: pandas>=3.0.5
19
- Requires-Dist: Pillow>=10.4
20
- Requires-Dist: platformdirs>=4
21
- Requires-Dist: polars>=1.43
22
- Requires-Dist: pydantic<2.14,>=2.13
23
- Requires-Dist: reportlab>=5.0.1
24
- Requires-Dist: scikit-image
25
- Requires-Dist: scikit-learn>=1.9
26
- Requires-Dist: scipy
27
- Requires-Dist: shapely>=2.1.2
28
- Requires-Dist: spatialdata>=0.8.0
29
- Requires-Dist: threadpoolctl>=3.6.0
30
- Requires-Dist: tifffile>=2026.7.31
31
- Requires-Dist: waitress
32
- Requires-Dist: Werkzeug>=3.1
33
- Requires-Dist: zarr>=3
34
- Provides-Extra: jupyter
35
- Requires-Dist: ipython; extra == "jupyter"
36
- Requires-Dist: jupyter-server-proxy; extra == "jupyter"
37
- Provides-Extra: dev
38
- Requires-Dist: pytest; extra == "dev"
39
- Requires-Dist: pytest-randomly>=4.1.0; extra == "dev"
40
- Dynamic: license-file
41
-
42
- # Plexora
43
-
44
- ![](./plexora/client/src/img/logo_with_text.svg)
45
-
46
- ## About
47
- This is an [openseadragon](https://openseadragon.github.io/) based **Cellular Image Viewing and Analysis Tool**.
48
- It is built with a python [Flask](http://flask.pocoo.org/) backend and a [Node.js](https://nodejs.org/en/) javascript frontend.
49
-
50
- ## Install (for Users)
51
-
52
- ```bash
53
- pip install plexora
54
- plexora
55
- ```
56
-
57
- That is the whole setup. `plexora` starts the server, prints the URL, and opens
58
- a browser when the environment looks interactive. On the first run it also
59
- prints where it will keep your projects.
60
-
61
- ```bash
62
- plexora my_dataset # open a project straight away
63
- plexora --port 9000 # a specific port (8000 is the default; if it is
64
- # busy, Plexora moves to a free one and says so)
65
- plexora --version
66
- python -m plexora # same thing, when the console script is not on PATH
67
- ```
68
-
69
- There are four ways to run Plexora, all of which end in the same viewer:
70
-
71
- | Where you are | What to run |
72
- | --- | --- |
73
- | Your own machine, a terminal | `plexora` |
74
- | Your own machine, a notebook | `plexora.view("my_dataset")` |
75
- | A remote machine you can ssh into | `plexora connect user@host` — or `plexora --remote` on the host |
76
- | A hosted notebook (JupyterHub, Open OnDemand, Colab) | `plexora.view("my_dataset")` — the proxy is detected for you |
77
-
78
- **[DEPLOYMENT.md](DEPLOYMENT.md) walks through all of them in detail**, from a
79
- fresh conda environment to HPC job submission, with the real output of each
80
- command. The rest of this README is the short version.
81
-
82
- ### Where your data lives
83
-
84
- Plexora keeps projects, figures and settings in one directory, chosen in this
85
- order:
86
-
87
- | Rule | Location |
88
- | --- | --- |
89
- | `--data-dir` / `PLEXORA_DATA_PATH` | whatever you pass |
90
- | a recorded setting | `plexora config set data-dir <path>` |
91
- | default | `%LOCALAPPDATA%\plexora`, `~/Library/Application Support/plexora`, or `~/.local/share/plexora` |
92
-
93
- It never depends on the directory you started from, and never lives inside the
94
- installed package.
95
-
96
- ```bash
97
- plexora where # which directory, and which rule chose it
98
- plexora config set data-dir /scratch/me/plexora
99
- ```
100
-
101
- Moving it matters on HPC and on Windows machines with a small system drive:
102
- derived image pyramids are large, and the default sits on your home or system
103
- volume. `plexora config set data-dir` records the choice permanently; the
104
- environment variable overrides it for one run.
105
-
106
- ### Shared projects
107
-
108
- Several people on one workstation or login node can share a directory of common
109
- datasets while keeping their own work private:
110
-
111
- ```bash
112
- export PLEXORA_SHARED_PATH=/srv/plexora/common # or: plexora config set shared-dirs ...
113
- plexora
114
- ```
115
-
116
- Shared projects appear in Open Project marked *Shared*. They can be opened and
117
- explored but not edited or deleted, and everything you produce while exploring
118
- one — gates, ROIs, figures, cached results — is written to **your** data
119
- directory, not the shared one. A project of your own with the same name takes
120
- precedence over the shared copy.
121
-
122
- Plexora has no user accounts and no authentication. For a multi-user
123
- deployment, run one process per user behind a reverse proxy that maps the
124
- authenticated user to their own `--data-dir`, and keep the server bound to
125
- loopback (the default).
126
-
127
- ## Running on a remote machine over SSH
128
-
129
- Plexora binds to loopback and has no authentication, so the way to reach one
130
- running on a server is an SSH tunnel rather than an open port. There are two
131
- ways to get one, and they do the same thing.
132
-
133
- **Have Plexora set it up.** Run this on *your own* computer:
134
-
135
- ```bash
136
- plexora connect user@server.lab.edu # starts, tunnels, opens a browser
137
- plexora connect user@server.lab.edu my_dataset # …straight into a project
138
- ```
139
-
140
- It stays in the foreground; Ctrl+C closes the tunnel and stops the remote
141
- server. It uses your system `ssh`, so whatever `~/.ssh/config`, an agent, a
142
- ProxyJump or a hardware token already do for `ssh user@host` happens here too.
143
-
144
- If the remote `plexora` is not on a non-interactive `PATH` — which is common
145
- with conda — name it explicitly:
146
-
147
- ```bash
148
- plexora connect user@server.lab.edu --remote-command "conda run -n imaging plexora"
149
- ```
150
-
151
- **Or do it by hand.** On the remote machine:
152
-
153
- ```bash
154
- plexora --remote
155
- ```
156
-
157
- It prints the exact `ssh -N -L …` command to paste into a terminal on your own
158
- computer, and the `http://localhost:<port>/` address to open afterwards.
159
-
160
- ### HPC clusters with compute nodes
161
-
162
- On a cluster you usually may not run anything heavy on the login node, so
163
- Plexora belongs in a job. `--srun` submits one and tunnels to whichever node
164
- the scheduler grants — the target is the *login* node:
165
-
166
- ```bash
167
- plexora connect user@o2.hms.harvard.edu --srun "-p interactive -t 4:00:00 --mem 16G"
168
- ```
169
-
170
- Allocation may queue; it says so while it waits. Ctrl+C ends the job.
171
-
172
- By hand, the same thing is two steps: start an interactive job
173
- (`srun --pty -p interactive -t 4:00:00 --mem 16G bash`), then run
174
- `plexora --remote` inside it. It detects the job, works out which compute node
175
- it is on and which login node you came through, and prints the two-hop
176
- `ssh -J` command for it.
177
-
178
- Some sites refuse SSH into a compute node. Add `--bind-node` at either end for
179
- a login-node forward instead — note that this makes the port reachable from
180
- the cluster's internal network while it runs.
181
-
182
- A lab's shared reference data pairs naturally with this: point
183
- `PLEXORA_SHARED_PATH` (or `plexora config set shared-dirs`) at a read-only
184
- directory on the cluster filesystem, and `--data-dir` or
185
- `plexora config set data-dir` at your own scratch space.
186
-
187
- ## Running as a Docker container
188
- **Note:** When running on an ARM machine (e.g. M1 Macbook), build the image with `docker build --platform linux/amd64 -t plexora .`
189
- * Build image: `docker build -t plexora .`
190
- * Run image with mounted path: `docker run --rm -dp 8000:8000 -v [source path]:/[target path] plexora`
191
-
192
- where
193
- * `--rm` cleans up the container after it finishes executing
194
- * `-v` mounts the "present working directory" (containing your data) to be `/data` inside the container. This is necessary in order to import your data via the import page.
195
- * `-dp` forwards the port 8000
196
-
197
- Once the container is running, go to `http://localhost:8000/` in your web browser.
198
- To import your imaging files in the import gui type in the mounted `/data/..`
199
-
200
- Inside the image, projects are written to `/app/data` (`PLEXORA_DATA_PATH`), so
201
- mount a volume there to keep them between runs:
202
-
203
- ```bash
204
- docker run --rm -dp 8000:8000 -v ~/plexora-data:/app/data -v /my/images:/data plexora
205
- ```
206
-
207
- The image also sets `PLEXORA_HOST=0.0.0.0` — published ports would never reach
208
- it otherwise — and `PLEXORA_DOCKER=1`, which switches the import page to
209
- container-shaped path hints.
210
-
211
- ## Clone and Run Codebase (for Developers)
212
-
213
- ```bash
214
- git clone https://github.com/nirmallab/plexora.git
215
- cd plexora
216
- python -m venv .venv && source .venv/bin/activate # or conda create -n plexora python=3.13
217
- pip install -e ".[dev,jupyter]"
218
- ```
219
-
220
- Any Python 3.12 or 3.13 environment works — conda, venv, uv, whatever you
221
- already use. The editable install pulls every runtime dependency plus the test
222
- and notebook extras; there is no separate environment file to keep in sync.
223
-
224
- Then start the server with `python run.py` (or `plexora`) and open
225
- `http://localhost:8000/`.
226
-
227
- ## Running in Jupyter notebooks
228
-
229
- Install the package into the same environment as Jupyter:
230
-
231
- ```bash
232
- pip install "plexora[jupyter]"
233
- ```
234
-
235
- Then, in a cell:
236
-
237
- ```python
238
- import plexora
239
-
240
- plexora.view("my_dataset")
241
- ```
242
-
243
- That is the whole thing, in every kind of notebook. Plexora starts a small
244
- server beside your kernel and shows it in the cell.
245
-
246
- `data_dir` is optional everywhere below: leaving it out uses the same directory
247
- `plexora where` reports, so a notebook and a terminal see the same projects.
248
- Pass it to work against a different one.
249
-
250
- ### Hosted notebooks — JupyterHub, Open OnDemand, Colab
251
-
252
- The same call. When your kernel is not on the machine with your browser, a
253
- `127.0.0.1` address would point at your own laptop, so Plexora detects the
254
- situation and builds the proxied URL your host actually serves it on.
255
-
256
- On a JupyterHub or Open OnDemand server, this needs `jupyter-server-proxy`
257
- installed **in the environment running the Jupyter server** (not necessarily
258
- the one running your kernel):
259
-
260
- ```bash
261
- pip install jupyter-server-proxy
262
- ```
263
-
264
- Colab needs nothing extra. Neither does local Jupyter or VS Code Remote, which
265
- keep the direct localhost address they always used.
266
-
267
- Override the detection if you need to:
268
-
269
- ```python
270
- plexora.view("my_dataset", proxy=True) # always proxy
271
- plexora.view("my_dataset", proxy=False) # always use 127.0.0.1
272
- plexora.view("my_dataset", base_url="/user/me/") # name the prefix yourself
273
- ```
274
-
275
- On a hub, `viewer.url` is a path rather than a full address — open it under
276
- your notebook server's own address, which is where your session is
277
- authenticated.
278
-
279
- Datasets can also be registered directly from notebook-visible files:
280
-
281
- ```python
282
- from plexora.jupyter import PlexoraViewer
283
-
284
- viewer = PlexoraViewer.from_files(
285
- name="my_dataset",
286
- image="/path/to/image.ome.tif",
287
- segmentation="/path/to/segmentation.ome.tif",
288
- features="/path/to/cells.csv",
289
- x="X_centroid",
290
- y="Y_centroid",
291
- id_column="CellID",
292
- )
293
- viewer
294
- ```
295
-
296
- ## Baseline smoke test
297
-
298
- Before upgrading dependencies or changing the viewer/server boundary, run the local `orion2` baseline:
299
-
300
- ```bash
301
- python -m tests.baseline_orion2
302
- ```
303
-
304
- The test checks Flask app import, `/config`, the viewer page, metadata JSON, channel metadata, and one image tile plus one segmentation tile. It skips with a clear message if the local `orion2` datasource or exemplar files are not available.
305
-
306
-
307
- #### (4. Node.js installation and packages)
308
- This step is only needed when you plan to edit js code. The codebase already included bundled js files.
309
- * Install [Node.js](https://nodejs.org/en/), then navigate to `/plexora/client` and run `npm install` to install all packages listed in package.json.
310
- * Run `npm run start` to package the Javascript, or run `npm run watch` if you plan on editing dependencies
311
-
312
-
313
- ## Packaging/Bundling Code as Executable (for Developers)
314
- Any tagged commit to a branch will trigger a build, where `tag == commit message`. This will appear under releases. Note building may take ~10 min.
315
-
316
- Tagging Conventions: All release tags should look like `v{version_number}_{branch_name}`.
317
-
318
- ## License
319
-
320
- Plexora is released under the **Plexora Academic License 1.0** (see [LICENSE](./LICENSE)).
321
- It is **not** an open source license. In short:
322
-
323
- | | |
324
- |---|---|
325
- | Academic research, teaching, personal study | ✅ Free |
326
- | Use by a nonprofit or government research institution | ✅ Free (whatever the funding source) |
327
- | Redistributing Plexora unmodified, with the license attached | ✅ Allowed |
328
- | Patching your own copy to fix a bug or a compatibility problem | ✅ Allowed |
329
- | Publishing a fork, a patched build, or a renamed version | ❌ Not allowed |
330
- | Commercial use of any kind | ❌ Requires a paid license |
331
-
332
- **Plugins are a deliberate exception.** Anything you build against the documented
333
- extension interfaces — the `plexora.plugins` entry point group and the `plexora.api`
334
- package — is yours. You may distribute and sell your plugin under whatever license
335
- you like, and you do not need our permission. Extending Plexora through the plugin
336
- API is the supported way to change what it does; editing its source is not.
337
-
338
- For a commercial license, contact Ajit Johnson Nirmal <ajitjohnson.n@gmail.com>.
339
-
340
- Some bundled components carry their own licenses, which are unaffected by the above —
341
- see section 8 of [LICENSE](./LICENSE).
1
+ Metadata-Version: 2.4
2
+ Name: plexora
3
+ Version: 0.0.7
4
+ Summary: OpenSeadragon-based cellular image viewing and analysis tool.
5
+ License-Expression: LicenseRef-Plexora-Academic-1.0
6
+ Requires-Python: <3.14,>=3.12
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: anndata>=0.10
10
+ Requires-Dist: Flask>=3.1
11
+ Requires-Dist: h5py>=3.16.0
12
+ Requires-Dist: imagecodecs
13
+ Requires-Dist: itsdangerous>=2.2
14
+ Requires-Dist: Jinja2>=3.1
15
+ Requires-Dist: numpy>=2.0
16
+ Requires-Dist: ome-types>=0.6.3
17
+ Requires-Dist: openpyxl>=3.1
18
+ Requires-Dist: orjson>=3.11
19
+ Requires-Dist: pandas>=3.0.5
20
+ Requires-Dist: Pillow>=10.4
21
+ Requires-Dist: platformdirs>=4
22
+ Requires-Dist: polars>=1.43
23
+ Requires-Dist: pydantic<2.14,>=2.13
24
+ Requires-Dist: reportlab>=5.0.1
25
+ Requires-Dist: scikit-image
26
+ Requires-Dist: scikit-learn>=1.9
27
+ Requires-Dist: scipy
28
+ Requires-Dist: shapely>=2.1.2
29
+ Requires-Dist: spatialdata>=0.8.0
30
+ Requires-Dist: threadpoolctl>=3.6.0
31
+ Requires-Dist: tifffile>=2026.7.31
32
+ Requires-Dist: urllib3>=2.0
33
+ Requires-Dist: waitress
34
+ Requires-Dist: Werkzeug>=3.1
35
+ Requires-Dist: zarr>=3
36
+ Provides-Extra: jupyter
37
+ Requires-Dist: ipython; extra == "jupyter"
38
+ Requires-Dist: jupyter-server-proxy; extra == "jupyter"
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest; extra == "dev"
41
+ Requires-Dist: pytest-randomly>=4.1.0; extra == "dev"
42
+ Dynamic: license-file
43
+
44
+ # Plexora
45
+
46
+ ![](./plexora/client/src/img/logo_with_text.svg)
47
+
48
+ ## About
49
+ This is an [openseadragon](https://openseadragon.github.io/) based **Cellular Image Viewing and Analysis Tool**.
50
+ It is built with a python [Flask](http://flask.pocoo.org/) backend and a [Node.js](https://nodejs.org/en/) javascript frontend.
51
+
52
+ ## Install (for Users)
53
+
54
+ ```bash
55
+ pip install plexora
56
+ plexora
57
+ ```
58
+
59
+ That is the whole setup. `plexora` starts the server, prints the URL, and opens
60
+ a browser when the environment looks interactive. On the first run it also
61
+ prints where it will keep your projects.
62
+
63
+ ```bash
64
+ plexora my_dataset # open a project straight away
65
+ plexora --port 9000 # a specific port (8000 is the default; if it is
66
+ # busy, Plexora moves to a free one and says so)
67
+ plexora --version
68
+ python -m plexora # same thing, when the console script is not on PATH
69
+ ```
70
+
71
+ There are four ways to run Plexora, all of which end in the same viewer:
72
+
73
+ | Where you are | What to run |
74
+ | --- | --- |
75
+ | Your own machine, a terminal | `plexora` |
76
+ | Your own machine, a notebook | `plexora.view("my_dataset")` |
77
+ | A remote machine you can ssh into | **Settings → Remote servers → Connect** — or `plexora connect user@host` |
78
+ | A hosted notebook or an HPC terminal | `plexora` — it works out where it is running and prints a URL that works |
79
+
80
+ Save a remote server once and reconnecting is a button: Plexora handles the SSH
81
+ connection, the ports, the tunnel and the URL, and relays a password or 2FA
82
+ prompt to the page if the server asks for one. It never stores the password.
83
+
84
+ **[docs/SETUP_GUIDE.md](docs/SETUP_GUIDE.md)** is the step-by-step version for
85
+ people who would rather not learn about tunnels — organised by where your data
86
+ is, with a compatibility matrix and a screenshot for every screen.
87
+ **[DEPLOYMENT.md](DEPLOYMENT.md)** is the same ground for a technical reader,
88
+ from a fresh conda environment to HPC job submission, with the real output of
89
+ each command. The rest of this README is the short version.
90
+
91
+ ### Where your data lives
92
+
93
+ Plexora keeps projects, figures and settings in one directory, chosen in this
94
+ order:
95
+
96
+ | Rule | Location |
97
+ | --- | --- |
98
+ | `--data-dir` / `PLEXORA_DATA_PATH` | whatever you pass |
99
+ | a recorded setting | `plexora config set data-dir <path>` |
100
+ | default | `%LOCALAPPDATA%\plexora`, `~/Library/Application Support/plexora`, or `~/.local/share/plexora` |
101
+
102
+ It never depends on the directory you started from, and never lives inside the
103
+ installed package.
104
+
105
+ ```bash
106
+ plexora where # which directory, and which rule chose it
107
+ plexora config set data-dir /scratch/me/plexora
108
+ ```
109
+
110
+ Moving it matters on HPC and on Windows machines with a small system drive:
111
+ derived image pyramids are large, and the default sits on your home or system
112
+ volume. `plexora config set data-dir` records the choice permanently; the
113
+ environment variable overrides it for one run.
114
+
115
+ ### Shared projects
116
+
117
+ Several people on one workstation or login node can share a directory of common
118
+ datasets while keeping their own work private:
119
+
120
+ ```bash
121
+ export PLEXORA_SHARED_PATH=/srv/plexora/common # or: plexora config set shared-dirs ...
122
+ plexora
123
+ ```
124
+
125
+ Shared projects appear in Open Project marked *Shared*. They can be opened and
126
+ explored but not edited or deleted, and everything you produce while exploring
127
+ one — gates, ROIs, figures, cached results — is written to **your** data
128
+ directory, not the shared one. A project of your own with the same name takes
129
+ precedence over the shared copy.
130
+
131
+ Plexora has no user accounts. For a multi-user deployment, run one process per
132
+ user behind a reverse proxy that maps the authenticated user to their own
133
+ `--data-dir`, and keep the server bound to loopback (the default). The one
134
+ place Plexora authenticates at all is where it cannot use loopback — the Open
135
+ OnDemand routes, which mint a per-server token — and that protects a
136
+ single-user server rather than telling several users apart.
137
+
138
+ ## Running on a remote machine over SSH
139
+
140
+ Plexora binds to loopback and has no authentication, so the way to reach one
141
+ running on a server is an SSH tunnel rather than an open port. There are two
142
+ ways to get one, and they do the same thing.
143
+
144
+ **Have Plexora set it up.** Run this on *your own* computer:
145
+
146
+ ```bash
147
+ plexora connect user@server.lab.edu # starts, tunnels, opens a browser
148
+ plexora connect user@server.lab.edu my_dataset # …straight into a project
149
+ ```
150
+
151
+ It stays in the foreground; Ctrl+C closes the tunnel and stops the remote
152
+ server. It uses your system `ssh`, so whatever `~/.ssh/config`, an agent, a
153
+ ProxyJump or a hardware token already do for `ssh user@host` happens here too.
154
+
155
+ If the remote `plexora` is not on a non-interactive `PATH` — which is common
156
+ with conda — name it explicitly:
157
+
158
+ ```bash
159
+ plexora connect user@server.lab.edu --remote-command /home/you/miniconda3/envs/imaging
160
+ ```
161
+
162
+ The environment path is enough — `bin/plexora` is filled in for you.
163
+
164
+ **Or do it by hand.** On the remote machine:
165
+
166
+ ```bash
167
+ plexora --remote
168
+ ```
169
+
170
+ It prints the exact `ssh -N -L …` command to paste into a terminal on your own
171
+ computer, and the `http://localhost:<port>/` address to open afterwards.
172
+
173
+ ### HPC clusters with compute nodes
174
+
175
+ On a cluster you usually may not run anything heavy on the login node, so
176
+ Plexora belongs in a job. `--srun` submits one and tunnels to whichever node
177
+ the scheduler grants — the target is the *login* node:
178
+
179
+ ```bash
180
+ plexora connect user@o2.hms.harvard.edu --srun "-p interactive -t 4:00:00 -c 16 --mem 128G"
181
+ ```
182
+
183
+ Allocation may queue; it says so while it waits. Ctrl+C ends the job.
184
+
185
+ By hand, the same thing is two steps: start an interactive job
186
+ (`srun --pty -p interactive -t 4:00:00 -c 16 --mem 128G bash`), then run
187
+ `plexora --remote` inside it. It detects the job, works out which compute node
188
+ it is on and which login node you came through, and prints the two-hop
189
+ `ssh -J` command for it.
190
+
191
+ Some sites refuse SSH into a compute node. Add `--bind-node` at either end for
192
+ a login-node forward instead — note that this makes the port reachable from
193
+ the cluster's internal network while it runs.
194
+
195
+ A lab's shared reference data pairs naturally with this: point
196
+ `PLEXORA_SHARED_PATH` (or `plexora config set shared-dirs`) at a read-only
197
+ directory on the cluster filesystem, and `--data-dir` or
198
+ `plexora config set data-dir` at your own scratch space.
199
+
200
+ ## Running as a Docker container
201
+ **Note:** When running on an ARM machine (e.g. M1 Macbook), build the image with `docker build --platform linux/amd64 -t plexora .`
202
+ * Build image: `docker build -t plexora .`
203
+ * Run image with mounted path: `docker run --rm -dp 8000:8000 -v [source path]:/[target path] plexora`
204
+
205
+ where
206
+ * `--rm` cleans up the container after it finishes executing
207
+ * `-v` mounts the "present working directory" (containing your data) to be `/data` inside the container. This is necessary in order to import your data via the import page.
208
+ * `-dp` forwards the port 8000
209
+
210
+ Once the container is running, go to `http://localhost:8000/` in your web browser.
211
+ To import your imaging files in the import gui type in the mounted `/data/..`
212
+
213
+ Inside the image, projects are written to `/app/data` (`PLEXORA_DATA_PATH`), so
214
+ mount a volume there to keep them between runs:
215
+
216
+ ```bash
217
+ docker run --rm -dp 8000:8000 -v ~/plexora-data:/app/data -v /my/images:/data plexora
218
+ ```
219
+
220
+ The image also sets `PLEXORA_HOST=0.0.0.0` — published ports would never reach
221
+ it otherwise — and `PLEXORA_DOCKER=1`, which switches the import page to
222
+ container-shaped path hints.
223
+
224
+ ## Data on more than one machine
225
+
226
+ Sometimes the image and the cell table are not on the same computer — the slide
227
+ is on cluster scratch and the `.h5ad` came back to your laptop. Start a **data
228
+ node** where the data is:
229
+
230
+ ```bash
231
+ plexora node serve --serve image:tumor=/scratch/me/tumor.ome.tif
232
+ ```
233
+
234
+ It prints a token. Register the node in the viewer under **Settings → Data
235
+ nodes**, then point a project at it from that project's **Edit** page, under
236
+ *Where the data lives*.
237
+
238
+ A node is a Plexora with the viewer switched off: it holds files and answers
239
+ questions about them. Your projects, ROIs, gates and figures all stay on the
240
+ machine you are looking at, so a node can restart or disappear without any of
241
+ your work being at risk — the project still opens, and whatever came from that
242
+ node is absent and says so.
243
+
244
+ See [DEPLOYMENT.md](DEPLOYMENT.md#7-data-on-more-than-one-machine) for the
245
+ tunnel recipes, what actually crosses the network, and the limits.
246
+
247
+ ## Clone and Run Codebase (for Developers)
248
+
249
+ ```bash
250
+ git clone https://github.com/nirmallab/plexora.git
251
+ cd plexora
252
+ python -m venv .venv && source .venv/bin/activate # or conda create -n plexora python=3.13
253
+ pip install -e ".[dev,jupyter]"
254
+ ```
255
+
256
+ Any Python 3.12 or 3.13 environment works — conda, venv, uv, whatever you
257
+ already use. The editable install pulls every runtime dependency plus the test
258
+ and notebook extras; there is no separate environment file to keep in sync.
259
+
260
+ Then start the server with `python run.py` (or `plexora`) and open
261
+ `http://localhost:8000/`.
262
+
263
+ ## Running in Jupyter notebooks
264
+
265
+ Install the package into the same environment as Jupyter:
266
+
267
+ ```bash
268
+ pip install "plexora[jupyter]"
269
+ ```
270
+
271
+ Then, in a cell:
272
+
273
+ ```python
274
+ import plexora
275
+
276
+ plexora.view("my_dataset")
277
+ ```
278
+
279
+ That is the whole thing, in every kind of notebook. Plexora starts a small
280
+ server beside your kernel and shows it in the cell.
281
+
282
+ `data_dir` is optional everywhere below: leaving it out uses the same directory
283
+ `plexora where` reports, so a notebook and a terminal see the same projects.
284
+ Pass it to work against a different one.
285
+
286
+ ### Hosted notebooks — JupyterHub, Open OnDemand, Colab
287
+
288
+ The same call. When your kernel is not on the machine with your browser, a
289
+ `127.0.0.1` address would point at your own laptop, so Plexora detects the
290
+ situation and builds the proxied URL your host actually serves it on.
291
+
292
+ On a JupyterHub server, this needs `jupyter-server-proxy` installed **in the
293
+ environment running the Jupyter server** (not necessarily the one running your
294
+ kernel):
295
+
296
+ ```bash
297
+ pip install jupyter-server-proxy
298
+ ```
299
+
300
+ **Open OnDemand needs nothing installed.** Plexora recognises the portal and
301
+ mounts itself under `/rnode/<node>/<port>`, the door OnDemand provides for apps
302
+ that serve at the root. That door is reached from the portal over the network,
303
+ so the viewer binds `0.0.0.0` and protects itself with a token carried in the
304
+ URL — it says so, once, when it starts. From a terminal in the same session,
305
+ `plexora --ood my_dataset` does the same thing for the standalone app.
306
+
307
+ Colab needs nothing extra either. Neither does local Jupyter or VS Code Remote,
308
+ which keep the direct localhost address they always used.
309
+
310
+ Override the detection if you need to:
311
+
312
+ ```python
313
+ plexora.view("my_dataset", proxy=True) # always proxy
314
+ plexora.view("my_dataset", proxy=False) # always use 127.0.0.1
315
+ plexora.view("my_dataset", base_url="/user/me/") # name the prefix yourself
316
+ ```
317
+
318
+ On a hub, `viewer.url` is a path rather than a full address — open it under
319
+ your notebook server's own address, which is where your session is
320
+ authenticated.
321
+
322
+ Datasets can also be registered directly from notebook-visible files:
323
+
324
+ ```python
325
+ from plexora.jupyter import PlexoraViewer
326
+
327
+ viewer = PlexoraViewer.from_files(
328
+ name="my_dataset",
329
+ image="/path/to/image.ome.tif",
330
+ segmentation="/path/to/segmentation.ome.tif",
331
+ features="/path/to/cells.csv",
332
+ x="X_centroid",
333
+ y="Y_centroid",
334
+ id_column="CellID",
335
+ )
336
+ viewer
337
+ ```
338
+
339
+ ## Baseline smoke test
340
+
341
+ Before upgrading dependencies or changing the viewer/server boundary, run the local `orion2` baseline:
342
+
343
+ ```bash
344
+ python -m tests.baseline_orion2
345
+ ```
346
+
347
+ The test checks Flask app import, `/config`, the viewer page, metadata JSON, channel metadata, and one image tile plus one segmentation tile. It skips with a clear message if the local `orion2` datasource or exemplar files are not available.
348
+
349
+
350
+ #### (4. Node.js installation and packages)
351
+ This step is only needed when you plan to edit js code. The codebase already included bundled js files.
352
+ * Install [Node.js](https://nodejs.org/en/), then navigate to `/plexora/client` and run `npm install` to install all packages listed in package.json.
353
+ * Run `npm run start` to package the Javascript, or run `npm run watch` if you plan on editing dependencies
354
+
355
+
356
+ ## Packaging/Bundling Code as Executable (for Developers)
357
+ Any tagged commit to a branch will trigger a build, where `tag == commit message`. This will appear under releases. Note building may take ~10 min.
358
+
359
+ Tagging Conventions: All release tags should look like `v{version_number}_{branch_name}`.
360
+
361
+ ## License
362
+
363
+ Plexora is released under the **Plexora Academic License 1.0** (see [LICENSE](./LICENSE)).
364
+ It is **not** an open source license. In short:
365
+
366
+ | | |
367
+ |---|---|
368
+ | Academic research, teaching, personal study | ✅ Free |
369
+ | Use by a nonprofit or government research institution | ✅ Free (whatever the funding source) |
370
+ | Redistributing Plexora unmodified, with the license attached | ✅ Allowed |
371
+ | Patching your own copy to fix a bug or a compatibility problem | ✅ Allowed |
372
+ | Publishing a fork, a patched build, or a renamed version | ❌ Not allowed |
373
+ | Commercial use of any kind | ❌ Requires a paid license |
374
+
375
+ **Plugins are a deliberate exception.** Anything you build against the documented
376
+ extension interfaces — the `plexora.plugins` entry point group and the `plexora.api`
377
+ package — is yours. You may distribute and sell your plugin under whatever license
378
+ you like, and you do not need our permission. Extending Plexora through the plugin
379
+ API is the supported way to change what it does; editing its source is not.
380
+
381
+ For a commercial license, contact Ajit Johnson Nirmal <ajitjohnson.n@gmail.com>.
382
+
383
+ Some bundled components carry their own licenses, which are unaffected by the above —
384
+ see section 8 of [LICENSE](./LICENSE).