SDK Guide

Rules Engine SDK

A drop-in Python SDK that translates TwinFyRx suspecting rules into executable SQL against your claims schema. Map your tables once with SchemaConfig, then run rules with RuleExecutor.

Concepts

Overview

The SDK bridges the gap between TwinFyRx's suspecting rules (structured JSON logic) and your existing claims data warehouse. It ships two core components:

SchemaConfigConfiguration

A dataclass that maps TwinFyRx canonical table and column names to your actual schema. Define this once — the SDK rewrites all generated SQL to match.

RuleExecutorExecution

Translates rule_logic JSON into executable SQL SELECT statements, or evaluates rules in-memory against a claim context dictionary.

Setup

Installation

The SDK is delivered as a Python package during onboarding. No external dependencies are required beyond the standard library.

from twinfyrx_sdk import RuleExecutor, SchemaConfig

Compatibility: Python 3.9+. The SDK generates SQL compatible with DuckDB, Snowflake, BigQuery, and standard ANSI SQL dialects.

Configuration

SchemaConfig

Map your claims schema to TwinFyRx's canonical model. Every table and column name is overridable — the SDK rewrites generated SQL to match your naming conventions.

from twinfyrx_sdk import SchemaConfig

config = SchemaConfig(
    # Table names
    rx_claims_table="pharmacy_claims",
    members_table="member_enrollment",
    providers_table="provider_directory",
    medical_claims_table="medical_claims",
    ndc_atc_table="ndc_atc_crosswalk",

    # Rx claims columns
    rx_claim_id="claim_id",
    rx_member_id="member_id",
    rx_ndc="ndc_code",
    rx_fill_date="date_of_service",
    rx_prescriber_npi="prescriber_npi",

    # Member columns
    mb_member_id="member_id",
    mb_gender="sex",
    mb_age="current_age",

    # Provider columns
    pr_npi="npi",
    pr_specialty="taxonomy_description",

    # Medical claims columns
    mc_member_id="member_id",
    mc_icd10_code="diagnosis_code",
    mc_procedure_code="cpt_code",
    mc_service_date="service_date",

    # NDC-ATC crosswalk columns
    na_ndc="ndc",
    na_atc_code="atc_code",
)

Default Schema Mapping

TableDefault Name
Rx Claimsrx_claims
Membersmembers
Providersproviders
Medical Claimsmedical_claims
NDC-ATCndc_atc
Execution

RuleExecutor

The core execution engine. Takes structured rule logic (JSON) from the TwinFyRx API and produces either executable SQL or in-memory evaluation results.

from twinfyrx_sdk import RuleExecutor, SchemaConfig

executor = RuleExecutor(schema=SchemaConfig(...))

# Fetch rules from the API
import requests
resp = requests.get(
    "https://api.twinfyrx.com/v1/drugs/617314/suspecting-rules",
    headers={"X-API-Key": "your_key"}
)
rules = resp.json()["rules"]

# Generate SQL for each rule
for rule in rules:
    sql = executor.generate_sql(
        rule_id=rule["rule_id"],
        icd10_code=rule["icd10_code"],
        rule_logic=rule["rule_logic"],
        rule_strength=rule["rule_strength"],
        confidence=rule["confidence"],
        drug_rxcui=617314,
        drug_ndcs=["00071015523", "00071015540"],
    )
    if sql:
        print(sql)
Output

SQL Generation

Each rule produces a SELECT statement that returns one row per qualifying rx claim. The output schema is consistent across all rule categories.

Output Columns

ColumnTypeDescription
member_idVARCHARMember identifier from your claims
claim_idVARCHAROriginating rx claim
ndcVARCHARNDC code on the claim
fill_dateDATEPrescription fill date
suspected_icd10VARCHARInferred ICD-10 diagnosis code
rule_confidenceDECIMALBase confidence score (0–1)
rule_strengthVARCHARstrong_prior, weak_prior, or exclusion
rule_idVARCHARTwinFyRx rule identifier
drug_rxcuiINTEGERDrug concept ID

Rule Categories & SQL Patterns

prescriber_specialty

Joins rx_claims → providers to check prescriber taxonomy

