bolster.data_sources.justice.nicts_quarterly

NICTS Quarterly Provisional Figures.

Provides access to the Northern Ireland Courts and Tribunals Service (NICTS) quarterly business statistics, covering caseload across every tier of the NI court system: receipts, disposals, waiting times, and judicial sitting days.

Ten court datasets are published in a single ODS workbook, one worksheet each:

  • court_of_appeal_criminal - criminal appeals by type and result.

  • court_of_appeal_civil - civil appeals received and disposed.

  • high_court_chancery_division - Chancery business (incl. mortgages).

  • high_court_kings_bench_division - King’s Bench writs and outcomes.

  • high_court_family_division - divorce, ancillary relief, and wardship.

  • crown_court - Crown Court cases and defendants.

  • county_court - County Court civil, family, and appeal business.

  • magistrates_courts - Magistrates’ Court criminal and civil business.

  • children_order - public and private law Children Order proceedings.

  • judge_court_sitting_days - sitting days and average sitting times.

Every worksheet shares the same period columns, so all ten concatenate into a single tidy frame. Each row is one (court, category, subcategory, detail, period) observation.

Data Source:

Publication Page: https://www.justice-ni.gov.uk/publications/nicts-business-data

The module scrapes this page for quarterly ODS bulletins (nicts-quarterly-provisional-figures-<months>-<year>.ods) and selects the most recent. Each bulletin carries the full series from 2017, so a single download gives complete history.

Update Frequency: Quarterly Geographic Coverage: Northern Ireland Reference Period: 2017 - present (annual totals to 2024, quarterly thereafter)

Note

These are provisional figures and are revised in later bulletins. The frame mixes annual totals (2024 Total) and quarters (2025 Q1) in the same period column — filter on quarter.isna() to separate them, or summing across periods will double-count.

Example

>>> from bolster.data_sources.justice import nicts_quarterly
>>> df = nicts_quarterly.get_crown_court()
>>> set(df["court"]) == {"crown_court"}
True
>>> "value" in df.columns
True

Attributes

logger

PUBLICATION_URL

Exceptions

NICTSDataError

Base exception for NICTS quarterly figures errors.

NICTSDataNotFoundError

Raised when the bulletin cannot be located or downloaded.

NICTSValidationError

Raised when parsed data fails validation.

Functions

list_publications([base_url])

List every quarterly bulletin linked from the publication page.

find_latest_publication([base_url])

Find the most recent quarterly bulletin.

download_file(url[, cache_ttl_hours, force_refresh])

Download a bulletin ODS file with caching.

parse_data(file_path)

Parse every court worksheet from a bulletin into one tidy frame.

get_latest_data([court, force_refresh])

Download and parse the latest quarterly bulletin.

list_courts([force_refresh])

List the court keys available in the latest bulletin.

get_crown_court([force_refresh])

Get Crown Court business (Table 6).

get_magistrates_courts([force_refresh])

Get Magistrates' Courts business (Table 8).

get_county_court([force_refresh])

Get County Court business (Table 7).

get_sitting_days([force_refresh])

Get judicial sitting days and average sitting times (Table 10).

validate_data(df[, min_records])

Validate a parsed NICTS quarterly DataFrame.

clear_cache()

Clear all cached NICTS bulletin files.

Module Contents

bolster.data_sources.justice.nicts_quarterly.logger[source]
bolster.data_sources.justice.nicts_quarterly.PUBLICATION_URL = 'https://www.justice-ni.gov.uk/publications/nicts-business-data'[source]
exception bolster.data_sources.justice.nicts_quarterly.NICTSDataError[source]

Bases: Exception

Base exception for NICTS quarterly figures errors.

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

exception bolster.data_sources.justice.nicts_quarterly.NICTSDataNotFoundError[source]

Bases: NICTSDataError

Raised when the bulletin cannot be located or downloaded.

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

exception bolster.data_sources.justice.nicts_quarterly.NICTSValidationError[source]

Bases: NICTSDataError

Raised when parsed data fails validation.

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

bolster.data_sources.justice.nicts_quarterly.list_publications(base_url=PUBLICATION_URL)[source]

List every quarterly bulletin linked from the publication page.

Parameters:

base_url (str) – URL of the NICTS business data listing page.

Returns:

List of dicts with url, year and quarter, newest first.

Raises:

NICTSDataNotFoundError – If the page cannot be fetched or no bulletins are found.

Return type:

list[dict]

Example

>>> pubs = list_publications()
>>> pubs[0]["url"].endswith(".ods")
True
>>> pubs[0]["year"] >= pubs[-1]["year"]
True
bolster.data_sources.justice.nicts_quarterly.find_latest_publication(base_url=PUBLICATION_URL)[source]

Find the most recent quarterly bulletin.

Parameters:

base_url (str) – URL of the NICTS business data listing page.

Returns:

Dict with url, year and quarter for the newest bulletin.

