Skip to content

Python SDK ​

The gispulse-sdk Python SDK is a type-safe HTTP client for the GISPulse REST API. It supports synchronous and asynchronous modes, SSE streaming, and WebSocket.

Installation ​

bash
pip install gispulse-sdk

# With WebSocket support
pip install "gispulse-sdk[ws]"

Requirements: Python 3.9+, httpx, pydantic>=2.0

Synchronous Client ​

python
from gispulse_sdk import GISPulseClient

# Local connection (no auth)
client = GISPulseClient("http://localhost:8001")

# Remote connection with API key
client = GISPulseClient(
    "https://gispulse.example.com",
    api_key="sk-gp-your-key",
)

Usage as a context manager ​

python
with GISPulseClient("http://localhost:8001") as client:
    datasets = client.datasets.list()
    print(datasets)
# Connection closed automatically

Asynchronous Client ​

python
from gispulse_sdk import AsyncGISPulseClient

async def main():
    async with AsyncGISPulseClient("http://localhost:8001") as client:
        datasets = await client.datasets.list()
        print(datasets)

import asyncio
asyncio.run(main())

Available Endpoints ​

client.XDescription
client.datasetsDataset management
client.jobsJob execution and monitoring
client.rulesRule CRUD
client.capabilitiesList capabilities
client.triggersTrigger management (Pro)
client.scenariosScenario management (Pro)
client.sessionsPostGIS sessions (Pro)
client.projectsProjects (Pro)
client.catalogOGC Catalog
client.ogcOGC Features API

Datasets ​

Upload a file ​

python
dataset = client.datasets.upload("data/parcelles.gpkg")
print(dataset.id)       # Dataset UUID
print(dataset.name)     # "parcelles.gpkg"
print(dataset.format)   # "GPKG"
print(dataset.crs)      # "EPSG:2154"

List datasets ​

python
datasets = client.datasets.list(limit=50, offset=0)
for ds in datasets:
    print(f"{ds.id} — {ds.name} ({ds.format})")

Retrieve features ​

python
fc = client.datasets.features(
    dataset_id=dataset.id,
    layer="parcelles",
    limit=1000,
    bbox=(2.3, 48.8, 2.4, 48.9),  # minx, miny, maxx, maxy
)
# fc is a GeoJSON FeatureCollection dict

Export a dataset ​

python
path = client.datasets.export(
    dataset_id=dataset.id,
    format="geojson",
    output_path="output/export.geojson",
)
print(f"Exported to {path}")

SQL query ​

python
result = client.datasets.sql(
    "SELECT code_dept, COUNT(*) as nb_parcelles FROM parcelles GROUP BY 1 ORDER BY 2 DESC"
)
print(result["rows"])

Register an OGC service ​

python
from gispulse_sdk.models import OGCDatasetCreate

dataset = client.datasets.upload_ogc(OGCDatasetCreate(
    url="https://wxs.ign.fr/parcellaire/geoportail/wfs",
    service_type="WFS",
    layer_name="BDPARCELLAIRE_VECTEUR:parcelle",
    name="IGN Parcels",
))

Jobs ​

Create and wait for a job ​

python
from gispulse_sdk.models import JobCreate

job = client.jobs.create(JobCreate(
    name="buffer_parcelles",
    dataset_id=dataset.id,
    parameters={"rule_ids": [str(rule.id)]},
))

# Wait for completion (polling)
import time
while True:
    job = client.jobs.get(job.id)
    if job.status in ("COMPLETED", "FAILED"):
        break
    time.sleep(1)

print(f"Job finished: {job.status}")

SSE streaming (async) ​

python
async with AsyncGISPulseClient("http://localhost:8001") as client:
    async for event in client.jobs.stream(job_id):
        print(event)

Rules ​

Full CRUD ​

python
from gispulse_sdk.models import RuleCreate

# Create
rule = client.rules.create(RuleCreate(
    name="buffer_50m",
    capability="buffer",
    config={"distance": 50},
    enabled=True,
))

# List
rules = client.rules.list()

# Update
rule = client.rules.update(rule.id, {"config": {"distance": 100}})

# Delete
client.rules.delete(rule.id)

Validate rules (dry-run) ​

python
results = client.rules.validate([
    {"capability": "buffer", "config": {"distance": 100}},
    {"capability": "reproject", "config": {"crs": "EPSG:2154"}},
])
for r in results:
    print(f"{r['name']}: {'OK' if r['valid'] else 'FAIL'}")

Capabilities ​

python
caps = client.capabilities()
for cap in caps:
    print(f"{cap.name}: {cap.description}")

WebSocket Streaming ​

Available with pip install "gispulse-sdk[ws]".

python
from gispulse_sdk import AsyncGISPulseClient

async def watch_job(job_id: str):
    async with AsyncGISPulseClient("http://localhost:8001") as client:
        async for message in client.streaming.watch_job(job_id):
            print(f"[{message['type']}] {message.get('message', '')}")

asyncio.run(watch_job("job-uuid"))

Error Handling ​

The SDK raises typed exceptions:

python
from gispulse_sdk.exceptions import (
    GISPulseError,       # Base
    NotFoundError,       # 404
    AuthError,           # 401/403
    ValidationError,     # 422
    RateLimitError,      # 429
    ServerError,         # 500
)

try:
    dataset = client.datasets.get("nonexistent-uuid")
except NotFoundError:
    print("Dataset not found")
except AuthError:
    print("Invalid API key")

Complete Example — Automated Pipeline ​

python
from gispulse_sdk import GISPulseClient
from gispulse_sdk.models import RuleCreate, JobCreate
import time

with GISPulseClient("http://localhost:8001") as client:
    # 1. Upload file
    print("Uploading...")
    ds = client.datasets.upload("data/communes_bretagne.gpkg")

    # 2. Create rules
    rules = [
        client.rules.create(RuleCreate(
            name="buffer_2km",
            capability="buffer",
            config={"distance": 2000, "order": 0},
        )),
        client.rules.create(RuleCreate(
            name="area_calc",
            capability="area_length",
            config={"area_column": "surface_buffer_m2", "order": 1},
        )),
    ]

    # 3. Launch the job
    print("Running...")
    job = client.jobs.create(JobCreate(
        name="analyse_communes",
        dataset_id=ds.id,
        parameters={"rule_ids": [str(r.id) for r in rules]},
    ))

    # 4. Wait for completion
    while True:
        job = client.jobs.get(job.id)
        if job.status in ("COMPLETED", "FAILED"):
            break
        time.sleep(0.5)

    if job.status == "COMPLETED":
        print("Success!")
        # 5. Export the result
        out = client.datasets.export(ds.id, format="geojson", output_path="output/result.geojson")
        print(f"Result: {out}")
    else:
        print(f"Failed: {job.status}")

Model Reference ​

Pydantic models are in gispulse_sdk/models.py. They are all exported from gispulse_sdk:

python
from gispulse_sdk.models import (
    DatasetResponse,
    JobResponse,
    RuleResponse,
    CapabilityInfo,
    HealthResponse,
    OGCDatasetCreate,
    RuleCreate,
    JobCreate,
)

Published under AGPL-3.0 license.