Files
swp-02-aufbereitung/version.py
T
2026-09-07 14:30:02 +02:00

70 lines
2.4 KiB
Python

"""coder_version: was hinter dem Hash steht.
Format aus der Spezifikation: p2-<ISO-Datum>-<hash8>.
Der Hash bildet alle Bestandteile, die das Ergebnis beeinflussen. Aendert
sich einer, aendert sich die Version, und alte Codings bleiben unangetastet
liegen. Das Datum ist das der letzten Aenderung an den Komponenten, nicht das
des Laufs - sonst waere die Version taeglich neu.
Anmerkung zur Spezifikation: sie sieht *eine* Version ueber alle fuenf Module
vor. Ein neues Sentimentlexikon entwertet damit auch die Embeddings, obwohl
es sie nicht beruehrt. Das ist teuer, aber es ist die festgelegte Semantik;
wer das aendern will, aendert die Spezifikation, nicht diese Datei.
"""
import hashlib
import json
import normalisierung
# Stand der Komponenten. Module, die es noch nicht gibt, stehen auf null -
# sie tragen dann nichts zum Hash bei, ausser dass sie erwaehnt sind.
KOMPONENTEN = {
"stand": "2026-09-07",
"normalisierung": normalisierung.REGELWERK_VERSION,
# Wird vom jeweiligen Modul beim Lauf eingesetzt (siehe komponenten()).
# Die Einstellungen stehen dort, wo sie wirken, nicht hier - sonst
# gerieten die beiden auseinander, und der Hash behauptete eine
# Gleichheit, die es nicht gibt.
"dubletten": None,
"akteure": None,
"geo": None,
"tonalitaet": None,
"embedding": None,
}
def komponenten(**module):
"""Kopie der Komponenten mit eingesetzten Modulangaben.
Ein Modul kennt seine Einstellungen selbst und reicht sie hier herein.
Aendert es eine Schwelle, aendert sich der Hash - genau so ist es
gemeint.
"""
k = dict(KOMPONENTEN)
k.update(module)
return k
def coder_version(komponenten=None):
k = KOMPONENTEN if komponenten is None else komponenten
# sort_keys: die Reihenfolge im Quelltext darf den Hash nicht bewegen.
roh = json.dumps(k, sort_keys=True, ensure_ascii=False, separators=(",", ":"))
hash8 = hashlib.blake2b(roh.encode("utf-8"), digest_size=4).hexdigest()
return f"p2-{k['stand']}-{hash8}"
def eintragen(conn, komponenten=None):
"""Version in coder_versionen festhalten. Ohne das sagt der Hash nichts."""
from psycopg.types.json import Jsonb
k = KOMPONENTEN if komponenten is None else komponenten
v = coder_version(k)
conn.execute(
"insert into coder_versionen (version, komponenten) values (%s, %s)"
" on conflict (version) do nothing",
(v, Jsonb(k)),
)
return v