sqlite_api / app.py
cwadayi's picture
Update app.py
7c69a57 verified
raw
history blame
3.86 kB
from fastapi import FastAPI, HTTPException, Query
from starlette.responses import JSONResponse
from obspy.clients.fdsn import Client
from obspy.core.utcdatetime import UTCDateTime
import logging
from datetime import date
# Configure logging
logging.basicConfig(level=logging.INFO)
# Initialize the FastAPI app
app = FastAPI(
title="Dynamic Earthquake Catalog API",
description="A robust API to fetch earthquake data from the IRIS FDSN web service using URL parameters.",
version="2.1.0",
)
# Initialize the IRIS FDSN client
try:
client = Client("IRIS")
logging.info("Successfully initialized IRIS FDSN client.")
except Exception as e:
client = None
logging.error(f"Could not initialize IRIS FDSN client on startup: {e}")
@app.get("/")
def greet_json():
"""
A simple 'Hello World' endpoint.
"""
return {"Hello": "World!", "message": "Go to /docs to try the dynamic earthquake endpoint. cwadayi \n https://cwadayi-python-app.hf.space/earthquakes?start_date=2024-07-01&end_date=2024-07-07&min_magnitude=5.0"}
@app.get("/earthquakes")
async def get_earthquake_catalog(
start_date: date = Query(default="2024-01-01", description="Start date in YYYY-MM-DD format"),
end_date: date = Query(default="2024-01-07", description="End date in YYYY-MM-DD format"),
min_magnitude: float = Query(default=4.5, description="Minimum earthquake magnitude (e.g., 5.5)", gt=0, le=10)
):
"""
Fetches earthquake data based on date and magnitude parameters provided in the URL.
"""
if not client:
raise HTTPException(status_code=503, detail="The IRIS FDSN client is not available.")
if start_date > end_date:
raise HTTPException(status_code=400, detail="The start_date cannot be after the end_date.")
try:
starttime = UTCDateTime(start_date)
endtime = UTCDateTime(end_date)
logging.info(f"Fetching events from {starttime} to {endtime} with min magnitude {min_magnitude}.")
catalog = client.get_events(
starttime=starttime,
endtime=endtime,
minmagnitude=min_magnitude,
)
logging.info(f"Found {len(catalog)} events. Now processing.")
earthquake_list = []
for event in catalog:
try:
origin = event.preferred_origin()
magnitude = event.preferred_magnitude()
if not origin or not magnitude:
continue
# --- Key Change Start ---
# Safely get the description using getattr. This avoids errors if the 'descriptions'
# attribute doesn't exist, by providing a default empty list [].
place = "N/A"
descriptions = getattr(event, 'descriptions', [])
if descriptions:
place = descriptions[0].text
# --- Key Change End ---
earthquake_list.append({
"time": origin.time.isoformat(),
"latitude": origin.latitude,
"longitude": origin.longitude,
"depth_km": origin.depth / 1000.0 if origin.depth is not None else None,
"magnitude": magnitude.mag,
"magnitude_type": magnitude.magnitude_type,
"place": place,
})
except Exception as e:
logging.warning(f"Skipping event due to unexpected processing error: {e}")
continue
logging.info(f"Successfully processed {len(earthquake_list)} events.")
return JSONResponse(content={"earthquakes": earthquake_list})
except Exception as e:
logging.error(f"A major error occurred during the request: {e}")
raise HTTPException(status_code=500, detail=f"An internal error occurred: {e}")