niivue-streamlit 0.0.0.dev14__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 (38) hide show
  1. niivue_streamlit-0.0.0.dev14/MANIFEST.in +9 -0
  2. niivue_streamlit-0.0.0.dev14/PKG-INFO +311 -0
  3. niivue_streamlit-0.0.0.dev14/README.md +282 -0
  4. niivue_streamlit-0.0.0.dev14/niivue_component/README.md +105 -0
  5. niivue_streamlit-0.0.0.dev14/niivue_component/__init__.py +182 -0
  6. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/.npmrc +2 -0
  7. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/.turbo/turbo-build.log +29 -0
  8. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/CHANGELOG.md +14 -0
  9. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/README.md +63 -0
  10. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/blosc.js +1 -0
  11. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/chunk-INHXZS53.js +1 -0
  12. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/dcm2niix.jpeg-CR3ddVLp.wasm +0 -0
  13. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/index.css +1 -0
  14. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/index.js +2 -0
  15. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/lz4.js +1 -0
  16. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/worker.jpeg-Ci0Y_zaw.js +1 -0
  17. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/assets/zstd.js +1 -0
  18. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/build/index.html +13 -0
  19. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/index.html +12 -0
  20. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/package.json +45 -0
  21. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/postcss.config.js +6 -0
  22. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/tailwind.config.js +12 -0
  23. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/test/UnstyledCanvas.test.tsx +13 -0
  24. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/test/setup.ts +1 -0
  25. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/test/utils.test.ts +138 -0
  26. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/tsconfig.json +34 -0
  27. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/vite.config.ts +94 -0
  28. niivue_streamlit-0.0.0.dev14/niivue_component/frontend/vitest.config.ts +27 -0
  29. niivue_streamlit-0.0.0.dev14/niivue_component/setup_dev.sh +37 -0
  30. niivue_streamlit-0.0.0.dev14/niivue_streamlit.egg-info/PKG-INFO +311 -0
  31. niivue_streamlit-0.0.0.dev14/niivue_streamlit.egg-info/SOURCES.txt +36 -0
  32. niivue_streamlit-0.0.0.dev14/niivue_streamlit.egg-info/dependency_links.txt +1 -0
  33. niivue_streamlit-0.0.0.dev14/niivue_streamlit.egg-info/requires.txt +6 -0
  34. niivue_streamlit-0.0.0.dev14/niivue_streamlit.egg-info/top_level.txt +1 -0
  35. niivue_streamlit-0.0.0.dev14/pyproject.toml +52 -0
  36. niivue_streamlit-0.0.0.dev14/setup.cfg +4 -0
  37. niivue_streamlit-0.0.0.dev14/tests/test_niivue_component.py +318 -0
  38. niivue_streamlit-0.0.0.dev14/tests/test_utils.py +39 -0
