Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
7458ee1
linux works
nilsnolde Apr 16, 2026
d4e62f9
add to agent.md
nilsnolde Apr 16, 2026
9fe055b
trigger CI
nilsnolde Apr 16, 2026
77de8bd
try CI
nilsnolde Apr 16, 2026
a752d92
try windows
nilsnolde Apr 16, 2026
e16b525
trigger CI
nilsnolde Apr 16, 2026
54ec941
more ci
nilsnolde Apr 16, 2026
0dd6b0d
suppress clang warnings
nilsnolde Apr 16, 2026
91855bc
suppress more
nilsnolde Apr 16, 2026
cfa1065
fix mac & win
nilsnolde Apr 17, 2026
3f3e452
fix path to conanrun.bat
nilsnolde Apr 17, 2026
3713f44
add sdist so that version resolves properly for linux
nilsnolde Apr 17, 2026
2493aeb
fix sdist to wheel
nilsnolde Apr 17, 2026
d2f5e1a
debug
nilsnolde Apr 17, 2026
a3d2ef7
try embedding in huge workflow
nilsnolde Apr 17, 2026
da8e068
trigger CI
nilsnolde Apr 17, 2026
ab38ab8
minor fix
nilsnolde Apr 17, 2026
3c5770f
huh, needs explicit vesion
nilsnolde Apr 17, 2026
062c020
more excluded for sdist
nilsnolde Apr 17, 2026
216bc0d
osx diagnostics
nilsnolde Apr 17, 2026
7dbde9a
Merge remote-tracking branch 'origin/master' into nn-py-bindings
nilsnolde Apr 17, 2026
427b420
trigger CI
nilsnolde Apr 17, 2026
a1209b0
more ci
nilsnolde Apr 17, 2026
89b2322
try again macos
nilsnolde Apr 20, 2026
636123b
Merge remote-tracking branch 'origin/master' into nn-py-bindings
nilsnolde Apr 20, 2026
f932c2e
let's try
nilsnolde Apr 21, 2026
1a6c95a
change caching behavior, try to remove libiconv workaround for macos
nilsnolde Apr 21, 2026
a964f66
change runner back to 15. alternatively python bindings could become …
nilsnolde Apr 21, 2026
74a9b4d
disable all other workflows
nilsnolde Apr 21, 2026
63c50f1
try pinning boost to 1.85
nilsnolde Apr 21, 2026
e203d40
push clang diagnostic around boost crc header include
nilsnolde Apr 21, 2026
5f713d0
trigger CI
nilsnolde Apr 21, 2026
4ccad42
use ccache cache on osx & linux for cibuildwheel
nilsnolde Apr 21, 2026
25d54d4
try forcing brew headers to be -isystem
nilsnolde Apr 21, 2026
f26f848
try windows now
nilsnolde Apr 22, 2026
1f3c201
try release on my fork
nilsnolde Apr 22, 2026
c958bf5
Merge remote-tracking branch 'origin/master' into nn-py-bindings
nilsnolde Apr 22, 2026
b57cd7b
strip to only use python stuff and release that
nilsnolde Apr 22, 2026
54b9347
use workflows from this branch
nilsnolde Apr 22, 2026
7eed6d3
chore: bump version to 26.4.4
github-actions[bot] Apr 22, 2026
ddd0a44
oops
nilsnolde Apr 22, 2026
ee44b63
Merge branch 'nn-py-bindings' of github.com:nilsnolde/osrm-backend in…
nilsnolde Apr 22, 2026
a1ba443
chore: bump version to 26.4.5
github-actions[bot] Apr 22, 2026
17174d1
revert CI testing stuff
nilsnolde Apr 22, 2026
e5a1e6c
Merge branch 'nn-py-bindings' of github.com:nilsnolde/osrm-backend in…
nilsnolde Apr 22, 2026
6bacda3
revert js package*.json
nilsnolde Apr 22, 2026
b08cf08
add other yml
nilsnolde Apr 22, 2026
d58f146
more uncommenting
nilsnolde Apr 22, 2026
f86e062
last fixes
nilsnolde Apr 22, 2026
b361809
add maintenancen commnet
nilsnolde Apr 22, 2026
9ab861d
update development.md
nilsnolde Apr 22, 2026
5b8412d
run pre-commit and add job to check python .pyi stub
nilsnolde Apr 22, 2026
2bcb003
revert version update
nilsnolde Apr 22, 2026
b65c287
docs update
nilsnolde Apr 22, 2026
760b656
change to real pypi
nilsnolde Apr 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ debug.lua
##########################
lib/binding_napi_v8

