How the Whitebox Geoprocessing Toolbox Integrates via the GeoLibre Sidecar

GeoLibre's Whitebox integration runs as a Python FastAPI micro-service inside a sidecar process that exposes REST endpoints for tool discovery, job submission, and result retrieval.

GeoLibre connects the Whitebox geoprocessing engine to its React front-end through a Python FastAPI sidecar (backend/geolibre_server). This architecture keeps the computational heavy-lifting isolated from the UI while providing a clean, language-agnostic API surface. The sidecar is launched on demand by the desktop Tauri wrapper—or proxied in web builds—making the Whitebox toolbox available whether you're running locally or in a browser.

Sidecar Architecture and Startup

The sidecar architecture separates the geoprocessing runtime from the main application. When GeoLibre needs Whitebox capabilities, it spawns the sidecar with a specific command and registers the Whitebox router under a dedicated URL prefix.

Launching the Sidecar Server

GeoLibre starts the sidecar using uv with frozen project dependencies:

uv run --frozen --project backend/geolibre_server

The server binds to 127.0.0.1:8765 and includes the Whitebox router at /whitebox. This registration happens in the main application file:


# backend/geolibre_server/geolibre_server/app/main.py

from geolibre_server.app.whitebox import router as whitebox_router

app = FastAPI()
app.include_router(whitebox_router, prefix="/whitebox")

The include_router() call mounts all Whitebox endpoints under the /whitebox namespace, keeping the API organized and versionable.

Whitebox API Endpoints

The Whitebox router in backend/geolibre_server/geolibre_server/app/whitebox.py implements a complete job lifecycle through six core endpoints:

  • GET /whitebox/status – Returns runtime import status and timeout configuration (whitebox_status)
  • GET /whitebox/tools – Lists available tools with optional tier/source filtering
  • GET /whitebox/tool/{tool_id} – Retrieves parameter schema for a specific tool
  • POST /whitebox/run – Submits a WhiteboxRunRequest and returns a job ID
  • GET /whitebox/job/{job_id} – Polls job state: queued, running, complete, or error
  • GET /whitebox/output/{path} – Streams generated output files (GeoJSON, GeoParquet, etc.)

This REST pattern follows classic async job design: submit, poll, then fetch results.

Front-End Integration with ProcessingDialog

The React UI drives Whitebox processing through the ProcessingDialog component in apps/geolibre-desktop/src/components/processing/ProcessingDialog.tsx. The component orchestrates the full workflow through four sequential API calls.

Step 1: Verify Runtime Availability

async function fetchWhiteboxStatus() {
  const res = await fetch('/whitebox/status');
  if (!res.ok) throw new Error('Whitebox sidecar not reachable');
  return await res.json(); // {available: true, timeout_secs: 120}
}

The status check confirms whitebox is importable and reports timeout settings before presenting tools to the user.

Step 2: Populate Tool Selector

async function listWhiteboxTools() {
  const url = new URL('/whitebox/tools', window.location.origin);
  url.searchParams.set('tier', 'open'); // or 'pro'
  const res = await fetch(url);
  return (await res.json()) as WhiteboxTool[];
}

Tools are fetched with tier filtering, allowing GeoLibre to expose different capability sets based on licensing.

Step 3: Fetch Tool Parameters

When a user selects a tool, the dialog calls whitebox_tool(tool_id) to retrieve the complete parameter schema. This dynamic loading ensures the UI always matches the installed Whitebox version.

Step 4: Submit and Poll Jobs

interface WhiteboxRunRequest {
  tool_id: string;
  parameters: Record<string, unknown>;
}

async function runWhiteboxTool(req: WhiteboxRunRequest) {
  const res = await fetch('/whitebox/run', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(req),
  });
  const { job_id } = await res.json();
  
  // Poll until completion
  while (true) {
    const statusRes = await fetch(`/whitebox/job/${job_id}`);
    const { state, output } = await statusRes.json();
    if (state === 'complete') return output;
    if (state === 'error') throw new Error('Job failed');
    await new Promise(r => setTimeout(r, 1000));
  }
}

The polling loop handles long-running geoprocessing operations without blocking the UI thread.

Displaying Results

Once complete, output URLs are fetched from /whitebox/output/{path} and added as layers:

const outputs = await runWhiteboxTool({
  tool_id: 'Clip',
  parameters: { input: 'layer1', clip: 'layer2' }
});
outputs.forEach(url => addGeoJsonLayer({ url, name: 'Whitebox Clip' }));

Security and Job Isolation

The sidecar implements multiple safeguards in backend/geolibre_server/geolibre_server/app/whitebox.py:

  • _JOBS_LOCK – A thread lock that serializes job creation, preventing race conditions
  • _runtime_cache_root() – Isolates temporary files to a sandboxed directory
  • GEOLIBRE_CONVERSION_ROOTS – Restricts file path inputs to configured roots, blocking arbitrary file access

These protections are verified by tests/test_security.py, which validates that path traversal attempts are rejected.

Local vs. Remote Execution Modes

GeoLibre's UI adapts based on sidecar availability:

  1. Local execution – The "Run locally" button attempts direct sidecar invocation through Tauri's command API
  2. Fallback behavior – If whitebox_workflows is missing, the UI displays whitebox_start_error and can proxy to a remote processing service

This dual-mode design ensures the toolbox remains accessible across deployment targets.

Summary

  • The Whitebox toolbox runs as a self-contained FastAPI micro-service inside GeoLibre's Python sidecar
  • All communication uses REST endpoints under /whitebox for status, tools, jobs, and outputs
  • The ProcessingDialog component manages the complete workflow: verify → list → configure → submit → poll → display
  • Security controls include job locks, cache isolation, and path confinement via GEOLIBRE_CONVERSION_ROOTS
  • Execution modes support both localhost sidecar and remote fallbacks for flexible deployment

Frequently Asked Questions

What is a sidecar in GeoLibre's architecture?

A sidecar is a separate process running alongside the main application. In GeoLibre, the Python FastAPI sidecar (backend/geolibre_server) hosts the Whitebox geoprocessing engine. It launches on demand, binds to 127.0.0.1:8765, and exposes HTTP endpoints that the React front-end calls. This isolates Python dependencies from the desktop Tauri wrapper or browser environment.

How does the front-end know if Whitebox is available?

The ProcessingDialog calls GET /whitebox/status on component mount. This endpoint returns {available: true/false, timeout_secs: N} based on whether whitebox imports successfully. If unavailable, the UI hides Whitebox options or displays whitebox_start_error with troubleshooting guidance.

Can I use Whitebox tools in GeoLibre's web build?

Yes. The web build proxies sidecar requests to a remote processing service rather than spawning a local Python process. The same /whitebox/* endpoints are served, so the ProcessingDialog requires no code changes. The proxy configuration determines whether execution is local or remote.

What file formats does the Whitebox sidecar output?

The /whitebox/output/{path} endpoint streams generated files directly. Supported formats include GeoJSON, GeoParquet, and other Whitebox-native outputs. The format depends on the specific tool executed and its configured output parameters.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →