Skip to main content

Relativities

Exact insurance rating and portfolio analysis in Python, on your own machine.

Relativities runs rating programs written in RSL, EffectiveAI's rating language, on a native Rust engine. Build a small rater in Python or load one from EffectiveAI, rate one submission or a whole book, and analyze the results with weights, exact decimals and every refusal kept in view. What you rate stays on your computer.

Install

pip install relativities
pip install "relativities[plot]"   # extras: pandas, models, plot

Requires Python 3.12 or newer. Prebuilt wheels cover macOS (Intel and Apple Silicon), Linux (x86_64 and aarch64, glibc 2.28+) and Windows (x86_64), so no compiler is needed.

Quickstart: build a rater and rate a book

from decimal import Decimal
from relativities import RSL, Dataset

program = RSL.Program("Home")
territory = program.enum("Territory", {"coastal": "coastal", "inland": "inland"})

coverage_a = program.input("coverage_a", precision="int", bounds=(100_000, 1_500_000))
home_territory = program.input("territory", dtype=territory)
claims_free = program.input("claims_free", dtype="Bool")

base_rate = program.table(
    "base_rate_per_1000", key=territory, rows=[("coastal", "4.10"), ("inland", "2.60")]
)
base = program.calculate("base_premium", coverage_a * base_rate(home_territory) * Decimal("0.001"))
discount = claims_free.choose(Decimal("0.90"), 1)
program.output("premium", (base * discount).round(2, mode="half_up"))

rate = program.compile()

homes = Dataset.from_records([
    {"id": "H1", "Home": {"coverage_a": 400_000, "territory": "inland", "claims_free": True}},
    {"id": "H2", "Home": {"coverage_a": 900_000, "territory": "coastal", "claims_free": False}},
    {"id": "H3", "Home": {"coverage_a": 2_000_000, "territory": "coastal", "claims_free": True}},
])
results = rate(homes)

for row in results.rows:
    print(row.id, row.status, row.outputs["premium"] if row.status == "succeeded" else row.error.code)
# H1 succeeded 936
# H2 succeeded 3690
# H3 invalid_inputs INPUT-RANGE

H3 is above the coverage limit, so it comes back as invalid_inputs with a named reason instead of disappearing or becoming a zero premium.

Analyze a book

Wrap your own records with Dataset.from_records(...) or Dataset.from_pandas(df, key="policy_id"), then add representation weights with Population. This example uses the bundled synthetic auto rater and households:

from operator import itemgetter
from relativities import Population, load_dataset, pipeline

households = load_dataset("example-auto-households")
population = Population(households, unit="household", weights="weight")

with pipeline("rating", rater="builtin://example-auto", preprocess=itemgetter("submission")) as rate:
    ratings = rate(households)

summary = ratings.summarize(output="/Policy/annual_premium", weights=population.weights)
print(summary.mean, summary.quantile(0.95))   # 640.625 1375
print(summary.rated_count, summary.unrated_count)   # 5 1
print([row.id for row in ratings.refusals])   # ['mileage-refusal']

Every input keeps exactly one result row and its ID. Rows are succeeded, invalid_inputs (malformed or out-of-range), refused (a coded business rule) or a mapping or runtime failure. Summaries report rated and unrated weight side by side, and a missing output is never treated as zero.

Rate EffectiveAI raters

With an EffectiveAI API key, catalog raters download once, are verified and cached, then rate locally:

export EFFECTIVE_API_KEY=sk-eai-...
from relativities import Hub, Rater

with Hub() as hub:
    print([row["raterId"] for row in hub.list_raters()])

with Rater.load("<rater-id>") as rater:
    print(rater.input_schema)          # this rater's submission shape
    result = rater(submission)
Setting Environment variable Argument
API key EFFECTIVE_API_KEY api_key=
Server (default https://effectiveai.app) EFFECTIVE_API_BASE_URL Hub(base_url=...)
Cache only, no network EFFECTIVE_OFFLINE=1 local_files_only=True

Pass revision= with a bundle ID to pin an exact version; a pinned rater then loads from the cache offline. Submissions and results are never uploaded.

Some catalog raters still use an older RSL version and can't be rated locally yet; Rater.load says so when that's the case.

Fit a simple loss model

Requires the models extra:

from relativities import Dataset, LossModel, evaluate, load_dataset, pipeline

experience = load_dataset("example-claims")
training = Dataset([row for _, row in experience.iter_rows() if row["split"] == "train"])
holdout = Dataset([row for _, row in experience.iter_rows() if row["split"] == "test"])

frequency = LossModel(
    family="poisson",
    features=("driver_age",),
    target="claim_count",
    exposure="exposure",
    unit="claims over supplied exposure",
).fit(training)

counts = pipeline("loss", model=frequency)(holdout).distributions["claim_count"]
print(counts.mean())
print(counts.survival(2))  # P(N > 2) for each record
print(evaluate(frequency, data=holdout).summary())

Why the numbers hold up

  • Exact arithmetic. Premiums are exact decimals. A value with no finite decimal form, such as one third, stays an exact fraction ({"$rational": "1/3"}) instead of being silently rounded.
  • Pinned and verified. Every rater is identified by an immutable bundle ID and its files are verified before anything runs.
  • One engine. Raters you build in Python and catalog raters both run on the same Rust engine that checks the RSL before rating.

Scope

  • The Python builder covers one flat record with numeric, Boolean and enum inputs, +, -, *, equality, conditionals (choose), single-key tables and rounding. Load a full RSL rater for anything more.
  • Loss models are Poisson frequency (with optional exposure) and Gamma severity GLMs with a log link and numeric predictors. They don't model parameter uncertainty or portfolio dependence.
  • The bundled datasets are small synthetic examples, not market data.

License and support

Relativities is proprietary software from EffectiveAI, licensed under the terms in the LICENSE file included with the package. Catalog raters and data are covered by separate agreements.

Metadata

Release files for relativities 0.2.0

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

Built distribution (wheel)

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

Release files / relativities-0.2.0-py3-none-any.whl

Download URL relativities-0.2.0-py3-none-any.whl
Size 111.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2abf0ec7b2c566507976700f83963af53fc7a2edce0aaa2e3f2d9a5284746ffd
BLAKE2b-256 checksum
How to use checksums
87a7fbde8d3790f6aa001b335e2cd238fd78edabe3fbc24ee78e844d5d6ef79d
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 Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

1 release file

This release

0.2.0 This release

1 release file

0.1.0

1 release file

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