Skip to main content

spm-calculator

Calculate Supplemental Poverty Measure (SPM) thresholds with published national inputs and conditional CE/ACS rolling forecasts. The package works offline for standalone calculations and supplies the same forecast artifact to optional PolicyEngine, Microcosm Frame and actual Axiom core integrations.

Install the package from PyPI. The calculator runs at policyengine.org/us/spm-calculator, the documentation is at policyengine-docs.vercel.app/spm-calculator, and the companion paper is at spm-threshold-paper.vercel.app.

PolicyEngine integrations require coordinated dependency pins; read the migration guide before upgrading an existing environment.

Published 2025 inputs

The national reference family has two SPM adults and two children. The bundled 2025 thresholds and tenure-specific housing shares come from the BLS workbooks:

Tenure Annual national threshold, USD Housing share
Owner with mortgage 41,322.707394 0.4285074824
Owner without mortgage 34,325.997720 0.3120194707
Renter 41,700.555713 0.4336857704

The BLS housing-share workbook supplies the shelter-plus-utilities fractions. The published-cell receipt links threshold cells to the source workbooks and rounded BLS page values. The source and validation guide distinguishes these published values from replicated or projected amounts. A published national base does not make a local 2025 estimate an official Census threshold: the selected area's rent input can be modeled.

Install

Python 3.9 or newer:

pip install spm-calculator==1.0.0.post1

With uv, uv pip install spm-calculator==1.0.0.post1, or uv add spm-calculator==1.0.0.post1 inside a uv project. To work on the package itself, install this checkout instead with python -m pip install -e ..

A calculation needs no Census API key or source download. Optional integrations require their own runtime installations; see the linked guides below.

Calculate a threshold

from spm_calculator import SPMUnit, load_forecast

forecast = load_forecast()
result = forecast.calculate_unit(
    SPMUnit(
        unit_id="example-family",
        num_adults=2,
        num_children=2,
        tenure="renter",
        year=2025,
        geography_kind="national",
        resources=40_000,
    )
)
print(f"Threshold: ${result['threshold']:,.2f}")  # $41,700.56
print(result["is_in_poverty"])  # True
print(forecast.forecast_id, forecast.content_sha256)

Here resources means already measured annual SPM resources, not gross income. Omit it when only a threshold is needed. SPMUnit accepts already classified counts. In person-based integrations, an adult is a person aged at least 18, or aged at least 15 with an explicit SPM independence role. Native SPM membership and source roles determine those counts; household size alone does not.

For a county, resolve its assignment for the target year, then calculate with that SPM estimation area:

from spm_calculator import SPMUnit, load_forecast

forecast = load_forecast()
assignment = forecast.resolve_county(
    2026, "06037", county_vintage="2020", scenario="ce_trend"
)
result = forecast.calculate_unit(
    SPMUnit(
        "example-family", 2, 2, "renter", 2026,
        geography_kind=assignment["kind"],
        geography_id=assignment["area_id"],
    ),
    scenario="ce_trend",
)
print(result["threshold"], result["national_status"])
print(result["provenance"]["geography"])

County is an assignment input, not an estimation unit. Use forecast.areas_for_year(year, scenario=...) to list that year's supported areas and their statuses. metro is the API kind for named MSAs, state residual metro/nonmetro areas and explicitly modeled residual areas; inspect area_type and official_published_area rather than inferring official status from the kind. National calculations are an explicit location choice. Unknown locations, years and scenarios raise errors.

Conditional 2026–2035 forecasts

The default schema-2 artifact covers 2022–2035. It preserves published national values through 2025 and projects 2026–2035 using moving five-year Consumer Expenditure Survey and American Community Survey windows. ce_trend is the default real-spending scenario; zero_real provides zero real-spending growth. The artifact records price assumptions, their source vintage, housing shares, rent indices, source windows and diagnostics separately for each selected year.

These are conditional research estimates. Public-use rent allocation, unresolved CE sample policies, fixed future donors and weights, and unestimated forecast uncertainty limit interpretation. Relative rent indices stabilize from 2029 under the baseline donor and price assumptions even as windows advance; this is not evidence of persistent local growth differences. Read the rolling forecast methods and validation limits before comparing scenarios or historical geography series breaks.

Command line

After installation:

spm-calculator info
spm-calculator verify
spm-calculator calculate --year 2025 --adults 2 --children 2 --tenure renter --national
spm-calculator --scenario ce_trend calculate --year 2026 --adults 2 --children 2 --county 06037
spm-calculator areas --year 2035
spm-calculator --scenario zero_real export --format csv

Global options (--forecast, --expect-sha256, --as-of, --scenario) precede the subcommand. Retain a reviewed content digest and supply it on replay; the reader does not obtain a newer artifact over the network. See the quickstart and artifact contract.

Integrations and app

  • PolicyEngine: in this integration the country model reads forecast configuration by default and retains its tax, benefit and resource formulas. The country and wrapper sides ship in their own packages: policyengine-us 2.0 and the policyengine wrapper 6.0 are in progress. Read the 1.0 migration guide before pinning them.
  • Microcosm Frame: preserve native membership and typed weights, attach canonical results and summarize with Frame operations.
  • Axiom core: execute person classification, native unit counts, bounded canonical scale lookup and threshold/housing/poverty arithmetic in real core. The dense Microcosm AxiomEngine does not support this bridge; exact decimal poverty boundaries can differ from Python float results.

The browser app is live at policyengine.org/us/spm-calculator. Run it locally from web with bun install --frozen-lockfile and bun run dev; its export consumes the canonical artifact.

Sources and research history

MIT license.

Metadata

Release files for spm-calculator 1.0.1

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

Source distribution (sdist)

Source distribution for spm-calculator 1.0.1
File Size Uploaded
spm_calculator-1.0.1.tar.gz 7.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for spm-calculator 1.0.1
File Interpreter ABI Platform
spm_calculator-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 14.5 MB

Release files / spm_calculator-1.0.1.tar.gz

Download URL spm_calculator-1.0.1.tar.gz
Size 7.2 MB
Tags Source
SHA-256 checksum
How to use checksums
90856d6bcef92ef2d1a13b5728ee59434968187e02d3ecc03b8efa2c9cc07d91
BLAKE2b-256 checksum
How to use checksums
60fb4fc8b2acccc34ae76604104fe654da46242b06820b7bee31e973212d957c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 12, 2026.

Transparency log

Release files / spm_calculator-1.0.1-py3-none-any.whl

Download URL spm_calculator-1.0.1-py3-none-any.whl
Size 7.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
aed4a691beac39ccfc5e1fb755446f3a9996c138cb0364a244e1d2f3ba31fdff
BLAKE2b-256 checksum
How to use checksums
db0991dae73934eac2cfc5cf1a80eb4b156ed0b70a53179a461ac66bc6a65984
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

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