@@ -0,0 +1,9 @@
1
+ include README.md
2
+ include LICENSE
3
+ recursive-include niivue_component *
4
+ recursive-include niivue_component/assets *
5
+ recursive-exclude niivue_component/frontend/node_modules *
6
+ recursive-exclude niivue_component/frontend/src *
7
+ recursive-exclude niivue_component/frontend/public *
8
+ global-exclude *.pyc
9
+ global-exclude __pycache__
@@ -0,0 +1,311 @@
1
+ Metadata-Version: 2.4
2
+ Name: niivue-streamlit
3
+ Version: 0.0.0.dev14
4
+ Summary: A Streamlit component for NiiVue neuroimaging viewer
5
+ Author: NiiVue Team
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/niivue/niivue
8
+ Project-URL: Documentation, https://niivue.github.io/niivue/
9
+ Project-URL: Repository, https://github.com/niivue/niivue
10
+ Project-URL: Issues, https://github.com/niivue/niivue/issues
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.7
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
21
+ Classifier: Topic :: Scientific/Engineering :: Visualization
22
+ Requires-Python: >=3.7
23
+ Description-Content-Type: text/markdown
24
+ Requires-Dist: streamlit>=1.28.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest; extra == "dev"
27
+ Requires-Dist: black; extra == "dev"
28
+ Requires-Dist: flake8; extra == "dev"
29
+
30
+ # NiiVue Streamlit Component
31
+
32
+ A modern Streamlit component for visualizing neuroimaging data using NiiVue, built with TypeScript, Preact, and Vite.
33
+
34
+ ## 🚀 Quick Start
35
+
36
+ ### Simple Installation & Usage
37
+
38
+ 1. **Install the component**:
39
+
40
+ ```bash
41
+ pip install --index-url https://test.pypi.org/simple/ --no-deps niivue-streamlit
42
+ ```
43
+
44
+ 2. **Use in your Streamlit app**:
45
+
46
+ ```python
47
+ import streamlit as st
48
+ from niivue_component import niivue_viewer
49
+
50
+ uploaded_file = st.file_uploader("Choose a NIFTI file", type=["nii", "nii.gz"])
51
+
52
+ if uploaded_file is not None:
53
+ result = niivue_viewer(
54
+ nifti_data=uploaded_file.getvalue(),
55
+ filename=uploaded_file.name,
56
+ height=700
57
+ )
58
+
59
+ # Handle click events
60
+ if result:
61
+ st.write(f"Clicked voxel: {result['voxel']}, Value: {result['value']}")
62
+ ```
63
+
64
+ ## ✨ Features
65
+
66
+ - 🎨 **Two Component Modes**:
67
+ - `StyledViewer`: Full-featured viewer with interactive menu and controls
68
+ - `UnstyledCanvas`: Minimal canvas-only viewer for embedding
69
+ - 🔄 **Multiple View Modes**:
70
+ - Axial, Coronal, Sagittal slices
71
+ - 3D render view
72
+ - Multiplanar view with render
73
+ - 📊 **Advanced Capabilities**:
74
+ - Multiple overlay images with custom colormaps
75
+ - Surface mesh rendering (FreeSurfer pial, white, inflated, GIfTI, STL, OBJ, etc.)
76
+ - Mesh overlays (curvature, thickness, annotations)
77
+ - Combined volume + mesh visualization
78
+ - Configurable display settings (crosshair, radiological convention, colorbar, interpolation)
79
+ - Bidirectional communication (click events from viewer to Python)
80
+ - DICOM support
81
+
82
+ ## 📖 Advanced Usage
83
+
84
+ ### With Overlays
85
+
86
+ ```python
87
+ from niivue_component import niivue_viewer
88
+
89
+ result = niivue_viewer(
90
+ nifti_data=main_image_bytes,
91
+ filename="brain.nii.gz",
92
+ overlays=[
93
+ {
94
+ "data": overlay_bytes,
95
+ "name": "activation.nii.gz",
96
+ "colormap": "hot",
97
+ "opacity": 0.7
98
+ }
99
+ ],
100
+ view_mode="multiplanar",
101
+ styled=True,
102
+ settings={
103
+ "crosshair": True,
104
+ "radiological": False,
105
+ "colorbar": True,
106
+ "interpolation": True
107
+ },
108
+ height=800
109
+ )
110
+ ```
111
+
112
+ ### With Mesh Surfaces
113
+
114
+ ```python
115
+ from niivue_component import niivue_viewer
116
+
117
+ # Load a FreeSurfer surface mesh
118
+ mesh_data = open("lh.pial", "rb").read()
119
+
120
+ result = niivue_viewer(
121
+ meshes=[{
122
+ "data": mesh_data,
123
+ "name": "lh.pial",
124
+ }],
125
+ view_mode="3d",
126
+ height=700
127
+ )
128
+ ```
129
+
130
+ ### Mesh with Overlays (Curvature, Thickness)
131
+
132
+ ```python
133
+ mesh_data = open("lh.pial", "rb").read()
134
+ thickness_data = open("lh.thickness", "rb").read()
135
+
136
+ result = niivue_viewer(
137
+ meshes=[{
138
+ "data": mesh_data,
139
+ "name": "lh.pial",
140
+ "overlays": [{
141
+ "data": thickness_data,
142
+ "name": "lh.thickness",
143
+ "colormap": "redyell",
144
+ "opacity": 0.7
145
+ }]
146
+ }],
147
+ view_mode="3d",
148
+ height=700
149
+ )
150
+ ```
151
+
152
+ ### Volume with Mesh
153
+
154
+ ```python
155
+ # Display a volume image alongside a surface mesh
156
+ volume_data = open("brain.nii.gz", "rb").read()
157
+ mesh_data = open("lh.pial", "rb").read()
158
+
159
+ result = niivue_viewer(
160
+ nifti_data=volume_data,
161
+ filename="brain.nii.gz",
162
+ meshes=[{
163
+ "data": mesh_data,
164
+ "name": "lh.pial",
165
+ }],
166
+ view_mode="3d",
167
+ height=700
168
+ )
169
+ ```
170
+
171
+ ### Minimal Viewer (No Menu)
172
+
173
+ ```python
174
+ # Perfect for embedding in complex layouts
175
+ result = niivue_viewer(
176
+ nifti_data=image_bytes,
177
+ filename="scan.nii",
178
+ styled=False, # Hide menu
179
+ view_mode="axial",
180
+ height=400
181
+ )
182
+ ```
183
+
184
+ ## 📚 API Reference
185
+
186
+ ### `niivue_viewer()`
187
+
188
+ **Parameters:**
189
+
190
+ - `nifti_data` (bytes, optional): Raw NIFTI file data
191
+ - `filename` (str): Displayed filename
192
+ - `overlays` (list[dict], optional): Overlay images list
193
+ - `data` (bytes): Overlay data
194
+ - `name` (str): Overlay name
195
+ - `colormap` (str): Colormap (default: 'red')
196
+ - `opacity` (float): 0-1 (default: 0.5)
197
+ - `meshes` (list[dict], optional): Mesh surfaces list
198
+ - `data` (bytes): Mesh file data
199
+ - `name` (str): Mesh filename (must include extension, e.g. 'lh.pial', 'brain.gii')
200
+ - `overlays` (list[dict], optional): Mesh overlays (curvature, thickness, etc.)
201
+ - `data` (bytes): Overlay data
202
+ - `name` (str): Overlay filename
203
+ - `colormap` (str): Colormap (default: 'redyell')
204
+ - `opacity` (float): 0-1 (default: 0.7)
205
+ - `height` (int): Height in pixels (default: 600)
206
+ - `view_mode` (str): 'axial', 'coronal', 'sagittal', '3d', 'multiplanar' (default)
207
+ - `styled` (bool): Show menu (default: True)
208
+ - `settings` (dict, optional):
209
+ - `crosshair` (bool): default True
210
+ - `radiological` (bool): default False
211
+ - `colorbar` (bool): default False
212
+ - `interpolation` (bool): default True
213
+ - `key` (str, optional): Component key
214
+
215
+ **Returns:**
216
+
217
+ dict or None with click event data:
218
+
219
+ - `type`: 'voxel_click'
220
+ - `voxel`: [x, y, z]
221
+ - `mm`: [x, y, z]
222
+ - `value`: float
223
+ - `filename`: str
224
+
225
+ ## 🛠️ Development
226
+
227
+ ### Dev mode (live reload)
228
+
229
+ In dev mode, the Python package points to a local Vite dev server instead of built files.
230
+
231
+ Terminal 1 — start the frontend dev server (port 3001):
232
+
233
+ ```bash
234
+ pnpm dev
235
+ ```
236
+
237
+ Terminal 2 — run the example app with the dev flag:
238
+
239
+ ```bash
240
+ NIIVUE_DEV=1 streamlit run app.py
241
+ ```
242
+
243
+ The frontend hot-reloads on changes.
244
+
245
+ ### Production mode (built files)
246
+
247
+ Build the frontend first, then run Streamlit normally:
248
+
249
+ ```bash
250
+ pnpm build
251
+ streamlit run app.py
252
+ ```
253
+
254
+ `_RELEASE = True` (the default) serves from `niivue_component/frontend/build/`.
255
+
256
+ ### Running Examples
257
+
258
+ ```bash
259
+ # Simple example
260
+ streamlit run app.py
261
+
262
+ # Advanced example with all features
263
+ streamlit run app_advanced.py
264
+ ```
265
+
266
+ ## 📁 Supported Formats
267
+
268
+ - **Volume-based**: NIFTI (.nii, .nii.gz), DICOM (.dcm), MINC (.mnc, .mnc.gz), MHA/MHD, NRRD, MGH/MGZ
269
+ - **Mesh-based**: [GIfTI](https://www.nitrc.org/projects/gifti/) (.gii), [FreeSurfer](http://www.grahamwideman.com/gw/brain/fs/surfacefileformats.htm) (pial, white, inflated), [MZ3](https://github.com/neurolabusc/surf-ice/tree/master/mz3) (.mz3), [STL](https://medium.com/3d-printing-stories/why-stl-format-is-bad-fea9ecf5e45) (.stl), [Wavefront OBJ](https://brainder.org/tag/obj/) (.obj), [PLY](https://en.wikipedia.org/wiki/PLY_%28file_format%29) (.ply), [BrainSuite DFS](http://brainsuite.org/formats/dfs/) (.dfs), [Legacy VTK](https://vtk.org/wp-content/uploads/2015/04/file-formats.pdf) (.vtk)
270
+ - **Mesh Overlays**: [GIfTI](https://www.nitrc.org/projects/gifti/) (.gii), [CIfTI-2](https://balsa.wustl.edu/about/fileTypes) (.nii), [MZ3](https://github.com/neurolabusc/surf-ice/tree/master/mz3) (.mz3), FreeSurfer (CURV, ANNOT), SMP, STC
271
+ - **Tractography**: [TCK](https://mrtrix.readthedocs.io/en/latest/getting_started/image_data.html#tracks-file-format-tck) (.tck), [TRK](http://trackvis.org/docs/?subsect=fileformat) (.trk), [TRX](https://github.com/frheault/tractography_file_format) (.trx), VTK (.vtk)
272
+
273
+ ## 🏗️ Architecture
274
+
275
+ ```
276
+ niivue_component/
277
+ ├── __init__.py # Python API
278
+ ├── frontend/
279
+ │ ├── src/
280
+ │ │ ├── components/
281
+ │ │ │ ├── StyledViewer.tsx
282
+ │ │ │ └── UnstyledCanvas.tsx
283
+ │ │ ├── types.ts
284
+ │ │ └── utils.ts
285
+ │ ├── vite.config.ts
286
+ │ └── package.json
287
+ └── build/ # Compiled assets (generated, not in git)
288
+ ```
289
+
290
+ ## 🔧 Building for Distribution
291
+
292
+ Build files are not committed to git. To prepare the Python package for release:
293
+
294
+ ```bash
295
+ pnpm build
296
+ python -m build
297
+ ```
298
+
299
+ This compiles frontend assets into `niivue_component/frontend/build/`, which is then bundled into the Python package.
300
+
301
+ ## 📄 License
302
+
303
+ BSD-2-Clause
304
+
305
+ ## 🙏 Credits
306
+
307
+ Built on top of:
308
+
309
+ - [NiiVue](https://github.com/niivue/niivue)
310
+ - [Streamlit](https://streamlit.io)
311
+ - [niivue-react](../../packages/niivue-react)
@@ -0,0 +1,282 @@
1
+ # NiiVue Streamlit Component
2
+
3
+ A modern Streamlit component for visualizing neuroimaging data using NiiVue, built with TypeScript, Preact, and Vite.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ ### Simple Installation & Usage
8
+
9
+ 1. **Install the component**:
10
+
11
+ ```bash
12
+ pip install --index-url https://test.pypi.org/simple/ --no-deps niivue-streamlit
13
+ ```
14
+
15
+ 2. **Use in your Streamlit app**:
16
+
17
+ ```python
18
+ import streamlit as st
19
+ from niivue_component import niivue_viewer
20
+
21
+ uploaded_file = st.file_uploader("Choose a NIFTI file", type=["nii", "nii.gz"])
22
+
23
+ if uploaded_file is not None:
24
+ result = niivue_viewer(
25
+ nifti_data=uploaded_file.getvalue(),
26
+ filename=uploaded_file.name,
27
+ height=700
28
+ )
29
+
30
+ # Handle click events
31
+ if result:
32
+ st.write(f"Clicked voxel: {result['voxel']}, Value: {result['value']}")
33
+ ```
34
+
35
+ ## ✨ Features
36
+
37
+ - 🎨 **Two Component Modes**:
38
+ - `StyledViewer`: Full-featured viewer with interactive menu and controls
39
+ - `UnstyledCanvas`: Minimal canvas-only viewer for embedding
40
+ - 🔄 **Multiple View Modes**:
41
+ - Axial, Coronal, Sagittal slices
42
+ - 3D render view
43
+ - Multiplanar view with render
44
+ - 📊 **Advanced Capabilities**:
45
+ - Multiple overlay images with custom colormaps
46
+ - Surface mesh rendering (FreeSurfer pial, white, inflated, GIfTI, STL, OBJ, etc.)
47
+ - Mesh overlays (curvature, thickness, annotations)
48
+ - Combined volume + mesh visualization
49
+ - Configurable display settings (crosshair, radiological convention, colorbar, interpolation)
50
+ - Bidirectional communication (click events from viewer to Python)
51
+ - DICOM support
52
+
53
+ ## 📖 Advanced Usage
54
+
55
+ ### With Overlays
56
+
57
+ ```python
58
+ from niivue_component import niivue_viewer
59
+
60
+ result = niivue_viewer(
61
+ nifti_data=main_image_bytes,
62
+ filename="brain.nii.gz",
63
+ overlays=[
64
+ {
65
+ "data": overlay_bytes,
66
+ "name": "activation.nii.gz",
67
+ "colormap": "hot",
68
+ "opacity": 0.7
69
+ }
70
+ ],
71
+ view_mode="multiplanar",
72
+ styled=True,
73
+ settings={
74
+ "crosshair": True,
75
+ "radiological": False,
76
+ "colorbar": True,
77
+ "interpolation": True
78
+ },
79
+ height=800
80
+ )
81
+ ```
82
+
83
+ ### With Mesh Surfaces
84
+
85
+ ```python
86
+ from niivue_component import niivue_viewer
87
+
88
+ # Load a FreeSurfer surface mesh
89
+ mesh_data = open("lh.pial", "rb").read()
90
+
91
+ result = niivue_viewer(
92
+ meshes=[{
93
+ "data": mesh_data,
94
+ "name": "lh.pial",
95
+ }],
96
+ view_mode="3d",
97
+ height=700
98
+ )
99
+ ```
100
+
101
+ ### Mesh with Overlays (Curvature, Thickness)
102
+
103
+ ```python
104
+ mesh_data = open("lh.pial", "rb").read()
105
+ thickness_data = open("lh.thickness", "rb").read()
106
+
107
+ result = niivue_viewer(
108
+ meshes=[{
109
+ "data": mesh_data,
110
+ "name": "lh.pial",
111
+ "overlays": [{
112
+ "data": thickness_data,
113
+ "name": "lh.thickness",
114
+ "colormap": "redyell",
115
+ "opacity": 0.7
116
+ }]
117
+ }],
118
+ view_mode="3d",
119
+ height=700
120
+ )
121
+ ```
122
+
123
+ ### Volume with Mesh
124
+
125
+ ```python
126
+ # Display a volume image alongside a surface mesh
127
+ volume_data = open("brain.nii.gz", "rb").read()
128
+ mesh_data = open("lh.pial", "rb").read()
129
+
130
+ result = niivue_viewer(
131
+ nifti_data=volume_data,
132
+ filename="brain.nii.gz",
133
+ meshes=[{
134
+ "data": mesh_data,
135
+ "name": "lh.pial",
136
+ }],
137
+ view_mode="3d",
138
+ height=700
139
+ )
140
+ ```
141
+
142
+ ### Minimal Viewer (No Menu)
143
+
144
+ ```python
145
+ # Perfect for embedding in complex layouts
146
+ result = niivue_viewer(
147
+ nifti_data=image_bytes,
148
+ filename="scan.nii",
149
+ styled=False, # Hide menu
150
+ view_mode="axial",
151
+ height=400
152
+ )
153
+ ```
154
+
155
+ ## 📚 API Reference
156
+
157
+ ### `niivue_viewer()`
158
+
159
+ **Parameters:**
160
+
161
+ - `nifti_data` (bytes, optional): Raw NIFTI file data
162
+ - `filename` (str): Displayed filename
163
+ - `overlays` (list[dict], optional): Overlay images list
164
+ - `data` (bytes): Overlay data
165
+ - `name` (str): Overlay name
166
+ - `colormap` (str): Colormap (default: 'red')
167
+ - `opacity` (float): 0-1 (default: 0.5)
168
+ - `meshes` (list[dict], optional): Mesh surfaces list
169
+ - `data` (bytes): Mesh file data
170
+ - `name` (str): Mesh filename (must include extension, e.g. 'lh.pial', 'brain.gii')
171
+ - `overlays` (list[dict], optional): Mesh overlays (curvature, thickness, etc.)
172
+ - `data` (bytes): Overlay data
173
+ - `name` (str): Overlay filename
174
+ - `colormap` (str): Colormap (default: 'redyell')
175
+ - `opacity` (float): 0-1 (default: 0.7)
176
+ - `height` (int): Height in pixels (default: 600)
177
+ - `view_mode` (str): 'axial', 'coronal', 'sagittal', '3d', 'multiplanar' (default)
178
+ - `styled` (bool): Show menu (default: True)
179
+ - `settings` (dict, optional):
180
+ - `crosshair` (bool): default True
181
+ - `radiological` (bool): default False
182
+ - `colorbar` (bool): default False
183
+ - `interpolation` (bool): default True
184
+ - `key` (str, optional): Component key
185
+
186
+ **Returns:**
187
+
188
+ dict or None with click event data:
189
+
190
+ - `type`: 'voxel_click'
191
+ - `voxel`: [x, y, z]
192
+ - `mm`: [x, y, z]
193
+ - `value`: float
194
+ - `filename`: str
195
+
196
+ ## 🛠️ Development
197
+
198
+ ### Dev mode (live reload)
199
+
200
+ In dev mode, the Python package points to a local Vite dev server instead of built files.
201
+
202
+ Terminal 1 — start the frontend dev server (port 3001):
203
+
204
+ ```bash
205
+ pnpm dev
206
+ ```
207
+
208
+ Terminal 2 — run the example app with the dev flag:
209
+
210
+ ```bash
211
+ NIIVUE_DEV=1 streamlit run app.py
212
+ ```
213
+
214
+ The frontend hot-reloads on changes.
215
+
216
+ ### Production mode (built files)
217
+
218
+ Build the frontend first, then run Streamlit normally:
219
+
220
+ ```bash
221
+ pnpm build
222
+ streamlit run app.py
223
+ ```
224
+
225
+ `_RELEASE = True` (the default) serves from `niivue_component/frontend/build/`.
226
+
227
+ ### Running Examples
228
+
229
+ ```bash
230
+ # Simple example
231
+ streamlit run app.py
232
+
233
+ # Advanced example with all features
234
+ streamlit run app_advanced.py
235
+ ```
236
+
237
+ ## 📁 Supported Formats
238
+
239
+ - **Volume-based**: NIFTI (.nii, .nii.gz), DICOM (.dcm), MINC (.mnc, .mnc.gz), MHA/MHD, NRRD, MGH/MGZ
240
+ - **Mesh-based**: [GIfTI](https://www.nitrc.org/projects/gifti/) (.gii), [FreeSurfer](http://www.grahamwideman.com/gw/brain/fs/surfacefileformats.htm) (pial, white, inflated), [MZ3](https://github.com/neurolabusc/surf-ice/tree/master/mz3) (.mz3), [STL](https://medium.com/3d-printing-stories/why-stl-format-is-bad-fea9ecf5e45) (.stl), [Wavefront OBJ](https://brainder.org/tag/obj/) (.obj), [PLY](https://en.wikipedia.org/wiki/PLY_%28file_format%29) (.ply), [BrainSuite DFS](http://brainsuite.org/formats/dfs/) (.dfs), [Legacy VTK](https://vtk.org/wp-content/uploads/2015/04/file-formats.pdf) (.vtk)
241
+ - **Mesh Overlays**: [GIfTI](https://www.nitrc.org/projects/gifti/) (.gii), [CIfTI-2](https://balsa.wustl.edu/about/fileTypes) (.nii), [MZ3](https://github.com/neurolabusc/surf-ice/tree/master/mz3) (.mz3), FreeSurfer (CURV, ANNOT), SMP, STC
242
+ - **Tractography**: [TCK](https://mrtrix.readthedocs.io/en/latest/getting_started/image_data.html#tracks-file-format-tck) (.tck), [TRK](http://trackvis.org/docs/?subsect=fileformat) (.trk), [TRX](https://github.com/frheault/tractography_file_format) (.trx), VTK (.vtk)
243
+
244
+ ## 🏗️ Architecture
245
+
246
+ ```
247
+ niivue_component/
248
+ ├── __init__.py # Python API
249
+ ├── frontend/
250
+ │ ├── src/
251
+ │ │ ├── components/
252
+ │ │ │ ├── StyledViewer.tsx
253
+ │ │ │ └── UnstyledCanvas.tsx
254
+ │ │ ├── types.ts
255
+ │ │ └── utils.ts
256
+ │ ├── vite.config.ts
257
+ │ └── package.json
258
+ └── build/ # Compiled assets (generated, not in git)
259
+ ```
260
+
261
+ ## 🔧 Building for Distribution
262
+
263
+ Build files are not committed to git. To prepare the Python package for release:
264
+
265
+ ```bash
266
+ pnpm build
267
+ python -m build
268
+ ```
269
+
270
+ This compiles frontend assets into `niivue_component/frontend/build/`, which is then bundled into the Python package.
271
+
272
+ ## 📄 License
273
+
274
+ BSD-2-Clause
275
+
276
+ ## 🙏 Credits
277
+
278
+ Built on top of:
279
+
280
+ - [NiiVue](https://github.com/niivue/niivue)
281
+ - [Streamlit](https://streamlit.io)
282
+ - [niivue-react](../../packages/niivue-react)
@@ -0,0 +1,105 @@
1
+ # NiiVue Streamlit Component
2
+
3
+ A Streamlit component for viewing NIFTI files using the NiiVue library.
4
+
5
+ ## Installation
6
+
7
+ ### From PyPI (Recommended)
8
+
9
+ ```bash
10
+ pip install niivue-streamlit
11
+ ```
12
+
13
+ ### Development Setup
14
+
15
+ 1. Clone the repository and navigate to the component directory:
16
+ ```bash
17
+ cd niivue_component
18
+ ```
19
+
20
+ 2. Install Python dependencies:
21
+ ```bash
22
+ pip install -e .
23
+ ```
24
+
25
+ 3. Install and build the frontend:
26
+ ```bash
27
+ cd frontend
28
+ npm install
29
+ npm run build
30
+ ```
31
+
32
+ 4. Install the component in development mode:
33
+ ```bash
34
+ pip install -e .
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ The component handles all NiiVue assets internally, making it simple to use:
40
+
41
+ ```python
42
+ import streamlit as st
43
+ from niivue_component import niivue_viewer
44
+
45
+ # Simple usage - no need to handle CSS/JS files
46
+ uploaded_file = st.file_uploader("Choose a NIFTI file", type=["nii", "nii.gz"])
47
+
48
+ if uploaded_file is not None:
49
+ file_bytes = uploaded_file.getvalue()
50
+
51
+ result = niivue_viewer(
52
+ nifti_data=file_bytes,
53
+ filename=uploaded_file.name,
54
+ height=600,
55
+ key="niivue_viewer"
56
+ )
57
+ ```
58
+
59
+ ## API Reference
60
+
61
+ ### `niivue_viewer(nifti_data=None, filename="", height=600, key=None)`
62
+
63
+ Parameters:
64
+ - `nifti_data` (bytes, optional): Raw NIFTI file data
65
+ - `filename` (str, optional): Name of the file being displayed
66
+ - `height` (int, optional): Height of the component in pixels (default: 600)
67
+ - `key` (str, optional): Unique key for the component
68
+
69
+ Returns:
70
+ - `dict` or `None`: Component return value (if any)
71
+
72
+ ## Development
73
+
74
+ ### For Development with Hot Reload
75
+
76
+ 1. In one terminal, start the React development server:
77
+ ```bash
78
+ cd frontend
79
+ npm start
80
+ ```
81
+
82
+ 2. In your Python component (`__init__.py`), set `_RELEASE = False`
83
+
84
+ 3. In another terminal, run your Streamlit app:
85
+ ```bash
86
+ streamlit run test_simplified_api.py
87
+ ```
88
+
89
+ ## Component Structure
90
+
91
+ - `__init__.py` - Main Python component with asset loading
92
+ - `assets/` - Bundled NiiVue CSS, JS, and WASM files (auto-generated, not in git)
93
+ - `frontend/` - React frontend
94
+ - `src/NiiVueViewer.tsx` - Main React component
95
+ - `package.json` - Node dependencies
96
+ - `pyproject.toml` - Package configuration
97
+
98
+ ## Publishing to PyPI
99
+
100
+ The component is ready for PyPI publication with all assets bundled:
101
+
102
+ ```bash
103
+ python -m build
104
+ twine upload dist/*
105
+ ```