PyVista Quick Look
Press the space bar on a mesh file in the Finder and turn it with the mouse, the same
way macOS already previews .ply and .usdz models.
Selecting flow.vtu and pressing space shows its surface in the Quick Look panel,
coloured by the active scalars and free to rotate and zoom.
Requirements
- macOS 12 or newer
Neither PyVista nor a compiler needs to be installed. The installer downloads a
published build of the app and provisions its own PyVista; Xcode command line tools
(xcode-select --install) are only needed to build from source.
Install
./scripts/install.sh
Then select a .vtu, .vtp, or .vtk file in the Finder and press space.
The installer fetches uv if it is missing, creates a
private environment holding PyVista, installs the pvql helper, builds and registers
PyVistaQuickLook.app, and loads PyVista once so the first preview is quick. Nothing
outside ~/Library/Application Support/PyVistaQuickLook, ~/Applications, and
~/.local/bin is touched, and no existing Python environment is used or changed.
./scripts/install.sh --prefix /Applications # install for all users
./scripts/install.sh --pyvista /path/to/venv/bin/pyvista # use an existing PyVista
./scripts/install.sh --app /path/to/PyVistaQuickLook.app # skip the build
Check the result with pvql doctor.
scripts/bootstrap.sh installs the same way from a URL, once this repository is
published:
curl -LsSf https://raw.githubusercontent.com/user27182/pyvista-quicklook/main/scripts/bootstrap.sh | sh
What gets installed
About 270 MB, in ~/Library/Application Support/PyVistaQuickLook/venv:
- PyVista, from git until 0.49 is released, installed with
--no-deps - cvista
[all], a VTK fork, in place of stock VTK - cyclopts, matplotlib, numpy, pillow, pooch, pyobjc-framework-Cocoa, scooby, typing-extensions
Installing PyVista with --no-deps and swapping stock VTK for cvista is what keeps this
down; stock VTK alone is 591 MB against cvista's 136 MB.
Point --pyvista at an environment you already have to use that instead.
Supported files
36 extensions are claimed by default, including .vtk, .vti, .vtp, .vtu, .vtm,
.vtkhdf, .pvd, .case, .exo, .foam, .cgns, .segy, and .xdmf.
pvql types # what is claimed now
pvql types --all # every format pvql knows about
Formats macOS already previews — .stl, .obj, .ply, .png — are deliberately not
claimed, so the built-in viewer keeps handling them. Claim them by adding them to the
config and reinstalling:
{ "extensions": { "add": [".stl", ".obj"], "remove": [".pdb"] } }
How it works
The app bundle contains a Quick Look extension that declares a uniform type identifier for each claimed extension. When the Finder previews one of those files, the extension hands it to a background render service, which reads it with PyVista, extracts the surface, colours the vertices by the active scalars, and writes a PLY. The extension shows that PLY in a SceneKit view, which is what makes the preview turnable.
Datasets with no surface to show fall back to a still image rendered by
pyvista plot --off-screen --screenshot, which keeps the scalar bar and axes that the
interactive view leaves out. Setting "interactive": false in the config always uses
that still image.
Both are cached under ~/Library/Caches/PyVistaQuickLook, keyed by the file's path,
size, and modification time, so editing a file invalidates its preview. Later previews
of the same file come from the cache.
Every preview runs PyVista in a fresh process, and VTK is 600 MB of libraries, so the
first one after a restart is slow until macOS has those pages cached. The service loads
them in the background when it starts, which is at login and whenever it is reinstalled,
so that cost is paid before you press space. pvql warmup does the same on demand, and
"warm_on_start": false turns the automatic pass off.
Cell data is sampled onto the points before colouring. Surfaces are sent whole:
decimating them costs more time than the larger file does, so max_scene_points is a
safety valve for very large meshes rather than a routine step. Set it to 0 to never
decimate.
When a preview fails, the Quick Look panel shows the error text instead.
The render service
macOS runs Quick Look extensions in a sandbox that VTK cannot render inside, so
rendering happens in a launch agent instead. scripts/install.sh sets it up.
pvql service # report whether it is loaded
pvql service --install # (re)install and start it
pvql service --uninstall
Its output goes to ~/Library/Logs/pvqld.log.
Files in the Desktop, Documents, and Downloads folders
macOS keeps those folders private to each program, and the render service cannot read them. The Quick Look extension copies the file it was asked to preview into its own container so that the service can render it anyway.
A dataset that points at neighbouring files — .pvd, .vtm, .case, .foam — needs
those neighbours, which the copy does not include. Keep such datasets outside those
three folders, or grant the render service Full Disk Access in System Settings under
Privacy & Security.
Configuration
~/Library/Application Support/PyVistaQuickLook/config.json
| Key | Default | Effect |
|---|---|---|
python |
set at install | Interpreter of the PyVista environment |
pyvista |
unset | Optional pyvista executable, for still images |
pvql |
discovered | Absolute path to the pvql helper |
interactive |
true |
Show a turnable surface instead of a still image |
max_scene_points |
2000000 |
Decimate only above this many points; 0 never does |
colormap |
'viridis' |
Colormap used to colour the surface |
warm_on_start |
true |
Load PyVista and VTK when the render service starts |
window_size |
[1024, 1024] |
Rendered preview size in pixels |
timeout |
60 |
Seconds before a render is abandoned |
max_file_size_mb |
512 |
Files above this size show a notice instead of a render |
background |
null |
Background color passed to pyvista plot |
extra_args |
[] |
Extra arguments appended to pyvista plot |
cache |
true |
Reuse previously rendered previews |
log |
false |
Append render activity to pvql.log beside the config file |
Changing extensions requires a reinstall, because the claimed types are baked into the
app bundle. Every other key takes effect on the next preview.
Commands
pvql preview FILE # render and print the path of the cached PNG
pvql warmup # load PyVista and VTK ahead of the first preview
pvql warm DIR # render a directory ahead of time
pvql types # list claimed extensions
pvql doctor # check every part of the integration
pvql service # manage the render service
pvql config --init # write a config file with discovered defaults
pvql cache --clear # delete cached previews
Troubleshooting
Run pvql doctor first; it checks the helper, the app, the extension registration, the
service, and a real render.
- The panel says the service is not answering. Run
pvql service --install. - Nothing happens on space bar. Confirm the type is claimed with
pvql types, then check that Finder resolves it:mdls -name kMDItemContentType yourfile.vtushould report anio.github.user27182.pyvista-quicklook.*type. - Previews are stale.
pvql cache --clear. - A render fails. Set
"log": truein the config; activity is appended topvql.logbeside it. The extension's own log is in~/Library/Containers/io.github.user27182.PyVistaQuickLook.QuickLook/Data/tmp/.
Development
uv sync --group dev
uv run pytest tests/ # helper tests, with coverage
uv run pre-commit run --all-files
./scripts/build.sh # compile and sign the app bundle
main is protected by a pre-commit hook, so work on a branch.
Releases are published to PyPI by CI through trusted publishing: push a v* tag and
the publish job uploads from the release environment. That requires a matching
pending publisher configured on PyPI for this repository and workflow.
Uninstall
./scripts/uninstall.sh
uv tool uninstall pyvista-quicklook
That removes the app, the private PyVista environment, the downloaded source, and the cache, leaving only the config file.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyvista_quicklook-0.2.0.tar.gz.
File metadata
- Download URL: pyvista_quicklook-0.2.0.tar.gz
- Upload date:
- Size: 173.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6349f115965fae0d7fcc6f9913f629f0a964981996e84e8175da48d84f26014e
|
|
| MD5 |
e1f3d69a76969e86708818aa8904b4e8
|
|
| BLAKE2b-256 |
9f0c00392d165de695bc9f83a9e2383e0cc72e90722cf587fa809e3c3537f800
|
Provenance
The following attestation bundles were made for pyvista_quicklook-0.2.0.tar.gz:
Publisher:
ci.yml on user27182/pyvista-quicklook
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyvista_quicklook-0.2.0.tar.gz -
Subject digest:
6349f115965fae0d7fcc6f9913f629f0a964981996e84e8175da48d84f26014e - Sigstore transparency entry: 2680818557
- Sigstore integration time:
-
Permalink:
user27182/pyvista-quicklook@813265a0a1acbf4d6817e678e45a06cdc7cee4c6 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/user27182
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@813265a0a1acbf4d6817e678e45a06cdc7cee4c6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyvista_quicklook-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pyvista_quicklook-0.2.0-py3-none-any.whl
- Upload date:
- Size: 28.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82aefe0834b1fefdb99bb1ce8e9b851e1e8ebcaf1fe7152c7ea356ef887cdffc
|
|
| MD5 |
0d4c68f6aaf513a5789747772001c9f5
|
|
| BLAKE2b-256 |
bf05ca3c8b7c463e7ce9c7f60f0ed63d0541b0517f583d2cac6247898b5c4f18
|
Provenance
The following attestation bundles were made for pyvista_quicklook-0.2.0-py3-none-any.whl:
Publisher:
ci.yml on user27182/pyvista-quicklook
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyvista_quicklook-0.2.0-py3-none-any.whl -
Subject digest:
82aefe0834b1fefdb99bb1ce8e9b851e1e8ebcaf1fe7152c7ea356ef887cdffc - Sigstore transparency entry: 2680818637
- Sigstore integration time:
-
Permalink:
user27182/pyvista-quicklook@813265a0a1acbf4d6817e678e45a06cdc7cee4c6 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/user27182
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@813265a0a1acbf4d6817e678e45a06cdc7cee4c6 -
Trigger Event:
push
-
Statement type: