How to Write Custom Whitebox Geoprocessing Tools for the GeoLibre Python Sidecar

You can extend GeoLibre's Whitebox toolbox by writing Python functions that use the whitebox-workflows API, registering them as FastAPI endpoints in the sidecar, and adding metadata to the Whitebox catalog JSON.

GeoLibre ships with a WebAssembly (Wasm) implementation of the Whitebox geoprocessing toolbox for browser-based analysis, but heavy processing tasks require the full-featured Python sidecar. This FastAPI service, located in backend/geolibre_server, can execute custom Whitebox tools that you author yourself. Learning how to write custom Whitebox geoprocessing tools for the Python sidecar lets you add bespoke raster processing logic while maintaining full integration with the GeoLibre user interface.

Prerequisites

Before creating custom tools, ensure your development environment includes the Python sidecar and its dependencies.

  • Python sidecar: Set up the FastAPI server from backend/geolibre_server. Install dependencies with pip install -e . after creating a virtual environment.
  • Whitebox-Workflows: The sidecar automatically installs this package on first run, providing the Whitebox Python class and CLI bindings.
  • FastAPI knowledge: Familiarity with APIRouter and Pydantic models is helpful, as the sidecar uses these for the existing /whitebox/run and /whitebox/status endpoints.

Write the Custom Whitebox Tool

A custom tool is a Python function that accepts a WhiteboxJob payload and returns a WhiteboxStatus dictionary. The function should validate inputs, execute the processing logic via the whitebox-workflows API, and package the results for the UI.

Create a new module at backend/geolibre_server/geolibre_server/custom_whitebox.py:

from fastapi import HTTPException
from whitebox_workflows import Whitebox
from geolibre_server.types import WhiteboxJob, WhiteboxStatus

def run_my_custom_tool(job: WhiteboxJob) -> WhiteboxStatus:
    """
    Example custom Whitebox tool implementation.
    
    Parameters
    ----------
    job : WhiteboxJob
        Contains input raster path (`job.input`), output path (`job.output`),
        and UI parameters (`job.params`).
        
    Returns
    -------
    WhiteboxStatus
        Dictionary with keys `output`, `log`, and `duration`.
    """
    if not job.input:
        raise HTTPException(status_code=400, detail="Missing input raster")
    
    factor = float(job.params.get("factor", 1.0))
    
    try:
        result = Whitebox.run(
            tool="my_custom_tool",
            input_raster=job.input,
            output_raster=job.output,
            factor=factor,
        )
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc))
    
    return {
        "output": job.output,
        "log": result.stdout,
        "duration": result.elapsed,
    }

The tool name (my_custom_tool in the example above) must match the entry you will add to the Whitebox catalog. The function receives the same WhiteboxJob model that the UI sends when users click Run, and it must return a dictionary conforming to the WhiteboxStatus schema.

Register the Endpoint in the FastAPI Router

Expose your function through the sidecar's existing Whitebox router in geolibre_server/app/whitebox.py. Add a dedicated route that forwards requests to your custom implementation:

from fastapi import APIRouter, Depends
from .custom_whitebox import run_my_custom_tool
from ..types import WhiteboxJob

router = APIRouter()

@router.post("/run/my_custom_tool")
async def run_my_custom_tool_endpoint(job: WhiteboxJob = Depends()):
    """Execute the custom Whitebox tool via the Python sidecar."""
    return run_my_custom_tool(job)

Using a dedicated path like /run/my_custom_tool keeps the sidecar's OpenAPI documentation tidy and simplifies routing logic compared to the generic /run endpoint that accepts a tool_id parameter.

Add the Tool to the Whitebox Catalog

The GeoLibre UI populates the toolbox from a JSON catalog snapshot. To make your tool visible, add its metadata to backend/geolibre_server/geolibre_server/whitebox_catalog.json:

