falaw.cost#
Cost estimation: ModelRecord.cost_estimate + Scene rollups.
Two surfaces here:
estimate_call_cost(record, *, count=1, seconds=None, megapixels=None, tokens=None)()— turn one model’sCostEstimateinto a USD figure.estimate_scene_cost(scene, *, ...)()— walk every Shot + Beat in afalaw.Sceneand sum the per-call costs thatfalaw.render_scene()would incur. Returns a structured rollup(per-line + totals) so UIs can show “this render would cost ~$0.42”.
A scene-level estimate is advisory. It’s based on the same
pick_model(category, quality_tier=...) lookup that the renderer
uses, multiplied by per-line duration / pixel budgets. Real costs vary
with model fluctuations and provider billing rules, but this is good
enough to gate on (e.g. --budget=1.00) and to surface in
muvid status.
Module Attributes
Pixel budget assumed for a |
Functions
|
Cost of one fal call against |
|
Estimate the USD cost of a full |
Classes
|
One line item in a scene rollup. |
|
Result of |
- class falaw.cost.CostLine(*, kind, item_id, model_id, amount, currency, note='')[source]#
Bases:
objectOne line item in a scene rollup.
- class falaw.cost.CostRollup(*, total_amount, currency='USD', lines=(), skipped=())[source]#
Bases:
objectResult of
estimate_scene_cost().
- falaw.cost.DFLT_MEGAPIXELS = 0.6#
Pixel budget assumed for a
per_megapixelcall when the caller gives none: a 16:9 canvas 1024 wide (≈0.59 MP), enough for a useful upper-bound estimate. Exported to the TypeScript twin, which must assume the same.
- falaw.cost.estimate_call_cost(record, *, count=1, seconds=None, megapixels=None, tokens=None)[source]#
Cost of one fal call against
record.Returns
Nonewhen the cost is unknown, so callers can distinguish “free” from “we can’t say”. That happens when the record carries nocost_estimateat all, or when its pricing is quantity-based (per_second/per_token) and the caller did not supply the quantity — an unpriceable call, not a free one.Returning
0.0for a missing quantity would be actively dangerous: aper_secondclip is the single most expensive thing fal bills for, and a caller gating a budget on the answer would read “$0.00” and spend real money without a prompt.Noneinstead propagates toCallPlan.estimated_cost_usdand lights upPlan.has_unknown_costs, which exists for exactly this case. Callers that know the quantity should pass it;per_secondcallers can fall back torecord.max_clip_secondsfor an upper bound.per_megapixelis deliberately different: an image’s pixel budget has a sane house default (below), so it stays priceable.
- falaw.cost.estimate_scene_cost(scene, *, tts_quality='balanced', lipsync_quality='high', shot_quality='balanced', shots_as_video=False, shot_seconds=None)[source]#
Estimate the USD cost of a full
render_scene()invocation.Walks every shot + beat with the same
pick_modelsemantics the renderer uses, then sums per-call costs. Returns a structuredCostRollupwith per-line breakdowns, plus a list of “skipped” entries the caller should surface (typically: a model with nocost_estimatepopulated).shot_secondsis the assumed clip length used to priceshots_as_video. AShotcarries no duration of its own — screen time comes from the renderer’s per-shot run — and image-to-video models bill per second, so without this the video lines are genuinely unpriceable and are reported inCostRollup.skippedrather than silently priced at $0.00. Pass the length you expect (the beat path has the same knob asestimated_seconds).- Return type: