# How the Optional Raster Extra Enables Server-Side Processing with Rasterio in GeoLibre

> Discover how the GeoLibre optional raster extra enables server-side raster processing with rasterio and numpy. Execute spatial algorithms securely on the server.

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

---

**The optional `raster` extra installs `rasterio` and `numpy` into GeoLibre's Python side-car, registering FastAPI endpoints that execute raster algorithms in sandboxed server-side processes.**

GeoLibre's optional Python side-car (`backend/geolibre_server`) handles heavy geospatial workloads outside the browser. The optional `raster` extra is the critical mechanism that brings **rasterio**—the industry-standard library for georeferenced raster I/O—into this server-side runtime. This article examines exactly how the extra works, from dependency declaration through runtime execution, using the actual source code from the opengeos/GeoLibre repository.

## How the Raster Extra Declares Its Dependencies

The `raster` extra is defined in [`backend/geolibre_server/pyproject.toml`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/pyproject.toml). When users install the side-car with the extra, pip pulls in `rasterio` (≥ 1.3.0) and `numpy` as conditional dependencies.

```bash
pip install -e "backend/geolibre_server[raster]"

```

This installation command references the dependency group declared at lines 26-30 of [`pyproject.toml`](https://github.com/opengeos/GeoLibre/blob/main/pyproject.toml). The base side-car remains lightweight for users who only need vector or SQL tools, while the extra transforms the environment into one capable of opening, reading, writing, and manipulating georeferenced raster files.

## Runtime Discovery and Job Infrastructure

The raster module reuses the generic job helpers from the conversion subsystem. In [`backend/geolibre_server/geolibre_server/app/raster.py`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/geolibre_server/app/raster.py), lines 24-34 import `_start_job`, `_validate_paths`, and related utilities from the conversion module.

This design choice ensures raster tools behave identically to conversion tools from the client's perspective. The same polling mechanism, status tracking, and result delivery apply whether you're converting a Shapefile or computing a hillshade from a DEM.

## Server-Side Raster Endpoints in FastAPI

All raster operations route through the `/raster` FastAPI router defined in [`raster.py`](https://github.com/opengeos/GeoLibre/blob/main/raster.py). Each endpoint receives a JSON payload specifying:

- `tool_id`: the raster algorithm to execute
- `input_path` and `output_path`: file locations
- `parameters`: algorithm-specific options

The router spawns a short-lived Python subprocess (lines 60-95) that runs embedded raster scripts. These scripts import `rasterio` directly and perform the computational work:

```python
import rasterio

```

Supported operations include hillshade generation, slope calculation, reprojection, and other QGIS-inspired raster algorithms—all executed server-side where memory and CPU constraints are more forgiving than in a browser environment.

## Safety, Isolation, and Optional Availability

Raster processing can be expensive. The side-car runs inside a **sandboxed UV-managed environment** to contain resource usage. The optional nature of the `raster` extra provides crucial flexibility: installations without it avoid the substantial dependency footprint of GDAL bindings and numeric libraries.

The server reports raster availability at the `/raster/status` endpoint (lines 8-12). The desktop application queries this endpoint and disables raster UI controls when the extra is absent, preventing user confusion and failed operations.

## Frontend Integration and API Usage

The desktop and web UIs communicate with the side-car via HTTP. Raster jobs follow the same lifecycle as conversion jobs:

1. **Submit**: `POST /raster` with tool configuration
2. **Poll**: `GET /conversion/jobs/{id}` for progress updates
3. **Retrieve**: Result contains `output_path` when `state` equals `"finished"`

### Complete API Example

Install and start the side-car:

```bash
pip install -e "backend/geolibre_server[raster]"
geolibre-server

```

Submit a hillshade job:

```bash
curl -X POST http://localhost:8765/raster \
  -H "Content-Type: application/json" \
  -d '{
        "tool_id":"hillshade",
        "input_path":"data/dem.tif",
        "output_path":"data/hillshade.tif",
        "parameters":{"azimuth":315,"altitude":45}
      }'

```

Poll for completion:

```bash
curl http://localhost:8765/conversion/jobs/<job-id>

```

### Python Client Implementation

```python
import requests
import json

payload = {
    "tool_id": "reproject",
    "input_path": "data/source.tif",
    "output_path": "data/reprojected.tif",
    "parameters": {"dst_crs": "EPSG:32633"}
}
resp = requests.post("http://localhost:8765/raster", json=payload)
job_id = resp.json()["job_id"]

while True:
    status = requests.get(
        f"http://localhost:8765/conversion/jobs/{job_id}"
    ).json()
    if status["state"] == "finished":
        print("Result at:", status["result"]["output_path"])
        break

```

## Key Source Files

| File | Purpose |
|------|---------|
| [`backend/geolibre_server/pyproject.toml`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/pyproject.toml) | Declares the `raster` extra and its `rasterio`/`numpy` dependencies |
| [`backend/geolibre_server/geolibre_server/app/raster.py`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/geolibre_server/app/raster.py) | FastAPI router, job orchestration, and embedded raster scripts |
| [`backend/geolibre_server/geolibre_server/app/conversion.py`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/geolibre_server/app/conversion.py) | Shared job infrastructure reused by the raster module |

## Summary

- The optional `raster` extra installs `rasterio` (≥ 1.3.0) and `numpy` through [`pyproject.toml`](https://github.com/opengeos/GeoLibre/blob/main/pyproject.toml) dependency groups
- The extra registers the `/raster` FastAPI router and enables server-side raster script execution
- Job execution reuses conversion subsystem helpers for consistent behavior across tool types
- Sandboxed UV-managed processes isolate expensive raster computations from the main application
- Runtime availability detection at `/raster/status` allows graceful UI degradation when the extra is absent

## Frequently Asked Questions

### What happens if I install the side-car without the raster extra?

The side-car installs and runs normally but lacks `rasterio` and the `/raster` endpoints. Vector conversion and SQL tools function identically; raster UI controls appear disabled in the desktop application, and API calls to `/raster` return 404 errors.

### Why does the raster module reuse conversion job helpers instead of implementing its own queue?

Code reuse ensures consistent behavior. By importing `_start_job`, `_validate_paths`, and related functions from [`conversion.py`](https://github.com/opengeos/GeoLibre/blob/main/conversion.py), the raster module guarantees that progress polling, error handling, and result delivery work identically across all server-side tools—reducing maintenance burden and user confusion.

### Can I use rasterio directly in my own scripts with the side-car installed?

Yes. Installing the `raster` extra makes `rasterio` and `numpy` available in the same Python environment that runs the side-car. You can import these libraries in custom scripts or extend the embedded raster tools in [`raster.py`](https://github.com/opengeos/GeoLibre/blob/main/raster.py) with additional algorithms.

### How does the side-car handle concurrent raster jobs?

Each raster operation spawns a short-lived Python subprocess through the shared job infrastructure. The UV-managed sandbox and job queue in the conversion module coordinate execution, preventing resource contention while allowing parallel processing when system capacity permits.