OSM: Fair-Use-Rate-Limit + User-Agent für Overpass-Anfragen
Semaphore 2→1 (nur 1 gleichzeitige Anfrage), 2s Mindestabstand, User-Agent mit App-Name und Kontakt — Standard-Höflichkeit für Community-Dienste wie kumi.systems.
This commit is contained in:
parent
92d583e661
commit
163b942ea4
1 changed files with 16 additions and 3 deletions
|
|
@ -24,8 +24,11 @@ OVERPASS_URLS = [
|
||||||
'https://overpass-api.de/api/interpreter',
|
'https://overpass-api.de/api/interpreter',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Globales Limit: max 2 gleichzeitige Overpass-Anfragen (Prewarm + User geteilt)
|
# Max 1 gleichzeitige Overpass-Anfrage + 2s Mindestabstand (Fair Use)
|
||||||
_overpass_sem = asyncio.Semaphore(2)
|
_overpass_sem = asyncio.Semaphore(1)
|
||||||
|
_overpass_last_req = 0.0
|
||||||
|
_OVERPASS_MIN_DELAY = 2.0 # Sekunden zwischen Anfragen
|
||||||
|
_OVERPASS_UA = 'BanYaro/1.0 (https://banyaro.app; dog-walking PWA; contact: mail@motocamp.de)'
|
||||||
|
|
||||||
OSM_QUERIES = {
|
OSM_QUERIES = {
|
||||||
'waste_basket': '[out:json][timeout:20];node["amenity"="waste_basket"]({bbox});out;',
|
'waste_basket': '[out:json][timeout:20];node["amenity"="waste_basket"]({bbox});out;',
|
||||||
|
|
@ -68,12 +71,22 @@ def _covering_tiles(south, west, north, east, zoom):
|
||||||
# Overpass-Fetch + Cache
|
# Overpass-Fetch + Cache
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
async def _fetch_overpass(query):
|
async def _fetch_overpass(query):
|
||||||
|
global _overpass_last_req
|
||||||
for url in OVERPASS_URLS:
|
for url in OVERPASS_URLS:
|
||||||
for attempt in range(2):
|
for attempt in range(2):
|
||||||
try:
|
try:
|
||||||
async with _overpass_sem:
|
async with _overpass_sem:
|
||||||
async with httpx.AsyncClient(timeout=40) as client:
|
# Fair-Use: Mindestabstand zwischen Anfragen einhalten
|
||||||
|
import time
|
||||||
|
wait = _OVERPASS_MIN_DELAY - (time.monotonic() - _overpass_last_req)
|
||||||
|
if wait > 0:
|
||||||
|
await asyncio.sleep(wait)
|
||||||
|
async with httpx.AsyncClient(
|
||||||
|
timeout=40,
|
||||||
|
headers={'User-Agent': _OVERPASS_UA},
|
||||||
|
) as client:
|
||||||
r = await client.post(url, data={'data': query})
|
r = await client.post(url, data={'data': query})
|
||||||
|
_overpass_last_req = time.monotonic()
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
return r.json().get('elements', [])
|
return r.json().get('elements', [])
|
||||||
if r.status_code == 429:
|
if r.status_code == 429:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue