Getting Started
Installation
C++ extension — pre-built wheels strongly recommended
py-osrm wraps the OSRM C++ backend.
Installing from source (e.g. uv sync, pip install ., or pip install git+...) requires
a full C++ toolchain including a recent compiler (GCC/Clang), CMake, Boost, libtbb, and Lua,
and takes 5–10 minutes to compile. Toolchain mismatches are common and will cause the build
to fail silently or with cryptic errors.
Use the pre-built wheels below unless you explicitly need to modify the C++ source.
py-osrm is distributed as pre-built wheels via GitHub Releases. No C++ compiler required.
Download the appropriate .whl from the Releases page and install:
Bulk processing support
Install Polars and tqdm to use the bulk processing functions with progress reporting:
Preprocessing
Before routing, you must preprocess OpenStreetMap (OSM) data into OSRM's internal format.
Built-in profiles are car, bicycle, and foot.
CH (Contraction Hierarchies) — recommended for most use cases
import osrm
# Step 1 — extract the road network from an OSM file
osrm.extract("region.osm.pbf", profile="car", output_path="region")
# Step 2 — build the CH routing graph
osrm.contract("region")
# Ready to route
engine = osrm.OSRM("region.osrm")
MLD (Multi-Level Dijkstra) — better for large datasets / dynamic weights
import osrm
osrm.extract("region.osm.pbf", profile="car", output_path="region")
osrm.partition("region")
osrm.customize("region")
engine = osrm.OSRM("region.osrm", algorithm="mld")
CLI equivalent
See Preprocessing for full API reference and custom profile support.
Routing
Single route
import osrm
engine = osrm.OSRM("region.osrm")
result = engine.Route(
coordinates=[(7.41337, 43.72956), (7.41546, 43.73077)],
steps=True,
geometries="geojson",
)
route = result["routes"][0]
print(f"Distance: {route['distance']:.1f} m")
print(f"Duration: {route['duration']:.1f} s")
Distance / duration matrix
coords = [
(7.41337, 43.72956),
(7.41546, 43.73077),
(7.41862, 43.73216),
]
result = engine.Table(coordinates=coords, annotations=["distance", "duration"])
print(result["durations"]) # 3×3 matrix
print(result["distances"]) # 3×3 matrix
Nearest road segment
result = engine.Nearest(coordinates=[(7.41337, 43.72956)], number=3)
for waypoint in result["waypoints"]:
print(waypoint["name"], waypoint["distance"])
HTTP Client
Use OSRM_HTTP when connecting to a remote osrm-routed server instead of loading data locally.
The interface is identical to the native OSRM class.
import osrm
# Public demo server (rate-limited — use for testing only)
client = osrm.OSRM_HTTP("http://router.project-osrm.org")
result = client.Route(
coordinates=[(7.41337, 43.72956), (7.41546, 43.73077)]
)
print(result["routes"][0]["distance"])
See HTTP Client for full reference.
Bulk Processing
Process large origin-destination matrices in parallel using a Polars DataFrame.
import polars as pl
import osrm
engine = osrm.OSRM("region.osrm")
df = pl.DataFrame({
"origin_lon": [7.41337, 7.41862, 7.42150],
"origin_lat": [43.72956, 43.73216, 43.73400],
"dest_lon": [7.41546, 7.42000, 7.42300],
"dest_lat": [43.73077, 43.73300, 43.73500],
})
results = osrm.bulk_route(engine, df, geometries="geojson")
print(results.select(["distance", "duration", "success"]))
See Bulk Processing for full reference including bulk_nearest and bulk_match.