Initial commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import httpx
|
||||
import asyncio
|
||||
from datetime import datetime, timezone
|
||||
|
||||
# USGS Earthquake Hazards Program - completely free, no API key
|
||||
# Significant earthquakes (M 4.5+) from the past 7 days
|
||||
USGS_URL = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_week.geojson"
|
||||
|
||||
|
||||
async def fetch_earthquakes() -> list:
|
||||
"""
|
||||
Fetches real earthquake data from USGS.
|
||||
Returns quakes with M >= 4.5 from the past week.
|
||||
"""
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(USGS_URL, timeout=12.0)
|
||||
if response.status_code != 200:
|
||||
print(f"[SEISMIC] USGS returned {response.status_code}")
|
||||
return []
|
||||
|
||||
data = response.json()
|
||||
quakes = []
|
||||
|
||||
for feature in data.get("features", []):
|
||||
props = feature.get("properties", {})
|
||||
geom = feature.get("geometry", {})
|
||||
coords = geom.get("coordinates", [])
|
||||
|
||||
if len(coords) < 2:
|
||||
continue
|
||||
|
||||
lon, lat = coords[0], coords[1]
|
||||
depth_km = coords[2] if len(coords) > 2 else 0
|
||||
mag = props.get("mag")
|
||||
|
||||
if mag is None:
|
||||
continue
|
||||
# Validate coordinates
|
||||
if not (-90 <= lat <= 90) or not (-180 <= lon <= 180):
|
||||
continue
|
||||
|
||||
# Severity classification
|
||||
if mag >= 7.0:
|
||||
severity = "MAJOR"
|
||||
elif mag >= 6.0:
|
||||
severity = "STRONG"
|
||||
elif mag >= 5.0:
|
||||
severity = "MODERATE"
|
||||
else:
|
||||
severity = "MINOR"
|
||||
|
||||
# Convert USGS epoch ms to ISO string
|
||||
epoch_ms = props.get("time", 0)
|
||||
try:
|
||||
dt = datetime.fromtimestamp(epoch_ms / 1000, tz=timezone.utc)
|
||||
time_str = dt.strftime("%Y-%m-%d %H:%M UTC")
|
||||
except Exception:
|
||||
time_str = "Unknown"
|
||||
|
||||
quakes.append({
|
||||
"id": feature.get("id", ""),
|
||||
"title": props.get("title", "Earthquake"),
|
||||
"place": props.get("place", "Unknown Location"),
|
||||
"lat": lat,
|
||||
"lon": lon,
|
||||
"depth_km": round(depth_km, 1),
|
||||
"magnitude": mag,
|
||||
"severity": severity,
|
||||
"time": time_str,
|
||||
"url": props.get("url", ""),
|
||||
"type": "earthquake",
|
||||
"felt": props.get("felt", 0),
|
||||
"tsunami": props.get("tsunami", 0),
|
||||
})
|
||||
|
||||
# Sort by magnitude descending
|
||||
quakes.sort(key=lambda q: q["magnitude"], reverse=True)
|
||||
print(f"[SEISMIC] {len(quakes)} earthquakes (M≥4.5) — strongest: M{quakes[0]['magnitude'] if quakes else 'N/A'}")
|
||||
return quakes
|
||||
|
||||
except Exception as e:
|
||||
print(f"[SEISMIC] Fetch error: {e}")
|
||||
return []
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = asyncio.run(fetch_earthquakes())
|
||||
print(f"Earthquakes: {len(result)}")
|
||||
for q in result[:5]:
|
||||
print(f" M{q['magnitude']} {q['severity']} — {q['place']}")
|
||||
Reference in New Issue
Block a user