Zugänge

SDK für Python

Das offizielle Paket ab Python 3.9, nur mit der Standardbibliothek. Jede Methode liefert ein dict mit denselben Feldern wie die API.

Installation

#

Das Paket quellenkontor läuft ab Python 3.9 und nutzt nur die Standardbibliothek. Es gibt also keine Abhängigkeiten, die mit deinem Projekt in Konflikt geraten.

Terminal
pip install quellenkontor
uv oder poetry
uv add quellenkontor
poetry add quellenkontor

Einrichten

#
Python
from quellenkontor import Quellenkontor

# liest den Schlüssel aus QK_KEY
qk = Quellenkontor()

# oder ausdrücklich, mit Optionen
qk = Quellenkontor(api_key="qk_live_…", timeout=10.0, wiederholungen=3)
ParameterStandardBedeutung
api_keyUmgebungsvariable QK_KEYDein API-Schlüssel
basis_urlhttps://api.quellenkontor.dev/v1Nur für Tests gegen einen anderen Server
timeout15.0Zeitlimit je Anfrage in Sekunden
wiederholungen2Wiederholungen bei Netzfehlern und Status 502, 503, 504, mit 0,3 und 0,6 Sekunden Pause
cacheTrueZwischenspeicher im Speicher dieser Instanz an oder aus, siehe unten
cache_ttl300.0 (5 Minuten)Wie lange eine Antwort ohne erneute Anfrage aus dem Zwischenspeicher kommt, in Sekunden
offlineTrueOffline-Stand als Fallback nutzen, wenn die API nicht erreichbar ist, siehe unten

Zwischenspeicher und ETag

Innerhalb von cache_ttl Sekunden kommt eine wiederholte Anfrage mit denselben Parametern ohne jeden Netzwerkaufruf aus dem Zwischenspeicher der Instanz zurück. Danach fragt das SDK mit der gemerkten ETag im Header If-None-Match nach: Hat sich der Wert nicht geändert, antwortet die API mit 304, das SDK reicht die gecachte Antwort weiter, und die Abfrage zählt nicht gegen dein Kontingent. Mehr zum Sparen von Abfragen unter Kontingente und Limits.

Python
qk = Quellenkontor(cache=False)  # immer eine frische Anfrage

# oder den Zwischenspeicher gezielt leeren, etwa nach einem Webhook
qk2 = Quellenkontor()
qk2.cache_leeren()

Offline-Stand

Ist die API nach allen Wiederholungen nicht erreichbar, weicht das SDK auf einen mitgelieferten Offline-Stand aus: den Verlauf jeder Tabelle mit Verlauf, im Paket erzeugt aus dem aktuellen Bestand (derselbe Stand wie /export). Die Antwort trägt dann offline: True und den datenstand des Pakets statt des amtlich aktuellen, ohne die berechneten Zusatzfelder wie zitat. Reine Rechner ohne Tabelle, etwa Kündigungsfrist, Urlaubsanspruch oder Dienstwagen, haben keinen Offline-Stand und bleiben ohne Verbindung ein QuellenkontorFehler mit Code netzwerk.

Python
qk = Quellenkontor(offline=False)  # stattdessen immer den Netzwerkfehler werfen

# mit Offline-Stand (Standard): erkennbar am Feld offline
qk_mit_fallback = Quellenkontor()
ml = qk_mit_fallback.hr.mindestlohn(datum="2027-01-15")
if ml.get("offline"):
    print("Offline-Stand vom", ml["datenstand"])

Alle Methoden

#

Jeder Datensatz ist eine Methode unter qk.hr. Sie liefert ein dict mit denselben Feldern wie die API. Optionale Parameter lässt du weg oder übergibst None.

