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 filteringGET /whitebox/tool/{tool_id}– Retrieves parameter schema for a specific toolPOST /whitebox/run– Submits aWhiteboxRunRequestand returns a job IDGET /whitebox/job/{job_id}– Polls job state:queued,running,complete, orerrorGET /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 directoryGEOLIBRE_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:
- Local execution – The "Run locally" button attempts direct sidecar invocation through Tauri's command API
- Fallback behavior – If
whitebox_workflowsis missing, the UI displayswhitebox_start_errorand 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
/whiteboxfor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →