# How the GeoLibre Desktop App Launches the Python Sidecar Using uv and Handles Permissions

> Discover how the GeoLibre desktop app uses Rust Tauri and uv to launch its Python FastAPI sidecar and manage crucial filesystem permissions and port conflicts.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: internals
- Published: 2026-08-05

---

**The GeoLibre desktop app uses a Rust-powered Tauri backend to bootstrap a dedicated uv environment, sync dependencies from a bundled `uv.lock`, and launch a FastAPI sidecar via `uv run`, with explicit error handling for filesystem permissions and port conflicts.**

The GeoLibre desktop application delivers geospatial processing capabilities by pairing a Rust-based Tauri frontend with a Python sidecar server built on FastAPI and uvicorn. This architecture requires careful orchestration of the Python runtime, dependency management, and permission boundaries. According to the GeoLibre source code, the app achieves this through a managed uv workflow that isolates the sidecar environment, reproduces builds deterministically, and surfaces user-friendly errors when permissions fail.

## Architecture Overview: The uv-Based Sidecar Pattern

The GeoLibre desktop app ships with a Python backend located in `backend/geolibre_server/`. Rather than relying on system Python or user-installed packages, the Tauri backend creates and manages its own uv environment per installation. This pattern ensures **reproducible builds** and **zero dependency on the host Python configuration**.

Key files in this architecture:

