bolster.data_sources.nisra.tourism.occupancy

NISRA Monthly Occupancy Statistics Data Source.

Provides access to monthly hotel and accommodation occupancy data for Northern Ireland.

Data includes:

  • Hotel room and bed occupancy rates from 2011 to present

  • Rooms and beds sold monthly (hotels)

  • Small Service Accommodation (SSA) occupancy from 2013 to present (B&Bs, guest houses, and similar establishments)

  • Rooms and beds sold monthly (SSA)

The survey provides indicative monthly occupancy rates that are revised and finalised in the Annual Publication.

Data Source:

Mother Page: https://www.nisra.gov.uk/statistics/tourism/occupancy-surveys

This page lists all occupancy survey publications. The module automatically scrapes this page to find the latest “Hotel Occupancy” or “Small Service Accommodation” publication, then downloads the Excel file.

Update Frequency: Monthly (published around the 15th of the following month) Geographic Coverage: Northern Ireland Reference Date: Month of survey

Example

>>> from bolster.data_sources.nisra.tourism import occupancy
>>> df = occupancy.get_latest_hotel_occupancy()
>>> 'room_occupancy' in df.columns
True
>>> df_sold = occupancy.get_latest_rooms_beds_sold()
>>> 'rooms_sold' in df_sold.columns
True
>>> df_combined = occupancy.get_combined_occupancy()
>>> 'accommodation_type' in df_combined.columns
True

Attributes

logger

OCCUPANCY_BASE_URL

Functions

get_latest_hotel_occupancy_publication_url()

Scrape NISRA occupancy surveys page to find the latest hotel occupancy file.

get_latest_ssa_occupancy_publication_url()

Scrape NISRA occupancy surveys page to find the latest SSA file.

parse_hotel_occupancy_rates(file_path)

Parse NISRA hotel occupancy rates from Excel file (Table 1).

parse_rooms_beds_sold(file_path)

Parse NISRA hotel rooms and beds sold from Excel file (Table 3).

get_latest_hotel_occupancy([force_refresh])

Get the latest monthly hotel occupancy rates data.

get_latest_rooms_beds_sold([force_refresh])

Get the latest monthly rooms and beds sold data.

parse_ssa_occupancy_rates(file_path)

Parse NISRA SSA occupancy rates from Excel file (Table 1).

parse_ssa_rooms_beds_sold(file_path)

Parse NISRA SSA rooms and beds sold from Excel file (Table 2).

get_latest_ssa_occupancy([force_refresh])

Get the latest monthly SSA occupancy rates data.

get_latest_ssa_rooms_beds_sold([force_refresh])

Get the latest monthly SSA rooms and beds sold data.

get_combined_occupancy([force_refresh])

Get combined hotel and SSA occupancy data with accommodation type column.

compare_accommodation_types(df[, metric])

Compare occupancy between hotel and SSA by year.

get_occupancy_by_year(df, year)

Filter occupancy data for a specific year.

get_occupancy_summary_by_year(df)

Calculate annual occupancy averages and statistics.

get_seasonal_patterns(df)

Calculate average occupancy by month across all years.

validate_occupancy_data(df)

Validate tourism occupancy data integrity.

Module Contents

bolster.data_sources.nisra.tourism.occupancy.logger[source]
bolster.data_sources.nisra.tourism.occupancy.OCCUPANCY_BASE_URL = 'https://www.nisra.gov.uk/statistics/tourism/occupancy-surveys'[source]
bolster.data_sources.nisra.tourism.occupancy.get_latest_hotel_occupancy_publication_url()[source]

Scrape NISRA occupancy surveys page to find the latest hotel occupancy file.

Navigates the publication structure: 1. Scrapes mother page for latest hotel occupancy publication 2. Follows link to publication detail page 3. Finds hotel occupancy Excel file

Returns:

Tuple of (excel_file_url, publication_date)

Raises:

NISRADataNotFoundError – If publication or file not found

Return type:

tuple[str, str]

bolster.data_sources.nisra.tourism.occupancy.get_latest_ssa_occupancy_publication_url()[source]

