Skip to main content

Async alternatives to osmnx's IO-bound public API functions

Project description

osmnx-async

Async versions of osmnx's network-bound functions. Same names, same parameters, same return types — just add await.

Note: This is an independent community project and is not affiliated with or endorsed by the osmnx project or its maintainers.

Why?

osmnx makes synchronous HTTP requests to the Overpass and Nominatim APIs. If you're building an async application (FastAPI, aiohttp, Discord bots, data pipelines with asyncio.gather), those blocking calls stall your entire event loop.

osmnx-async replaces only the HTTP layer with httpx AsyncClient. All business logic — graph construction, simplification, GeoDataFrame creation — is delegated to osmnx itself. You get identical results, verified by integration tests that compare every node, edge, and attribute.

Installation

pip install osmnx-async

Requires Python 3.11+ and osmnx 2.x.

Quick start

import asyncio
import osmnx_async as ox

async def main():
    # Exactly the same call you'd make with osmnx — just awaited
    G = await ox.graph_from_place("Piedmont, CA, USA", network_type="drive")
    print(f"{len(G)} nodes, {len(G.edges)} edges")

asyncio.run(main())

Migrating from osmnx

The function signatures are identical. Add await and swap the import:

# Before (sync)
import osmnx as ox

G = ox.graph_from_address("1600 Pennsylvania Ave, Washington DC", dist=500)
gdf = ox.features_from_place("Manhattan, NY", tags={"building": True})
point = ox.geocode("London, UK")
# After (async)
import osmnx_async as ox

G = await ox.graph_from_address("1600 Pennsylvania Ave, Washington DC", dist=500)
gdf = await ox.features_from_place("Manhattan, NY", tags={"building": True})
point = await ox.geocode("London, UK")

Module-level access works too:

from osmnx_async import graph, features, geocoder

G = await graph.graph_from_place("Piedmont, CA, USA")
gdf = await features.features_from_bbox(bbox, tags={"amenity": True})
point = await geocoder.geocode("Tokyo, Japan")

Settings

osmnx-async reads settings directly from osmnx.settings. Configure them the same way you always have:

import osmnx as ox

ox.settings.use_cache = True
ox.settings.cache_folder = "./my_cache"
ox.settings.overpass_rate_limit = True
ox.settings.requests_timeout = 300

The cache is shared — a response cached by a sync osmnx call is reused by osmnx-async, and vice versa.

Concurrent requests

The main reason to go async. Fetch multiple graphs in parallel instead of sequentially:

import asyncio
import osmnx_async as ox

async def main():
    cities = ["Piedmont, CA, USA", "Berkeley, CA, USA", "Emeryville, CA, USA"]
    graphs = await asyncio.gather(
        *(ox.graph_from_place(c, network_type="drive") for c in cities)
    )
    for city, G in zip(cities, graphs):
        print(f"{city}: {len(G)} nodes")

asyncio.run(main())

Note: Overpass and Nominatim enforce rate limits. osmnx-async respects these automatically (Nominatim: 1 req/sec per hostname, Overpass: server-side slot management). Concurrent tasks will wait as needed.

Available functions

Every osmnx function that makes HTTP requests has an async equivalent:

Module Function What it does
graph graph_from_bbox Graph within bounding box
graph graph_from_point Graph within distance of point
graph graph_from_address Graph within distance of address
graph graph_from_place Graph within place boundary
graph graph_from_polygon Graph within polygon
features features_from_bbox OSM features within bounding box
features features_from_point OSM features within distance of point
features features_from_address OSM features within distance of address
features features_from_place OSM features within place boundary
features features_from_polygon OSM features within polygon
geocoder geocode Place name to (lat, lon)
geocoder geocode_to_gdf Place name to GeoDataFrame
elevation add_node_elevations_google Add elevation data to graph nodes

Functions that don't make network requests (plotting, stats, simplification, IO, routing, etc.) are pure computation and don't need async variants. Use them directly from osmnx as usual.

Compatibility

osmnx-async validates at import time that the osmnx internals it depends on are present and have the expected signatures. If osmnx releases a breaking change, you'll get a clear error at import osmnx_async rather than a cryptic failure deep in a call stack:

OsmnxCompatibilityError: osmnx-async depends on osmnx internals that are
missing in the installed version. Missing: osmnx.graph._create_graph

Supported: osmnx >= 2.0, < 3.0.

Development

git clone https://github.com/cmcconomyfwig/osmnx-async.git
cd osmnx-async
uv sync

# Unit tests (mocked, fast)
make test

# Integration tests (real API calls, slower)
make test-integration

# Build (syncs version from installed osmnx, then builds wheel)
make build

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

osmnx_async-2.1.0.post1.tar.gz (79.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

osmnx_async-2.1.0.post1-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file osmnx_async-2.1.0.post1.tar.gz.

File metadata

  • Download URL: osmnx_async-2.1.0.post1.tar.gz
  • Upload date:
  • Size: 79.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for osmnx_async-2.1.0.post1.tar.gz
Algorithm Hash digest
SHA256 7de6b9d07f6daec045ebc03d3eaeaa100fb5a2cbde080d315d1391b5b3a94a77
MD5 4f3376cddf90f7a12ecf338b88cb9c9e
BLAKE2b-256 8e48a0634f17c7610b02a1fdd30a8003d0352981b4a30fcdc104b3003f9a0082

See more details on using hashes here.

Provenance

The following attestation bundles were made for osmnx_async-2.1.0.post1.tar.gz:

Publisher: publish.yml on cmcconomyfwig/osmnx-async

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file osmnx_async-2.1.0.post1-py3-none-any.whl.

File metadata

File hashes

Hashes for osmnx_async-2.1.0.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 f34151b9343f5effd0ebbe941783e77ecfee61de3de60ad022c2e2f201916b69
MD5 b4b941981f6bb1a705390367f43e2153
BLAKE2b-256 f48ceca554fcc01b78a18c655f6149b84e7ec0efa8e23db6421333ac4f667db5

See more details on using hashes here.

Provenance

The following attestation bundles were made for osmnx_async-2.1.0.post1-py3-none-any.whl:

Publisher: publish.yml on cmcconomyfwig/osmnx-async

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page