CommunityCodierung & Entwicklunggithub.com

YarlisAISolutions/rules-cascade-python

Erzwinge Rule-Cascade-Regeln in Python-Diensten und -Jobs (FastAPI, Django, Flask, Celery, Batch-Skripte) mit dem rule-cascade-Paket. Verwende es, um Regeln in einen Python-Codepfad einzubinden, Pydantic-Validatoren oder manuelle Prüfungen durch die Engine zu ersetzen oder viele Datensätze in einem Batch auszuwerten.

Was ist rules-cascade-python?

Diese Fähigkeit integriert das rule-cascade-Paket in Python-Anwendungen, um Geschäftslogikregeln konsistent und performant auszuführen. Sie unterstützt die gängigsten Python-Webframeworks (FastAPI, Django, Flask) sowie Hintergrund-Jobs (Celery, Batch-Skripte). Der Entwickler lädt ein kompiliertes Regelbündel einmalig beim Start und wertet es dann pro Anfrage aus – entweder über einen Dekorator oder eine manuelle `enforce`-Methode. Bei Regelverstößen wird standardisiert ein 422-Status mit Problem-Details zurückgegeben. Die Fähigkeit ermöglicht das Ersetzen von bestehenden Pydantic-Validatoren, Django-Validatoren und manuellen Prüfungen durch eine zentrale Regelengine, die auch im Batch-Betrieb mit vielen Datensätzen effizient arbeitet. Ein Hintergrund-Reload-Mechanismus (`RuleSetHolder`) sorgt für Aktualisierungen ohne Dienstunterbrechung. Tests prüfen die Entscheidungen und Findings-Codes, während die Regeln selbst über goldene Tests (`rcas check`) validiert werden.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/YarlisAISolutions/rule-cascade-skills/tree/main/plugins/rules-cascade/skills/rules-cascade-python

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Rule Cascade in Python

Paket: pip install rule-cascade (Python 3.11+; Import rule_cascade). Bündel kommen von rcas compile --all nach build/rules/. Werte YAML niemals zur Laufzeit aus und kopiere niemals eine Regel in den Code.

Einmal laden, pro Anfrage auswerten

import json
from rule_cascade import RuleSet, RequestError

# Beim Start (Modulebene, FastAPI-Lifespan, Django AppConfig.ready). Ein fehlerhaftes Bündel löst einen Fehler aus: Nicht ausliefern.
with open("build/rules/<ruleset-id>.bundle.json", encoding="utf-8") as f:
    rules = RuleSet.from_bundle(json.load(f))

Den Dekorator bevorzugen (ab 1.0.0-alpha.7): Er erstellt die Anfrage, erzwingt die Regeln vor der Ausführung der Funktion und löst RuleViolation aus, dessen problem() die 422-Antwort unten ist.

from rule_cascade import enforce_rules, current_evaluation
from rule_cascade.fastapi import install            # oder rule_cascade.flask.init_app(app), oder die Django-Middleware

install(app)                                        # RuleViolation -> 422, RequestError -> 400

@app.post("/orders", status_code=201)
@enforce_rules(rules, entity="Order", operation="create", data="order", actor="user")   # unter dem Routen-Dekorator
def create_order(order: Order, user: User = Depends(current_user)):
    evaluation = current_evaluation()               # das erlaubte Ergebnis: Warnungen, berechnete Werte, Befehle

rules.enforce(request, "server") macht dasselbe ohne Dekorator. Dahinter gibt rules.evaluate(request, "server") ein Dictionary zurück: decision (allow oder deny), findings, effects, commands. Es löst RequestError für eine fehlerhafte Anfrage aus (Antwort 400). Jeder zustandsändernde Endpunkt folgt vier Schritten:

  1. Auf dem Server auswerten mit {"entity", "operation", "data", "original", "actor", "resolutions"}; actor kommt aus der Authentifizierung ({"id", "roles"}), niemals aus einem Feld, das der Aufrufer sendet.
  2. Bei deny ablehnen mit 422 Problem-Details (application/problem+json, type: "urn:rule-cascade:rule-violation"), die das Ergebnis enthalten, sodass Clients findings[].fields auf Eingaben abbilden können.
  3. Persistieren, nachdem compute-Effekte angewendet wurden (effect["type"] == "value"): Der Wert des Servers wird gespeichert.
  4. result["commands"] ausführen nach dem Commit, einmal pro idempotencyKey (eine Outbox-Tabelle oder eine Aufgabenwarteschlange mit Deduplizierung).

Framework-Platzierung: FastAPI eine Abhängigkeit (Depends(get_rules)) und einen Exception-Handler, der eine RuleViolation in die 422 umwandelt; Django eine Service-Funktion, die von jedem View oder Serializer-validate() der Entität aufgerufen wird, plus Middleware oder DRF-Exception-Handler für die 422; Flask ein Erweiterungsobjekt, das in der App-Factory erstellt wird. Celery- und Batch-Jobs werten vor jedem Schreibzugriff auf die gleiche Weise aus.

RuleSetHolder(load_bundle, interval=300) (oder cron="0 * * * *") lädt Bündel im Hintergrund neu und behält die letzten gültigen Regeln, wenn ein Neuladen fehlschlägt.

Viele Datensätze

Starte für Dateien und Warteschlangen einmal rcas engine und sende JSON-Lines-Anfragen hindurch, oder rufe rules.evaluate in einer Schleife auf: Lade das Bündel in beiden Fällen nur einmal. Siehe https://rulescascade.com/examples/batch/.

Bestehende Validierung ersetzen

rcas analyze --module <module> listet Pydantic Field(le=...) und Validatoren, Marshmallow-Schemas, Django-Validatoren, clean()-Methoden und Berechtigungen, handgeschriebene raise-Prüfungen, benannte Limits (MAX_QTY = 10), Vergleiche mit Zahlen und match-Zweige auf. Ein Kandidat mit drift bedeutet, dass eine andere Sprache des Projekts (oft das Frontend) denselben Namen mit einem anderen Wert entscheidet: Ein Regelsatz muss ihn für beide entscheiden. Behalte Typ- und Formvalidierung (Pydantic-Modelle) dort, wo sie ist; verschiebe Geschäftsentscheidungen in Regeln. Füge einen Paritätstest hinzu, der die alte Prüfung und die Engine mit denselben Eingaben ausführt, und lösche die alte Prüfung erst, wenn sie übereinstimmen.

Tests

Prüfe decision und Finding-codes, nicht Nachrichtentexte. Die Regeln selbst werden durch ihre goldenen Tests (rcas check) getestet. Führe in CI rcas check und rcas compile --all vor pytest aus.

Referenz: https://rulescascade.com/usage/python/

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Verwandte Skills