- [`apps/geolibre-desktop/src-tauri/src/lib.rs`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src-tauri/src/lib.rs) — Core Rust backend containing `ensure_managed_uv` and sidecar orchestration
- [`backend/geolibre_server/app/main.py`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/app/main.py) — FastAPI/uvicorn entry point
- `backend/geolibre_server/uv.lock` — Frozen dependency lock bundled with the app
- [`docs/architecture.md`](https://github.com/opengeos/GeoLibre/blob/main/docs/architecture.md) — Reverse-proxy routing to `/sidecar`

## Step 1: Creating the Managed uv Environment with `ensure_managed_uv`

The entry point for sidecar initialization is the `ensure_managed_uv` function in the Tauri backend. This function establishes a **token-gated uv project environment** that remains isolated from both the FastAPI sidecar's runtime environment and any user Python installations.

As noted in the source comments around line 126-131 of [`src/lib.rs`](https://github.com/opengeos/GeoLibre/blob/main/src/lib.rs), this creates:

> "a token‑gated, managed uv project environment"

The function performs several critical checks:

1. **Verify or create the uv cache directory** — typically under the application data folder
2. **Download the uv installer** if the binary is missing, using official distribution channels
3. **Validate the installation** and return a path to the uv executable for subsequent commands

The implementation handles network failures, checksum validation, and platform-specific binary selection (Windows, macOS, Linux) during this bootstrap phase.

## Step 2: Synchronizing Dependencies with `uv sync`

With uv available, the app proceeds to install the sidecar's Python dependencies. The command executed is effectively:

```bash
uv sync --frozen --no-cache

```

This operation:

- Reads the **bundled `uv.lock`** file that ships with the application installer
- Creates a virtual environment in the managed uv directory
- Installs FastAPI, uvicorn, WhiteboxTools, JupyterLab, and all transitive dependencies

The `--frozen` flag ensures exact reproduction of the lock file, while `--no-cache` prevents pollution from the user's global uv cache. As noted in source comments around line 2162, this **cold-cache `uv sync`** can be slow on first run but guarantees consistency.

Permission errors during this phase most commonly occur when:

- The application is installed to a **read-only system directory** (e.g., `/usr/lib/` on Linux)
- Antivirus or enterprise policies block binary execution in the cache location
- User account permissions prevent write access to the application data folder

## Step 3: Launching the Sidecar with `uv run`

After successful synchronization, the desktop app spawns the Python sidecar using `uv run` rather than direct Python execution. This design choice provides **interpreter isolation** and **deterministic environment selection**.

The invocation follows this pattern:

```bash
uv run -q -p <python-executable> -m uvicorn geolibre_server.app.main:app --host 127.0.0.1 --port 8765

```

Key flags and their purposes:

| Flag | Purpose |
|------|---------|
| `-q` | Quiet mode suppressing uv's output |
| `-p` | Explicit Python interpreter path selected by uv |
| `-m uvicorn` | Module execution of the ASGI server |

Source comments around line 2672 explicitly note that the implementation **does not inherit `PYTHONHOME`** from the host environment. This prevents:

- Host Python packages from leaking into the sidecar
- Virtual environment activation scripts from interfering
- Version conflicts with system site-packages

## Permission Error Handling Throughout the Lifecycle

The GeoLibre backend implements structured error handling at each stage of the uv workflow. The source code specifically addresses **filesystem permission errors** and **runtime binding conflicts**.

### Lock File Permission Denied

Around line 2124, comments indicate handling for scenarios where uv cannot write its lock file:

> "reading bundled uv.lock and permission denied"

When the sidecar runs from a read-only installation directory, uv's attempt to update or verify the lock file triggers a permission error. The Rust wrapper catches this condition and surfaces a message directing users to either:

- Reinstall to a user-writable location (e.g., `~/Applications` on macOS, `%LOCALAPPDATA%` on Windows)
- Run with elevated permissions if system-wide installation is required

### Port Binding Conflicts

If the uvicorn server cannot bind to port 8765, the child process exit code is captured and transformed from a raw traceback into actionable guidance. Users receive notification that the port is in use rather than a Python stack trace.

### Command Spawning Failures

The `Command::new(&uv).spawn()` pattern shown around line 1892 includes comprehensive error mapping:

```rust
.spawn()
.map_err(|e| format!("Failed to start sidecar: {e}"))?;

```

This ensures that **uv binary not found**, **exec permission denied**, or **resource limit exceeded** errors all produce intelligible messages in the application's logging interface.

## Configuration and User Control

Users can influence sidecar behavior through environment variables documented in [`docs/user-guide/projects.md`](https://github.com/opengeos/GeoLibre/blob/main/docs/user-guide/projects.md):

| Variable | Effect |
|----------|--------|
| `GEOLIBRE_DISABLE_SIDECAR=1` | Completely skip sidecar launch; desktop operates in limited mode |
| `GEOLIBRE_SIDECAR_PORT` | Override the default 8765 port |
| `GEOLIBRE_UV_CACHE` | Specify an alternative uv cache directory |

These options provide escape hatches when default permission handling or port selection fails in restricted environments.

## Summary

- **`ensure_managed_uv`** creates an isolated, token-gated uv project environment separate from host Python
- **`uv sync --frozen`** reproduces exact dependencies from the bundled `uv.lock` without cache pollution
- **`uv run`** launches uvicorn with explicit interpreter selection and no `PYTHONHOME` inheritance
- **Permission errors** at lock file, cache, and port binding stages are caught and converted to user-friendly messages
- **Configuration options** allow users to bypass or customize when defaults fail

## Frequently Asked Questions

### How does GeoLibre handle uv installation if the binary is missing?

The `ensure_managed_uv` function downloads the official uv installer for the current platform, verifies its integrity, and caches it in the application data directory. This occurs automatically on first launch without user intervention, provided network access and write permissions are available.

### What causes "permission denied" errors when starting the sidecar?

These typically stem from installing GeoLibre to system-protected directories like `/usr/lib/` or `C:\Program Files\` where uv cannot write its cache or lock files. The solution is reinstalling to a user-writable location or adjusting directory permissions.

### Why does GeoLibre use `uv run` instead of activating a virtual environment?

`uv run` provides deterministic interpreter selection without relying on shell activation scripts or inherited environment variables. The explicit `-p` flag and `PYTHONHOME` exclusion guarantee the sidecar runs exactly the Python version and packages managed by uv, eliminating host environment interference.

### Can I use my own Python installation with GeoLibre's sidecar?

The desktop app is designed around its managed uv environment for reproducibility. While advanced users could theoretically substitute their own interpreter, this voids consistency guarantees and is not supported through official configuration options.