betterwithage's picture
chore(sync): mirror backend .py + Dockerfile to Space (hf-sync-backend)
c308a36 verified
Raw
History Blame
6.33 kB
# SPDX-License-Identifier: Apache-2.0
# © 2026 Lutar, Stephen P. — SZL Holdings · Doctrine v11 · Perplexity Computer Agent.
"""killinchu / shared geo live connectors (keyless → CONNECTED now).
usgs USGS earthquake feeds (GeoJSON) keyless
noaa NOAA api.weather.gov forecast/alerts keyless (UA header)
overpass OpenStreetMap Overpass API keyless
"""
from __future__ import annotations
import time
from typing import Any
from ..base import Connector, Records, State, http_json, http_text, _now
from ..registry import register
_CACHE: dict[str, tuple[float, Any]] = {}
def _cached(k, ttl):
h = _CACHE.get(k)
return h[1] if h and (time.time() - h[0]) < ttl else None
def _put(k, v):
_CACHE[k] = (time.time(), v)
@register
class UsgsConnector(Connector):
id = "usgs"
label = "USGS earthquakes"
category = "geo"
auth_kind = "none"
free_tier = True
provider_base = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson"
docs_url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php"
schema_preview = ["mag", "place", "time", "longitude", "latitude", "depth"]
def _probe(self):
st, _ = http_json(self.provider_base)
return (st == 200), f"USGS HTTP {st}"
def read(self, query: dict | None = None) -> Records:
window = (query or {}).get("window", "all_day") # all_day|2.5_week|4.5_month
limit = max(1, min(int((query or {}).get("limit", 15)), 50))
url = f"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/{window}.geojson"
ck = f"usgs:{window}:{limit}"
c = _cached(ck, 120)
if c:
return c
st, raw = http_json(url)
if st == 200 and isinstance(raw, dict):
items = []
for f in (raw.get("features", []) or [])[:limit]:
p = f.get("properties", {}); g = f.get("geometry", {}).get("coordinates", [None, None, None])
items.append({"mag": p.get("mag"), "place": p.get("place"), "time": p.get("time"),
"longitude": g[0], "latitude": g[1], "depth": g[2]})
r = Records(connector_id=self.id, category=self.category, state=State.CONNECTED,
records=items, source=f"USGS {window} GeoJSON", live=True,
note=f"live · {len(raw.get('features', []))} events", schema_preview=self.schema_preview)
_put(ck, r)
return r
return self._ready_records(f"USGS unreachable (HTTP {st})")
@register
class NoaaConnector(Connector):
id = "noaa"
label = "NOAA weather (api.weather.gov)"
category = "geo"
auth_kind = "none"
free_tier = True
provider_base = "https://api.weather.gov"
docs_url = "https://www.weather.gov/documentation/services-web-api"
schema_preview = ["event", "severity", "area", "effective", "headline"]
def _probe(self):
st, _ = http_json(self.provider_base + "/alerts/active?limit=1")
return (st == 200), f"NOAA HTTP {st}"
def read(self, query: dict | None = None) -> Records:
limit = max(1, min(int((query or {}).get("limit", 12)), 50))
area = (query or {}).get("area", "")
url = f"{self.provider_base}/alerts/active?limit={limit}" + (f"&area={area}" if area else "")
ck = f"noaa:{area}:{limit}"
c = _cached(ck, 180)
if c:
return c
st, raw = http_json(url)
if st == 200 and isinstance(raw, dict):
items = []
for f in (raw.get("features", []) or [])[:limit]:
p = f.get("properties", {})
items.append({"event": p.get("event"), "severity": p.get("severity"),
"area": p.get("areaDesc"), "effective": p.get("effective"),
"headline": (p.get("headline") or "")[:120]})
r = Records(connector_id=self.id, category=self.category, state=State.CONNECTED,
records=items, source="NOAA /alerts/active", live=True,
note=f"live · {len(raw.get('features', []))} active alerts", schema_preview=self.schema_preview)
_put(ck, r)
return r
return self._ready_records(f"NOAA unreachable (HTTP {st})")
@register
class OverpassConnector(Connector):
id = "overpass"
label = "OpenStreetMap Overpass"
category = "geo"
auth_kind = "none"
free_tier = True
provider_base = "https://overpass-api.de/api/interpreter"
docs_url = "https://wiki.openstreetmap.org/wiki/Overpass_API"
schema_preview = ["type", "id", "name", "lat", "lon"]
def _probe(self):
q = "[out:json][timeout:8];node(1);out;"
import urllib.parse as up
st, _ = http_json(self.provider_base + "?data=" + up.quote(q), timeout=10.0)
return (st == 200), f"Overpass HTTP {st}"
def read(self, query: dict | None = None) -> Records:
# default: harbours/ports near a bbox (maritime/coastline use)
oql = (query or {}).get("oql") or (
"[out:json][timeout:15];node[\"harbour\"=\"yes\"](36.0,-6.0,44.0,3.0);out 15;")
limit = max(1, min(int((query or {}).get("limit", 15)), 40))
import urllib.parse as up
ck = f"overpass:{hash(oql)}:{limit}"
c = _cached(ck, 600)
if c:
return c
st, raw = http_json(self.provider_base + "?data=" + up.quote(oql), timeout=20.0)
if st == 200 and isinstance(raw, dict):
items = []
for el in (raw.get("elements", []) or [])[:limit]:
items.append({"type": el.get("type"), "id": el.get("id"),
"name": (el.get("tags", {}) or {}).get("name"),
"lat": el.get("lat"), "lon": el.get("lon")})
r = Records(connector_id=self.id, category=self.category, state=State.CONNECTED,
records=items, source="OpenStreetMap Overpass", live=True,
note=f"live · {len(raw.get('elements', []))} elements", schema_preview=self.schema_preview)
_put(ck, r)
return r
return self._ready_records(f"Overpass unreachable (HTTP {st})")
__all__ = ["UsgsConnector", "NoaaConnector", "OverpassConnector"]