diff --git a/README.md b/README.md index 9843dc89..8dd6804f 100644 --- a/README.md +++ b/README.md @@ -86,8 +86,9 @@ For PyPI, Docker, and manual install instructions, see the [Installation guide]( If you already have Python 3.10–3.14 and prefer the command line: ```bash -uv tool install photomapai --torch-backend auto # or: pip install photomapai +uv tool install photomapai --python 3.12 --python-preference only-managed --torch-backend auto start_photomap +# (or simply: pip install photomapai && start_photomap) ``` Then open your browser to [http://127.0.0.1:8050](http://127.0.0.1:8050) (it opens automatically) and follow the prompts to create your first album. diff --git a/README.zh-TW.md b/README.zh-TW.md index e5872a85..42426ba7 100644 --- a/README.zh-TW.md +++ b/README.zh-TW.md @@ -101,8 +101,9 @@ PhotoMapAI 也支援多相簿管理、依時間瀏覽照片、簡潔的全螢幕 如果你已經安裝 Python 3.10–3.14,並偏好使用命令列: ```bash -uv tool install photomapai --torch-backend auto # 或:pip install photomapai +uv tool install photomapai --python 3.12 --python-preference only-managed --torch-backend auto start_photomap +# (或改用 pip:pip install photomapai && start_photomap) ``` 接著開啟瀏覽器,前往 [http://127.0.0.1:8050](http://127.0.0.1:8050)(會自動開啟),並依照畫面提示建立你的第一個相簿。 diff --git a/docs/index.md b/docs/index.md index 53917424..f67ddad8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -90,8 +90,9 @@ See the [Installation guide](installation.md) for PyPI, Docker, source, GPU over If you already have Python 3.10–3.14: ```bash -uv tool install photomapai --torch-backend auto # or: pip install photomapai +uv tool install photomapai --python 3.12 --python-preference only-managed --torch-backend auto start_photomap +# (or simply: pip install photomapai && start_photomap) ``` After the startup messages your browser opens to http://localhost:8050 automatically. diff --git a/docs/installation.md b/docs/installation.md index 16f7245f..bac2ee36 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -74,11 +74,14 @@ To also remove the downloaded Python/libraries, run `photomap --uninstall` (path If you are comfortable with the command line and already have Python 3.10–3.14, you can install the package directly. We recommend [uv](https://docs.astral.sh/uv/): ```bash -uv tool install photomapai --torch-backend auto +uv tool install photomapai --python 3.12 --python-preference only-managed --torch-backend auto start_photomap ``` -`--torch-backend auto` picks GPU or CPU PyTorch automatically. Or with plain `pip` in a virtual environment: +`--torch-backend auto` picks GPU or CPU PyTorch automatically. `--python 3.12 +--python-preference only-managed` tells `uv` to use its own managed Python build +rather than a system one; on macOS this avoids a pop-up that asks to install the +Xcode command-line tools. Or with plain `pip` in a virtual environment: ```bash python -m venv photomap --prompt photomap @@ -128,4 +131,4 @@ start_photomap Both create an isolated virtual environment in `./.venv`; the difference is only which tool builds it. If you intend to *modify* the source, add `-e` to do an editable install (`uv pip install -e .` or `pip install -e .`) — but then the environment is tied to this folder's location, so don't move or rename it afterwards. -GPU acceleration needs only a recent **NVIDIA driver** — *not* the CUDA Toolkit (see [NVIDIA GPU Acceleration](installation/cuda.md)). On Linux and macOS the default `pip install .` already pulls a GPU-capable build of PyTorch, so there's nothing extra to do. On Windows the default PyTorch from PyPI is CPU-only; to enable the GPU, install the CUDA build of PyTorch from PyTorch's [official index](https://pytorch.org/get-started/locally/), or use the `uv tool install photomapai --torch-backend auto` recipe above, which selects the right build automatically. To start the server again later, re-run `start_photomap` from the activated environment. +GPU acceleration needs only a recent **NVIDIA driver** — *not* the CUDA Toolkit (see [NVIDIA GPU Acceleration](installation/cuda.md)). On Linux and macOS the default `pip install .` already pulls a GPU-capable build of PyTorch, so there's nothing extra to do. On Windows the default PyTorch from PyPI is CPU-only; to enable the GPU, install the CUDA build of PyTorch from PyTorch's [official index](https://pytorch.org/get-started/locally/), or use the `uv tool install` recipe above, which selects the right build automatically. To start the server again later, re-run `start_photomap` from the activated environment. diff --git a/docs/installation/cuda.md b/docs/installation/cuda.md index c09c363d..1e596fa2 100644 --- a/docs/installation/cuda.md +++ b/docs/installation/cuda.md @@ -89,8 +89,8 @@ installs the *driver*, not the CUDA Toolkit. (or want to force a re-detect), launch with the `--gpu` flag — see [GPU acceleration](../installation.md#gpu-acceleration) in the main installation guide. -- **PyPI / `uv`:** `uv tool install photomapai --torch-backend auto` picks the GPU - or CPU build of PyTorch automatically based on what `nvidia-smi` reports. +- **PyPI / `uv`:** `uv tool install photomapai --python 3.12 --python-preference only-managed --torch-backend auto` + picks the GPU or CPU build of PyTorch automatically based on what `nvidia-smi` reports. To confirm GPU support is active, watch for a console message about GPU acceleration when PhotoMapAI starts up. diff --git a/launcher/uv.go b/launcher/uv.go index 01dd1549..d7fdbab8 100644 --- a/launcher/uv.go +++ b/launcher/uv.go @@ -45,6 +45,15 @@ func (l layout) uvEnv() []string { "UV_CACHE_DIR="+l.cacheDir, // Don't let a managed-Python download be disabled by inherited config. "UV_PYTHON_DOWNLOADS=automatic", + // Only ever use uv's managed (python-build-standalone) interpreters, + // never a system/framework CPython. uv's default preference ("managed") + // will still fall back to a system interpreter if it finds a matching + // version — on macOS that's the non-relocatable python.org framework + // build at /Library/Frameworks/Python.framework. Building a venv from it + // makes uv rewrite Mach-O load paths with `install_name_tool`, which + // triggers the Xcode Command Line Tools install prompt. Managed builds + // are relocatable, so forcing only-managed avoids that prompt entirely. + "UV_PYTHON_PREFERENCE=only-managed", ) return env } diff --git a/launcher/uv_test.go b/launcher/uv_test.go index a1851a97..e591cf34 100644 --- a/launcher/uv_test.go +++ b/launcher/uv_test.go @@ -51,6 +51,35 @@ func TestMarkerRoundTrip(t *testing.T) { } } +func TestUVEnvForcesManagedPython(t *testing.T) { + l := layout{ + pythonDir: "/tmp/pm/python", + toolDir: "/tmp/pm/tools", + toolBin: "/tmp/pm/bin", + cacheDir: "/tmp/pm/cache", + } + want := map[string]string{ + "UV_PYTHON_INSTALL_DIR": l.pythonDir, + "UV_TOOL_DIR": l.toolDir, + "UV_TOOL_BIN_DIR": l.toolBin, + "UV_CACHE_DIR": l.cacheDir, + // only-managed keeps uv off the non-relocatable macOS framework Python, + // which would otherwise trigger the Xcode install_name_tool prompt. + "UV_PYTHON_PREFERENCE": "only-managed", + } + got := map[string]string{} + for _, kv := range l.uvEnv() { + if k, v, ok := strings.Cut(kv, "="); ok { + got[k] = v + } + } + for k, v := range want { + if got[k] != v { + t.Errorf("uvEnv()[%q] = %q, want %q", k, got[k], v) + } + } +} + // TestDownloadUVIntegration exercises the download + archive-extraction + exec // path against the real uv release (~30 MB, no torch). Skipped with -short. func TestDownloadUVIntegration(t *testing.T) {