Overview
Python client for the JustRouting API — routing, distance matrices, geocoding, map matching, trips, nearest-road lookup, and vehicle routing optimization across Southeast Asia. No dependencies outside the standard library. Requires Python 3.9+.Install
Or install from a clone of the repository:
Quickstart
The coordinates above are in Singapore. See Coordinates must share a country.
Services
AClient exposes eight services.
Routes
Routes.get returns the best route. Routes.get_all additionally returns alternatives and the snapped input waypoints.
route.geometry holds whichever encoding you asked for:
Matrix
Travel time and distance between many points at once.None for unreachable pairs. The API reports those as null, which is deliberately kept distinct from a genuine zero.
Geocode
Turn addresses into coordinates, free-form or structured:structured (an address as typed fields) is mutually exclusive with text; bias steers results toward a location. An empty results list means nothing matched — it is a valid answer, not an error.
Map Matching
Snap a noisy GPS trace onto the road network:Match extends Route, so distance, duration, geometry, and legs are all available. get_all also returns tracepoints aligned with the input coordinates — None entries mark points that could not be matched. Use gaps="ignore", tidy=True, waypoints=[0, 5], or snapping="any" to shape the matching.
Trip
The fastest order to visit a set of coordinates:source="first" / destination="last" pin where the trip starts and ends.
Nearest
The road segment closest to a coordinate:Optimization
Assign tasks to a fleet and order each vehicle’s stops.Shipments instead of Jobs for pickup-and-delivery pairs that must be served in order by the same vehicle.
Health
The only call that works without an API key, which makes it a useful connectivity check.Error handling
Every failure raises a subclass ofjustrouting.Error. Classify it with except clauses rather than matching on message text:
When the engine finds nothing — an empty
matchings, trips, or waypoints list on an “Ok” response — map matching, trip, and nearest raise Error with status_code == 200 and osrm_code "NoMatch", "NoTrip", or "NoSegment" (no dedicated subclass; check e.osrm_code).
Catch justrouting.Error itself when you need the status code, engine code, or raw body:
TransportError (network-level, retried like a 5xx) or DecodeError (unparseable success response) instead; neither is a subclass of Error.
Configuration
Invalid options raise
ValueError immediately. (The Go client defers them to the first request because its constructor cannot fail; Python constructors can.)
Timeouts and retries
Rate limits (429), server errors (5xx), and transport failures are retried with exponential backoff and jitter; aRetry-After header takes precedence when present. Other 4xx responses are returned immediately — they would fail identically on a retry and would still consume quota.
Client(timeout=...) covers a single HTTP attempt, like http.Client.Timeout in Go. Pass the per-call timeout argument to bound the whole retry sequence:
HTTP_PROXY / HTTPS_PROXY environment variables.
Things to know
Coordinates are [longitude, latitude]
This is the GeoJSON order, and the reverse of the “lat, lng” used by most map UIs. Swapped coordinates are usually caught locally — a longitude in the latitude slot fails the [-90, 90] check before a request is sent — but a swap that stays in range will silently route somewhere unexpected.
Point is a list subclass, so both of these work:
Coordinates must share a country
Every coordinate in a single request must fall within one country; the API routes each request to a per-country engine. A Singapore → Kuala Lumpur request fails withCrossCountryError.
Supported countries: Brunei, Cambodia, Indonesia, Laos, Malaysia, Myanmar, the Philippines, Singapore, Thailand, and Vietnam.
Plan limits
Exceeding a size limit raises
PlanLimitExceededError; exhausting the daily allowance raises QuotaExceededError.
Examples
Runnable scripts live inexamples/:
Development
http.server instances — no network access and no API key.
Integration tests hit a live API and are behind a marker, so they never run by accident:
Differences from the Go client
- Exceptions replace sentinel errors and
errors.Is;QuotaExceededErrorsubclassesRateLimitedError. - Constructor options are keyword arguments; invalid ones raise
ValueErrorimmediately instead of being deferred to the first request. - There is no
context.Context; the per-calltimeoutargument plays the role of a context deadline. - Matrix accessors return
float | Noneinstead of(float, ok). - There is no custom-HTTP-client option; use
base_url,timeout, and the standard proxy environment variables instead.