# Python
##########################
__pycache__/
*.whl

# documentation related files
##########################
.vitepress/cache
Expand Down
17 changes: 17 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
repos:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is harmless for most people. I really like pre-commit, avoids the loop over ci when triggered before committing locally

- repo: https://github.com/pre-commit/mirrors-clang-format
# matches (more or less) the current clang-format on OSRM CI
# TODO(nils): we should change to pypi's clang tools for reproducibility
rev: v18.1.8
hooks:
- id: clang-format
types_or: [c, c++]
files: ^src/python/
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.5
hooks:
- id: ruff
args: [--fix]
files: ^(src/python/|test/python/)
- id: ruff-format
files: ^(src/python/|test/python/)
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ option(ENABLE_DEBUG_LOGGING "Use debug logging in release mode" OFF)
option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF)
option(ENABLE_LTO "Use Link Time Optimisation" ON)
option(ENABLE_NODE_BINDINGS "Build NodeJs bindings" OFF)
option(ENABLE_PYTHON_BINDINGS "Build Python bindings" OFF)
option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF)

if (ENABLE_CONAN)
Expand Down Expand Up @@ -719,6 +720,10 @@ if (ENABLE_NODE_BINDINGS)
add_subdirectory(src/nodejs)
endif()

if (ENABLE_PYTHON_BINDINGS)
add_subdirectory(src/python)
endif()

