Python SDK

The witan PyPI package installs the Witan CLI and a typed Python SDK. The SDK opens a witan xlsx rpc subprocess, keeps a workbook session alive, and exposes the same spreadsheet operations as witan xlsx exec with Pythonic snake_case method names.

Use the SDK when your application is already Python and needs repeated reads, writes, searches, recalculation, rendering, or linting against the same workbook.

Install

pip install witan

For one-shot CLI use without a persistent install, use uvx witan. For SDK imports, install the package into your Python environment.

Open a workbook

from witan import Workbook

with Workbook("report.xlsx") as wb:
    sheets = wb.list_sheets()
    tsv = wb.read_range_tsv("Summary!A1:F20")

print([sheet["sheet"] for sheet in sheets])
print(tsv)

The context manager closes the subprocess automatically. In notebooks or REPLs, use explicit close:

from witan import Workbook

wb = Workbook("report.xlsx")
try:
    tsv = wb.read_range_tsv("Summary!A1:F20")
finally:
    wb.close()

Create and save

from witan import Workbook

with Workbook("model.xlsx", create=True) as wb:
    wb.add_sheet("Inputs")
    result = wb.set_cells([
        {"address": "Inputs!A1", "value": "Revenue"},
        {"address": "Inputs!B1", "value": 1250000},
        {"address": "Inputs!C1", "formula": "=B1*1.1", "value": None},
    ])

    if result["errors"]:
        raise RuntimeError(result["errors"])

    wb.save()

Writes update the live workbook session and recalculate dependent formulas. Call save() when you want to write the workbook bytes back to disk.

Async sessions

Use AsyncWorkbook in asyncio services, notebooks, and concurrent workflows:

from witan import AsyncWorkbook

async with AsyncWorkbook("report.xlsx") as wb:
    cell = await wb.read_cell("Summary!A1")
    lint = await wb.lint(range_addresses=["Summary!A1:F20"])

print(cell["text"], lint["total"])

In Jupyter/IPython, top-level await works with explicit close:

from witan import AsyncWorkbook

wb = AsyncWorkbook("report.xlsx")
cell = await wb.read_cell("Summary!A1")
await wb.close()

Common workflows

from witan import Workbook, Regex

with Workbook("report.xlsx") as wb:
    sheets = wb.list_sheets()
    cell = wb.read_cell("Summary!B5")
    rows = wb.read_range_tsv("Summary!A1:F20")
    matches = wb.find_cells(Regex(r"revenue|ebitda", "i"), in_="Summary!A:Z")

Use read_range_tsv, read_row_tsv, and read_column_tsv when passing workbook data to a language model. TSV is usually smaller and easier to scan than nested JSON.

Edit and verify

with Workbook("report.xlsx") as wb:
    before = wb.preview_styles("Summary!A1:F20")

    result = wb.set_cells([
        {"address": "Summary!B5", "formula": "=SUM(Revenue!B2:B13)", "value": None}
    ])
    lint = wb.lint(range_addresses=["Summary!A1:F20"])
    after = wb.preview_styles("Summary!A1:F20")

    if result["errors"] or lint["total"]:
        raise RuntimeError({"formula_errors": result["errors"], "lint": lint})

    wb.save()

preview_styles() returns a data:image/...;base64,... URL for the rendered range. For command-line image files and pixel diffs, use witan xlsx render.

Trace and run scenarios

with Workbook("model.xlsx") as wb:
    inputs = wb.trace_to_inputs("Summary!F25")
    sweep = wb.sweep_inputs(
        [{"address": "Inputs!B5", "values": [0.02, 0.04, 0.06]}],
        ["Summary!F25"],
        mode="cartesian",
        include_stats=True,
    )

print(sweep["tsv"])

Method map

The Python SDK follows the xlsx exec API with snake_case names:

Area Methods
Workbook and sheets list_sheets, add_sheet, delete_sheet, rename_sheet, get_sheet_properties, set_sheet_properties
Reading read_cell, read_range, read_row, read_column, read_range_tsv, read_row_tsv, read_column_tsv
Search find_cells, find_rows, find_and_replace, describe_sheet, table_lookup
Writing set_cells, copy_range, scale_range, insert_row_after, delete_rows, insert_column_after, delete_columns
Formulas evaluate_formula, evaluate_formulas, get_cell_precedents, get_cell_dependents, trace_to_inputs, trace_to_outputs, sweep_inputs
Verification lint, preview_styles
Tables and charts get_list_object, add_list_object, set_list_object, get_data_table, add_data_table, list_charts, get_chart, add_chart, set_chart

Options

Pass options when opening the workbook:

wb = Workbook(
    "report.xlsx",
    locale="en-US",
    stateless=True,
    api_key="sk_...",
    api_url="https://api.witanlabs.com",
    request_timeout=60,
)

Most configuration can also come from environment variables. See Configuration.

Errors

from witan import Workbook, WitanRPCError, WitanProcessError, WitanTimeoutError

try:
    with Workbook("report.xlsx") as wb:
        wb.read_range("InvalidRange!!!")
except WitanTimeoutError as exc:
    print("request timed out", exc)
except WitanRPCError as exc:
    print("RPC error", exc)
except WitanProcessError as exc:
    print("process error", exc)

Next steps

  • JavaScript SDK — use the same workbook API from Node.js.
  • CLI — run one-off workbook scripts with witan xlsx exec.
  • Concepts — understand the shared workbook model underneath every SDK.