Add central bundeslaender.py module with all 16 states (#7)
Introduces app/bundeslaender.py as the single source of truth for all bundesland-specific data (parliament name, current legislative period, upcoming elections, governing coalition, doku system, base URLs, drucksache format, dokukratie scraper code, active flag, optional remarks). Data reflects April 2026 state. main.py::index() and /api/bundeslaender now derive their lists from this module instead of hardcoding. Frontend dropdown now shows all 16 bundesländer (15 disabled with "(bald)" suffix); previously the landing template showed only 4. NRW remains the only "aktiv" entry. API behaviour change worth noting: the /api/bundeslaender endpoint previously emitted code "ST" for Sachsen-Anhalt; it now emits "LSA" to match the politically dominant abbreviation. No functional impact because non-NRW bundesländer were inactive in both versions. Foundation for #5 and #2; deliberately a no-op for NRW so it can ship and rollback independently. Resolves issue #7. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
bcd532be89
commit
ac18743ff2
361
app/bundeslaender.py
Normal file
361
app/bundeslaender.py
Normal file
@ -0,0 +1,361 @@
|
||||
"""Zentrale Konfiguration aller 16 deutschen Bundesländer.
|
||||
|
||||
Dieses Modul ist die Single Source of Truth für alle bundeslandspezifischen
|
||||
Daten: Parlamente, Regierungen, Wahlperioden, Doku-Systeme, etc. Andere
|
||||
Module (main.py, parlamente.py, wahlprogramme.py, analyzer.py) lesen
|
||||
ausschließlich von hier.
|
||||
|
||||
Stand: April 2026. Nach jeder Landtagswahl bzw. Regierungsbildung müssen
|
||||
die betroffenen Einträge aktualisiert werden.
|
||||
|
||||
Datenquellen: Wikipedia, offizielle Landtagsseiten, parlamentsspiegel.de,
|
||||
https://github.com/okfde/dokukratie (für Doku-System-Zuordnung).
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class Bundesland:
|
||||
"""Konfiguration eines deutschen Bundeslands.
|
||||
|
||||
Attributes:
|
||||
code: Übliches Kürzel im politischen Sprachgebrauch (NRW, BY, LSA…).
|
||||
Bei Mehrdeutigkeit ISO-3166-2-DE-Suffix; Sachsen-Anhalt nutzt
|
||||
jedoch das politisch dominante "LSA" statt ISO "ST".
|
||||
name: Vollständiger Landesname.
|
||||
parlament_name: Offizieller Name des Parlaments.
|
||||
wahlperiode: Aktuelle Wahlperiode als Zahl.
|
||||
wahlperiode_start: Beginn der aktuellen WP (ISO-Datum).
|
||||
naechste_wahl: Nächste reguläre Landtagswahl (ISO-Datum), oder None
|
||||
wenn noch nicht festgesetzt.
|
||||
regierungsfraktionen: Parteien der aktuellen Landesregierung in
|
||||
Reihenfolge der Größe.
|
||||
landtagsfraktionen: Alle aktuell im Landtag vertretenen Fraktionen.
|
||||
doku_system: Verwendetes Parlamentsdokumentationssystem.
|
||||
Werte: "OPAL", "StarWeb", "ParlDok", "PARDOK", "PARLIS",
|
||||
"PARiS", "Eigensystem".
|
||||
doku_base_url: Basis-URL der Parlamentsdokumentation.
|
||||
drucksache_format: Beispielhaftes Format einer Drucksachen-ID,
|
||||
z.B. "18/12345" für NRW WP18.
|
||||
dokukratie_scraper: Code-Name des Dokukratie-Scrapers (falls
|
||||
vorhanden), nützlich für künftige Adapter-Implementierung.
|
||||
aktiv: Ob das Bundesland im Frontend auswählbar und im Analyzer
|
||||
unterstützt ist. Inaktive Bundesländer werden im UI als
|
||||
"(bald)" angezeigt und sind disabled.
|
||||
anmerkung: Optionale Hinweise zu Sondersituationen (z.B.
|
||||
Koalitionsverhandlungen, jüngste Wahl, geschätzte Termine).
|
||||
"""
|
||||
|
||||
code: str
|
||||
name: str
|
||||
parlament_name: str
|
||||
wahlperiode: int
|
||||
wahlperiode_start: str
|
||||
naechste_wahl: Optional[str]
|
||||
regierungsfraktionen: list[str]
|
||||
landtagsfraktionen: list[str]
|
||||
doku_system: str
|
||||
doku_base_url: str
|
||||
drucksache_format: str
|
||||
dokukratie_scraper: Optional[str]
|
||||
aktiv: bool = False
|
||||
anmerkung: str = ""
|
||||
|
||||
|
||||
# Hauptregister: code -> Bundesland-Instanz.
|
||||
# Reihenfolge alphabetisch nach offiziellem Namen für stabile UI-Sortierung.
|
||||
BUNDESLAENDER: dict[str, Bundesland] = {
|
||||
"BW": Bundesland(
|
||||
code="BW",
|
||||
name="Baden-Württemberg",
|
||||
parlament_name="Landtag von Baden-Württemberg",
|
||||
wahlperiode=17,
|
||||
wahlperiode_start="2021-05-01",
|
||||
naechste_wahl="2031-03-08",
|
||||
regierungsfraktionen=["GRÜNE", "CDU"],
|
||||
landtagsfraktionen=["GRÜNE", "CDU", "AfD", "SPD", "FDP"],
|
||||
doku_system="PARLIS",
|
||||
doku_base_url="https://parlis.landtag-bw.de",
|
||||
drucksache_format="17/12345",
|
||||
dokukratie_scraper="bw",
|
||||
anmerkung=(
|
||||
"Wahl zum 18. Landtag fand am 08.03.2026 statt; Koalitionsverhandlungen "
|
||||
"GRÜNE+CDU laufen, Kabinett Kretschmann III geschäftsführend. Nach "
|
||||
"Konstituierung des 18. LT ca. Mai 2026 müssen WP und Wahltermin aktualisiert werden."
|
||||
),
|
||||
),
|
||||
"BY": Bundesland(
|
||||
code="BY",
|
||||
name="Bayern",
|
||||
parlament_name="Bayerischer Landtag",
|
||||
wahlperiode=19,
|
||||
wahlperiode_start="2023-10-30",
|
||||
naechste_wahl="2028-10-08",
|
||||
regierungsfraktionen=["CSU", "FW"],
|
||||
landtagsfraktionen=["CSU", "GRÜNE", "FW", "AfD", "SPD"],
|
||||
doku_system="Eigensystem",
|
||||
doku_base_url="https://www.bayern.landtag.de",
|
||||
drucksache_format="19/1234",
|
||||
dokukratie_scraper="by",
|
||||
anmerkung="Wahltermin 2028 noch nicht offiziell festgesetzt; Schätzung Herbst 2028.",
|
||||
),
|
||||
"BE": Bundesland(
|
||||
code="BE",
|
||||
name="Berlin",
|
||||
parlament_name="Abgeordnetenhaus von Berlin",
|
||||
wahlperiode=19,
|
||||
wahlperiode_start="2023-04-27",
|
||||
naechste_wahl="2026-09-20",
|
||||
regierungsfraktionen=["CDU", "SPD"],
|
||||
landtagsfraktionen=["CDU", "SPD", "GRÜNE", "LINKE", "AfD"],
|
||||
doku_system="PARDOK",
|
||||
doku_base_url="https://pardok.parlament-berlin.de",
|
||||
drucksache_format="19/1234",
|
||||
dokukratie_scraper="be",
|
||||
anmerkung=(
|
||||
"PARDOK basiert auf StarWeb-Software (portala-Frontend). Berlin bietet "
|
||||
"zusätzlich Open-Data-XML unter parlament-berlin.de/dokumente/open-data."
|
||||
),
|
||||
),
|
||||
"BB": Bundesland(
|
||||
code="BB",
|
||||
name="Brandenburg",
|
||||
parlament_name="Landtag Brandenburg",
|
||||
wahlperiode=8,
|
||||
wahlperiode_start="2024-10-23",
|
||||
naechste_wahl="2029-09-23",
|
||||
regierungsfraktionen=["SPD", "BSW"],
|
||||
landtagsfraktionen=["SPD", "AfD", "CDU", "BSW"],
|
||||
doku_system="StarWeb",
|
||||
doku_base_url="https://www.parlamentsdokumentation.brandenburg.de",
|
||||
drucksache_format="8/1234",
|
||||
dokukratie_scraper="bb",
|
||||
anmerkung="Kabinett Woidke IV (SPD-BSW) seit Dezember 2024. Knappe Mehrheit (zwei Sitze).",
|
||||
),
|
||||
"HB": Bundesland(
|
||||
code="HB",
|
||||
name="Bremen",
|
||||
parlament_name="Bremische Bürgerschaft",
|
||||
wahlperiode=21,
|
||||
wahlperiode_start="2023-07-05",
|
||||
naechste_wahl="2027-05-09",
|
||||
regierungsfraktionen=["SPD", "GRÜNE", "LINKE"],
|
||||
landtagsfraktionen=["SPD", "CDU", "GRÜNE", "LINKE", "AfD", "BiW"],
|
||||
doku_system="PARiS",
|
||||
doku_base_url="https://paris.bremische-buergerschaft.de",
|
||||
drucksache_format="21/1234",
|
||||
dokukratie_scraper="hb",
|
||||
anmerkung=(
|
||||
"PARiS basiert auf StarWeb. AfD durch Listenstreichung 2023 nicht im Landtag, "
|
||||
"stattdessen Bürger in Wut (BiW). Wahltag 2027 noch nicht festgesetzt."
|
||||
),
|
||||
),
|
||||
"HH": Bundesland(
|
||||
code="HH",
|
||||
name="Hamburg",
|
||||
parlament_name="Hamburgische Bürgerschaft",
|
||||
wahlperiode=23,
|
||||
wahlperiode_start="2025-03-26",
|
||||
naechste_wahl="2030-03-03",
|
||||
regierungsfraktionen=["SPD", "GRÜNE"],
|
||||
landtagsfraktionen=["SPD", "CDU", "GRÜNE", "LINKE", "AfD"],
|
||||
doku_system="ParlDok",
|
||||
doku_base_url="https://www.buergerschaft-hh.de/parldok",
|
||||
drucksache_format="23/1234",
|
||||
dokukratie_scraper="hh",
|
||||
anmerkung="Wahl am 02.03.2025; Senat Tschentscher III seit 07.05.2025 vereidigt.",
|
||||
),
|
||||
"HE": Bundesland(
|
||||
code="HE",
|
||||
name="Hessen",
|
||||
parlament_name="Hessischer Landtag",
|
||||
wahlperiode=21,
|
||||
wahlperiode_start="2024-01-18",
|
||||
naechste_wahl="2028-10-22",
|
||||
regierungsfraktionen=["CDU", "SPD"],
|
||||
landtagsfraktionen=["CDU", "AfD", "SPD", "GRÜNE", "FDP"],
|
||||
doku_system="StarWeb",
|
||||
doku_base_url="https://starweb.hessen.de/starweb/LIS",
|
||||
drucksache_format="21/1234",
|
||||
dokukratie_scraper="he",
|
||||
anmerkung="Wahltermin 2028 ist Schätzung.",
|
||||
),
|
||||
"MV": Bundesland(
|
||||
code="MV",
|
||||
name="Mecklenburg-Vorpommern",
|
||||
parlament_name="Landtag Mecklenburg-Vorpommern",
|
||||
wahlperiode=8,
|
||||
wahlperiode_start="2021-10-26",
|
||||
naechste_wahl="2026-09-20",
|
||||
regierungsfraktionen=["SPD", "LINKE"],
|
||||
landtagsfraktionen=["SPD", "AfD", "CDU", "LINKE", "GRÜNE", "FDP"],
|
||||
doku_system="ParlDok",
|
||||
doku_base_url="https://www.dokumentation.landtag-mv.de",
|
||||
drucksache_format="8/1234",
|
||||
dokukratie_scraper="mv",
|
||||
anmerkung="Wahltag offiziell auf 20.09.2026 festgelegt.",
|
||||
),
|
||||
"NI": Bundesland(
|
||||
code="NI",
|
||||
name="Niedersachsen",
|
||||
parlament_name="Niedersächsischer Landtag",
|
||||
wahlperiode=19,
|
||||
wahlperiode_start="2022-11-08",
|
||||
naechste_wahl="2027-10-10",
|
||||
regierungsfraktionen=["SPD", "GRÜNE"],
|
||||
landtagsfraktionen=["SPD", "CDU", "GRÜNE", "AfD"],
|
||||
doku_system="StarWeb",
|
||||
doku_base_url="https://www.landtag-niedersachsen.de",
|
||||
drucksache_format="19/12345",
|
||||
dokukratie_scraper="ni",
|
||||
anmerkung=(
|
||||
"Wahltermin Herbst 2027 (zwischen 11.07. und 03.10.2027) noch nicht festgesetzt; "
|
||||
"geschätzt. Olaf Lies (SPD) seit 20.05.2025 Ministerpräsident."
|
||||
),
|
||||
),
|
||||
"NRW": Bundesland(
|
||||
code="NRW",
|
||||
name="Nordrhein-Westfalen",
|
||||
parlament_name="Landtag Nordrhein-Westfalen",
|
||||
wahlperiode=18,
|
||||
wahlperiode_start="2022-06-01",
|
||||
naechste_wahl="2027-05-15",
|
||||
regierungsfraktionen=["CDU", "GRÜNE"],
|
||||
landtagsfraktionen=["CDU", "SPD", "GRÜNE", "FDP", "AfD"],
|
||||
doku_system="OPAL",
|
||||
doku_base_url="https://opal.landtag.nrw.de",
|
||||
drucksache_format="18/12345",
|
||||
dokukratie_scraper="nw",
|
||||
aktiv=True,
|
||||
anmerkung=(
|
||||
"OPAL in NRW ist eine eigene Implementierung, nicht identisch mit dem "
|
||||
"StarWeb-basierten OPAL in RLP. Wahltermin 2027 ist Schätzung."
|
||||
),
|
||||
),
|
||||
"RP": Bundesland(
|
||||
code="RP",
|
||||
name="Rheinland-Pfalz",
|
||||
parlament_name="Landtag Rheinland-Pfalz",
|
||||
wahlperiode=18,
|
||||
wahlperiode_start="2021-05-18",
|
||||
naechste_wahl="2031-03-22",
|
||||
regierungsfraktionen=["SPD", "GRÜNE", "FDP"],
|
||||
landtagsfraktionen=["SPD", "CDU", "AfD", "GRÜNE", "FREIE WÄHLER", "FDP"],
|
||||
doku_system="StarWeb",
|
||||
doku_base_url="https://opal.rlp.de",
|
||||
drucksache_format="18/12345",
|
||||
dokukratie_scraper="rp",
|
||||
anmerkung=(
|
||||
"OPAL in RLP basiert auf StarWeb. Wahl zum 19. Landtag fand am 22.03.2026 "
|
||||
"statt; Koalitionsverhandlungen CDU+SPD laufen, Kabinett Schweitzer I "
|
||||
"geschäftsführend. Nach Konstituierung müssen WP und Wahltermin aktualisiert werden."
|
||||
),
|
||||
),
|
||||
"SL": Bundesland(
|
||||
code="SL",
|
||||
name="Saarland",
|
||||
parlament_name="Landtag des Saarlandes",
|
||||
wahlperiode=17,
|
||||
wahlperiode_start="2022-04-25",
|
||||
naechste_wahl="2027-04-18",
|
||||
regierungsfraktionen=["SPD"],
|
||||
landtagsfraktionen=["SPD", "CDU", "AfD"],
|
||||
doku_system="Eigensystem",
|
||||
doku_base_url="https://www.landtag-saar.de",
|
||||
drucksache_format="17/1234",
|
||||
dokukratie_scraper="sl",
|
||||
anmerkung=(
|
||||
"Einzige SPD-Alleinregierung in Deutschland. AfD-Status im 17. LT vor "
|
||||
"produktiver Nutzung verifizieren."
|
||||
),
|
||||
),
|
||||
"SN": Bundesland(
|
||||
code="SN",
|
||||
name="Sachsen",
|
||||
parlament_name="Sächsischer Landtag",
|
||||
wahlperiode=8,
|
||||
wahlperiode_start="2024-10-01",
|
||||
naechste_wahl="2029-09-02",
|
||||
regierungsfraktionen=["CDU", "SPD"],
|
||||
landtagsfraktionen=["CDU", "AfD", "BSW", "SPD", "LINKE", "GRÜNE"],
|
||||
doku_system="ParlDok",
|
||||
doku_base_url="https://edas.landtag.sachsen.de",
|
||||
drucksache_format="8/1234",
|
||||
dokukratie_scraper="sn",
|
||||
anmerkung=(
|
||||
"Minderheitsregierung CDU+SPD (Kabinett Kretschmer III seit 18.12.2024). "
|
||||
"Doku-System EDAS basiert auf ParlDok."
|
||||
),
|
||||
),
|
||||
"LSA": Bundesland(
|
||||
code="LSA",
|
||||
name="Sachsen-Anhalt",
|
||||
parlament_name="Landtag von Sachsen-Anhalt",
|
||||
wahlperiode=8,
|
||||
wahlperiode_start="2021-07-06",
|
||||
naechste_wahl="2026-09-06",
|
||||
regierungsfraktionen=["CDU", "SPD", "FDP"],
|
||||
landtagsfraktionen=["CDU", "AfD", "LINKE", "SPD", "GRÜNE", "FDP"],
|
||||
doku_system="StarWeb",
|
||||
doku_base_url="https://padoka.landtag.sachsen-anhalt.de",
|
||||
drucksache_format="8/1234",
|
||||
dokukratie_scraper="st",
|
||||
anmerkung=(
|
||||
"ISO-Code wäre ST; LSA ist im politischen Sprachgebrauch dominant. "
|
||||
"Sven Schulze (CDU) seit 28.01.2026 MP nach Rücktritt Haseloff. "
|
||||
"PADOKA = Parlamentsdokumentationssystem auf StarWeb-6.0.01-Basis."
|
||||
),
|
||||
),
|
||||
"SH": Bundesland(
|
||||
code="SH",
|
||||
name="Schleswig-Holstein",
|
||||
parlament_name="Schleswig-Holsteinischer Landtag",
|
||||
wahlperiode=20,
|
||||
wahlperiode_start="2022-06-07",
|
||||
naechste_wahl="2027-04-18",
|
||||
regierungsfraktionen=["CDU", "GRÜNE"],
|
||||
landtagsfraktionen=["CDU", "GRÜNE", "SPD", "FDP", "SSW"],
|
||||
doku_system="StarWeb",
|
||||
doku_base_url="https://www.landtag.ltsh.de",
|
||||
drucksache_format="20/1234",
|
||||
dokukratie_scraper="sh",
|
||||
anmerkung="SSW ist von der 5%-Hürde befreit.",
|
||||
),
|
||||
"TH": Bundesland(
|
||||
code="TH",
|
||||
name="Thüringen",
|
||||
parlament_name="Thüringer Landtag",
|
||||
wahlperiode=8,
|
||||
wahlperiode_start="2024-10-01",
|
||||
naechste_wahl="2029-09-01",
|
||||
regierungsfraktionen=["CDU", "BSW", "SPD"],
|
||||
landtagsfraktionen=["AfD", "CDU", "LINKE", "BSW", "SPD"],
|
||||
doku_system="StarWeb",
|
||||
doku_base_url="https://parldok.thueringen.de",
|
||||
drucksache_format="8/1234",
|
||||
dokukratie_scraper="th",
|
||||
anmerkung=(
|
||||
"Erste Brombeer-Koalition Deutschlands (CDU+BSW+SPD) als Minderheitsregierung "
|
||||
"mit 44 von 88 Sitzen. Mario Voigt (CDU) seit Dezember 2024 MP."
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def get(code: str) -> Optional[Bundesland]:
|
||||
"""Bundesland-Konfig per Code abrufen, oder None."""
|
||||
return BUNDESLAENDER.get(code)
|
||||
|
||||
|
||||
def aktive_bundeslaender() -> list[Bundesland]:
|
||||
"""Alle aktuell aktiven (im Analyzer unterstützten) Bundesländer."""
|
||||
return [bl for bl in BUNDESLAENDER.values() if bl.aktiv]
|
||||
|
||||
|
||||
def alle_bundeslaender() -> list[Bundesland]:
|
||||
"""Alle 16 Bundesländer (aktive zuerst, dann alphabetisch nach Name)."""
|
||||
aktiv = sorted([bl for bl in BUNDESLAENDER.values() if bl.aktiv], key=lambda b: b.name)
|
||||
inaktiv = sorted([bl for bl in BUNDESLAENDER.values() if not bl.aktiv], key=lambda b: b.name)
|
||||
return aktiv + inaktiv
|
||||
25
app/main.py
25
app/main.py
@ -17,6 +17,7 @@ from .database import (
|
||||
search_assessments
|
||||
)
|
||||
from .parlamente import get_adapter, ADAPTERS
|
||||
from .bundeslaender import alle_bundeslaender
|
||||
from .analyzer import analyze_antrag
|
||||
from .report import generate_html_report, generate_pdf_report
|
||||
from .embeddings import (
|
||||
@ -87,10 +88,8 @@ async def index(request: Request):
|
||||
"request": request,
|
||||
"app_name": settings.app_name,
|
||||
"bundeslaender": [
|
||||
{"code": "NRW", "name": "Nordrhein-Westfalen", "active": True},
|
||||
{"code": "BY", "name": "Bayern", "active": False},
|
||||
{"code": "BW", "name": "Baden-Württemberg", "active": False},
|
||||
{"code": "HE", "name": "Hessen", "active": False},
|
||||
{"code": bl.code, "name": bl.name, "active": bl.aktiv}
|
||||
for bl in alle_bundeslaender()
|
||||
],
|
||||
})
|
||||
|
||||
@ -495,22 +494,8 @@ async def run_drucksache_analysis(
|
||||
async def list_bundeslaender():
|
||||
"""List available bundesländer with their status."""
|
||||
return [
|
||||
{"code": "NRW", "name": "Nordrhein-Westfalen", "active": True},
|
||||
{"code": "BY", "name": "Bayern", "active": False},
|
||||
{"code": "BW", "name": "Baden-Württemberg", "active": False},
|
||||
{"code": "HE", "name": "Hessen", "active": False},
|
||||
{"code": "NI", "name": "Niedersachsen", "active": False},
|
||||
{"code": "RP", "name": "Rheinland-Pfalz", "active": False},
|
||||
{"code": "SH", "name": "Schleswig-Holstein", "active": False},
|
||||
{"code": "SL", "name": "Saarland", "active": False},
|
||||
{"code": "SN", "name": "Sachsen", "active": False},
|
||||
{"code": "ST", "name": "Sachsen-Anhalt", "active": False},
|
||||
{"code": "TH", "name": "Thüringen", "active": False},
|
||||
{"code": "BB", "name": "Brandenburg", "active": False},
|
||||
{"code": "MV", "name": "Mecklenburg-Vorpommern", "active": False},
|
||||
{"code": "HH", "name": "Hamburg", "active": False},
|
||||
{"code": "HB", "name": "Bremen", "active": False},
|
||||
{"code": "BE", "name": "Berlin", "active": False},
|
||||
{"code": bl.code, "name": bl.name, "active": bl.aktiv}
|
||||
for bl in alle_bundeslaender()
|
||||
]
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user