Skip to main content

Verdict — Python

The Python implementation of Verdict — a small, zero-dependency, async-native rule-evaluation engine.

Install

pip install verdict-rules

The distribution on PyPI is named verdict-rules (the name verdict was already taken by an unrelated package), but the import name is plain verdict:

from verdict import Rule, FunctionRule, AndRule, OrRule, RulesEngine

A first rule

FunctionRule wraps a plain async predicate — a reusable one can build several named rules from the same code, each checking a different field against its own floor:

import asyncio
from verdict import FunctionRule, AndRule, RuleResult, RulesEngine

def at_least(name: str, field: str, floor: float) -> FunctionRule:
    async def predicate(context: dict) -> RuleResult:
        value = context[field]
        return RuleResult(rule_name=name, passed=value >= floor, detail=f"{value} vs {floor}")
    return FunctionRule(name, predicate)

async def main() -> None:
    eligible = AndRule("eligible", [
        at_least("age_ok", "age", 18),
        at_least("score_ok", "score", 60),
    ])
    engine = RulesEngine([eligible])
    verdict = await engine.run_named("eligible", {"age": 21, "score": 55})
    print(verdict.passed)  # False
    print(verdict.detail)  # "'score_ok' failed: 55 vs 60"

asyncio.run(main())

If it has the shape, it is a rule

Rule is a Protocol, and Python's typing is structural — so any object with the right attributes and an evaluate coroutine already is a Rule. No inheritance, no registration:

class IsBusinessHours:
    name = "is_business_hours"
    group = None

    async def evaluate(self, context: dict) -> RuleResult:
        hour = context["hour"]
        return RuleResult(rule_name="is_business_hours", passed=9 <= hour < 17)

await AndRule("open", [IsBusinessHours()]).evaluate({"hour": 21})

Most rules need no class at all either: FunctionRule wraps a plain async function.

What it guarantees

  • Sequential evaluation, never concurrent. Composites use a plain for loop with await, never asyncio.gather. Short-circuiting only means something if later work never starts — and because the returned boolean is identical either way, getting this wrong is silent.
  • Vacuous truth has a polarity. AndRule([]) passes, OrRule([]) fails. Deliberately asymmetric.
  • Emptiness is not absence. An empty composite folds to its identity; an unknown rule name or group raises KeyError. A group exists only because some rule declared it, so a lookup matching nothing can only be a mistake — and a misspelled group silently approving is the worst failure an eligibility check can have. Use rule_names / group_names to check rather than catch.
  • RuleResult.data is opaque — only what actually ran, never padded, never flattened.
  • Zero runtime dependencies.

Where to go next

Doc For
docs/quickstart.md The quickstart — core concepts and a full worked example
docs/architecture/ Why it's shaped this way, in depth — type structure, the execution model
docs/extending/ Building on top of it from your own code, with no changes here
docs/maintenance/ Changing this package itself
docs/testing/ How the test suite is organized, and what a change needs to prove
docs/samples/ Worked examples — dynamic discounts, fee waivers, tier promotions, moderation routing, data-driven rule sets
examples/ Full, tested mini-projects behind the more comprehensive samples — real code, real tests, real docs

Release files for verdict-rules 0.2.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for verdict-rules 0.2.7
File Size Uploaded
verdict_rules-0.2.7.tar.gz 8.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for verdict-rules 0.2.7
File Interpreter ABI Platform
verdict_rules-0.2.7-py3-none-any.whl Python 3 none any Details

Total release size:18.0 kB

Release files / verdict_rules-0.2.7.tar.gz

Download URL verdict_rules-0.2.7.tar.gz
Size 8.1 kB
Tags Source
SHA-256 checksum
How to use checksums
41bee5c1af0f6dda7d29e6763be3f4ba636a1de07d1fe281a0d4fc8462d5a29c
BLAKE2b-256 checksum
How to use checksums
aace1b54b81e3b0840d36ec4db7781d668285f2d526d380617bc69b300212a1d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / verdict_rules-0.2.7-py3-none-any.whl

Download URL verdict_rules-0.2.7-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8586065d29c7b5d6b2bad63e7d0c6ecd2458cc3728b3e312289600b6e181bb88
BLAKE2b-256 checksum
How to use checksums
dc5312a9717408fec3e71de21e31a6dc161af70a4124940f6c804e5794c214ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.1

2 release files

0.3.0

2 release files

0.2.9

2 release files

0.2.8

2 release files

This release

0.2.7 This release

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page