bolster.data_sources.justice.mortgages
NICTS Mortgages: Action for Possession Data.
Provides access to quarterly statistics on mortgage possession proceedings in the Chancery Division of the Northern Ireland High Court, published by the Northern Ireland Courts and Tribunals Service (NICTS).
Three datasets are available:
Cases received - writs and originating summonses issued (Table 1).
Cases disposed - cases concluded by the court (Table 2).
Final orders - the type of final order made, e.g. possession, suspended possession, strike out (Table 3, available from 2017 onwards).
- Data Source:
Publication Page: https://www.justice-ni.gov.uk/publications/nicts-mortgages-action-possession
The module scrapes this page to find the latest quarterly ODS file (
mortgages-bulletin-tables-<period>.ods), which contains separate worksheets for received, disposed and final-order statistics.
Update Frequency: Quarterly Geographic Coverage: Northern Ireland Reference Period: 2007 - present (final orders: 2017 - present)
This data pairs well with bolster.data_sources.ni_house_price_index
for contextualising the housing market against repossession activity.
Example
>>> from bolster.data_sources.justice import mortgages
>>> df = mortgages.get_cases_received()
>>> "applications" in df.columns
True
>>> {"Q1", "Q2", "Q3", "Q4"}.issubset(set(df["quarter"]))
True
Attributes
Exceptions
Base exception for NICTS mortgages data errors. |
|
Raised when the data file cannot be located or downloaded. |
|
Raised when downloaded data fails validation. |
Functions
|
Find the URL of the most recent mortgages bulletin ODS file. |
|
Download a bulletin ODS file with caching. |
|
Parse all mortgage tables from a bulletin ODS file. |
|
Download and parse the latest mortgages bulletin. |
|
Get quarterly mortgage possession cases received (Table 1). |
|
Get quarterly mortgage possession cases disposed (Table 2). |
|
Get mortgage possession final orders by type (Table 3). |
|
Validate a parsed quarterly mortgages DataFrame. |
Clear all cached mortgages bulletin files. |
Module Contents
- bolster.data_sources.justice.mortgages.PUBLICATION_URL = 'https://www.justice-ni.gov.uk/publications/nicts-mortgages-action-possession'[source]
- exception bolster.data_sources.justice.mortgages.MortgagesDataError[source]
Bases:
ExceptionBase exception for NICTS mortgages data errors.
Initialize self. See help(type(self)) for accurate signature.
- exception bolster.data_sources.justice.mortgages.MortgagesDataNotFoundError[source]
Bases:
MortgagesDataErrorRaised when the data file cannot be located or downloaded.
Initialize self. See help(type(self)) for accurate signature.
- exception bolster.data_sources.justice.mortgages.MortgagesValidationError[source]
Bases:
MortgagesDataErrorRaised when downloaded data fails validation.
Initialize self. See help(type(self)) for accurate signature.
- bolster.data_sources.justice.mortgages.get_latest_publication_url(base_url=PUBLICATION_URL)[source]
Find the URL of the most recent mortgages bulletin ODS file.
Scrapes the publication landing page for links to
.odsfiles and returns the first one found (the page lists newest first).- Parameters:
base_url (str) – URL of the publication listing page.
- Returns:
Absolute URL of the latest ODS bulletin file.
- Raises:
MortgagesDataNotFoundError – If the page cannot be fetched or no ODS link is found.
- Return type:
Example
>>> url = get_latest_publication_url() >>> url.endswith(".ods") True
- bolster.data_sources.justice.mortgages.download_file(url, cache_ttl_hours=24 * 7, force_refresh=False)[source]
Download a bulletin ODS file with caching.
- Parameters:
- Returns:
Path to the downloaded (or cached) file.
- Raises:
MortgagesDataNotFoundError – If the download fails.
- Return type:
- bolster.data_sources.justice.mortgages.parse_data(file_path)[source]
Parse all mortgage tables from a bulletin ODS file.
- Parameters:
file_path (pathlib.Path) – Path to the ODS bulletin file.
- Returns:
Dictionary with keys
received,disposedandfinal_ordersmapping to tidy long-format DataFrames.final_ordersmay be absent if the file pre-dates 2017.- Return type:
Example
>>> tables = parse_data(download_file(get_latest_publication_url())) >>> sorted(tables) ['disposed', 'final_orders', 'received']
- bolster.data_sources.justice.mortgages.get_latest_data(force_refresh=False)[source]
Download and parse the latest mortgages bulletin.
- Parameters:
force_refresh (bool) – If True, bypass the cache and download fresh data.
- Returns:
Dictionary of tidy DataFrames keyed
received,disposedand (where available)final_orders.- Return type:
Example
>>> data = get_latest_data() >>> "received" in data and "disposed" in data True
- bolster.data_sources.justice.mortgages.get_cases_received(force_refresh=False)[source]
Get quarterly mortgage possession cases received (Table 1).
- Parameters:
force_refresh (bool) – If True, bypass the cache and download fresh data.
- Returns:
year, quarter, period, applications, annual_total, annual_pct_change. One row per (year, quarter) from 2007.
- Return type:
DataFrame with columns
Example
>>> df = get_cases_received() >>> "applications" in df.columns True
- bolster.data_sources.justice.mortgages.get_cases_disposed(force_refresh=False)[source]
Get quarterly mortgage possession cases disposed (Table 2).
- Parameters:
force_refresh (bool) – If True, bypass the cache and download fresh data.
- Returns:
year, quarter, period, applications, annual_total, annual_pct_change. One row per (year, quarter) from 2007.
- Return type:
DataFrame with columns
Example
>>> df = get_cases_disposed() >>> "applications" in df.columns True
- bolster.data_sources.justice.mortgages.get_final_orders(force_refresh=False)[source]
Get mortgage possession final orders by type (Table 3).
Final orders have been published from 2017 onwards. Earlier years are reported annually; from 2025 they are broken down by quarter.
- Parameters:
force_refresh (bool) – If True, bypass the cache and download fresh data.
- Returns:
order_type, year, quarter, period, count.
- Return type:
DataFrame with columns
- Raises:
MortgagesDataNotFoundError – If the bulletin does not include final orders (e.g. very old files).
Example
>>> df = get_final_orders() >>> "order_type" in df.columns True
- bolster.data_sources.justice.mortgages.validate_data(df, value_col='applications', min_records=40)[source]
Validate a parsed quarterly mortgages DataFrame.
Checks structure and sanity of received/disposed tables:
Required columns are present.
There are at least
min_recordsrows (>= 10 years of quarters).Years fall within a plausible range (2007 onwards).
All non-null counts are non-negative.
- Parameters:
df (pandas.DataFrame) – DataFrame to validate (received or disposed).
value_col (str) – Name of the count column to check (default: “applications”).
min_records (int) – Minimum acceptable number of rows.
- Returns:
True if the data passes all checks.
- Raises:
MortgagesValidationError – If any validation check fails.
- Return type:
Example
>>> import pandas as pd >>> validate_data(pd.DataFrame()) Traceback (most recent call last): ... bolster.data_sources.justice.mortgages.MortgagesValidationError: DataFrame is empty