feat: Add Windows setup script (installs Python 3.12 + Git, napari 0.7) - #407
Open
hongquanli wants to merge 4 commits into
Open
feat: Add Windows setup script (installs Python 3.12 + Git, napari 0.7)#407hongquanli wants to merge 4 commits into
hongquanli wants to merge 4 commits into
Conversation
Adds PowerShell setup script for Windows that: - Checks for Python and Git prerequisites - Clones the Squid repository - Installs Python dependencies via pip - Creates desktop shortcut with icon 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Require 64-bit Python 3.12 explicitly instead of accepting whatever `python` resolves to: probe `py -3.12` first, then python3.12/python3/ python, and pin every later pip call and the desktop shortcut to the resolved sys.executable. Install napari as napari[pyqt5]==0.7.1 rather than napari[all]. As of napari 0.7 the all/qt extras resolve to PyQt6, while Squid's GUI is PyQt5 via qtpy, so the old list installed no PyQt5 at all. A post-install check warns if PyQt6 ends up in the environment anyway. Align the dependency list with setup_26.04.sh and with what master actually imports: - drop aicsimageio/basicpy (only importer is control/stitcher.py, which nothing imports) and the numpy<2 cap that existed for them - add pyqtgraph and PyQt5, which the Ubuntu scripts get from apt - add pyyaml, platformdirs, filelock, lxml_html_clean, mcp and ndv, all hard imports that were missing - add tensorstore, required by the ZARR_V3 file_saving_option - install in a single pip call so the resolver sees every constraint Also fix two latent failures: - git clone now recurses submodules; control/ndviewer_light and fluidics_v2 are submodules and the GUI will not start without them - $ErrorActionPreference does not apply to native executables, so a failing pip or git only set $LASTEXITCODE and the script carried on to create a desktop shortcut for a broken install Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
hongquanli
force-pushed
the
feat/add-windows-setup-script
branch
from
August 9, 2026 09:05
d126d65 to
98ad847
Compare
The script previously required the user to have installed Python 3.12 themselves and failed with instructions otherwise. Install it instead: download the official python.org installer, verify its SHA256, and run it silently. The install is per-user (InstallAllUsers=0, InstallLauncherAllUsers=0), so it needs no admin rights and raises no UAC prompt. Since the installer only edits PATH for new processes, the script refreshes $env:Path from the registry afterwards and also probes the default per-user install location directly, then re-runs discovery. Pins 3.12.10 because it is the last 3.12 release with a Windows binary installer - 3.12.11 and later are source-only security releases. Pass -SkipPythonInstall to keep the old fail-with-instructions behaviour on machines where Python is managed centrally. Interpreter discovery moves into Find-Python312 so it can run both before and after the install. Fixes a bitness check that rejected every interpreter: the probe printed 8 * (sys.maxsize > 2**32), which is 8 on a 64-bit Python rather than 64, because Python's True is 1. Compared against 64, no interpreter could ever be accepted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Git was the last prerequisite the script still required the user to install by hand. Fetch it the same way as Python: download the pinned Git for Windows installer, verify its SHA256, run it silently. Git for Windows is an Inno Setup installer built with PrivilegesRequired=none, so an unelevated run installs per-user into %LOCALAPPDATA%\Programs\Git and records itself under HKCU rather than HKLM - no UAC prompt, matching the Python install. Run elevated it installs machine-wide instead; Find-Git handles either by checking PATH, then both registry keys, then the two default directories. Every git call site now uses the resolved $GitExe rather than bare `git`, since a Git installed by this script is not on this process's PATH. The download/verify/run/refresh-PATH sequence is now shared by both prerequisites as Invoke-SilentInstaller instead of being duplicated, with the per-installer differences (silent flags, accepted exit codes, manual-install URL) passed in. Git is pinned at 2.55.0.3 for reproducibility rather than compatibility - Squid works with any modern Git. Its SHA256 is the one published in the release notes, which matches the GitHub API's asset digest. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
software/setup_windows.ps1, a one-shot installer for Windows: it installs theprerequisites, clones the repo, installs the Python dependencies, and drops a desktop
shortcut. Targets Python 3.12 and napari 0.7.
Running it on a clean Windows 10/11 machine with nothing preinstalled should be enough
to get to a launchable Squid.
What it does
hosts, checked against a pinned SHA256 before being run, and installed silently
per-user — no admin rights, no UAC prompt.
-SkipPythonInstall/-SkipGitInstallopt out on machines where these are managed centrally.
pythonhappens tobe. Probes
py -3.12first, thenpython3.12/python3/python, then the defaultper-user install directory, checking version and 64-bitness. Every later
pipcalland the desktop shortcut are pinned to that exact
sys.executable.--recurse-submodulesand updates submodules on an existing checkout.pipcall, then warns if PyQt6 endedup in the environment anyway.
Squid_hcs.lnkon the Desktop with the Cephla icon.in the repo).
Notable decisions
napari[pyqt5]==0.7.1, notnapari[all]. As of napari 0.7 theall/qtextrasresolve to PyQt6, while Squid's GUI is PyQt5 via qtpy. The PyQt5 extra is requested
explicitly so the two bindings can't end up side by side.
Python is pinned at 3.12.10 because that is the last 3.12 release with a Windows
binary installer — 3.12.11 and later are source-only security releases. This version
will not need bumping.
Git is pinned at 2.55.0.3 for reproducibility rather than compatibility; Squid works
with any modern Git. Its SHA256 is the one published in the release notes, which matches
the GitHub API's asset digest.
Dependency list follows
setup_26.04.sh(#568) and whatmasteractually imports:aicsimageio/basicpy— their only importer iscontrol/stitcher.py, whichnothing imports (the active stitcher is
tools/stitcher.py, the ImageJ path). Both areawkward to build on Windows, so dropping the dead dependency de-risks the install. This
also removes the reason for the
numpy<2cap.pyqtgraphand PyQt5, which the Ubuntu scripts get fromaptpyyaml,platformdirs,filelock,lxml_html_clean,mcp,ndv— all hardimports on
masterthat were missingtensorstore, required by theZARR_V3file_saving_optionDeliberately still not installed:
pipython(lazy import, real-hardware path behindUSE_PI_FOCUS_STAGE) andscyjava(standalone ImageJ tool, needs a JVM).Verification
Resolved the full dependency set against Windows / Python 3.12
(
pip install --dry-run --only-binary=:all: --python-version 3.12 --platform win_amd64):napari-0.7.1,PyQt5-5.15.11, no PyQt6,numpy-2.5.1,tensorstore-0.1.85, andqtconsole/ipythonarriving transitively vianapari-consolesocontrol/console.pyworks.
The script itself parses clean (0 syntax errors) and passes PSScriptAnalyzer apart from
PSAvoidUsingWriteHost, which is intentional for a colored interactive installer. Thehelper functions were unit-tested by extracting them from the AST: interpreter probing
against a real 3.12, the rejection paths (missing binary, non-zero exit with stderr,
truncated output), and the installer integrity gate — a wrong hash aborts before anything
executes, names both hashes, and deletes the download.
Not yet verified: the download-and-install path has never run on real Windows.
Start-Processbehavior, the silent-install flags, and the post-install PATH refresh areall Windows-only and need a real machine.
Test plan
.\setup_windows.ps1on a clean Windows 10/11 box with no Python and noGit installed — both should install without a UAC prompt
pipthe one used
python -c "import qtpy; print(qtpy.API_NAME)"reports PyQt5tensorstorelanded)🤖 Generated with Claude Code