Skip to main content

clipspyx

Python bindings and DSL for CLIPS, the production rule engine. Write rules as Python classes, run them with an async goal handler loop, trace fact derivation chains, and visualize your rule network as D2 diagrams.

Originally forked from clipspy, clipspyx adds a Python-native DSL, async backward chaining, fact tracing, and full CLIPS 7.0 support while keeping the low-level CFFI API available for everything else.

Quick start

pip install clipspyx          # or: uv add clipspyx

Low-level API

from clipspyx import Environment

env = Environment()
env.build('(defrule hello (initial-fact) => (println "Hello CLIPS!"))')
env.reset()
env.run()

Python DSL

Define CLIPS templates and rules as Python classes:

from clipspyx import Environment
from clipspyx.dsl import Template, Rule, Multi

class Employee(Template):
    name: str
    title: str
    years: int = 0

class Skill(Template):
    name: str
    proficiency: int = 1

class Project(Template):
    name: str
    required_skill: str
    min_proficiency: int = 1

class AssignProject(Rule):
    """Match employees to projects by skill."""
    e = Employee(name=name)
    Skill(name=skill, proficiency=prof)
    Project(name=proj, required_skill=skill, min_proficiency=min_prof)
    prof >= min_prof

    def __action__(self):
        print(f"Assign {self.name} to project {self.proj}")

env = Environment()
NewEmployee = env.define(Employee)
NewSkill = env.define(Skill)
NewProject = env.define(Project)
env.define(AssignProject)

env.reset()
NewEmployee(name="Alice", title="Engineer", years=5)
NewSkill(name="Python", proficiency=4)
NewProject(name="Atlas", required_skill="Python", min_proficiency=3)
env.run()
# => Assign Alice to project Atlas

The DSL supports the full range of CLIPS conditional elements:

Python syntax CLIPS CE
p = Person(name=name) Assigned pattern
Person(age=_) Wildcard
Person(age=25) Literal constraint
Person(name=not "Bob") Field negation
Person(age=25 or 30) Field or
age >= 18 Test CE
~Person(name="Bob") Negation
exists(Person()) Exists CE
forall(Person(name=n), Badge(owner=n)) Forall CE
logical(Person(name=n)) Logical CE

Rules can declare effects without a Python bridge function:

class DoubleInput(Rule):
    i = Input(value=v)
    asserts(Output(value=v * 2))

class Cleanup(Rule):
    p = Temp(flag=Symbol("done"))
    retracts(p)

Fact tracing

Track which rules produced which facts:

env.enable_tracing()
env.reset()
# ... assert facts and run ...

for firing in env.find_template('RuleFiring').facts():
    print(f"{firing['rule']}: {firing['inputs']} -> {firing['outputs']}")

Each RuleFiring fact records the rule name, the input facts that matched, and the output facts that were asserted.

Visualization

Generate D2 diagrams of your rule network:

# Print D2 text
print(env.visualize(group_by_kind=True))

# Render to SVG (requires d2 CLI)
env.visualize(output="diagram.svg", group_by_kind=True)

Templates, rules, pattern edges, fact-address references, and effect edges are all represented. See examples/hr_system.py for a full example.

Async goal handlers (CLIPS 7.0)

CLIPS 7.0 backward chaining generates goals when a rule needs a fact that doesn't exist yet. clipspyx dispatches these goals to Python async handlers, enabling rules that wait on timers, HTTP calls, or any async I/O:

import asyncio
from clipspyx import Environment
from clipspyx.dsl import Template, Rule, TimerEvent, AFTER
from clipspyx.values import Symbol

class Alert(Template):
    msg: str

class DelayedAlert(Rule):
    te = TimerEvent(kind=AFTER, name=Symbol("alarm"), seconds=2.0)
    asserts(Alert(msg=Symbol("time-is-up")))

env = Environment()
env.enable_goal_handlers()
env.define(Alert)
env.define(DelayedAlert)
env.reset()
asyncio.run(env.async_run())

Built-in TimerEvent supports one-shot (AFTER), absolute (AT), and periodic (EVERY) timers. Register custom handlers for your own goal templates:

async def query_handler(goal, env):
    result = await fetch_from_service(goal['service'], goal['query'])
    env.find_template('QueryResult').assert_fact(result=result)

env.register_goal_handler('query-goal', query_handler)

CLIPS 7.0 features

When built against CLIPS 7.0x, clipspyx also supports:

  • Template inheritance: (deftemplate car (is-a vehicle) (slot doors))
  • Certainty factors: (deftemplate sensor (is-a CFD) (slot reading)) with CF propagation through rule chains
  • Deftables: static lookup tables accessible from rules and Python
  • Backward chaining: goal generation with (goal ...) patterns
  • update_slots: selective rete re-evaluation (only rules matching the changed slot)

Building from source

clipspyx compiles CLIPS source directly into the CFFI extension. No separate libclips build step.

Prerequisites

  • Python 3.10+
  • C compiler (gcc/clang on Linux/macOS, MSVC on Windows)
  • CLIPS source (auto-checked out from orphan branch, or provide your own)

Install for development

# Install with 64x backend (CLIPS 6.4x)
uv sync --extra 64x

# Install with 70x backend (CLIPS 7.0x)
uv sync --extra 70x

Switching backends

The 64x and 70x backends conflict with each other. Always use uv sync to switch:

uv sync --extra 64x   # switch to 6.4x
uv sync --extra 70x   # switch to 7.0x

uv run --extra does not remove the previously installed conflicting backend. Only uv sync --extra <variant> correctly handles the switch.

CLIPS source override

CLIPS_SOURCE_DIR=/path/to/clips/core uv sync --extra 64x

Build distributable wheels

uv run scripts/build-backend.py 64x   # builds clipspyx-ffi + clipspyx-ffi-64x wheels
uv run scripts/build-backend.py 70x   # builds clipspyx-ffi + clipspyx-ffi-70x wheels

Testing

uv run pytest tests/ -v

License

BSD-3-Clause. See LICENSE.txt.

Metadata

Release files for clipspyx 0.10.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 clipspyx 0.10.7
File Size Uploaded
clipspyx-0.10.7.tar.gz 129.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for clipspyx 0.10.7
File Interpreter ABI Platform
clipspyx-0.10.7-py3-none-any.whl Python 3 none any Details

Total release size: 214.0 kB

Release files / clipspyx-0.10.7.tar.gz

Download URL clipspyx-0.10.7.tar.gz
Size 129.8 kB
Tags Source
SHA-256 checksum
How to use checksums
23eff5b5361c31106c5e3a1af15f28caf172be6422c597a9f0728453dd4f243f
BLAKE2b-256 checksum
How to use checksums
23cb87aaea0e35b4db974bc704bcd2abef5b5c60f0e52e250168ff94c104bec6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 31, 2026.

Transparency log

Release files / clipspyx-0.10.7-py3-none-any.whl

Download URL clipspyx-0.10.7-py3-none-any.whl
Size 84.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
527a7b39c0d69dca85e69304b48b7bd6ae0b8ed3b8e178566464c6ee46f842dc
BLAKE2b-256 checksum
How to use checksums
24de61145cd7eefbfae32a53998c2c9603cc301930a06878e2e21b17ad95c468
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Mar 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.10.7 This release

2 release files

0.10.6

2 release files

0.10.5

2 release files

0.10.4

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

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