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

logger

PUBLICATION_URL

BASE_URL

SHEET_RECEIVED

SHEET_DISPOSED

SHEET_FINAL_ORDERS

QUARTERS

Exceptions

MortgagesDataError

Base exception for NICTS mortgages data errors.

MortgagesDataNotFoundError

Raised when the data file cannot be located or downloaded.

MortgagesValidationError

Raised when downloaded data fails validation.

Functions

get_latest_publication_url([base_url])

Find the URL of the most recent mortgages bulletin ODS file.

download_file(url[, cache_ttl_hours, force_refresh])

Download a bulletin ODS file with caching.

parse_data(file_path)

Parse all mortgage tables from a bulletin ODS file.

get_latest_data([force_refresh])

Download and parse the latest mortgages bulletin.

get_cases_received([force_refresh])

Get quarterly mortgage possession cases received (Table 1).

get_cases_disposed([force_refresh])

Get quarterly mortgage possession cases disposed (Table 2).

get_final_orders([force_refresh])

Get mortgage possession final orders by type (Table 3).

validate_data(df[, value_col, min_records])

Validate a parsed quarterly mortgages DataFrame.

clear_cache()

Clear all cached mortgages bulletin files.

Module Contents

bolster.data_sources.justice.mortgages.logger[source]
bolster.data_sources.justice.mortgages.PUBLICATION_URL = 'https://www.justice-ni.gov.uk/publications/nicts-mortgages-action-possession'[source]
bolster.data_sources.justice.mortgages.BASE_URL = 'https://www.justice-ni.gov.uk'[source]
bolster.data_sources.justice.mortgages.SHEET_RECEIVED = 'Mortgages_received'[source]
bolster.data_sources.justice.mortgages.SHEET_DISPOSED = 'Mortgages_disposed'[source]
bolster.data_sources.justice.mortgages.SHEET_FINAL_ORDERS = 'Mortgages_final_orders'[source]
bolster.data_sources.justice.mortgages.QUARTERS = ['Q1', 'Q2', 'Q3', 'Q4'][source]
exception bolster.data_sources.justice.mortgages.MortgagesDataError[source]

Bases: Exception

Base exception for NICTS mortgages data errors.

Initialize self. See help(type(self)) for accurate signature.

exception bolster.data_sources.justice.mortgages.MortgagesDataNotFoundError[source]

Bases: MortgagesDataError

Raised 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: MortgagesDataError

Raised 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 .ods files 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:

str

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:
  • url (str) – URL of the ODS file to download.

  • cache_ttl_hours (int) – Cache validity in hours (default: 7 days, since data is published quarterly).

  • force_refresh (bool) – If True, bypass the cache and re-download.

Returns:

Path to the downloaded (or cached) file.

Raises:

MortgagesDataNotFoundError – If the download fails.

Return type:

pathlib.Path

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, disposed and final_orders mapping to tidy long-format DataFrames. final_orders may be absent if the file pre-dates 2017.

Return type:

dict[str, pandas.DataFrame]

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, disposed and (where available) final_orders.

Return type:

dict[str, pandas.DataFrame]

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_records rows (>= 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:

bool

Example

>>> import pandas as pd
>>> validate_data(pd.DataFrame())
Traceback (most recent call last):
...
bolster.data_sources.justice.mortgages.MortgagesValidationError: DataFrame is empty
bolster.data_sources.justice.mortgages.clear_cache()[source]

Clear all cached mortgages bulletin files.

Returns:

Number of files deleted.

Return type:

int