Repository navigation
Fix Overpass status check, cap retries, add CI - #34
Conversation
Build the User-Agent from the package version and repo URL and send it with both the interpreter request and the /api/status request, which also moves to https. Without it the status endpoint returns HTTP 406.
The /api/status layout gained "Rate limit" and "Announced endpoint" lines, so reading line index 3 no longer finds the slot line. Find it by content instead. overpass_request() recursed forever on 429/504 and get_pause_duration() recursed forever while the server was busy. Both now loop with a max_retries keyword (default 5). overpass_request() raises OverpassRetryError when retries run out; get_pause_duration() falls back to default_duration.
Mock requests so the tests need no network. The status page text captured from overpass-api.de on 2026-10-04 is kept as a fixture.
Runs the unit tests that do not need the network on pushes and pull requests to dev.
Now that the status request succeeds, get_pause_duration() returns 0 whenever slots are free, including while the server is overloaded and returning 504s, so all retries fired back to back. Unless error_pause_duration is given, wait at least 5 seconds, doubling with each retry up to 60, or longer if the status page asks for it. Also send the interpreter request to overpass-api.de, the host the status request uses; log server remarks at WARNING (the level was passed to str.format instead of log); note that pause_duration is unused; and point CI at main, which becomes the integration branch.
- osm_net_download(), ways_in_bbox() and network_from_bbox() take max_retries and pass it on to overpass_request(). One request that runs out of retries fails the whole download, so callers with large bounding boxes need a way to allow more. - Read the wait for the next slot from the status line's "in N seconds", which does not depend on the local clock, and fall back on the timestamp (parsed with strptime). This drops the dateutil import, which was never a declared dependency. - Treat "0 slots available" as no free slot. - Count status checks correctly in the give-up log message, and log each busy status check, so the time spent polling shows in the log. - Raise ValueError for a negative max_retries instead of failing with UnboundLocalError, and work out the host once per request.
smmaurer
left a comment
There was a problem hiding this comment.
Thanks Paul, this looks good! I pushed a couple of follow-up commits and retargeted the PR to main, which we'll make the default branch as part of the new release.
Retry backoff. With the status request working, get_pause_duration() returns 0 whenever slots are free, including while the server is overloaded and returning 504s. So the 5 retries ran back to back. I saw this in a live test run: test_column_names raised OverpassRetryError after several "Re-trying request in 0.00 seconds" messages. Before this PR, the 406 on the status request meant the pause always fell back to 10 s. Now, unless error_pause_duration is given, each retry waits at least 5 s, doubling up to 60 s, or longer if the status page asks for it. In a live run today the server returned four 504s in a row; the retries waited 5, 10, 20 and 40 s and the fifth attempt succeeded.
Smaller items:
- Consistent domains for interpreter request and status request.
- Server remarks are logged at WARNING. The existing code passed
level=tostr.format()instead oflog(). - The
pause_durationdocstring now clarifies that the argument is unused. ci.ymlnow runs onmain.
Four new offline tests cover these changes, and there are three changelog bullets. Offline: 28 passed, 14 skipped; pycodestyle is clean. Live, only the six tests with outdated OSM element counts still fail. A packaging/CI PR will follow and run those tests against saved Overpass responses.
#33 (Rhys Williams) fixed the HTTP 406 on the main Overpass request by sending a User-Agent and switching to https. This follows up on the rest of that code path.
What this changes
get_pause_duration()still calledhttp://overpass-api.de/api/statuswith no User-Agent, so it got the 406 page and always fell back to 10 s. It now uses https and the same User-Agent.osmnet/<version> (+https://github.com/UDST/osmnet), built fromosmnet.__version__and used by both requests. To make that importable,__version__is now set inosmnet/__init__.pybeforefrom .load import *.Rate limitandAnnounced endpointlines, so that index no longer holds the slot line. It now finds the line by content:N slots available, thenSlot available after: <time>(earliest one), thenCurrently running queries.overpass_request()used to recurse forever on 429/504; it now loops with a newmax_retries=5keyword and raisesOverpassRetryErrorwhen the retries run out.get_pause_duration()used to recurse forever while the server was busy; it now takesmax_retries=5and falls back todefault_duration. Existing call signatures are unchanged. One side effect: an expliciterror_pause_durationnow applies to every retry, not just the first. The status request also gets a 30 s timeout.Live
/api/statuspage fetched on 2026-10-04, also saved as a test fixture:Tests and CI
osmnet/tests/test_overpass.py(17 tests,requestsmocked, no network). It covers the live layout, the old layout,Slot available after,Currently running, the 406 HTML page, the User-Agent on both requests, and retry exhaustion. 15 of the 17 fail against currentdev.test_load.pythat query Overpass are skipped whenOSMNET_SKIP_NETWORK_TESTS=1. There was no existing marker. Local runs are unchanged unless the variable is set..github/workflows/ci.ymlruns the offline tests on Python 3.10–3.13 (ubuntu-latest) on push and pull_request todev. CI has effectively been dead:.travis.ymlandappveyor.ymlare still in the repo but no longer run. I left them in place.Local results on Python 3.13 (pandas 3.0.6, geopandas 1.2.0):
OSMNET_SKIP_NETWORK_TESTS=1: 24 passed, 14 skipped.test_make_osm_query,test_parse_network_osm_query,test_intersection_nodes2,test_node_pairs_two_way,test_node_pairs_one_wayandtest_custom_query_pass. They assert hard-coded element counts that no longer match current OSM data, and they fail the same way on unmodifieddev.pycodestyle --max-line-length=100 osmnetis clean.Not done here
CHANGELOG.rsthas a new "Unreleased" entry that credits Fix Overpass API 406 errors by setting request headers #33. A 0.1.8 release should follow this.unary_unionand the stale counts in the live tests are untouched.