GeoLibre Python Sidecar (FastAPI) Architecture: A Complete Guide to Geoprocessing Tools and Implementation

The GeoLibre Python sidecar is an optional FastAPI server running on 127.0.0.1:8765 that hosts heavyweight geoprocessing libraries—WhiteboxTools, GDAL/Rasterio, GeoPandas, Apache Sedona, and SamGeo—behind a secure, token-gated API with asynchronous job queuing.

The GeoLibre Python sidecar bridges the gap between browser-based GIS workflows and computationally demanding geoprocessing tasks. According to the opengeos/GeoLibre source code, this FastAPI application runs locally as a trusted companion to the desktop client, executing operations that cannot safely run inside the Tauri sandbox or browser environment. This guide examines its architecture, security model, router organization, managed runtime system, and the complete set of geoprocessing tools it exposes.

FastAPI Application Structure and Entry Point

The sidecar's foundation lives in geolibre_server/app/main.py, where the FastAPI instance is created and configured with modular routers for each tool category.


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

app = FastAPI(title="GeoLibre Server", version="0.8.0")
app.include_router(whitebox_router)
app.include_router(conversion_router)
app.include_router(raster_router)
app.include_router(vector_router)
app.include_router(postgis_router)
app.include_router(sql_router)
app.include_router(ml_router)

This router-based organization keeps each geoprocessing domain isolated and testable. The application follows standard FastAPI patterns: Pydantic models for request validation, dependency injection for shared services, and explicit path prefixes for API versioning.

Security Architecture and Request Gating

The GeoLibre sidecar implements defense-in-depth for a local service that handles file system paths and subprocess execution.

Security Layer Implementation Source Location
Per-launch token authentication Desktop shell generates GEOLIBRE_SIDECAR_TOKEN; middleware validates X-GeoLibre-Token or Authorization: Bearer headers; exempted only when unset for local testing main.py lines 37–84
Trusted host validation TrustedHostMiddleware restricts to loopback addresses (localhost, 127.0.0.1, testserver) main.py lines 87–97
CORS policy Limited to Vite dev server (:5173) and Tauri webview origins; credentials disallowed main.py lines 98–110
Health endpoint exemption /health skips token checks for readiness probes via _TOKEN_EXEMPT_PATHS main.py line 53

The token middleware aggressively rejects requests from unexpected origins, mitigating DNS rebinding attacks against local services. As implemented in opengeos/GeoLibre, the environment variable escape hatch (GEOLIBRE_SIDECAR_TOKEN unset) exists solely for pytest automation, not production deployments.

Router Modules and Geoprocessing Tool Groups

Each router encapsulates a specific geoprocessing domain. The GeoLibre sidecar provides seven primary tool groups:

WhiteboxRouter (/whitebox)

WhiteboxTools integration via geolibre_server/app/whitebox.py. This router wraps the WhiteboxTools CLI, automatically bootstrapping a managed virtual environment on first use. Heavy geomorphometric and hydrologic analyses execute in isolated subprocesses with streaming output capture.

ConversionRouter (/conversion)

The most complex router, implemented in geolibre_server/app/conversion.py, handles format conversion across the geospatial stack:

  • Vector → GeoParquet (Hilbert-sorted for spatial performance)
  • Vector → FlatGeobuf
  • Vector → PMTiles (via freestiler)
  • CSV (lon/lat) → GeoParquet
  • Raster → Cloud-Optimized GeoTIFF

This router implements uv-managed runtime bootstrapping, job queuing, and persistent result storage.

RasterRouter (/raster)

Lightweight wrapper in geolibre_server/app/raster.py for rio-cogeo Cloud-Optimized GeoTIFF generation. Delegates to the conversion runtime for actual execution.

VectorRouter (/vector)

Placeholder utilities in geolibre_server/app/vector.py: bounding box extraction, buffer operations, and reprojection. Future iterations will integrate full GDAL/GeoPandas workflows.

PostGISRouter (/postgis)