Scrape NISRA occupancy surveys page to find the latest SSA file.

SSA = Small Service Accommodation (B&Bs, guest houses, etc.)

Navigates the publication structure: 1. Scrapes mother page for latest SSA occupancy publication 2. Follows link to publication detail page 3. Finds SSA occupancy Excel file

Returns:

Tuple of (excel_file_url, publication_date)

Raises:

NISRADataNotFoundError – If publication or file not found

Return type:

tuple[str, str]

bolster.data_sources.nisra.tourism.occupancy.parse_hotel_occupancy_rates(file_path)[source]

Parse NISRA hotel occupancy rates from Excel file (Table 1).

Parameters:

file_path (str | pathlib.Path) – Path to the hotel occupancy Excel file

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • room_occupancy: float (room occupancy rate, 0-1)

  • bed_occupancy: float (bed occupancy rate, 0-1)

Return type:

DataFrame with columns

Raises:

NISRAValidationError – If file structure is unexpected

bolster.data_sources.nisra.tourism.occupancy.parse_rooms_beds_sold(file_path)[source]

Parse NISRA hotel rooms and beds sold from Excel file (Table 3).

Parameters:

file_path (str | pathlib.Path) – Path to the hotel occupancy Excel file

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • rooms_sold: float (number of rooms sold)

  • beds_sold: float (number of beds sold)

Return type:

DataFrame with columns

Raises:

NISRAValidationError – If file structure is unexpected

bolster.data_sources.nisra.tourism.occupancy.get_latest_hotel_occupancy(force_refresh=False)[source]

Get the latest monthly hotel occupancy rates data.

Automatically discovers and downloads the most recent hotel occupancy data from the NISRA website.

Parameters:

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

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • room_occupancy: float (room occupancy rate, 0-1)

  • bed_occupancy: float (bed occupancy rate, 0-1)

Return type:

DataFrame with columns

Raises:
  • NISRADataNotFoundError – If latest publication cannot be found

  • NISRAValidationError – If file structure is unexpected

Example

>>> df = get_latest_hotel_occupancy()
>>> 'room_occupancy' in df.columns
True
bolster.data_sources.nisra.tourism.occupancy.get_latest_rooms_beds_sold(force_refresh=False)[source]

Get the latest monthly rooms and beds sold data.

Parameters:

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

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • rooms_sold: float (number of rooms sold)

  • beds_sold: float (number of beds sold)

Return type:

DataFrame with columns

Example

>>> df = get_latest_rooms_beds_sold()
>>> 'rooms_sold' in df.columns
True
bolster.data_sources.nisra.tourism.occupancy.parse_ssa_occupancy_rates(file_path)[source]

Parse NISRA SSA occupancy rates from Excel file (Table 1).

SSA = Small Service Accommodation (B&Bs, guest houses, etc.)

Parameters:

file_path (str | pathlib.Path) – Path to the SSA occupancy Excel file

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • room_occupancy: float (room occupancy rate, 0-1)

  • bed_occupancy: float (bed occupancy rate, 0-1)

Return type:

DataFrame with columns

Raises:

NISRAValidationError – If file structure is unexpected

bolster.data_sources.nisra.tourism.occupancy.parse_ssa_rooms_beds_sold(file_path)[source]

Parse NISRA SSA rooms and beds sold from Excel file (Table 2).

Note: SSA uses Table 2 for rooms/beds sold, while Hotel uses Table 3.

Parameters:

file_path (str | pathlib.Path) – Path to the SSA occupancy Excel file

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • rooms_sold: float (number of rooms sold)

  • beds_sold: float (number of beds sold)

Return type:

DataFrame with columns

Raises:

NISRAValidationError – If file structure is unexpected

bolster.data_sources.nisra.tourism.occupancy.get_latest_ssa_occupancy(force_refresh=False)[source]

Get the latest monthly SSA occupancy rates data.

SSA = Small Service Accommodation (B&Bs, guest houses, etc.)

Automatically discovers and downloads the most recent SSA occupancy data from the NISRA website.

