2.5 KiB
2.5 KiB
Task 12 — Storage-Abstraktion mit ABC
Rückblick Task 11: Externe Konfiguration
Ihr habt alle Konfigurationswerte in eine config.yaml ausgelagert. Die wichtigsten Punkte:
- Config vs. Umgebungsvariablen: In die YAML-Datei gehören Werte, die das
Verhalten der Applikation steuern (Bboxen, Timeouts, aktive Queries). In
Umgebungsvariablen (
.env) gehören Secrets und Deployment-spezifische Werte (Passwörter, API-Keys, Datenbankpfade) — also alles, was nicht ins Git-Repository soll. - Ungültiger
PoiType-Wert:PoiType("gondelbahn")wirft einenValueError, weil der Wert nicht im Enum existiert. Das ist eigentlich gut — fail fast. Inmain.pykönnte man diesen Fehler abfangen und eine sprechende Fehlermeldung ausgeben. Path(__file__).parent / "config.yaml": Gleiche Logik wie bei den Query-Dateien — der Pfad wird immer relativ zurmain.pyaufgelöst, nicht zum Arbeitsverzeichnis.
Aufgabe
Aktuell landen die gefetchten POIs nirgends — sie werden nur geloggt und dann verworfen. Ziel ist es, die POIs in eine JSON-Datei zu speichern.
Wir wollen das aber so umsetzen, dass das Storage-Backend später leicht
ausgetauscht werden kann (z.B. gegen eine Datenbank) — ohne main.py oder
die Fetch-Logik anzufassen.
Konkret:
- Lege eine neue Datei
storage.pyan. - Definiere darin eine abstrakte Basisklasse
Storage(erbt vonABC) mit einer abstrakten Methode:
@abstractmethod
def store(self, pois: list[POI]) -> str:
...
Die Methode soll die POIs speichern und einen Identifier zurückgeben
(z.B. den Dateipfad oder Tabellennamen).
3. Implementiere eine konkrete Klasse JsonStorage(Storage):
- Nimmt einen
output_dir: str | Pathim Konstruktor entgegen. store()schreibt alle POIs als JSON-Datei in dieses Verzeichnis, benannt nach dempoi_type(z.B.bergbahn.json).
- Instanziiere
JsonStorageinmain.pyund rufe nach dem Fetchenstorage.store(pois)auf. - Ergänze in
config.yamleinenstorage-Abschnitt:
storage:
output_dir: ./data/results
Fragen zum Nachdenken:
- Was ist eine abstrakte Basisklasse (ABC) — und was passiert, wenn man
Storage()direkt instanziiert oder eine Unterklasse schreibt, diestore()nicht implementiert? - Warum gibt
store()einenstrzurück (den Identifier) statt nichts (None)? - Was wäre der Nachteil, wenn
main.pydirektJsonStorageinstanziieren und überall verwenden würde — ohne dasStorage-Interface?