main.py¶
Startup Event¶
Beim Start der FastAPI-Anwendung wird die startup_event-Funktion aufgerufen, welche die Initialisierung der Stationsdaten übernimmt.
- Initialisierung: Setzt den initialen Status der Anwendung (
stations_ready = False). - Hintergrundverarbeitung: Startet den Importprozess mittels
asyncio.create_task, damit der Webserver sofort bereit ist und nicht auf das Laden der Daten warten muss. - Threading: Nutzt
asyncio.to_thread, um die potenziell blockierende Funktionensure_stations_imported(I/O oder CPU-intensiv) außerhalb des Haupt-Event-Loops auszuführen. - Fehlerbehandlung: Erfasst eventuelle Fehler beim Import und speichert sie im Anwendungsstatus, um sie über API-Endpunkte (wie
/api/ready) kommunizierbar zu machen.
API Status Check (/api/ready)¶
Der /api/ready-Endpunkt und die zugehörige interne Guard-Funktion stellen sicher, dass die API erst dann auf komplexere Anfragen reagiert, wenn der Hintergrund-Import vollständig abgeschlossen ist.
ready():- Endpoint:
GET /api/ready - Beschreibung: Gibt den aktuellen Initialisierungsstatus der Stationsdatenbank zurück. Dies ist entscheidend für das Frontend, um Ladezustände anzuzeigen oder Suchfunktionen erst nach erfolgreichem Datenimport freizuschalten.
- Endpoint:
_require_ready():- Beschreibung: Eine interne Guard-Funktion. Sie prüft, ob die Stationen einsatzbereit sind.
- Fehlerbehandlung: Wirft eine
HTTPExceptionmit Status 500 bei einem kritischen Import-Fehler oder 503 (Service Unavailable), solange der Import-Task im Hintergrund noch läuft.
Datenmodelle (Pydantic)¶
Die internen Klassen StationSearchRequest und StationItem definieren die Struktur der JSON-Objekte für Anfragen und Antworten an die API ab.
-
StationSearchRequest:- Definiert die Eingabeparameter für die Umgebungssuche.
- Felder:
latundlonfür die Zielkoordinaten,radius_kmfür den Suchkreis. - Filter:
start_yearundend_yearerlauben die Eingrenzung auf Stationen mit historischen Daten in spezifischen Zeiträumen. - Limit: Begrenzt die Anzahl der zurückgegebenen Stationen (Default: 25).
-
StationItem:- Repräsentiert eine einzelne Wetterstation im Suchergebnis.
- Enthält neben den Stammdaten (
station_id,name,lat,lon) auch das berechnete Felddistance_km, welches die Entfernung zum im Request angegebenen Standort angibt.
Stations Search (/api/stations/search)¶
Der Endpunkt erlaubt die Suche nach Wetterstationen in einem bestimmten Umkreis um übergebene Koordinaten. Dabei wird auf die Logik aus stations_search.py zurückgegriffen.
-
Endpoint:
POST /api/stations/search- Beschreibung: Sucht nach Wetterstationen in einem bestimmten Umkreis um die angegebenen Koordinaten.
- Logik:
- Validiert den Systemstatus über
_require_ready(), um sicherzustellen, dass die Datenbasis geladen ist. - Nutzt die Hilfsfunktion
find_stations_nearby, um Stationen basierend auf Radius, Koordinaten und optionalen Zeitfiltern zu finden.
- Validiert den Systemstatus über
- Rückgabewert: Eine Liste von
StationItem-Objekten, die die gefundenen Stationen und deren Distanz zum Zielpunkt enthalten.
-
_background_save_to_db(Hilfsfunktion):- Beschreibung: Eine Hilfsfunktion für Hintergrundprozesse, um Daten persistent in der SQLite-Datenbank zu speichern.
- Logik:
- Öffnet eine neue, dedizierte Datenbankverbindung, um Thread-Sicherheit bei asynchronen Schreibvorgängen zu gewährleisten.
- Stellt sicher, dass das Zielschema (
create_temps_schema) existiert. - Führt den Batch-Schreibvorgang der Stationsdaten durch und schließt die Verbindung zuverlässig im
finally-Block.
Station Temps (/api/stations/{station_id}/temps)¶
Der Endpunkt /api/stations/{station_id}/temps stellt historische Temperaturdaten (TMAX/TMIN) für eine ausgewählte Wetterstation bereit. Hierbei wird eine dedizierte hybride Caching-Logik verwendet, um die Antwortzeiten zu minimieren.
- Caching-Strategie (Hybrid-Ansatz):
- Lokale Datenbank: Das System prüft zuerst, ob für die angeforderte
station_idbereits Daten in der lokalen SQLite-Datenbank vorliegen. Dies ermöglicht extrem schnelle Antwortzeiten bei wiederholten Abfragen. - On-Demand Ingestion: Falls keine lokalen Daten vorhanden sind, werden diese "live" von externen Quellen bezogen und geparst.
- Lokale Datenbank: Das System prüft zuerst, ob für die angeforderte
- Performance-Optimierung:
- Write-Behind Caching: Neu abgerufene Daten werden asynchron über
BackgroundTasksin die Datenbank geschrieben. Dadurch erhält der Nutzer die Daten sofort, ohne auf den Abschluss des Schreibvorgangs warten zu müssen. - Browser-Caching: Über den
Cache-Control-Header wird dem Client mitgeteilt, dass die Daten für 24 Stunden (max-age=86400) zwischengespeichert werden können.
- Write-Behind Caching: Neu abgerufene Daten werden asynchron über
- Validierung und Filterung:
- Unterstützt die Eingrenzung der Daten über
start_yearundend_year. - Validiert die Logik der Zeitspanne (Startjahr muss vor oder gleich dem Endjahr liegen) und liefert bei Fehlern einen
400 Bad Request.
- Unterstützt die Eingrenzung der Daten über
- Fehlerbehandlung: Differenziert zwischen fehlenden Daten (
404 Not Found), ungültigen Anfragen (400) und internen Verarbeitungsfehlern (500).