bolster.data_sources.nisra.housing_stock ======================================== .. py:module:: bolster.data_sources.nisra.housing_stock .. autoapi-nested-parse:: Northern Ireland Housing Stock Statistics. Annual housing stock statistics for Northern Ireland, published by Land and Property Services (LPS), a division of the Department of Finance (DoF) NI. Provides dwelling counts by property type (converted apartment, purpose built apartment, detached, semi-detached, terrace) at LGD, Electoral Ward, and Super Output Area level. Note: This data is **not** available in the NISRA PxStat API. It is published directly by DoF/LPS as Excel workbooks. Publisher: Department of Finance NI (DoF) — Land and Property Services (LPS). This data is NOT published by NISRA directly; the source is: https://www.finance-ni.gov.uk/topics/housing-stock-statistics Data files (confirmed 2026 edition): - LGD-level: https://www.finance-ni.gov.uk/sites/default/files/2026-06/Housing%20Stock%20Tables%202008%20-%202026.xlsx - Electoral Ward: https://www.finance-ni.gov.uk/sites/default/files/2026-06/Housing%20Stock%20LGD%20Ward%20Tables%202008%20-%202026.xlsx - Super Output Area (SOA): https://www.finance-ni.gov.uk/sites/default/files/2026-06/SOA%20Housing%20Stock%202008%20-%202026.xlsx Coverage: Annual (April/May reference date), 2008–2026. Geography: 11 Local Government Districts (LGDs) + NI total. .. rubric:: Example >>> from bolster.data_sources.nisra import housing_stock >>> df = housing_stock.get_latest_housing_stock(geo='lgd') >>> 'total' in df.columns True Attributes ---------- .. autoapisummary:: bolster.data_sources.nisra.housing_stock.logger Functions --------- .. autoapisummary:: bolster.data_sources.nisra.housing_stock.get_latest_publication_url bolster.data_sources.nisra.housing_stock.parse_lgd_file bolster.data_sources.nisra.housing_stock.get_latest_housing_stock bolster.data_sources.nisra.housing_stock.validate_housing_stock Module Contents --------------- .. py:data:: logger .. py:function:: get_latest_publication_url(geo = 'lgd') Scrape the DoF NI housing stock page for the latest Excel download URL. Attempts to find the most recent Excel link on the source page. Falls back to the hardcoded 2026 URL if scraping fails or returns no match. :param geo: Geography type — 'lgd' (default), 'ward', or 'soa'. :returns: Absolute URL of the Excel file. .. rubric:: Example >>> url = get_latest_publication_url('lgd') >>> url.endswith('.xlsx') True .. py:function:: parse_lgd_file(file_path) Parse the LGD-level housing stock Excel workbook into a tidy DataFrame. Iterates over every data sheet (``Table 1.1`` … ``Table 1.19``), extracts the reference year from the sheet title, parses the 11-LGD table plus the NI aggregate row, and stacks all years into a single long-format DataFrame. :param file_path: Path to the downloaded Excel file. :returns: year, lgd_code, lgd_name, converted_apartment, purpose_built_apartment, detached, semi_detached, terrace, total. :rtype: Long-format DataFrame with columns .. rubric:: Example >>> import pathlib >>> df = parse_lgd_file("/tmp/housing_stock_lgd.xlsx") >>> 'total' in df.columns True .. py:function:: get_latest_housing_stock(geo = 'lgd', force_refresh = False) Download and return NI housing stock data in long format. :param geo: Geography granularity: - ``'lgd'`` (default): 11 Local Government Districts + NI total. - ``'ward'``: Electoral Ward level. - ``'soa'``: Super Output Area level. :param force_refresh: If ``True``, bypass the local file cache and re-download the source file. :returns: - **year** (int): Reference year (e.g. 2008). - **lgd_code** (str): LGD 2014 code (e.g. ``"N09000001"``). - **lgd_name** (str): LGD name (e.g. ``"Antrim and Newtownabbey"``), or ``"Northern Ireland"`` for the NI-wide total row. - **converted_apartment** (int): Converted apartment dwellings. - **purpose_built_apartment** (int): Purpose-built apartment dwellings. - **detached** (int): Detached dwellings. - **semi_detached** (int): Semi-detached dwellings. - **terrace** (int): Terrace dwellings. - **total** (int): Total housing stock. Ward and SOA files share the same column schema but may have additional geography columns. :rtype: Long-format DataFrame. For ``geo='lgd'`` the columns are :raises ValueError: If ``geo`` is not one of ``'lgd'``, ``'ward'``, ``'soa'``. :raises NISRADataNotFoundError: If the source file cannot be downloaded. .. rubric:: Example >>> df = get_latest_housing_stock(geo='lgd') >>> set(df.columns) >= {'year', 'lgd_code', 'lgd_name', 'total'} True .. py:function:: validate_housing_stock(df) Validate an LGD housing stock DataFrame. Checks that the DataFrame has the expected structure and plausible values. :param df: DataFrame returned by :func:`get_latest_housing_stock`. :returns: ``True`` if all checks pass. :raises NISRAValidationError: If any check fails, with a descriptive message. .. rubric:: Example >>> df = get_latest_housing_stock() >>> validate_housing_stock(df) True