docs: expand pegels API documentation

This commit is contained in:
Matthias Jacob committed 2026-10-14 05:33:29 +02:00
1 parent 7e9dc86446
commit bc70066bc2
2 files changed
+238 -140

No files matched your search

+88 -3
View File
@@ -1,5 +1,6 @@
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import feedparser
import re
import html
@@ -9,7 +10,56 @@ from urllib.error import URLError, HTTPError
from email.utils import parsedate_to_datetime
from typing import TypedDict, Any
app = FastAPI()
app = FastAPI(
title="Sachsen Pegel Proxy API",
description=(
"Liefert Stationslisten und Wasserstandsmessungen des sächsischen "
"Hochwasser- und Wasserstands-Informationssystems (HWIMS) als JSON.\n\n"
"Die API liest die offiziellen HWIMS-Übersichts- und RSS-Quellen aus. "
"Messwerte und Stationsnamen können `null` sein, wenn sie in der "
"Quelldatei fehlen oder nicht erkannt werden. Zeitstempel werden als "
"ISO-8601-Werte mit Zeitzoneninformation ausgegeben.\n\n"
"Die interaktive Dokumentation steht unter `/docs`, das OpenAPI-Schema "
"unter `/openapi.json` bereit."
),
version="1.0.0",
openapi_tags=[
{
"name": "Pegel",
"description": "Entdecken von Pegelstationen und Abrufen ihrer Messwerte.",
}
],
)
class PegelStation(BaseModel):
station_id: str
station_title: str | None
source: str
class PegelIndexResponse(BaseModel):
count: int
total_available: int
items: list[PegelStation]
source: str
fetched_at: str
warnings: list[str] | None = None
cache_fetched_at: str | None = None
class PegelEntry(BaseModel):
timestamp: str | None
title: str | None
water_level_cm: float | None
flow_m3s: float | None
flood_alert_level: str | None
class PegelResponse(BaseModel):
station_id: str
station_title: str | None
count: int
latest: PegelEntry
entries: list[PegelEntry]
source: str
fetched_at: str
BASE = "https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/feed/wasserstand-pegel-{}"
DISCOVERY_URL = "https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/wasserstand-uebersicht"
@@ -173,7 +223,25 @@ def _get_latest_for_station(station_id: str):
}
return latest
@app.get("/api/pegel")
@app.get(
"/api/pegel",
response_model=PegelIndexResponse,
tags=["Pegel"],
summary="Pegelstationen auflisten",
description=(
"Liefert die auf der HWIMS-Übersichtsseite gefundenen Pegelstationen. "
"Mit `limit` lässt sich die zurückgegebene Liste begrenzen; "
"`total_available` enthält weiterhin die Gesamtzahl. Der Index wird "
"15 Minuten zwischengespeichert. Ist die Quelle nicht erreichbar, "
"wird ein vorhandener Cache verwendet und die Antwort enthält `warnings` "
"sowie `cache_fetched_at`. Ohne verfügbaren Cache wird HTTP 502 geliefert."
),
response_description="Stationsliste mit Quelle und Abrufzeitpunkt.",
responses={
400: {"description": "`limit` ist keine positive Zahl."},
502: {"description": "Die Discovery-Quelle ist nicht verfügbar und es gibt keinen Cache."},
},
)
def list_pegel(limit: int | None = None):
if limit is not None and limit <= 0:
raise HTTPException(400, "Ungültiger limit-Parameter")
@@ -219,7 +287,24 @@ def list_pegel(limit: int | None = None):
return JSONResponse(response)
@app.get("/api/pegel/{pegel_id}")
@app.get(
"/api/pegel/{pegel_id}",
response_model=PegelResponse,
tags=["Pegel"],
summary="Messwerte eines Pegels abrufen",
description=(
"Liefert alle im RSS-Feed verfügbaren Einträge einer Station. "
"`latest` ist der neueste Eintrag und entspricht `entries[0]`; "
"die Reihenfolge von `entries` folgt dem Feed (neueste zuerst). "
"Pegel-IDs bestehen aus mindestens sechs Ziffern. Nicht vorhandene "
"Messwerte werden als `null` ausgegeben."
),
response_description="Stationsmetadaten, neuester Messwert und Feed-Historie.",
responses={
400: {"description": "Die Pegel-ID besteht nicht aus mindestens sechs Ziffern."},
404: {"description": "Für diese Pegel-ID enthält der RSS-Feed keine Einträge."},
},
)
def get_pegel(pegel_id: str):
if not re.fullmatch(r"\d{6,}", pegel_id):
raise HTTPException(400, "Ungültige Pegel-ID")