Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)(會自動開啟),並依照畫面提示建立你的第一個相簿。
Expand Down
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 6 additions & 3 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
4 changes: 2 additions & 2 deletions docs/installation/cuda.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
9 changes: 9 additions & 0 deletions launcher/uv.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
29 changes: 29 additions & 0 deletions launcher/uv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading