Python bindings · raster · preview
Every other demo on this site is TerraServe running as a server. This one is TerraServe as a Python library: render_png() takes a COG window and hands back PNG bytes, no HTTP involved, byte-identical to what the CLI or a live WMS server would draw for the same request.
Preview · v0.1.0
This is a preview, not a 1.0. render_png() covers the raster path only: a COG in, a styled PNG out. Vector layers and text labels (GeoPackage, FlatGeoBuf, SLD) are designed as the next release and aren't built yet, and band-math (NDVI-style expressions) is deferred too. It isn't on PyPI: install the wheel straight from the GitHub release below. Expect the API to still move before a 1.0.

Install
v0.1.0 is a GitHub release, not a PyPI package. It ships as one abi3 wheel, built once and compatible with CPython 3.9 and every version after it, plus a matching aarch64 wheel for arm. Both are manylinux_2_28, which covers most Linux from the last few years, and PROJ is compiled in, so it imports with no system libproj to install first.
# not on PyPI yet, install straight from the GitHub release pip install https://github.com/terraops-org/terraserve/releases/download/v0.1.0/terraserve-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl # arm64 (aarch64) is the same tag, a separate wheel pip install https://github.com/terraops-org/terraserve/releases/download/v0.1.0/terraserve-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl
The exact call
Eight keyword arguments in, PNG bytes out. This is the literal call, same bounding box and same style file the fixtures in TerraServe's own test suite use, that rendered the image at the top of this page.
# the exact call that made the screenshot above import terraserve png = terraserve.render_png( cog_path="cascais.cog.deflate.tif", bbox=(-116201.25, -108717.25, -109034.0, -103918.25), crs="EPSG:3763", src_crs="EPSG:3763", width=1680, height=1125, style="rgb.json", resample="bilinear", ) open("cascais.png", "wb").write(png)
| cog_path | The COG to read: a local path or s3://bucket/key. Same idea as --cog on the CLI. |
| bbox | The window to render, (minx, miny, maxx, maxy), in crs units. |
| crs | The output projection, e.g. EPSG:3857. |
| src_crs | The COG's own projection, e.g. EPSG:32629. Optional, but be careful: the fallback is EPSG:3763, a leftover default from the pilot fixture this wheel was built against, not a sensible default for your data. Pass it explicitly. |
| width, height | Output size in pixels. |
| style | Path to a style.json: rgb (band passthrough) or pseudocolor (a value ramp). Same file format as --style on the CLI. |
| resample | "nearest" or "bilinear". Optional, defaults to bilinear. |
| -> returns | bytes: the PNG file, in memory. Nothing touches disk unless you write it yourself. |
Measured via the CLI, which runs the identical render() call under the hood: the image above, 1680×1125 pixels, bilinear-resampled, renders in about 0.15 s.
Source. A 25 cm RGB aerial orthophoto over Cascais, Portugal (EPSG:3763), the same fixture TerraServe's own correctness tests and pilot benchmark run against.
What v0.1.0 covers
The binding calls the same render() and PNG encoder the CLI and the live WMS server use underneath, so the output is byte-identical, not an approximation. The GIL is released for the whole render, so concurrent callers, pygeoapi's worker processes among them, actually run in parallel instead of queuing behind Python's interpreter lock.
Today's wheel only reads a COG and draws it as RGB or a pseudocolor ramp. Styled vector layers (GeoPackage / FlatGeoBuf + SLD) and text labels are designed as the next release, not built. Band-math expressions like the live NDVI demo already run in the Rust engine, they're just not wired into this function yet.
A type: map provider referenced by its dotted Python path, no pygeoapi core change needed, the same pattern as the mapscript provider it can replace:
# pygeoapi config.yml: a dotted Python path, like the mapscript provider it can replace providers: - type: map name: terraserve.pygeoapi.TerraServeProvider data: /data/cascais.cog.tif options: src_crs: EPSG:3763 style: /data/rgb.json