Metadata-Version: 2.4
Name: rule-engine-core
Version: 0.2.0
Summary: A rule engine core library for Python.
Home-page: https://github.com/temp-noob/rule-engine
Author: Mohit Tripathi
Author-email: tripathimohit051@gmail.com
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: psycopg2-binary
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# rule-engine-core

Shared domain library for the rule-engine platform, published to PyPI as
[`rule-engine-core`](https://pypi.org/project/rule-engine-core/). The three
FastAPI services (`metadata_service`, `position_server`, `platform_service`,
`rule_engine`) all depend on it.

## What's in it

- **Expression parser** (`parser.py`) — recursive-descent parser turning an infix
  rule/filter expression into a `Node` tree (`! & |`, comparisons, arithmetic,
  parentheses; `AND`/`OR`/`NOT` are accepted as aliases).
- **Entities** — `Rule` and `Filter` (both extend `EntityBase`) with `validate()`
  and `evaluate()` over metadata fields and nested entities.
- **`MetadataStore`** — loads column metadata from a JSON file or over HTTP.
- **Postgres DAOs** — `EntityDao` (rules/filters, persisted as pickled objects)
  and `MetadataDao` (the `metadata` table).
- **`DbPool`** — thread-safe psycopg2 connection pool; one connection per unit of
  work via `with pool.acquire() as conn:`.
- **`tracing`** — lightweight `X-Trace-Id` propagation (contextvars + log stamping
  + thread/pool helpers) shared across services.
- **`identity`** — `CurrentUser`, header parsing, `require_admin`, and the
  `app_user`/`user_account_access` lookup; framework-neutral identity primitives
  shared across services.

## Install

```bash
pip install rule-engine-core
```

## Build & publish (manual)

`setup.py` reads its dependencies from `$BUILD_PATH/requirements.txt`, so
`BUILD_PATH` must be set.

```bash
python -m pip install --upgrade setuptools wheel twine
cd rule-engine-core
BUILD_PATH="$(pwd)" python setup.py sdist bdist_wheel
twine upload dist/*
```

Releases are normally cut automatically — see `.github/workflows/publish.yml`,
which publishes to PyPI (then builds the service images) after CI passes on `main`.

### Release order for consumer services

Every service installs this package from PyPI, so a change here is invisible to them until
it's published. When a service needs new core API:

1. Bump `version` in `setup.py`.
2. Build and `twine upload`.
3. Then bump the `rule-engine-core>=<version>` floor in that service's `requirements.txt`
   and `pyproject.toml`.

Until step 2 lands, a service PR carrying a raised floor fails at `pip install` and its CI
goes red. That's the point — it's the reminder to publish, and it beats an `ImportError`
in prod. So publish before merging the consumer.

## Note on the pickle serialization contract

Rules and filters are stored in Postgres as **pickled Python objects**, and
`entity_dao.py` installs `sys.modules` aliases so older pickles still load.
Renaming/moving core modules or changing `EntityBase`'s pickled fields can break
unpickling of already-stored entities — treat these as a compatibility contract.

## Docker

-> `psql --username=$POSTGRES_USER -d $POSTGRES_DB`
