Replaces: jazzband/geojson (4.5M/month PyPI, 984 stars)
Package name: geospec (verified available on PyPI)
Language: Python (3.10+)
License: BSD-3-Clause
The jazzband/geojson package is at risk:
- Jazzband is sunsetting by end of 2026 (AI spam crisis, governance failure)
- Last meaningful commit: Dec 2024 (release 3.2.0)
- Python 3.14 compatibility PR sitting unmerged for 3 months
- 28 open issues, 25 open PRs — no maintainer response
- No standalone drop-in alternative exists (geojson-pydantic requires Pydantic, different API)
Lightweight, zero-dependency Python library implementing RFC 7946 GeoJSON objects with:
- All 7 geometry types + Feature + FeatureCollection
- JSON serialization/deserialization with GeoJSON object hooks
- Coordinate validation per RFC 7946
__geo_interface__protocol support- Coordinate utility functions (extraction, transformation)
geospec/
├── __init__.py # Public API re-exports
├── _types.py # Type aliases (Coord2D, Coord3D, BBox, etc.)
├── base.py # GeoJSON base class (dict subclass)
├── geometry.py # Point, LineString, Polygon, Multi*, GeometryCollection
├── feature.py # Feature, FeatureCollection
├── codec.py # dump, dumps, load, loads, GeoJSONEncoder
├── validation.py # RFC 7946 validation logic (separated from geometry)
├── utils.py # coords, map_coords, map_tuples, map_geometries
└── py.typed # PEP 561 marker
-
Dict subclass — same as jazzband/geojson. GeoJSON objects behave as dicts with attribute access. This ensures JSON serialization compatibility and familiar API.
-
Separated validation — validation logic in its own module for testability. Each geometry type delegates to validation functions.
-
Type hints throughout — full type annotations with
py.typedmarker. TypeAlias for coordinate types (Coord2D = tuple[float, float],Coord3D = tuple[float, float, float]). -
RFC 7946 strictness — optional strict mode validates:
- Longitude range [-180, 180], Latitude range [-90, 90]
- Right-hand rule for polygon winding order
- Linear ring closure (first == last coordinate)
- Minimum coordinate counts per geometry type
-
Zero dependencies — stdlib
jsononly. No simplejson fallback (unnecessary for modern Python). -
API compatibility — drop-in replacement for jazzband/geojson:
- Same class names:
Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection,Feature,FeatureCollection - Same functions:
dump,dumps,load,loads,coords,map_coords - Same
__geo_interface__protocol - Same
errors()/is_validAPI - Same dict-like behavior with attribute access
- Same class names:
GeoJSON— base classPoint(coordinates, validate=False, precision=6)LineString(coordinates, validate=False, precision=6)Polygon(coordinates, validate=False, precision=6)MultiPoint(coordinates, validate=False, precision=6)MultiLineString(coordinates, validate=False, precision=6)MultiPolygon(coordinates, validate=False, precision=6)GeometryCollection(geometries=None)Feature(id=None, geometry=None, properties=None)FeatureCollection(features)
dump(obj, fp)/dumps(obj)— serialize to GeoJSONload(fp)/loads(s)— deserialize from GeoJSONcoords(obj)— yield coordinate tuples from any GeoJSON objectmap_coords(func, obj)— apply function to each coordinate dimensionmap_tuples(func, obj)— apply function to each coordinate tuplemap_geometries(func, obj)— apply function to each geometry
obj.is_valid— bool, True if no validation errorsobj.errors()— list of validation error stringsobj.__geo_interface__— GeoJSON-compatible dict
- Type hints — full annotations,
py.typedmarker for IDE support - RFC 7946 range validation — optional lat/lon bounds checking
- Winding order validation — check right-hand rule for polygons
- No simplejson dependency — stdlib json only
- Python 3.10+ — modern syntax, no legacy compatibility code
- Separated validation module — cleaner, more testable
- Core implementation (all classes, codec, validation, utils)
- Comprehensive test suite (pytest)
- pyproject.toml with modern packaging
- CI/CD (GitHub Actions)
- Migration guide from jazzband/geojson