Bolster
A Python library for accessing Northern Ireland and UK government open data. Covers population, health, crime, economy, transport, housing, and more — each source normalised into a clean pandas DataFrame with a matching CLI command.
Full documentation: bolster.readthedocs.io
Installation
pip install bolster
Requires Python 3.11+.
What can you do with it?
A few examples using real data:
Who is claiming UC/JSA, and where?
from bolster.data_sources.nisra import claimant_count
df = claimant_count.get_latest_claimant_count("lgd")
# 33,930 claimants across NI as of May 2026
# Derry City & Strabane has the highest rate at 4.1%
print(
df[df["date"] == df["date"].max()].sort_values("claimant_rate_total_pct", ascending=False)[
["geography", "claimants_total", "claimant_rate_total_pct"]
]
)
How many people are on the hypertension register at each GP practice?
from bolster.data_sources.health_ni import disease_prevalence
# NI-wide: 304,952 patients on the hypertension register in 2024/25
summary = disease_prevalence.get_latest_disease_prevalence(level="ni")
# GP-practice level: ~360 practices across ~17 financial years
gp = disease_prevalence.get_latest_gp_prevalence()
print(gp[gp["disease"] == "Hypertension"].groupby("financial_year")["registered_patients"].sum())
How does GP list size vary by Trust, and how has it changed?
from bolster.data_sources.health_ni import gms
df = gms.get_list_size(level="trust")
# Western Trust has the largest lists at 1,619.8 patients/GP in 2025/26,
# Belfast the smallest at 1,277.0 -- both up from five years earlier
latest = df[df["period"] == df["period"].max()].sort_values("list_size")
print(latest)
How has the security situation in NI changed since the Troubles?
from bolster.data_sources.psni import security_situation
df = security_situation.get_deaths()
# 470 deaths in 1972, the worst year on record; 0 in both 2023 and 2025 --
# a dramatic long-term decline, though the series hasn't reached zero every year
print(df[["year", "total"]].sort_values("total", ascending=False).head(3))
print(df[df["year"] >= 2020][["year", "total"]])
How is NI's economy tracking against pre-pandemic levels?
from bolster.data_sources.nisra import composite_index
df = composite_index.get_latest_nicei()
# NICEI at 105.9 in Q1 2026 (base 100 = 2016)
# Breakdown by sector: services, production, construction, agriculture
print(df.tail(4)[["year", "quarter", "nicei", "services", "production"]])
What are A&E waiting times doing across HSC Trusts?
from bolster.data_sources.health_ni import emergency_care_waiting_times
df = emergency_care_waiting_times.get_latest_data()
# Monthly attendance and % seen within 4 hours by Trust and department type
latest = df[df["date"] == df["date"].max()]
print(latest.groupby("trust")["pct_within_4hrs"].mean().sort_values())
What is the median full-time weekly wage in NI?
from bolster.data_sources.nisra import ashe
df = ashe.get_latest_ashe_timeseries("weekly")
# £713.10 median full-time weekly earnings in 2025
print(df[df["work_pattern"] == "Full-time"].tail(5)[["year", "median_weekly_earnings"]])
Data sources
Sources are organised by publisher. Each module follows the same pattern:
get_latest_*() returns a tidy DataFrame; bolster <command> --help gives
CLI access.
NISRA — NI Statistics and Research Agency
People and society:
population,
births,
deaths,
marriages,
stillbirths,
migration,
population_projections,
baby_names,
registrar_general,
deprivation,
wellbeing,
public_confidence,
drug_related_deaths,
armed_forces_veterans
Economy and labour:
labour_market,
claimant_count,
ashe,
quarterly_employment_survey,
composite_index,
index_of_production,
index_of_services,
construction_output,
business_register,
planning_statistics,
housing_stock,
housing_bulletin,
tourism,
work_quality,
workless_households,
neet
Education:
teacher_workforce,
school_leavers,
highest_qualification
Department of Health NI (health_ni)
disease_prevalence (NI / LGD / HSCT / GP-practice level),
cancer_waiting_times,
diagnostic_waiting_times,
elective_waiting_times,
hospital_activity (beds, independent-sector activity, theatre usage),
emergency_care_waiting_times,
child_protection,
hsc_workforce / hsc_recruitment,
gms (GP practices/GPs/patients by trust, LGD or GP federation, funding, access equity)
PSNI — Police Service of Northern Ireland
crime_statistics (historical),
road_traffic_collisions,
stop_and_search,
pace,
police_ombudsman,
motoring_offences,
road_safety_partnership (safety camera detections),
security_situation (deaths, incidents, paramilitary attacks, arrests, 1969-present),
breath_tests (preliminary breath tests conducted, 2010-present)
Department of Justice (justice)
prosecutions_convictions,
first_time_entrants,
nicts_quarterly,
mortgages,
pbni_caseload,
pps_statistical_bulletin
Other sources
| Source | Module | What it covers |
|---|---|---|
| DVA | dva |
Vehicle, driver, and theory test statistics (monthly) |
| NI Water | ni_water |
Drinking water quality by supply zone and postcode |
| NI House Price Index | ni_house_price_index |
Quarterly house price index and sales volumes |
| NI Assembly | niassembly |
MLAs, oral/written questions, votes (2007–present) |
| EONI | eoni |
Assembly election results (2016, 2022) |
| Translink | translink |
Live departures and vehicle positions |
| ONS | ons_cpi |
CPI / CPIH / RPI inflation indices |
| Bank of England | boe_base_rate |
Official Bank Rate (1694–present) |
| European Central Bank | ecb_interest_rates |
Eurozone key policy rates (MRR, DFR, MLFR), 1999–present |
| Companies House | companies_house |
UK company data |
| Gender Pay Gap | gender_pay_gap |
UK GPG reporting (250+ employees, 2017–present) |
| DAERA | daera_waste, daera_greenhouse_gas, daera_air_quality |
NI municipal waste statistics; greenhouse gas emissions inventory; NO2/PM10/PM2.5 air quality |
| Communities (DfC) | family_resources_survey, child_maintenance |
Household income/food security/tenure; Child Maintenance Service statistics |
| Infrastructure (DfI) | school_travel |
Young Persons' Behaviour and Attitudes Survey travel module |
| Economy (DfE) | electricity_renewables, higher_education_enrolments, higher_education_qualifications, higher_level_apprenticeships |
Electricity consumption and renewable generation progress; NI/UK HEI enrolments (HESA); NI/UK HEI qualifications gained (HESA); HLA starts/participants/qualifiers |
| Met Office | metoffice |
UK precipitation maps (requires API key) |
CLI
Every data source has a matching CLI command:
bolster nisra deaths # latest weekly deaths
bolster nisra claimant-count --breakdown lgd
bolster nisra composite-index
bolster health-ni disease-prevalence --level gp
bolster psni stop-and-search
bolster translink departures "Europa Buscentre"
bolster water-quality BT1 5GS
bolster dva vehicle-tests
bolster --help # full command list
Utilities
Bolster also includes general-purpose helpers used internally:
poolmap()— ThreadPoolExecutor with progress bar and error handlingbackoff()— exponential backoff retry decoratormemoize()— instance method cache with hit/miss trackingget_recursively()/flatten_dict()— nested dict navigationCachedDownloader— disk-cached HTTP download with TTLsession— sharedrequests.Sessionwith retry/jitter logic
import bolster
results = bolster.poolmap(lambda x: x**2, range(1000), max_workers=4)
@bolster.backoff(Exception, tries=3, delay=1, backoff=2)
def unreliable(): ...
Development
git clone https://github.com/andrewbolster/bolster.git
cd bolster
uv sync --all-extras --dev
uv run pre-commit install
uv run pytest tests/ -q --no-cov # quick run
uv run pytest tests/ --cov=src/bolster # with coverage
See AGENTS.md for the data source development workflow and CONTRIBUTING.md for guidelines.
License
Metadata
Release files for bolster 0.11.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bolster-0.11.4.tar.gz | 520.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bolster-0.11.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.2 MB
Release files / bolster-0.11.4.tar.gz
| Download URL | bolster-0.11.4.tar.gz |
|---|---|
| Size | 520.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
160cd2299590dbaad57e2727018038bab21d32acb107960008ae98606a6498f6
|
|
BLAKE2b-256 checksum How to use checksums |
9c668f9fcc82205aa79bf1ec9ee38e2d7708a23b83a9b17079cefc4f793df29c
|
| 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 Sep 29, 2026.
Transparency logRelease files / bolster-0.11.4-py3-none-any.whl
| Download URL | bolster-0.11.4-py3-none-any.whl |
|---|---|
| Size | 635.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6cc748d4279ac95691bcde2b1b406e33899a5bf2080eaf4d8f890cfaf03776a7
|
|
BLAKE2b-256 checksum How to use checksums |
467e369c6fa0f8979d3bfcb28cef561a681e0daf2c44e5867da5afbdda488817
|
| 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 Sep 29, 2026.
Transparency log