The official Python client for the Topolab dataset and geospatial API.
Lightweight, GeoJSON-first, sync & async.
📖 Docs: topolab-bv.github.io/topolab-python · full platform docs at docs.topolab.nl
pip install topolab # core — GeoJSON-first, minimal dependencies
pip install "topolab[geo]" # adds GeoPandas for .to_geodataframe()Pre-release: until the first version is published to PyPI, install from Git:
pip install "git+https://github.com/topolab-bv/topolab-python.git"
Requires Python 3.10+.
# Fetch all NL Domino's locations and write to disk
from topolab import Client
tl = Client(api_key="tlb_prod_...")
df = tl.dataset("nl-domino-poi").to_geodataframe()
df.to_file("dominos-nl.geojson")Your API key carries your scope and add-ons — bulk downloads need API_ACCESS,
spatial queries need GIS_ACCESS, and data routes require an
organization-scoped key. Set TOPOLAB_API_KEY in the environment to avoid
hard-coding it:
import os
from topolab import Client
tl = Client(api_key=os.environ["TOPOLAB_API_KEY"])The client targets production (https://api.topolab.nl) by default. Point it
at staging with the environment argument:
tl = Client(api_key="tlb_staging_...", environment="staging") # https://api-staging.topolab.nlOr set TOPOLAB_ENV=staging in the environment. An explicit base_url= always
wins (for self-hosting or tests). Precedence: base_url → environment →
TOPOLAB_BASE_URL → TOPOLAB_ENV → production.
for ds in tl.datasets.list(country="NL", limit=10).data:
print(ds.table, ds.metadata)ds = tl.dataset("nl-domino-poi")
fc = ds.to_geojson() # GeoJSON FeatureCollection (a dict)
gdf = ds.to_geodataframe() # GeoPandas GeoDataFrame (needs [geo])
path = ds.download("dominos.geojson") # streamed to disk, never bufferedfc = tl.dataset("nl-domino-poi").items(limit=100, bbox=[4.7, 52.2, 5.1, 52.5])
# or stream every feature, paging transparently:
for feature in tl.dataset("nl-domino-poi").iter_items(page_size=500):
...Every call has an await-able mirror on AsyncClient:
import asyncio
from topolab import AsyncClient
async def main():
async with AsyncClient() as tl: # reads TOPOLAB_API_KEY
md = await tl.dataset("nl-domino-poi").metadata()
print(md.table)
asyncio.run(main())Every failure raises a subclass of TopolabError, so you never parse raw JSON:
| Exception | When |
|---|---|
AuthenticationError |
missing or invalid API key (401) |
AddonRequiredError |
key lacks the add-on — .addon names it (403) |
AccessDeniedError |
dataset not accessible to your organization (403) |
InsufficientCreditsError |
not enough credits — .required / .available (402) |
NotFoundError |
unknown dataset (404) |
RateLimitError |
rate limited — .retry_after, retried automatically (429) |
from topolab import Client, AddonRequiredError
try:
tl.dataset("nl-domino-poi").download("out.geojson")
except AddonRequiredError as e:
print("Your key needs the add-on:", e.addon)- Full docs: docs.topolab.nl
- Two access patterns (bulk export vs. spatial OGC query), credits, and
add-ons are explained in the SDK conventions and in
the
topolab-sdk-specrepository. - A runnable example lives in
examples/quickstart.py.
Issues and pull requests are welcome. See CONTRIBUTING.md.
Run the test suite with pytest; build the wheel with uv build.
MIT © Topolab B.V.
