fix(upgrade): use uv tool upgrade for launcher (pip-less) installs#327
Merged
Conversation
The inline self-upgrade endpoint hardcoded
`python -m pip install --upgrade photomapai`. The desktop launcher
installs PhotoMapAI via `uv tool install`, which produces a deliberately
pip-less environment, so `POST /version/update` failed there with a 500
and `No module named pip` — i.e. inline upgrade was broken for every
launcher install (the primary distribution path; the uv launcher first
shipped in v1.0.6rc1 and has never been in a stable release).
Choose the upgrade command by install type instead:
- pip importable (dev venv, legacy installer scripts) -> keep
`python -m pip install --upgrade photomapai`
- pip absent (uv tool install) -> locate `uv` (PATH, then the
`~/.local/bin` location uv self-installs to) and run
`uv tool upgrade photomapai`
- pip absent and no `uv` -> 500 with actionable guidance ("re-run the
launcher with --reinstall") instead of the cryptic pip error
Branches on whether pip actually imports rather than sniffing install
paths, since that is the exact condition that made the old command fail.
Restart is unchanged — the supervisor already respawns the worker after
an upgrade.
Adds tests/backend/test_upgrade.py covering command selection for both
install types, the unavailable case, the X-Requested-With guard, and the
subprocess-failure / timeout paths.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document that #327 fixes the About -> Update button for launcher (pip-less) installs, and tell 1.0.6rc1 launcher testers to re-run the launcher with --reinstall if their in-app Update fails with 'No module named pip'. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mmit) The previous commit landed tests/backend/test_upgrade.py but the corresponding changes to upgrade.py were not committed, so the tests referenced a non-existent `_pip_available` and CI failed across the matrix with AttributeError. This adds the actual implementation: `_pip_available`, `_find_uv`, `_build_upgrade_command`, and `UpgradeUnavailableError`, and switches `update_version` to choose pip vs `uv tool upgrade` by install type. Also drops a header-rejection test that duplicates test_upgrade_router.py. Verified against a non-editable install (mirroring CI): both test_upgrade.py and test_upgrade_router.py pass; ruff clean. Co-Authored-By: Claude Opus 4.8 (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.
Problem
Clicking Update in the About dialog returns a 500 on
POST /version/updatefor launcher installs, with:{"success": false, "message": "Update failed", "error": ".../uv/tools/photomapai/bin/python3: No module named pip\n"}The endpoint hardcoded
python -m pip install --upgrade photomapai, but the desktop launcher installs viauv tool install(launcher/uv.go), which produces a deliberately pip-less environment. So inline upgrade was broken for every launcher install — the primary distribution path. It only worked in pip-based installs (dev.venv, legacy installer scripts).The
X-Requested-With403 some may hit is unrelated — that's the CSRF guard firing only from Swagger's "Try it out" (which omits the header); the realabout.jssends it.Fix
Choose the upgrade command by install type, branching on whether pip actually imports (the exact failure condition) rather than sniffing install paths:
python -m pip install --upgrade photomapai(unchanged)uv(PATH, then the~/.local/binlocation uv self-installs to) →uv tool upgrade photomapaiuv→ 500 with actionable guidance ("re-run the launcher with--reinstall") instead of the cryptic pip errorRestart is unchanged — the supervisor (
photomap_server.py:167) already respawns the worker after an upgrade, so new code loads.Tests
New
tests/backend/test_upgrade.py(9 tests): command selection for both install types, the unavailable case, theX-Requested-Withguard, and the subprocess-failure / timeout paths.ruffclean.Release / "breaking change" note
The uv launcher first shipped in v1.0.6rc1 and has never been in a stable release. Landing this in 1.1.0 (first stable with the launcher) means no public breaking change:
--reinstallThe already-running rc1 code can't be fixed remotely (the pip command is baked in), but that group is small/known and the re-run-launcher recovery needs no uv knowledge. Worth a one-line mention in the 1.1.0 release notes.
🤖 Generated with Claude Code