Packaging for non-developer users (pip/uvx installable, GUI bundled)#86
Merged
Conversation
Make `pip install magnetics` runnable with no extras: move fastapi/ uvicorn into core dependencies (+ platformdirs), drop the `service` extra, and add `magnetics` / `magnetics-fetch` console scripts. Lower requires-python to >=3.12 (the 3.14 pin was a project choice, not forced by any dependency; .python-version stays 3.14 for dev). Fixes 9 PEP 758 unparenthesized-`except` sites that only compiled on 3.14, and adds a 3.12+3.14 CI test matrix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New `magnetics` console script starts the service and opens the bundled GUI in a browser (free-port pick like run.sh; browser opens once the server binds; --host/--port/--no-browser). No Node/dev stack needed. data_dir() now falls back to a per-user data dir (platformdirs) when not run from a source checkout, so an installed wheel writes shot data to a real, writable location instead of a path under site-packages. $MAGNETICS_DATA_DIR still overrides. Drop inspect.py's dead default (pointed at a never-shipped shot file). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The packaged app serves the GUI and the API on one origin, but api.ts decided live-vs-mock from the build-time VITE_API_BASE truthiness, so a plain `vite build` (no env) shipped a MOCK-mode bundle — `run.sh --prod` and any pip-installed app silently served demo fixtures. Now: an explicit VITE_API_BASE still wins (trailing slashes trimmed); a production build with none defaults to "" (same-origin, relative /api/… URLs); the dev server stays in mock mode. Since "" is a valid live base, every live-vs-mock check switches from truthiness to an explicit LIVE flag, and QuasiStationaryTab's `!apiBase()` guard becomes `!usingLiveBackend()`. Verified with Playwright against the packaged app: badge "● live backend", same-origin /api/ requests, zero /mock/ hits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On a `v*` tag: build the GUI, stage it into the package, build sdist + wheel, assert the GUI and device data are bundled, smoke-test the wheel in a clean 3.12 venv (install, import, boot the launcher, curl the API and GUI), then publish via PyPI trusted publishing and cut a GitHub Release. `workflow_dispatch` runs build + smoke test only (no publish) for dry runs. docs/RELEASING.md covers the one-time trusted-publisher setup and the GitFlow-lite release procedure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A --data-dir flag sets MAGNETICS_DATA_DIR for the run, so non-developers can choose where shot data lands without touching env vars. On a cluster this points at scratch/project space instead of the quota'd home dir. The flag is applied before any code resolves h5source.data_dir(); toksearch's default output path is recomputed at fetch time (not from the import-time DATA_DIR) so a late override still takes effect. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document `uvx magnetics` / `pip install magnetics` + `magnetics` as the one-command install-and-run path, the --port/--no-browser/--data-dir flags, the magnetics-fetch/magnetics-service scripts, and where shot data is cached (incl. the cluster → MAGNETICS_DATA_DIR=scratch pattern). Keep the dev setup and point to docs/RELEASING.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
run.sh only ever ran the dev stack; rename it to run-dev.sh to make room for a distribution builder. scripts/build-dist.sh does the staging dance `uv build` can't: build the GUI, stage it into the package, build the sdist + wheel, verify the GUI/device data are bundled, and (with --smoke) install and boot the wheel in a clean 3.12 venv. The release workflow now calls build-dist.sh so local and CI builds can't drift. Fixes a SIGPIPE in the bundle-verify greps (`… | grep -q` under `set -o pipefail` aborted once grep matched) by capturing the listings first. Updates the run.sh references in the README, CLAUDE.md, and code comments. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a README section showing `uvx --from ./dist/*.whl magnetics` to try a freshly built wheel in a throwaway env that touches neither the repo's .venv nor its data/ dir, plus the --data-dir and --reinstall variants. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
FYI @logan-nc @ebursch this is the build pipeline newly set up. This enables the building of a wheel. The method for running this as an user will be |
Collaborator
|
awesome! thanks @matt-pharr ! |
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.
Closes #79.
Makes the app installable and runnable by non-developers:
uvx magnetics(orpip install magnetics && magnetics) starts the service and opens the bundled GUI in a browser — no Node or dev stack. The GUI ships inside the wheel.What's here
serviceextra, addmagnetics/magnetics-fetch/magnetics-serviceconsole scripts. Lowerrequires-pythonto>=3.12(.python-versionstays 3.14 for dev). CI now tests 3.12 and 3.14.exceptsites (except A, B:) that only compiled on 3.14 and would break every 3.12 install.magneticslauncher (src/magnetics/cli.py) — free-port pick, opens the browser once the server binds,--host/--port/--no-browser/--data-dir.data_dir()falls back to a persistent per-user dir (platformdirs) when not run from a source checkout, so an installed wheel writes shot data somewhere real and writable.$MAGNETICS_DATA_DIR/--data-diroverride (the knob for clusters → scratch).vite buildnow defaults to relative/api/…URLs, fixing the silently-mock--prod/wheel. Verified with Playwright (live badge, same-origin calls, zero/mock/hits).release.yml(build GUI → stage →uv build→ verify bundle → smoke-test the wheel → PyPI trusted-publish → GitHub Release).workflow_dispatch= build + smoke only. Docs indocs/RELEASING.md.run.sh→run-dev.sh(dev only); newscripts/build-dist.shdoes the GUI-stage-then-uv builddance (--smokeinstalls+boots the wheel). The release workflow calls this script so local and CI builds can't drift.Verification
ty, eslint, tsc, 41 vitest — all green.build-dist.sh --smoke):import magnetics, all 3 scripts installed, launched from a non-checkout dir →/api/machines200, GUI 200,data_dir()→ per-user dir (not site-packages).Follow-up for a maintainer (not in this PR)
The first PyPI publish needs the one-time trusted-publisher setup (project
magneticsis unclaimed) and thepypiGitHub environment — steps are indocs/RELEASING.md. Version bump + tag cuts the release.