WHERE pr.specialty LIKE '%Endocrinology%'
patient_age

Joins rx_claims → members to filter by age range

WHERE mb.age BETWEEN 40 AND 75
patient_gender

Joins rx_claims → members to filter by sex

WHERE mb.gender = 'F'
concurrent_rx

Self-joins rx_claims with NDC-ATC crosswalk to detect co-prescribing patterns

WHERE atc.atc_code LIKE 'A10B%' -- other antidiabetics
medical_claims_history

Joins rx_claims → medical_claims to check for prior diagnoses or procedures

WHERE mc.icd10_code LIKE 'E11%' -- Type 2 diabetes
compound

Combines multiple signal sources using AND/OR logic in a single query

WHERE (specialty AND age_range) OR prior_diagnosis
Alternative

In-Memory Evaluation

For real-time or streaming scenarios, evaluate rules directly against a claim context dictionary without generating SQL.

result = executor.evaluate(
    rule_logic={
        "type": "prescriber_specialty",
        "specialty_pattern": "Endocrinology"
    },
    context={
        "gender": "M",
        "age": 58,
        "prescriber_specialty": "Endocrinology",
        "concurrent_atc": ["A10BA02", "C10AA05"],
        "prior_icd10": ["E11.9", "I10"],
        "prior_cpt": [],
    }
)

print(result)  # True — prescriber is an endocrinologist

Context fields: gender, age, prescriber_specialty, concurrent_atc (list), prior_icd10 (list), prior_cpt (list). Omitted fields are treated as unknown and won't match rules that require them.

Analytics

Confidence Scoring

When multiple rules fire for the same member × diagnosis, the SDK aggregates confidence scores using noisy-OR probability combination. This prevents double-counting while allowing multiple weak signals to compound into strong ones.

Noisy-OR Formula

P(diagnosis) = 1 − ∏(1 − cᵢ)

Where cᵢ is the confidence of each independently firing rule. Rules with exclusion strength reduce the aggregated score rather than contributing to it.

strong_prior

0.6 – 0.9

High-confidence signal. Single rule may be sufficient for suspecting.

weak_prior

0.15 – 0.45

Supporting evidence. Multiple weak priors can compound to strong confidence.

exclusion

−0.3 – −0.8

Counter-evidence. Reduces aggregated score when matched.

Validation

Synthetic Testing

The SDK ships with a synthetic claims generator for testing rule execution before connecting to production data. Generate realistic claims data with controlled demographics and prescribing patterns.

from twinfyrx_sdk.synthetic_claims_generator import generate_claims

# Generate synthetic claims for a drug
claims_df = generate_claims(
    drug_rxcui=617314,
    drug_ndcs=["00071015523", "00071015540"],
    n_members=500,
)

# claims_df contains:
#   - rx_claims: pharmacy claims with fill dates, NDCs, prescriber NPIs
#   - members: member demographics (age, gender)
#   - providers: prescriber specialties
#   - medical_claims: diagnosis and procedure history
#   - ndc_atc: NDC-to-ATC crosswalk for concurrent Rx detection

Run the full end-to-end pipeline against synthetic data to validate rule coverage, confidence distributions, and output format before deploying against your claims warehouse.

Deployment

Integration Workflow

01

Fetch rules from the API

Pull suspecting rules for your target drugs via GET /v1/drugs/{rxcui}/suspecting-rules. Rules include structured JSON logic, confidence scores, and metadata.

02

Configure SchemaConfig

Map your claims schema table and column names to the canonical model. This is a one-time setup — the same config works across all rules and drugs.

03

Generate and execute SQL

Use RuleExecutor.generate_sql() to produce per-rule SELECT statements. Execute against your warehouse and collect per-member rule hits.

04

Aggregate confidence scores

Group results by member × diagnosis and apply noisy-OR aggregation to produce a final confidence score for each suspected diagnosis.

05

Rank and deliver

Surface suspected diagnoses ranked by confidence. Filter by threshold, rule strength, or rule category depending on your use case.

Ready to integrate?

The SDK is included with your API access. Request access to receive the package, your API key, and onboarding support.