Skip to content

Commit 2bc8681

Browse files
authored
Merge pull request #134 from KaartGroup/api_status
Methods to check API status
2 parents cd544c5 + 9e4a885 commit 2bc8681

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

overpass/api.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import csv
99
import geojson
1010
import logging
11+
import re
1112
from datetime import datetime
1213
from shapely.geometry import Polygon, Point
1314
from io import StringIO
@@ -138,6 +139,70 @@ def get(self, query, responseformat="geojson", verbosity="body", build=True, dat
138139
# construct geojson
139140
return self._as_geojson(response["elements"])
140141

142+
@staticmethod
143+
def _api_status() -> dict:
144+
"""
145+
:returns: dict describing the client's status with the API
146+
"""
147+
endpoint = "https://overpass-api.de/api/status"
148+
149+
r = requests.get(endpoint)
150+
lines = tuple(r.text.splitlines())
151+
152+
available_re = re.compile(r'\d(?= slots? available)')
153+
available_slots = int(
154+
available_re.search(lines[3]).group()
155+
if available_re.search(lines[3])
156+
else 0
157+
)
158+
159+
waiting_re = re.compile(r'(?<=Slot available after: )[\d\-TZ:]{20}')
160+
waiting_slots = tuple(
161+
datetime.strptime(
162+
waiting_re.search(line).group(), "%Y-%m-%dT%H:%M:%S%z"
163+
)
164+
for line in lines if waiting_re.search(line)
165+
)
166+
167+
current_idx = next(
168+
i for i, word in enumerate(lines)
169+
if word.startswith('Currently running queries')
170+
)
171+
running_slots = tuple(tuple(line.split()) for line in lines[current_idx + 1:])
172+
running_slots_datetimes = tuple(
173+
datetime.strptime(
174+
slot[3], "%Y-%m-%dT%H:%M:%S%z"
175+
)
176+
for slot in running_slots
177+
)
178+
179+
return {
180+
"available_slots": available_slots,
181+
"waiting_slots": waiting_slots,
182+
"running_slots": running_slots_datetimes,
183+
}
184+
185+
@property
186+
def slots_available(self) -> int:
187+
"""
188+
:returns: count of open slots the client has on the server
189+
"""
190+
return self._api_status()["available_slots"]
191+
192+
@property
193+
def slots_waiting(self) -> tuple:
194+
"""
195+
:returns: tuple of datetimes representing waiting slots and when they will be available
196+
"""
197+
return self._api_status()["waiting_slots"]
198+
199+
@property
200+
def slots_running(self) -> tuple:
201+
"""
202+
:returns: tuple of datetimes representing running slots and when they will be freed
203+
"""
204+
return self._api_status()["running_slots"]
205+
141206
def search(self, feature_type, regex=False):
142207
"""Search for something."""
143208
raise NotImplementedError()

tests/test_api.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,30 @@ def _get_from_overpass(self, query):
5353
osm_geo = api.get("rel(6518385);out body geom;way(10322303);out body geom;node(4927326183);", verbosity='body geom')
5454
ref_geo = geojson.load(open(os.path.join(os.path.dirname(__file__), "example.json"), "r"))
5555
assert osm_geo==ref_geo
56+
57+
58+
def test_slots_available():
59+
api = overpass.API(debug=True)
60+
61+
map_query = overpass.MapQuery(37.86517, -122.31851, 37.86687, -122.31635)
62+
api.get(map_query)
63+
64+
assert api.slots_available <= 2 and api.slots_available >= 0
65+
66+
67+
def test_slots_running():
68+
api = overpass.API(debug=True)
69+
70+
map_query = overpass.MapQuery(37.86517, -122.31851, 37.86687, -122.31635)
71+
api.get(map_query)
72+
73+
assert isinstance(api.slots_running, tuple)
74+
75+
76+
def test_slots_waiting():
77+
api = overpass.API(debug=True)
78+
79+
map_query = overpass.MapQuery(37.86517, -122.31851, 37.86687, -122.31635)
80+
api.get(map_query)
81+
82+
assert isinstance(api.slots_waiting, tuple)

0 commit comments

Comments
 (0)