Skip to main content

finvariant

CI PyPI License: MIT

Deterministic integrity checks for financial statements.

Give finvariant income statement, balance sheet and cash flow data; it verifies the accounting invariants - the balance sheet balances, the cash flow ties to the balance sheet, subtotals foot, and the three statements articulate - and returns a structured, auditable report. It verifies; it does not parse, fetch or build statements.

Motivation

Python has plenty of libraries to retrieve statements (financetoolkit, the SEC tools) and to build models (DCF templates, FP&A scripts). What none of them do is check that a set of statements or a model is internally consistent: that assets equal liabilities plus equity, that the cash flow's ending cash matches the balance sheet, that retained earnings roll forward by net income less dividends, that every subtotal foots. That check is exactly what a spreadsheet silently gets wrong - and surveys put an error in the large majority of business spreadsheets.

finvariant encodes those invariants as deterministic, testable rules. The same thing a large language model cannot be trusted to get right (consistent arithmetic across linked statements), a small library can guarantee. Every result is one report: a verdict, the exact failing checks with expected vs actual, and provenance, so a verification can be reproduced and audited later.

pip install finvariant

No runtime dependencies.

Usage

Catch an error:

import finvariant as fv

s = fv.Statements(
    periods=["FY2024"],
    balance_sheet={"FY2024": {
        "total_assets": 540,          # should be 538
        "total_liabilities": 158,
        "total_equity": 380,
    }},
)

r = fv.check(s)
r.ok            # False
print(r.summary())
# finvariant audit - 2026-...
#   1 checks run, 0 passed, 1 failed, 0 skipped
#   [ERROR] EQ.accounting_equation assets = liabilities + equity (FY2024): expected 538, got 540, off by 2
# Verdict: FAIL - statements do not tie out

Real statements tie out (Apple FY2024, from the 10-K):

s = fv.Statements(
    periods=["FY2024"],
    income_statement={"FY2024": {
        "revenue": 391035, "cogs": 210352, "gross_profit": 180683,
        "operating_expenses": 57467, "operating_income": 123216,
        "other_income": 269, "pretax_income": 123485, "tax": 29749,
        "net_income": 93736,
    }},
    balance_sheet={"FY2024": {
        "total_current_assets": 152987, "total_non_current_assets": 211993,
        "total_assets": 364980,
        "total_current_liabilities": 176392, "total_non_current_liabilities": 131638,
        "total_liabilities": 308030,
        "common_stock": 83276, "retained_earnings": -19154,
        "accumulated_oci": -7172, "total_equity": 56950,
    }},
)
fv.check(s).ok          # True

The report carries named findings, counts, ok, summary() and a JSON-safe to_dict() with provenance (version, input hash, timestamp).

What it checks

Group Invariant
Footing every subtotal equals the sum of its line items (all three statements)
Equation total assets = total liabilities + total equity
Cash net change = cfo + cfi + cff; ending cash ties to the balance sheet; beginning cash ties to the prior period
Articulation net income agrees across statements; retained earnings roll forward by net income less dividends

Provide only the fields you have: a check whose inputs are missing is reported as skipped, never failed. Tolerances absorb the rounding in statements reported in whole millions.

Status

Version 0.1.0. Single entity, single currency, one or more periods, in a canonical schema. The Statements input and AuditReport output are the contract and are append-only from here.

Roadmap

Version Scope
0.2 roll-forward checks (PP&E = opening + capex - depreciation - disposals; debt; equity); working-capital changes reconciled to operating cash flow
0.3 an MCP server so an agent can verify financial statements it reads or generates
0.4 optional readers to map common export formats into the canonical schema

Out of scope: retrieving statements (see financetoolkit, the SEC tools), building or forecasting models, ratio analysis, consolidation and currency translation.

License

MIT. Written and maintained by Atakan Arikan, MSc Student at Tsinghua University and Politecnico di Milano.

Metadata

Release files for finvariant 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for finvariant 0.1.0
File Size Uploaded
finvariant-0.1.0.tar.gz 14.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for finvariant 0.1.0
File Interpreter ABI Platform
finvariant-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.5 kB

Release files / finvariant-0.1.0.tar.gz

Download URL finvariant-0.1.0.tar.gz
Size 14.1 kB
Tags Source
SHA-256 checksum
How to use checksums
aa3cf507573c142ce33f90300444b699a663b8ded566fd2b9ebbbe01851983ed
BLAKE2b-256 checksum
How to use checksums
cafa87f6c540602144543cca481da5544b5400417ef4153ab93ea14648ec4c2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / finvariant-0.1.0-py3-none-any.whl

Download URL finvariant-0.1.0-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
88e7435493e0b40aa19b825e1d2de880d469e61762119abdcaa2db1634c99726
BLAKE2b-256 checksum
How to use checksums
b8fac712193d826664fc83086c61715bbe364ef5bcdf0677967c9575bd8b8dae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page