Raises:

NICTSDataNotFoundError – If no bulletin can be located.

Return type:

dict

Example

>>> latest = find_latest_publication()
>>> 1 <= latest["quarter"] <= 4
True
bolster.data_sources.justice.nicts_quarterly.download_file(url, cache_ttl_hours=_CACHE_TTL_HOURS, force_refresh=False)[source]

Download a bulletin ODS file with caching.

Parameters:
  • url (str) – URL of the ODS file.

  • cache_ttl_hours (int) – Cache validity in hours (default: 90 days).

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

Returns:

Path to the downloaded (or cached) file.

Raises:

NICTSDataNotFoundError – If the download fails.

Return type:

pathlib.Path

bolster.data_sources.justice.nicts_quarterly.parse_data(file_path)[source]

Parse every court worksheet from a bulletin into one tidy frame.

Parameters:

file_path (pathlib.Path) – Path to the ODS bulletin file.

Returns:

DataFrame with columns court, category, subcategory, detail, period, year, quarter, value — all ten courts concatenated.

Raises:

NICTSDataError – If the workbook contains no parseable court data.

Return type:

pandas.DataFrame

bolster.data_sources.justice.nicts_quarterly.get_latest_data(court='all', force_refresh=False)[source]

Download and parse the latest quarterly bulletin.

Parameters:
  • court (str) – Court key to return (see list_courts()), or "all" for every court in one frame.

  • force_refresh (bool) – If True, bypass the cache and download fresh data.

Returns:

Tidy DataFrame with columns court, category, subcategory, detail, period, year, quarter, value.

Raises:

NICTSDataNotFoundError – If court is not a known court key.

Return type:

pandas.DataFrame

Example

>>> df = get_latest_data("county_court")
>>> set(df["court"]) == {"county_court"}
True
bolster.data_sources.justice.nicts_quarterly.list_courts(force_refresh=False)[source]

List the court keys available in the latest bulletin.

Parameters:

force_refresh (bool) – If True, bypass the cache and download fresh data.

Returns:

Sorted list of court keys.

Return type:

list[str]

Example

>>> "crown_court" in list_courts()
True
bolster.data_sources.justice.nicts_quarterly.get_crown_court(force_refresh=False)[source]

Get Crown Court business (Table 6).

Parameters:

force_refresh (bool) – If True, bypass the cache and download fresh data.

Returns:

Tidy DataFrame of Crown Court receipts, disposals, and waiting times at both case and defendant level.

Return type:

pandas.DataFrame

Example

>>> df = get_crown_court()
>>> "Received" in set(df["subcategory"])
True
bolster.data_sources.justice.nicts_quarterly.get_magistrates_courts(force_refresh=False)[source]

Get Magistrates’ Courts business (Table 8).

Parameters:

force_refresh (bool) – If True, bypass the cache and download fresh data.

Returns:

Tidy DataFrame of Magistrates’ Court criminal and civil business.

Return type:

pandas.DataFrame

Example

>>> df = get_magistrates_courts()
>>> set(df["court"]) == {"magistrates_courts"}
True
bolster.data_sources.justice.nicts_quarterly.get_county_court(force_refresh=False)[source]

Get County Court business (Table 7).

Parameters:

force_refresh (bool) – If True, bypass the cache and download fresh data.

Returns:

Tidy DataFrame of County Court civil, family, and appeal business.

Return type:

pandas.DataFrame

Example

>>> df = get_county_court()
>>> set(df["court"]) == {"county_court"}
True
bolster.data_sources.justice.nicts_quarterly.get_sitting_days(force_refresh=False)[source]

Get judicial sitting days and average sitting times (Table 10).

Sitting times are reported as durations and are returned in fractional hours, so a published 6485:30 becomes 6485.5.

Parameters:

force_refresh (bool) – If True, bypass the cache and download fresh data.

Returns:

Tidy DataFrame of sitting days and times by judge level and court type.

Return type:

pandas.DataFrame

Example

>>> df = get_sitting_days()
>>> "Total Sitting Days" in set(df["category"])
True
bolster.data_sources.justice.nicts_quarterly.validate_data(df, min_records=1000)[source]

Validate a parsed NICTS quarterly DataFrame.

Checks structure and sanity:

  • Required columns are present.

  • There are at least min_records rows.

  • Years fall within a plausible range (2017 onwards).

  • Quarters, where present, are 1-4.

  • All non-null values are non-negative.

Parameters:
  • df (pandas.DataFrame) – DataFrame to validate.

  • min_records (int) – Minimum acceptable number of rows.

Returns:

True if the data passes all checks.

Raises:

NICTSValidationError – 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.nicts_quarterly.NICTSValidationError: DataFrame is empty
bolster.data_sources.justice.nicts_quarterly.clear_cache()[source]

Clear all cached NICTS bulletin files.

Returns:

Number of files deleted.

Return type:

int