[
  {
    "id": "my_custom_tool",
    "name": "My Custom Tool",
    "category": "Custom",
    "description": "User-defined raster processor with scale factor.",
    "parameters": [
      {
        "name": "factor",
        "type": "float",
        "default": 1.0,
        "description": "Scale factor for raster values."
      }
    ]
  }
]

After updating the JSON file, regenerate the TypeScript menu catalog used by the UI:

node scripts/gen-whitebox-menu-catalog.mjs

This script outputs to apps/geolibre-desktop/src/lib/whitebox-menu-catalog.ts, which the UI imports to build the toolbox menu. According to the source code in packages/processing/src/wasm-client.ts (lines 172-180), the sidecar merges this catalog with Wasm-only tools at runtime.

Test the Custom Tool

Start the sidecar to validate your implementation:

cd backend/geolibre_server
uvicorn geolibre_server.app.main:app --reload

Send a test request using curl or any HTTP client:

curl -X POST http://127.0.0.1:8765/whitebox/run/my_custom_tool \
     -H "Content-Type: application/json" \
     -d '{"input":"/data/input.tif","output":"/tmp/out.tif","params":{"factor":2.5}}'

Expect a JSON response containing output, log, and duration fields. Open GeoLibre Desktop, navigate to Processing → Whitebox, and verify that My Custom Tool appears under the Custom category. Running it on a raster should display results on the map and populate the processing dialog with logs.

Advanced Configuration

Consider these enhancements when deploying custom tools to production:

  • Parameter validation: Use Pydantic models for complex parameter structures, leveraging the sidecar's existing type system.
  • Multiple outputs: Return a list of raster paths in the output field; the UI will add each as a separate layer.
  • Streaming logs: The sidecar supports Server-Sent Events for real-time log streaming. See fetchWhiteboxJob in packages/processing/src/sidecar-client.ts for implementation details.
  • Unit testing: Mock Whitebox.run in backend/geolibre_server/tests/test_custom_whitebox.py to test logic without heavy raster I/O.

Summary

Writing custom Whitebox geoprocessing tools for the GeoLibre Python sidecar involves four key steps:

  • Implement the processing logic in a Python module using the whitebox-workflows API and WhiteboxJob types.
  • Register a FastAPI endpoint in the sidecar router to expose the function via HTTP POST.
  • Catalog the tool by adding metadata to the JSON manifest and regenerating the TypeScript menu file.
  • Test the endpoint locally before committing changes to the repository.

This workflow allows you to extend the Whitebox toolbox with domain-specific raster operations while maintaining seamless integration with the GeoLibre user interface.

Frequently Asked Questions

What is the Python sidecar in GeoLibre?

The Python sidecar is a FastAPI service located in backend/geolibre_server that provides heavy-duty geoprocessing capabilities beyond what the browser-based WebAssembly implementation can handle. It runs the whitebox-workflows package and other Python dependencies, exposing them through REST endpoints that the GeoLibre desktop and web applications consume.

Do custom tools work in the browser?

Custom tools written for the Python sidecar require the sidecar to be running, as they execute Python code and potentially call underlying C++ binaries. They do not run in the browser's Wasm sandbox. However, the GeoLibre UI treats them identically to built-in tools once they are registered in the catalog, providing a seamless experience for end users.

How do I validate parameters for my custom tool?

Validate parameters using Pydantic models or manual checks at the start of your function. The WhiteboxJob model passed from the UI includes a params dictionary containing user inputs. Raise HTTPException with appropriate status codes (such as 400 for bad input or 500 for processing errors) to communicate failures to the client, which will display them in the processing dialog.

Can I stream logs while the tool runs?

Yes. While the basic implementation returns logs after completion, the sidecar supports streaming Whitebox stdout line-by-line via Server-Sent Events. Implement this by modifying the client-side code in packages/processing/src/sidecar-client.ts to handle streaming responses from your endpoint, allowing users to see progress updates in real time.

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 →