Remote PostGIS connection management with strict host whitelisting via GEOLIBRE_POSTGIS_HOSTS. See geolibre_server/app/postgis.py for connection registration and status monitoring.

SQLRouter (/sql) — Apache Sedona Integration

Apache Sedona spatial SQL via the Rust SedonaDB engine. The geolibre_server/app/sql.py router exposes:

  • GET /sql/status — Engine availability probe
  • POST /sql/run — Execute spatial SQL over registered layers

MLRouter (/ml) — SamGeo Proxy

Reverse-proxy design in geolibre_server/app/ml.py. The sidecar never loads PyTorch; instead, it forwards requests to an external SamGeo server running the Segment Anything Model 3. This architecture keeps the sidecar lightweight while enabling AI-powered segmentation.

Managed Runtime System with uv

The conversion and raster tools require heavy native dependencies (DuckDB, rio-cogeo, freestiler) that cannot bloat the base sidecar installation. The GeoLibre sidecar solves this with an on-demand virtual environment managed by uv.

Bootstrap Flow

  1. Interpreter resolution — GEOLIBRE_CONVERSION_PYTHON environment variable takes precedence; otherwise _ensure_managed_runtime() creates a venv under ~/.cache/geolibre/conversion-runtime

  2. Package installation — _run_runtime_setup_command installs locked dependency versions

  3. Verification and caching — _check_runtime_import validates imports; path cached in _CHECKED_RUNTIME_PYTHON

All runtime management functions reside in conversion.py lines 461–735: _runtime_python, _ensure_managed_runtime, and _check_runtime_import.

This design ensures native wheels download once, remain isolated from the sidecar process, and can be rebuilt independently when dependency versions change.

Asynchronous Job Queue Architecture

Conversion and raster operations are long-running and CPU-bound. The GeoLibre sidecar implements a lightweight async job system without external message queues.

Job Lifecycle


# Simplified flow from conversion.py

def submit_conversion(request: ConversionRequest) -> JobState:
    job_id = str(uuid.uuid4())
    state = JobState(id=job_id, status="pending", ...)
    _JOBS[job_id] = state
    
    threading.Thread(
        target=_run_conversion_job,
        args=(job_id, request),
        daemon=True
    ).start()
    return state

The background thread:

  1. Spawns the managed runtime subprocess
  2. Streams stdout for progress messages
  3. Parses __GEOLIBRE_CONVERSION_RESULT__ or __GEOLIBRE_CONVERSION_ERROR__ markers
  4. Updates _JOBS[job_id] with status, messages, and final result

Memory is bounded via MAX_RETAINED_JOBS = 100; completed jobs evict oldest entries first.

Polling-Based Client Interaction

Clients poll /conversion/jobs/{job_id} for state transitions:

curl http://127.0.0.1:8765/conversion/jobs/$JOB_ID \
  -H "X-GeoLibre-Token: $GEOLIBRE_SIDECAR_TOKEN"

Response schema includes status (pending|running|succeeded|failed), messages (progress log), and result (final output metadata on completion).

Optional Dependencies and Extras Installation

The sidecar's pyproject.toml defines modular extras for selective capability enablement:

[project.optional-dependencies]
conversion = ["duckdb>=1.1.0", "rio-cogeo>=5.0.0", "freestiler>=0.1.0", ...]
vector = ["geopandas", "shapely"]
raster = ["rasterio"]
sedona = ["apache-sedona[db]"]
ml = ["samgeo-api"]  # client-only; model server external

whitebox = ["whitebox-workflows"]

Install patterns:


# Core sidecar only

pip install -e .

# With conversion tools

pip install -e ".[conversion]"

# Full geoprocessing stack

pip install -e ".[conversion,vector,raster,sedona,whitebox]"

Router endpoints dynamically respond to availability; the UI queries /conversion/status, /sql/status, and /ml/status to enable or disable features.

Complete Endpoint Reference

