Skip to main content
Version: 2.x

PricingEngine

PricingEngine is Bursar's database-free operation-pricing core. It validates the same canonical configuration as the rest of the SDK and prices UsageMetrics events without any store, connection, or facade.

Creating an engine

from bursar import PricingEngine

engine = PricingEngine.from_dict(config_dict)

from_dict accepts a canonical config document and returns an engine, or raises ConfigError. Unknown fields, undeclared measures or dimensions, invalid matcher types, and unsafe cross-references are rejected at construction. Credit accounting is a fixed Bursar convention rather than a configuration field; plan rank has an authoring default.

The engine is safe to construct from a config you already validated with load_config_from_dict.

Calculating cost

from bursar import UsageMetrics

cost = engine.calculate(
UsageMetrics(
operation="completion",
measures={"input_tokens": 500, "output_tokens": 200},
dimensions={"model": "gpt-4o"},
)
)

print(cost.total)

calculate(metrics, *, rate_card=None) prices one event. The optional rate_card key is required when the config contains more than one rate card and the caller has not otherwise selected one (via get_rate_card_for_plan).

calculate_batch(metrics, *, rate_card=None) evaluates a list of UsageMetrics with the same rate-card selection and returns a list[CostBreakdown] in the same order.

get_rate_card_for_plan(plan_id) returns the rate-card key referenced by a configured plan — the canonical way to resolve the rate card for a user whose plan is known.

pricing_schema returns the validated, canonicalized config as a dict.

Example

Using the canonical demo configuration (pricing.operations.completion, rate card standard, per-million-token rates for gpt-4o/gpt-4o-mini, and an expression-based fallback for unmatched models):

from decimal import Decimal

config = {
"version": 1,
"pricing": {
"operations": {
"completion": {
"measures": {
"input_tokens": {"unit": "token"},
"output_tokens": {"unit": "token"},
"cache_read_tokens": {"unit": "token"},
},
"dimensions": {"model": {"type": "string"}},
}
},
"rate_cards": {
"standard": {
"operations": {
"completion": {
"rules": [
{
"when": {"model": {"op": "in", "values": ["gpt-4o", "gpt-4o-mini"]}},
"charge": {
"type": "sum",
"components": [
{"type": "per_unit", "measure": "input_tokens", "rate": "0.0025", "unit_size": "1000000"},
{"type": "per_unit", "measure": "output_tokens", "rate": "0.0100", "unit_size": "1000000"},
{"type": "per_unit", "measure": "cache_read_tokens", "rate": "0.00125", "unit_size": "1000000"},
],
},
}
],
"unmatched": {
"action": "charge",
"charge": {
"type": "expression",
"formula": "input_tokens * 0.005 + output_tokens * 0.015",
},
},
}
}
}
},
},
"credits": {},
}

engine = PricingEngine.from_dict(config)
cost = engine.calculate(
UsageMetrics(
operation="completion",
measures={"input_tokens": 2_000_000, "output_tokens": 500_000},
dimensions={"model": "gpt-4o"},
)
)
assert cost.total == Decimal("0.01") # 2,000,000 × 0.0025/M + 500,000 × 0.0100/M

UsageMetrics

FieldTypeMeaning
operationstrA key declared in pricing.operations
measuresdict[str, Decimal]Non-negative billable quantities declared by the operation
dimensionsdict[str, str | Decimal | bool]Typed values used to select the first matching rate rule
metadatadict[str, Any]Caller metadata; it does not participate in pricing

Declared measures omitted by the caller are treated as zero. Required dimensions must be present. Undeclared measures or dimensions are rejected.

CostBreakdown

All monetary fields are Decimal values quantized to six decimal places with half-up rounding. Operation pricing is reported in operation_credits; total is the complete quantized result.

FieldType
operation_creditsDecimal
model_creditsDecimal
tool_creditsDecimal
search_creditsDecimal
cache_savingsDecimal
fixed_creditsDecimal
totalDecimal
breakdowndict[str, Any]

See Pricing for how rate cards, rules, and unmatched actions compose, and Expressions for the supported expression operators and functions.