diff --git a/TASK.md b/TASK.md index 4167170..c24c073 100644 --- a/TASK.md +++ b/TASK.md @@ -1,6 +1,7 @@ -# TASK 2: +# TASK 3: - * Fügt der aktuellen Funktion einen aussagekräftigen docstrings und typehints hinzu - * Versucht ein Error-Management mit in die Funktion einzubauen. Benutzt dazu eine eigene `OverpassApiError`-Klasse. - -> Überlegt: Was könnte nicht klappen? Wo könnte es Fehler geben? - * Versucht mal bbox auf (45.8, 5.9, 47.8, 10.5) zu setzen und die Funktion aufzurufen. Klappt das? \ No newline at end of file +* verlagert als Nächstes die Logik von 'fetch_bergbahnen' in ein eigenes Modul `overpass.py` aus. +* nennt die Funktion allgemeiner `fetch_overpass` (anstelle `fetch_bergbahnen`) -> somit würde es Sinn + machen, wenn wir den Query der Funktion als Argument mitgeben könnten (ist genereller). +* Erstellt in diesem `main.py` eine eigene 'main-Funktion', welche nur die Hauptlogik beinhalten und somit `fetch_overpass` + importiert und aufruft. \ No newline at end of file diff --git a/main.py b/main.py index dd04dd2..007f5e0 100644 --- a/main.py +++ b/main.py @@ -17,21 +17,71 @@ out center body; """ -def fetch_bergbahnen(bbox) -> dict: +class OverpassApiError(Exception): + pass + + + +def fetch_bergbahnen(bbox: tuple) -> dict: + """ + Fragt die Overpass API nach Bergbahnen in der angegebenen Bounding Box ab. + Sendet einen HTTP-POST-Request an die Overpass API und gibt die geparste + JSON-Antwort zurück. + + Args: + bbox (tuple): Bounding Box als 4-Tuple in Dezimalgrad: + (south, west, north, east) + Beispiel Davos: (46.72, 9.70, 46.92, 10.00) + Beispiel Schweiz: (45.8, 5.9, 47.8, 10.5) + + Returns: + dict: Geparste JSON-Antwort der Overpass API. Die Antwort enthält + unter dem Schlüssel "elements" eine Liste von OSM-Objekten + (nodes und ways) mit ihren Tags und Koordinaten. + Beispiel: + { + "elements": [ + { + "type": "node", + "id": 123456, + "lat": 46.8, "lon": 9.8, + "tags": {"aerialway": "station", "name": "Jakobshorn"} + }, + ... + ] + } + + Raises: + OverpassApiError: Wenn die API nicht innerhalb des gesetzten Timeouts + antwortet (clientseitig, unabhängig vom serverseitigen + Timeout im Query). + OverpassApiError: Wenn der Request aus einem anderen Grund fehlschlägt + (z.B. 429 Too Many Requests, 504 Gateway Timeout, + Netzwerkfehler). + """ + bbox_str = ",".join(map(str, bbox)) query = BERGBAHN_QUERY.format(bbox=bbox_str) - resp = requests.post( - OVERPASS_URL, - data={"data": query}, - timeout=5, - headers={"User-Agent": "CDS Exercise"}, - ) - return resp.json() + try: + response = requests.post( + OVERPASS_URL, + data={"data": query}, + timeout=5, + headers={"User-Agent": "CDS Exercise"}, + ) + response.raise_for_status() # prüft den HTTP-Statuscode der Antwort und wirft eine Exception, wenn es ein Fehler war (requests.HTTPError) + except requests.Timeout as exc: + raise OverpassApiError("Overpass-API Timeout") from exc + except requests.RequestException as exc: + raise OverpassApiError("Overpass-API Request fehlgeschlagen") from exc + return response.json() + if __name__ == "__main__": - bbox = (46.72, 9.70, 46.92, 10.00) + # bbox = (46.72, 9.70, 46.92, 10.00) + bbox = (45.8, 5.9, 47.8, 10.5) result = fetch_bergbahnen(bbox) pprint(result) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e69de29..663bd1f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1 @@ +requests \ No newline at end of file