MethodeReferenz
qk.hr.mindestlohn(datum=None)Mindestlohn
qk.hr.mindestausbildungsverguetung(beginn=None, ausbildungsjahr=None, bestandteil=None)Ausbildungsvergütung
qk.hr.pflegemindestlohn(datum=None, bestandteil=None)Pflegemindestlohn
qk.hr.rechengroessen(jahr=None, datum=None)Beitragsbemessungsgrenzen
qk.hr.beitragssaetze(datum=None)Beitragssätze
qk.hr.sachbezugswerte(jahr=None, datum=None)Sachbezugswerte
qk.hr.pfaendungsfreigrenzen(datum=None, unterhaltspflichten=None, netto=None)Pfändungsfreigrenzen
qk.hr.uebergangsbereich(datum=None)Übergangsbereich
qk.hr.minijob_abgaben(datum=None, bestandteil=None)Minijob-Abgaben
qk.hr.kuenstlersozialabgabe(jahr=None, datum=None, bestandteil=None)Künstlersozialabgabe
qk.hr.ausgleichsabgabe(jahr=None, datum=None, arbeitsplaetze=None, besetzt=None, bestandteil=None)Ausgleichsabgabe
qk.hr.steuerfreie_betraege(datum=None, bestandteil=None)Freibeträge und Pauschalen
qk.hr.reisekosten_inland(datum=None, bestandteil=None)Reisekosten
qk.hr.sfn_zuschlaege(datum=None, grundlohn_stunde=None, bestandteil=None)SFN-Zuschläge
qk.hr.dienstwagen(listenpreis: float, antrieb=None, anschaffung=None, ueberlassung=None, entfernung_km=None, fahrten_monat=None, zuzahlung_monat=None, co2_g_km=None, reichweite_km=None, batterie_kwh=None, datum=None)Dienstwagen
qk.hr.einkommensteuer_eckwerte(jahr=None, datum=None, bestandteil=None)Grundfreibetrag
qk.hr.kuendigungsfrist(eintritt: str, zugang: str, seite=None, probezeit=None)Kündigungsfrist
qk.hr.urlaubsanspruch(arbeitstage_pro_woche: float, jahr=None, eintritt=None, austritt=None)Urlaubsanspruch
qk.hr.mutterschutz(termin=None, geburt=None, fall=None, ssw=None)Mutterschutz
qk.hr.feiertage(jahr=None, land=None)Feiertage
qk.hr.arbeitstage(von: str, bis: str, land: str, samstag=None, regionale=None)Arbeitstage
qk.hr.regelaltersgrenze(geburtsdatum=None, geburtsjahr=None, vertrauensschutz=None)Regelaltersgrenze
qk.hr.pausen(arbeitszeit_stunden: float, jugendlich=None)Pausenregelung
qk.hr.verlauf(datensatz)alle Stufen einer Tabelle seit 2015
qk.datensaetze()Katalog, ohne Schlüssel
qk.aenderungen()Änderungsprotokoll, ohne Schlüssel
qk.anfrage(pfad, werte, format="json")rohe Anfrage an jeden Pfad, auch für CSV

Wahrheitswerte übergibst du als True oder False, das SDK schreibt sie für die API als true und false.

Beispiele

#

Kündigungsfrist

Python
frist = qk.hr.kuendigungsfrist(eintritt="2017-03-01", zugang="2026-11-10")
print(frist["ende"])  # 2027-02-28

Urlaubsanspruch bei Teilzeit

Python
urlaub = qk.hr.urlaubsanspruch(arbeitstage_pro_woche=3, jahr=2027)
print(urlaub["anspruch_tage_jahr"])

Beitragssätze an einem Stichtag

Python
saetze = qk.hr.beitragssaetze(datum="2026-07-01")
for b in saetze["bestandteile"]:
    print(b["name"], b["satz_prozent"])

Fehler behandeln

#

Antwortet die API mit einem Fehler, löst das SDK QuellenkontorFehler aus, mit den Attributen status, code und parameter. Ohne Verbindung ist der Status 0 und der Code netzwerk.

Python
from quellenkontor import Quellenkontor, QuellenkontorFehler

try:
    r = qk.hr.rechengroessen(jahr=2030)
except QuellenkontorFehler as e:
    if e.code == "kein_wert":
        print("Noch nicht verkündet:", e)
    elif e.status == 429:
        print("Kontingent aufgebraucht")
    else:
        raise

CSV und pandas

#

Mit format="csv" liefert anfrage den CSV-Text. Das Byte-Order-Mark entfernt das SDK, du kannst den Text direkt einlesen:

Python
import io
import pandas as pd

csv = qk.anfrage("/hr/mindestlohn/verlauf", {}, format="csv")
df = pd.read_csv(io.StringIO(csv), parse_dates=["gueltig_ab"])
print(df[["gueltig_ab", "mindestlohn_brutto_stunde"]].tail())

Fehlt etwas oder ist etwas unklar? Schreib uns, wir ergänzen die Doku.