Method Path Description Router
GET /health Service readiness Core
GET /algorithms Placeholder algorithm registry Core
POST /shutdown Graceful termination Core
GET /conversion/status Runtime availability Conversion
POST /conversion/vector-to-geoparquet Shapefile/GeoJSON → GeoParquet Conversion
POST /conversion/vector-to-flatgeobuf ZIP shapefile → FlatGeobuf Conversion
POST /conversion/csv-to-geoparquet CSV with lon/lat → GeoParquet Conversion
POST /conversion/vector-to-pmtiles Vector → PMTiles via freestiler Conversion
POST /conversion/raster-to-cog GeoTIFF → Cloud-Optimized GeoTIFF Conversion
GET/POST /conversion/jobs/{id} Job status polling and control Conversion
GET /whitebox/status WhiteboxTools runtime check Whitebox
POST /whitebox/run Execute WhiteboxTools command Whitebox
GET /raster/status rio-cogeo availability Raster
POST /raster/to-cog Raster COG conversion Raster
GET /postgis/status Connection pool health PostGIS
POST /postgis/connect Register whitelisted PostGIS server PostGIS
GET /sql/status SedonaDB engine availability SQL
POST /sql/run Execute spatial SQL SQL
GET /ml/status SamGeo proxy reachability ML
POST /ml/segment/* SAM 3 segmentation endpoints ML

Typical Usage Flow

  1. Desktop launcher spawns geolibre-server with GEOLIBRE_SIDECAR_TOKEN set; binds to 127.0.0.1:8765

  2. Health probe — UI polls /health until {"status":"ok"}

  3. Capability detection — Parallel queries to /*/status endpoints determine enabled features

  4. Job submission — POST to conversion endpoint returns job_id immediately; work continues in background thread

  5. Progress monitoring — Client polls /conversion/jobs/{id} at interval, updating UI with messages array

  6. Result retrieval — On status: succeeded, client reads result.output_path for generated file location

  7. Cleanup — Desktop app calls POST /shutdown on exit; sidecar terminates cleanly

Summary

  • The GeoLibre Python sidecar is a FastAPI application providing secure, local access to heavyweight geoprocessing libraries that cannot run in browser or Tauri contexts

  • Security layers include per-launch token authentication, trusted host validation, and restricted CORS—implemented in main.py lines 37–110

  • Seven router modules organize tools by domain: WhiteboxTools, conversion, raster, vector, PostGIS, Apache Sedona SQL, and SamGeo ML proxy

  • uv-managed runtimes isolate heavy dependencies (DuckDB, rio-cogeo, freestiler) in cached virtual environments, bootstrapped on demand via conversion.py

  • Asynchronous job execution uses in-memory state with background threads, bounded retention, and polling-based client interaction

  • Optional extras in pyproject.toml enable selective installation; routers degrade gracefully when dependencies are absent

Frequently Asked Questions

What is the default port for the GeoLibre Python sidecar?

The sidecar binds to 127.0.0.1:8765 by default. This loopback-only binding, combined with TrustedHostMiddleware, prevents external network access. The port is not currently configurable without source modification.

Why does the sidecar use a reverse proxy for SamGeo instead of loading PyTorch directly?

The ML router in geolibre_server/app/ml.py forwards requests to an external SamGeo server to keep the sidecar memory footprint small and startup time fast. Loading PyTorch and the SAM 3 model would add gigabytes to the runtime and complicate cross-platform distribution. This architecture lets the SamGeo server run on GPU hardware while the sidecar remains CPU-only.

How does the conversion job queue handle failures and retries?

Failed jobs capture __GEOLIBRE_CONVERSION_ERROR__ markers from subprocess stderr, storing the error message in JobState.messages. The sidecar does not implement automatic retry; clients receive status: failed and must resubmit. Successful and failed jobs persist in _JOBS until MAX_RETAINED_JOBS eviction, allowing post-hoc debugging.

Can I run the sidecar without the GeoLibre desktop application?

Yes. Set GEOLIBRE_SIDECAR_TOKEN to any value for development mode where token checks are skipped, or provide a consistent token via environment variable for scripted access. The README in backend/geolibre_server/README.md documents manual startup with python -m geolibre_server.app.main or uvicorn.

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 →