if (ENABLE_FUZZING)
# Requires libosrm being built with sanitizers; make configurable and default to ubsan
set(FUZZ_SANITIZER "undefined" CACHE STRING "Sanitizer to be used for Fuzz testing")
Expand Down
10 changes: 8 additions & 2 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ export default defineConfig({
nav: [
{ text: 'Home', link: '/' },
{ text: 'HTTP API', link: '/http' },
{ text: 'Node.js API', link: '/nodejs/api' }
{ text: 'Node.js API', link: '/nodejs/api' },
{ text: 'Python', items: [
{ text: 'API', link: '/python/api' },
{ text: 'Development', link: '/python/development' }
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to be really thorough, so I had claude add some python development and API docs. python doesn't work very well with vitepress with pulling out docstrings etc. it's mostly mkdocs these days in python land. not sure, but I could imagine mkdocs support JS docstrings as well. I guess you just switched to vitepress @DennisOSRM , not sure you'd be open to ditch it again potentially?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for reference, this is the mkdocs based documentation I configured for valhalla: https://valhalla.github.io/valhalla/

]}
],

sidebar: [
Expand All @@ -24,7 +28,8 @@ export default defineConfig({
{ text: 'Tool options', link: '/tools'},
{ text: 'Developing', link: '/developing' },
{ text: 'Testing', link: '/testing' },
{ text: 'Releasing', link: '/releasing' }
{ text: 'Releasing', link: '/releasing' },
{ text: 'Python Development', link: '/python/development' }
]
},
{
Expand All @@ -33,6 +38,7 @@ export default defineConfig({
{ text: 'HTTP API', link: '/http' },
{ text: 'Node.js API', link: '/nodejs/api' },
{ text: 'libosrm C++ API', link: '/libosrm' },
{ text: 'Python API', link: '/python/api' },
]
},
{
Expand Down
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ hero:
- theme: alt
text: Node.js API
link: /nodejs/api
- theme: alt
text: Python API
link: /python/api
- theme: alt
text: View on GitHub
link: https://github.com/Project-OSRM/osrm-backend
Expand Down Expand Up @@ -46,6 +49,7 @@ OSRM provides powerful routing services through both HTTP and Node.js APIs:

- **[HTTP API](./http.md)** - RESTful API for routing services
- **[Node.js API](./nodejs/api.md)** - Native Node.js bindings for embedded use
- **[Python API](./python/api.md)** - Python bindings via nanobind ([Development Guide](./python/development.md))

## Documentation

Expand Down
243 changes: 243 additions & 0 deletions docs/python/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
# Python API
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no real support it seems for python docstrings -> vitepress. I added a line in AGENT.md to keep this doc up-to-date when there's python API changes


The Python bindings provide access to OSRM's routing services through the `osrm` package. Install with `pip install osrm-bindings`.

## OSRM

The `OSRM` class is the main entry point. It requires a `.osrm.*` dataset prepared by the OSRM toolchain.

```python
import osrm

# From file
engine = osrm.OSRM("path/to/data.osrm")

# With keyword arguments
engine = osrm.OSRM(
storage_config="path/to/data.osrm",
algorithm="CH", # or "MLD"
use_shared_memory=False,
max_locations_trip=3,
max_locations_viaroute=3,
max_locations_distance_table=3,
max_locations_map_matching=3,
max_results_nearest=1,
max_alternatives=1,
default_radius="unlimited",
)

# Using shared memory (requires osrm-datastore)
engine = osrm.OSRM(use_shared_memory=True)
```

### Parameters

- **`storage_config`** `str` - Path to the `.osrm` dataset.
- **`algorithm`** `str` - Routing algorithm: `"CH"` or `"MLD"`. Default: `"CH"`.
- **`use_shared_memory`** `bool` - Connect to shared memory datastore. Default: `True`.
- **`dataset_name`** `str` - Named shared memory dataset (requires `osrm-datastore --dataset_name`).
- **`memory_file`** `str` - **Deprecated.** Equivalent to `use_mmap=True`.
- **`use_mmap`** `bool` - Memory-map files instead of loading into RAM.
- **`max_locations_trip`** `int` - Max locations in trip queries.
- **`max_locations_viaroute`** `int` - Max locations in route queries.
- **`max_locations_distance_table`** `int` - Max locations in table queries.
- **`max_locations_map_matching`** `int` - Max locations in match queries.
- **`max_results_nearest`** `int` - Max results in nearest queries.
- **`max_alternatives`** `int` - Max alternative routes.
- **`default_radius`** `float | "unlimited"` - Default search radius in meters.

### Services

All service methods take a parameters object and return a dict-like `Object`:

```python
result = engine.Route(route_params)
print(result["routes"])
print(result["waypoints"])
```

## Route

Finds the fastest route between two or more coordinates.

```python
params = osrm.RouteParameters(
coordinates=[(7.41337, 43.72956), (7.41546, 43.73077)],
steps=True,
alternatives=2,
annotations=["speed", "duration"],
geometries="geojson",
overview="full",
)
result = engine.Route(params)
```

### RouteParameters

Inherits all [BaseParameters](#baseparameters).

- **`steps`** `bool` - Return route steps for each leg. Default: `False`.
- **`alternatives`** `int` - Number of alternative routes to search for. Default: `0`.
- **`annotations`** `list[str]` - Additional metadata: `"none"`, `"duration"`, `"nodes"`, `"distance"`, `"weight"`, `"datasources"`, `"speed"`, `"all"`. Default: `[]`.
- **`geometries`** `str` - Geometry format: `"polyline"`, `"polyline6"`, `"geojson"`. Default: `"polyline"`.
- **`overview`** `str` - Overview geometry: `"simplified"`, `"full"`, `"false"`. Default: `"simplified"`.
- **`continue_straight`** `bool | None` - Force route to continue straight at waypoints.
- **`waypoints`** `list[int]` - Indices of coordinates to treat as waypoints. Must include first and last.

## Table

Computes duration/distance matrices between coordinates.

```python
params = osrm.TableParameters(
coordinates=[(7.41337, 43.72956), (7.41546, 43.73077), (7.41862, 43.73216)],
sources=[0],
destinations=[1, 2],
annotations=["duration", "distance"],
)
result = engine.Table(params)
```

### TableParameters

Inherits all [BaseParameters](#baseparameters).

- **`sources`** `list[int]` - Indices of source coordinates. Default: all.
- **`destinations`** `list[int]` - Indices of destination coordinates. Default: all.
- **`annotations`** `list[str]` - `"duration"`, `"distance"`, `"all"`. Default: `["duration"]`.
- **`fallback_speed`** `float` - Speed for crow-flies fallback when no route found.
- **`fallback_coordinate_type`** `str` - `"input"` or `"snapped"`.
- **`scale_factor`** `float` - Scales duration values. Default: `1.0`.

## Nearest

Finds the nearest street segment for a coordinate.

```python
params = osrm.NearestParameters(
coordinates=[(7.41337, 43.72956)],
number_of_results=3,
)
result = engine.Nearest(params)
```

### NearestParameters

Inherits all [BaseParameters](#baseparameters).

- **`number_of_results`** `int` - Number of nearest segments to return. Default: `1`.

## Match

Snaps noisy GPS traces to the road network.

```python
params = osrm.MatchParameters(
coordinates=[(7.41337, 43.72956), (7.41546, 43.73077), (7.41862, 43.73216)],
timestamps=[1424684612, 1424684616, 1424684620],
radiuses=[5.0, 5.0, 5.0],
annotations=["speed"],
geometries="geojson",
)
result = engine.Match(params)
```

### MatchParameters

Inherits all [RouteParameters](#routeparameters) and [BaseParameters](#baseparameters).

- **`timestamps`** `list[int]` - UNIX timestamps for each coordinate.
- **`gaps`** `str` - Gap handling: `"split"` or `"ignore"`. Default: `"split"`.
- **`tidy`** `bool` - Remove duplicates. Default: `False`.
- **`waypoints`** `list[int]` - Indices of coordinates to treat as waypoints.

## Trip

Solves the Traveling Salesman Problem for the given coordinates.

```python
params = osrm.TripParameters(
coordinates=[(7.41337, 43.72956), (7.41546, 43.73077), (7.41862, 43.73216)],
source="first",
destination="last",
roundtrip=True,
annotations=["duration"],
geometries="geojson",
)
result = engine.Trip(params)
```

### TripParameters

Inherits all [RouteParameters](#routeparameters) and [BaseParameters](#baseparameters).

- **`source`** `str` - `"any"` or `"first"`. Default: `"any"`.
- **`destination`** `str` - `"any"` or `"last"`. Default: `"any"`.
- **`roundtrip`** `bool` - Return to first location. Default: `True`.

## Tile

Generates vector tiles with internal routing graph data.

```python
params = osrm.TileParameters(x=17059, y=11948, z=15)
result = engine.Tile(params) # returns bytes
```

### TileParameters

- **`x`** `int` - Tile x coordinate.
- **`y`** `int` - Tile y coordinate.
- **`z`** `int` - Tile zoom level.

## BaseParameters

Shared parameters inherited by Nearest, Table, Route, Match, and Trip.

- **`coordinates`** `list[tuple[float, float]]` - List of `(longitude, latitude)` pairs.
- **`hints`** `list[str | None]` - Base64-encoded hints from previous requests.
- **`radiuses`** `list[float | None]` - Search radius per coordinate in meters. `None` for unlimited.
- **`bearings`** `list[tuple[int, int] | None]` - `(bearing, range)` pairs in degrees. `None` for unrestricted.
- **`approaches`** `list[str | None]` - `"curb"`, `"unrestricted"`, or `None`.
- **`generate_hints`** `bool` - Include hints in response. Default: `True`.
- **`exclude`** `list[str]` - Road classes to avoid (e.g. `["motorway"]`).
- **`snapping`** `str` - `"default"` or `"any"`. Default: `"default"`.

## Types

### Coordinate

```python
coord = osrm.Coordinate((7.41337, 43.72956))
print(coord.lon, coord.lat)
```

### Bearing

```python
bearing = osrm.Bearing((200, 180))
print(bearing.bearing, bearing.range)
```

### Object / Array

Service results are returned as `Object` (dict-like) and `Array` (list-like) wrappers around OSRM's internal JSON types. They support `[]`, `len()`, `in`, and iteration.

```python
result = engine.Route(params)
for route in result["routes"]:
print(route["distance"], route["duration"])
```

## CLI

The package also installs OSRM command-line tools, accessible via `python -m osrm`:

```bash
python -m osrm extract data.osm.pbf -p profiles/car.lua
python -m osrm contract data.osrm
python -m osrm partition data.osrm
python -m osrm customize data.osrm
python -m osrm datastore data.osrm
python -m osrm routed data.osrm
```
Loading
Loading