python_app / app.py
cwadayi's picture
Update app.py
feff408 verified
raw
history blame
3.65 kB
from fastapi import FastAPI, HTTPException
from starlette.responses import JSONResponse
from obspy.clients.fdsn import Client
from obspy.core.utcdatetime import UTCDateTime
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
# Initialize the FastAPI app
app = FastAPI(
title="Earthquake Catalog API",
description="An API to fetch earthquake data from the IRIS FDSN web service, ready for Hugging Face.",
version="1.0.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 /earthquakes to fetch data, or /docs for the API documentation. Dayi"}
@app.get("/earthquakes")
async def get_earthquake_catalog():
"""
Fetches earthquake data with a magnitude larger than 5.0
from 2015-01-05 to 2016-03-05.
"""
if not client:
raise HTTPException(
status_code=503, # Service Unavailable
detail="The IRIS FDSN client is not available or failed to initialize.",
)
try:
starttime = UTCDateTime("2015-01-05")
endtime = UTCDateTime("2016-03-05")
min_magnitude = 5.0
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 = []
# --- Key Change Start ---
# Loop through each event and process it individually to prevent one bad event from crashing the app.
for event in catalog:
try:
# Ensure the event has a preferred origin and magnitude
if not event.preferred_origin() or not event.preferred_magnitude():
continue # Skip to the next event if essential data is missing
origin = event.preferred_origin()
magnitude = event.preferred_magnitude()
# Safely extract the place description
place = "N/A"
if event.descriptions: # Check if the descriptions list exists and is not empty
place = event.descriptions[0].text
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:
# If a single event fails, log it and continue with the others.
logging.warning(f"Skipping one event due to a processing error: {e}")
continue
# --- Key Change End ---
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, # Internal Server Error
detail=f"An internal error occurred: {e}",
)