add first implementation

This commit is contained in:
Matthias Jacob
2026-05-05 03:18:42 +02:00
parent a9ae00528d
commit 8b53d5cdf1
2 changed files with 81 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
import feedparser
import re
import datetime as dt
from email.utils import parsedate_to_datetime
app = FastAPI()
BASE = "https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/feed/wasserstand-pegel-{}"
def parse_number(pattern, text):
m = re.search(pattern, text, re.I)
return float(m.group(1).replace(",", ".")) if m else None
def parse_text(pattern, text):
m = re.search(pattern, text, re.I)
return m.group(1).strip() if m else None
def clean_text(text):
text = re.sub(r"<br\s*/?>", "\n", text, flags=re.I)
text = re.sub(r"<[^>]+>", " ", text)
return text
def extract_station_name(title: str):
if not title:
return None
m = re.search(r"Pegel\s+(.+)$", title)
return m.group(1).strip() if m else title
def parse_timestamp(entry):
if entry.get("dc_date"):
return entry.get("dc_date")
if entry.get("published"):
return parsedate_to_datetime(entry.get("published")).isoformat()
return None
def parse_entry(entry):
text = clean_text(entry.get("description", ""))
return {
"timestamp": parse_timestamp(entry),
"title": entry.get("title"),
"water_level_cm": parse_number(
r"Wasserstand:\s*([0-9]+(?:[,.][0-9]+)?)\s*cm", text
),
"flow_m3s": parse_number(
r"Durchfluss:\s*([0-9]+(?:[,.][0-9]+)?)\s*m³/s", text
),
"flood_alert_level": parse_text(
r"Meldestufe:\s*([^\n\r]+)", text
),
}
@app.get("/api/pegel/{pegel_id}")
def get_pegel(pegel_id: str):
if not re.fullmatch(r"\d{6,}", pegel_id):
raise HTTPException(400, "Ungültige Pegel-ID")
url = BASE.format(pegel_id)
feed = feedparser.parse(url)
if not feed.entries:
raise HTTPException(404, "Keine Daten gefunden")
entries = [parse_entry(entry) for entry in feed.entries]
return JSONResponse({
"station_id": pegel_id,
"station_title": extract_station_name(feed.feed.get("title")),
"count": len(entries),
"latest": entries[0],
"entries": entries,
"source": url,
"fetched_at": dt.datetime.now(dt.UTC).isoformat(),
})
+2
View File
@@ -0,0 +1,2 @@
fastapi
feedparser