A Python interface to the OpenStreetMap Overpass API for querying geographical data
—
Comprehensive exception classes for handling various types of Overpass API errors. These exceptions provide specific error information to help diagnose and handle different failure modes when querying the Overpass API.
Base exception class for all Overpass API-related errors.
class OverpassError(Exception):
"""
Base exception class for all Overpass API errors.
Super class that all other Overpass exceptions inherit from.
Use this for general exception handling when you want to catch
any Overpass-related error.
"""import overpass
api = overpass.API()
try:
response = api.get('invalid query syntax')
except overpass.OverpassError as e:
print(f"Overpass error occurred: {e}")
# Handle any Overpass-related errorException raised when the Overpass query contains syntax errors.
class OverpassSyntaxError(OverpassError, ValueError):
"""
Exception for syntax errors in Overpass queries.
Inherits from both OverpassError and ValueError.
Raised when the Overpass API returns HTTP 400 indicating malformed query.
"""
def __init__(self, request: str):
"""
Args:
request: The malformed request that caused the error
"""
self.request = requesttry:
# Invalid Overpass QL syntax
response = api.get('node[name="City" invalid_syntax')
except overpass.OverpassSyntaxError as e:
print(f"Query syntax error: {e}")
print(f"Problematic query: {e.request}")
# Fix the query syntax and retryException raised when a request exceeds the configured timeout period.
class TimeoutError(OverpassError):
"""
Exception for request timeouts.
Raised when the HTTP request to the Overpass API exceeds the timeout limit.
"""
def __init__(self, timeout: Union[int, float, Tuple[int, int]]):
"""
Args:
timeout: The timeout value that was exceeded
"""
self.timeout = timeouttry:
# Long-running query that might timeout
response = api.get('way[highway=motorway](area:3602758138);')
except overpass.TimeoutError as e:
print(f"Query timed out after {e.timeout} seconds")
# Retry with longer timeout or simplify query
api = overpass.API(timeout=120) # Increase timeoutException raised when attempting to run multiple simultaneous requests.
class MultipleRequestsError(OverpassError):
"""
Exception for multiple simultaneous requests.
Raised when the Overpass API returns HTTP 429 indicating that
the client is attempting multiple requests at the same time.
"""try:
# Don't do this - multiple simultaneous requests
import threading
def query_worker():
api.get('node["name"="City"]')
threads = [threading.Thread(target=query_worker) for _ in range(5)]
for t in threads:
t.start()
except overpass.MultipleRequestsError:
print("Cannot run multiple requests simultaneously")
# Implement request queuing or sequential executionException raised when the Overpass server is under high load and declines the request.
class ServerLoadError(OverpassError):
"""
Exception when server is under load.
Raised when the Overpass API returns HTTP 504 indicating the server
is currently under load and declined the request.
"""
def __init__(self, timeout: Union[int, float, Tuple[int, int]]):
"""
Args:
timeout: The timeout value used for the failed request
"""
self.timeout = timeoutimport time
try:
response = api.get('complex_query_here')
except overpass.ServerLoadError as e:
print(f"Server is under load, timeout was {e.timeout}")
# Check server status and wait
wait_time = api.slot_available_countdown
if wait_time > 0:
print(f"Waiting {wait_time} seconds for server availability")
time.sleep(wait_time)
# Retry the request
response = api.get('complex_query_here')Exception raised when the Overpass server returns a runtime error.
class ServerRuntimeError(OverpassError):
"""
Exception for server runtime errors.
Raised when the Overpass server encounters a runtime error during query execution.
This typically indicates issues with the query logic or server-side processing problems.
"""
def __init__(self, message: str):
"""
Args:
message: The runtime error message from the server
"""
self.message = messagetry:
# Query that might cause server runtime error
response = api.get('very_complex_query_with_potential_issues')
except overpass.ServerRuntimeError as e:
print(f"Server runtime error: {e.message}")
# Simplify query or report issueException for unhandled or unknown Overpass API errors.
class UnknownOverpassError(OverpassError):
"""
Exception for unknown errors.
Raised when an unexpected error occurs during the request that
doesn't fit into other specific error categories.
"""
def __init__(self, message: str):
"""
Args:
message: Description of the unknown error
"""
self.message = messagetry:
response = api.get('node["name"="City"]')
except overpass.UnknownOverpassError as e:
print(f"Unknown error occurred: {e.message}")
# Log error details and possibly report to developersimport overpass
import time
def robust_query(api, query, max_retries=3):
"""Execute query with comprehensive error handling and retries."""
for attempt in range(max_retries):
try:
return api.get(query)
except overpass.OverpassSyntaxError as e:
print(f"Syntax error in query: {e.request}")
raise # Don't retry syntax errors
except overpass.TimeoutError as e:
print(f"Timeout after {e.timeout}s, attempt {attempt + 1}")
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
continue
raise
except overpass.ServerLoadError as e:
print(f"Server under load, attempt {attempt + 1}")
wait_time = api.slot_available_countdown
if wait_time > 0 and attempt < max_retries - 1:
time.sleep(wait_time)
continue
raise
except overpass.MultipleRequestsError:
print("Multiple requests detected, waiting...")
time.sleep(5)
if attempt < max_retries - 1:
continue
raise
except overpass.ServerRuntimeError as e:
print(f"Server runtime error: {e.message}")
raise # Don't retry runtime errors - they're typically query logic issues
except overpass.OverpassError as e:
print(f"General Overpass error: {e}")
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
continue
raise
raise Exception("Max retries exceeded")
# Usage
api = overpass.API()
try:
response = robust_query(api, 'node["name"="Salt Lake City"]')
except overpass.OverpassError:
print("Failed to execute query after all retries")The exceptions are mapped to specific HTTP status codes:
OverpassSyntaxError - Malformed queryMultipleRequestsError - Too many simultaneous requestsServerLoadError - Server under load/timeoutUnknownOverpassError - Unexpected status codesInstall with Tessl CLI
npx tessl i tessl/pypi-overpass