thinwrap-location

thinwrap-location for Python — unified facade across 6 providers for routing, matrix, geocoding, and isochrone, with built-in polyline utilities. Zero runtime deps (stdlib urllib), synchronous, stateless, BYO transport.

Python constraints

Runtime dependencies
Zero runtime dependencies
BYO HTTP client
Transport protocol: any object with send(HttpRequest) -> HttpResponse, passed as transport=
Provenance
PEP 740 attestations (PyPI Trusted Publishing)
Minimum runtime
Python 3.10+
  • Truly zero dependencies — the standard library urllib.request is the only HTTP surface, and AWS SigV4 (SES, SNS, Bedrock) / JWT signing (FCM RS256, APNs ES256) are implemented in pure Python on hashlib and hmac, with no cryptography package.
  • Synchronous by design. For async or pooled HTTP, inject an httpx or requests based Transport; the library never imports either.
  • The default transport never follows redirects — a 3xx surfaces as an error rather than silently re-sending auth headers to another host.

30-second install

pip install thinwrap-location

2-minute end-to-end example

Compute a route between two waypoints through any supported provider. The example below uses Mapbox; switching providers means changing the config class — input and output shape stay identical.

import os
from thinwrap.location import Routing, RoutingOptions, MapboxConfig, LatLng, ConnectorError

r = Routing(MapboxConfig(access_token=os.environ["MAPBOX_TOKEN"]))

try:
    res = r.route(RoutingOptions(waypoints=[
        LatLng(37.7749, -122.4194),
        LatLng(37.3382, -121.8863),
    ]))
    print(f"{res.total_distance_meters / 1000:.1f} km, {res.total_duration_seconds / 60:.0f} min")
    print(res.polyline)  # Google precision-5 encoded
except ConnectorError as e:
    print(e.provider_code.value, e.provider_message)

Same code works for all supported routing providers — swap to GoogleConfig, HereConfig,EsriConfig, TomTomConfig, orOsrmConfig(base_url=…). Output normalizes to a singleRoutingResult shape across every provider.

Supported providers

6 providers ship with thinwrap-location@1.3.0.
ProviderOperationsAuthREADME
google Google Maps Platformrouting, matrix, geocodingquerydocs
mapbox Mapboxrouting, matrix, geocoding, isochronequerydocs
here HERErouting, matrix, geocoding, isochroneheaderdocs
esri ESRI ArcGISrouting, matrix, geocoding, isochronebearerdocs
tomtom TomTomrouting, matrix, geocoding, isochronequerydocs
osrm OSRM (self-hosted)routing, matrixheaderdocs

Migration paths

Built-in polyline utilities

Every routing connector emits a Google precision-5 encoded polyline onres.polyline. Decode, re-encode, or convert HERE's flex-polyline / ESRI's path geometry without a third-party library:

from thinwrap.location import decode_polyline, encode_polyline, decode_flex_polyline, encode_esri_paths

points = decode_polyline(res.polyline)        # list[LatLng]
re_encoded = encode_polyline(points)          # back to precision-5
here = decode_flex_polyline("BFoz5...")       # HERE flex-polyline
esri = encode_esri_paths(paths)               # ESRI-JSON {paths, spatialReference}

The four polyline primitives are the only encode/decode exports — the same four as every sibling, standard library only.

Operation coverage

Provider × operation gaps below are architectural, not bugs:

  • OSRM ships only routing +matrix — geocoding and isochrone are out of scope by design for OSRM. Building Geocoding(OsrmConfig(…)) raisesValueError straight away.
  • Google does not expose a public isochrone API.

Bring your own transport

The default transport is standard-library urllib: it never follows redirects and refuses cleartext http:// URLs. To reach a self-hosted OSRM over plain HTTP, or to usehttpx/requests, pass any object withsend(HttpRequest) -> HttpResponse astransport=. The wrapper holds no state — the HERE/TomTom async-matrix submit-poll-retrieve cycle stays hidden inside a singlematrix call.

Cross-language siblings

The TypeScript (/packages/location-ts), PHP (/packages/location-php), and Go (/packages/location-go) variants ship the same facade shape and provider set — cross-language parity is a design goal, not a hard release gate.

Read more