Read Native Sheet Inputs in a Model
Use NativeSheetReader when Python model code consumes cells from a committed
Native Sheet. It distinguishes a missing cell, a literal blank, a formula
without a cached value, a formula error, and numeric zero. Directly loading a
.btsheet.json file bypasses these checks and does not emit the canonical cell
identities used for lineage reconciliation.
Install the versioned helper
Section titled “Install the versioned helper”Download the immutable
native_sheet_reader.py v1.0.0 source
from Bridge Town’s public GitHub release. Its SHA-256 digest is
9849fff47d88d8ef15642d3825e69cd95ebfedd0c564b274d949aff3173ad8f5.
The release includes the complete
SHA256SUMS,
source at the immutable tag,
runnable example,
changelog, MIT license, and ownership record.
Verify the file outside the network-isolated model sandbox:
curl -fL -o native_sheet_reader.py \ https://github.com/Bridge-Town/financial-modeling-mcp/releases/download/model-authoring-helpers-v1.0.0/native_sheet_reader.pyprintf '%s %s\n' \ 9849fff47d88d8ef15642d3825e69cd95ebfedd0c564b274d949aff3173ad8f5 \ native_sheet_reader.py | sha256sum --checkCopy the verified file byte-for-byte into the model repository as
lib/native_sheet_reader.py with create_file or commit_files. The helper
uses only Python’s standard library and makes no network calls.
Read required values
Section titled “Read required values”Import the helper from a model file and use it as a context manager:
from lib.native_sheet_reader import NativeSheetReader
with NativeSheetReader() as sheets: base_revenue = sheets.read_value("sht_inputs", "tab_drivers", "B2") growth_rate = sheets.read_value("sht_inputs", "tab_drivers", "B3")
result = { "next_period_revenue": round(float(base_revenue) * (1 + float(growth_rate)), 2)}Use the canonical sheet_id and tab_id returned by
get_native_sheet. A tab’s
exact display name is also accepted, but telemetry always records its stable
tab_id. A1 references are normalized to uppercase.
After a successful with block, the helper writes
/outputs/native_sheet_read_set.json. The artifact contains only bounded
sheet_id/tab_id/cell_ref identities and read-status labels — never cell
values. Repeated reads are deduplicated, the default maximum is 1,000 entries,
and truncation is explicit.
Handle a meaningful blank
Section titled “Handle a meaningful blank”read_value is intentionally strict: a missing cell, literal blank, formula
without a cached value, or formula error raises a specific exception rather
than substituting zero. When a literal blank has business meaning, call
read_cell and branch on its status:
from lib.native_sheet_reader import NativeSheetReader
with NativeSheetReader() as sheets: optional_bonus = sheets.read_cell("sht_inputs", "tab_drivers", "B4") bonus = 0.0 if optional_bonus.status == "literal_blank" else float(optional_bonus.value)Do not catch the base exception and continue with an invented value. Formula cache and error failures mean the sheet must be fixed and recalculated before the model runs.
Pair reads with output lineage
Section titled “Pair reads with output lineage”The read-set artifact says which canonical cells the model read. To explain
how an input drives an output, install the separately versioned
output_lineage.py helper and pass
the same sheet_id, tab_id, and cell_ref through InputSourceRef when
building the output trace.