Skip to main content

gratisgis (Python client)

Talk to a GratisGIS portal from Python: notebooks, scheduled scripts, CI, or an editor on your own machine.

pip install gratisgis

Until the first PyPI release, install from source:

pip install "gratisgis @ git+https://github.com/palavido-dev/gratis-gis#subdirectory=clients/python"

The full guide, with worked examples for filtering, buffering, writing a new layer, and exporting, is in the portal at /help/reference/python-client.

Get a key

In the portal: Profile -> API keys -> Create key. The token is shown once. A key acts as the user who created it, so it sees exactly what you see, with the same sharing and geographic limits. Tick Read only unless the script needs to write.

Use it

from gratisgis import GratisGIS

gg = GratisGIS("https://your-portal.org", api_key="ggk_...")

# Which account is this key?
print(gg.whoami()["username"])

# Find a layer and read it as GeoJSON
layer = gg.find_items(type="data_layer", query="parcels")[0]
fc = gg.read_features(layer["id"], "parcels", limit=500)
print(len(fc["features"]), "features")

Prefer environment variables so the secret stays out of your source, which also means the same script runs unchanged anywhere:

# GRATISGIS_URL=https://your-portal.org
# GRATISGIS_API_KEY=ggk_...
gg = GratisGIS.from_env()

Writing

features = [
    {
        "type": "Feature",
        "geometry": {"type": "Point", "coordinates": [-79.85, 38.93]},
        "properties": {"name": "New hydrant", "status": "active"},
    }
]
gg.add_features(layer_id, "hydrants", features)

add_features batches for you. The portal refuses more than 5000 features in one request, so hand it a list or a generator of any size and it splits the work.

Edits are recorded as new observations rather than overwriting rows, so a feature's history stays intact and remains queryable:

gg.update_feature(layer_id, "hydrants", feature_id,
                  properties={"status": "needs service"})

A monthly refresh, end to end

The shape most people want. Point it at a source, replace what changed, and let cron run it:

import os
from gratisgis import GratisGIS, PortalError

def main() -> int:
    gg = GratisGIS.from_env()
    layer_id = os.environ["PARCEL_LAYER_ID"]
    try:
        incoming = fetch_from_county()          # your code
        result = gg.add_features(layer_id, "parcels", incoming)
        print(f"appended {result['appended']} features")
        return 0
    except PortalError as exc:
        # Non-zero so cron / systemd notices, and the portal's own
        # message reaches your logs verbatim.
        print(f"refresh failed: {exc}")
        return 1

if __name__ == "__main__":
    raise SystemExit(main())

Errors

Every failure raises a subclass of PortalError carrying the portal's own message, plus the status and route:

Class When
AuthError 401 / 403. Bad, expired, or revoked key; read-only key attempting a write; a key used on an admin route
NotFoundError 404. Missing, or not visible to this key
ValidationError 400 / 422. Understood and refused
ConflictError 409. Something moved under you
RateLimitError 429. Carries retry_after when the portal sends it
PortalError Anything else, including a network failure

What this does not do

It wraps the item API and the feature endpoints, which is what automation needs. It is not a mirror of every portal route.

It also has exactly one dependency, httpx. GeoPandas, Shapely and friends belong to your environment, not to a portal client: bring the stack you already use and hand this GeoJSON.

There is no hosted execution environment. Scripts run wherever you run them. Server-side scheduled execution is tracked separately.

Development

pip install -e ".[dev]"
pytest

The tests run against httpx.MockTransport, so no portal is needed.

Metadata

Release files for gratisgis 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gratisgis 0.6.0
File Size Uploaded
gratisgis-0.6.0.tar.gz 33.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gratisgis 0.6.0
File Interpreter ABI Platform
gratisgis-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 55.2 kB

Release files / gratisgis-0.6.0.tar.gz

Download URL gratisgis-0.6.0.tar.gz
Size 33.2 kB
Tags Source
SHA-256 checksum
How to use checksums
8bb7129e6cd6efc7a37c33a84a9e6d7d2aaff919a316bcfa0b4b66df7fb43ccb
BLAKE2b-256 checksum
How to use checksums
15abb738540c2a14e6de2b86be0436d7a9fc7a8ce0ba28dc4dba4e0efe5a92e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.

Transparency log

Release files / gratisgis-0.6.0-py3-none-any.whl

Download URL gratisgis-0.6.0-py3-none-any.whl
Size 22.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b684a85867d9cdc33e4083475328fe46fb5829650e648d3f901cb7483185aed2
BLAKE2b-256 checksum
How to use checksums
dcaabd71faedfefc98e04a3f0c3d800ed5fcab7facbbdd516756e017c3a03566
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.7.0

2 release files

This release

0.6.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page