Parameters:

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

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • room_occupancy: float (room occupancy rate, 0-1)

  • bed_occupancy: float (bed occupancy rate, 0-1)

Return type:

DataFrame with columns

Raises:
  • NISRADataNotFoundError – If latest publication cannot be found

  • NISRAValidationError – If file structure is unexpected

Example

>>> df = get_latest_ssa_occupancy()
>>> 'room_occupancy' in df.columns
True
bolster.data_sources.nisra.tourism.occupancy.get_latest_ssa_rooms_beds_sold(force_refresh=False)[source]

Get the latest monthly SSA rooms and beds sold data.

SSA = Small Service Accommodation (B&Bs, guest houses, etc.)

Parameters:

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

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • rooms_sold: float (number of rooms sold)

  • beds_sold: float (number of beds sold)

Return type:

DataFrame with columns

Example

>>> df = get_latest_ssa_rooms_beds_sold()
>>> 'rooms_sold' in df.columns
True
bolster.data_sources.nisra.tourism.occupancy.get_combined_occupancy(force_refresh=False)[source]

Get combined hotel and SSA occupancy data with accommodation type column.

This function fetches both hotel and SSA occupancy data and combines them into a single DataFrame with an ‘accommodation_type’ column to distinguish between the two accommodation types.

Parameters:

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

Returns:

  • date: datetime (first day of month)

  • year: int

  • month: str (month name)

  • room_occupancy: float (room occupancy rate, 0-1)

  • bed_occupancy: float (bed occupancy rate, 0-1)

  • accommodation_type: str (‘hotel’ or ‘ssa’)

Return type:

DataFrame with columns

Example

>>> df = get_combined_occupancy()
>>> 'accommodation_type' in df.columns
True
bolster.data_sources.nisra.tourism.occupancy.compare_accommodation_types(df, metric='room_occupancy')[source]

Compare occupancy between hotel and SSA by year.

Parameters:
  • df (pandas.DataFrame) – DataFrame from get_combined_occupancy()

  • metric (Literal['room_occupancy', 'bed_occupancy']) – Which occupancy metric to compare

Returns:

  • year: int

  • hotel_{metric}: float

  • ssa_{metric}: float

  • difference: float (hotel - ssa)

  • ratio: float (hotel / ssa)

Return type:

DataFrame with columns

Example

>>> df = get_combined_occupancy()
>>> comparison = compare_accommodation_types(df)
>>> 'difference' in comparison.columns
True
bolster.data_sources.nisra.tourism.occupancy.get_occupancy_by_year(df, year)[source]

Filter occupancy data for a specific year.

Parameters:
  • df (pandas.DataFrame) – DataFrame from get_latest_hotel_occupancy()

  • year (int) – Year to filter

Returns:

Filtered DataFrame

Return type:

pandas.DataFrame

bolster.data_sources.nisra.tourism.occupancy.get_occupancy_summary_by_year(df)[source]

Calculate annual occupancy averages and statistics.

Parameters:

df (pandas.DataFrame) – DataFrame from get_latest_hotel_occupancy()

Returns:

  • year: int

  • avg_room_occupancy: float

  • avg_bed_occupancy: float

  • months_reported: int

Return type:

DataFrame with columns

bolster.data_sources.nisra.tourism.occupancy.get_seasonal_patterns(df)[source]

Calculate average occupancy by month across all years.

Parameters:

df (pandas.DataFrame) – DataFrame from get_latest_hotel_occupancy()

Returns:

  • month: str (month name)

  • avg_room_occupancy: float

  • avg_bed_occupancy: float

Return type:

DataFrame with columns

Example

>>> df = get_latest_hotel_occupancy()
>>> seasonal = get_seasonal_patterns(df)
>>> 'avg_room_occupancy' in seasonal.columns
True
bolster.data_sources.nisra.tourism.occupancy.validate_occupancy_data(df)[source]

Validate tourism occupancy data integrity.

Parameters:

df (pandas.DataFrame) – DataFrame from get_latest_occupancy_data

Returns:

True if validation passes, False otherwise

Return type:

bool