synpop_tools
Databricks synpop generation utilities.
This module provides utility functions for the synpop generation process.
Requires: - databricks-sdk - time
Author: Gino F. Fazzi gino.franco.fazzi@audienceproject.com Facundo Fernández facundo.fernandez@audienceproject.com
synpop_tools.synpop_retrieve_available_countries(format='country', stage=None)
Retrieve the countries and versions available for synpop generation.
Reads available_countries.json and, when stage is given, narrows the
result to the country-version pairs recorded in the approvals table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
format
|
str
|
Shape of the returned value. One of |
'country'
|
stage
|
str | None
|
Optional approvals-table filter. |
None
|
Returns:
| Type | Description |
|---|---|
list of str or dict
|
For |
Raises:
| Type | Description |
|---|---|
Exception
|
If |
Examples:
>>> synpop_retrieve_available_countries(format="country,version", stage="active")
['DE|v1', 'DK|v2']
synpop_tools.synpop_get_widget_countries()
Return the curated country-version list formatted for a Databricks widget.
Returns:
| Type | Description |
|---|---|
list of str
|
Sorted |
synpop_tools.safe_download_tercet_files(file_url, output_path)
Download and validate a GISCO TERCET ZIP archive with cURL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_url
|
Path relative to the GISCO |
required | |
output_path
|
Local directory in which to recreate |
required |
Returns:
| Type | Description |
|---|---|
|
None. An existing file with a ZIP signature is reused. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If cURL fails, GISCO returns HTML, or the downloaded file does not have a ZIP signature. |
Notes
The cURL request emulates a browser, follows redirects, retries transient failures five times, and has a five-minute maximum duration.
synpop_tools.EurostatAPI
Eurostat API wrapper for retrieving European statistical datasets.
This class provides methods to interact with the Eurostat API, retrieve datasets, format them into tables, and execute the synpop extract process.
Attributes:
| Name | Type | Description |
|---|---|---|
BASE_URL |
str
|
Base URL for the Eurostat API endpoint. |
ENDPOINTS |
dict
|
Mapping of table names to Eurostat dataset identifiers. |
country_code |
list
|
List of supported European country names. |
Example
eurostat = EurostatAPI() df = eurostat.get_table("pjanedu")
synpop_tools.EurostatAPI.__init__()
Initialize the EurostatAPI with default configuration.
Sets up the base URL, endpoint mappings, and supported country codes.
synpop_tools.EurostatAPI.get_table(table, dtype='Pandas', labels=True, return_update_date=False, params=None)
Retrieve a Eurostat table and optionally return its update date.
Fetches data from the Eurostat API for the specified table, converts it to a DataFrame, and optionally returns the dataset's update timestamp.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
str
|
The table name key (e.g., 'pjanedu', 'edat', 'd2jan', 'isoc', 'pjangrp3'). |
required |
dtype
|
str
|
The output DataFrame type. Must be 'Pandas' or 'PySpark'. Defaults to 'Pandas'. |
'Pandas'
|
labels
|
bool
|
Whether to use human-readable labels for dimension values. Defaults to True. |
True
|
return_update_date
|
bool
|
If True, returns a tuple of (update_date, DataFrame). Defaults to False. |
False
|
params
|
dict
|
Additional query parameters to pass to the Eurostat API. Defaults to None. |
None
|
Returns:
| Type | Description |
|---|---|
|
DataFrame or tuple: If return_update_date is False, returns a DataFrame of the requested table. If True, returns a tuple of (update_date: str, df: DataFrame). |
Raises:
| Type | Description |
|---|---|
Exception
|
If an invalid dtype is provided. |
Example
eurostat = EurostatAPI() df = eurostat.get_table("pjanedu", dtype="Pandas") update_date, df = eurostat.get_table("edat", return_update_date=True)
synpop_tools.EurostatAPI.get_endpoint_data(table, params)
Fetch raw JSON data from a Eurostat API endpoint.
Makes a GET request to the Eurostat API and returns the raw JSON response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
str
|
The table name key (e.g., 'pjanedu', 'edat', 'd2jan', 'isoc', 'pjangrp3'). |
required |
params
|
dict
|
Query parameters to pass to the API. Defaults to an empty dict. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dict |
The JSON response from the Eurostat API containing the dataset structure with dimensions, sizes, and values. |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If the API request fails. |
Example
data = eurostat.get_endpoint_data("pjanedu", {"sex": "F"})
synpop_tools.EurostatAPI.format_JSON_stat_data_to_table(dataset, use_labels=True)
Convert Eurostat JSON-stat format to a Pandas DataFrame.
Takes a JSON-stat dataset object (which has a nested structure with dimensions, sizes, and values) and converts it to a flat, friendly Pandas DataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset
|
dict
|
The JSON-stat dataset object from the Eurostat API. |
required |
use_labels
|
bool
|
Whether to use human-readable labels for dimension values. If False, uses the raw dimension keys. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
|
pd.DataFrame: A DataFrame with columns for each dimension plus a 'value' column containing the data values. |
Note
- Handles both dense (list) and sparse (dict) value representations
- Creates a MultiIndex from dimension combinations, then flattens it
- Dimension order is preserved from the original dataset
Example
data = eurostat.get_endpoint_data("pjanedu") df = eurostat.format_JSON_stat_data_to_table(data)
synpop_tools.EurostatAPI.execute_synpop_extract(s3_base_path, logger=None)
Execute the Eurostat synpop data extract and upload to S3.
Retrieves the latest Eurostat data for all configured tables, checks for updates against the stored metadata, and uploads new data to S3 if available.
This method: 1. Reads the current metadata from S3 to determine last update dates 2. Iterates through all Eurostat tables (pjanedu, edat, d2jan, isoc, pjangrp3) 3. Checks if new data is available (by comparing update dates) 4. Applies table-specific transformations and filters 5. Writes new data to S3 and updates the metadata file
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s3_base_path
|
str
|
The base S3 path where Eurostat data should be stored (e.g., 's3://ap-synthetic-population/dev/raw_data/eurostat'). |
required |
logger
|
Logger
|
A logger instance for tracking progress and reporting status. If not provided, logging is disabled. Defaults to None. |
None
|
Raises:
| Type | Description |
|---|---|
Exception
|
If metadata cannot be read or if data retrieval fails. |
Note
- Only tables with data newer than the stored metadata are updated
- Each table has specific filters applied (e.g., removing 'TOTAL' age)
- Metadata is updated in S3 after all processing completes
Example
eurostat = EurostatAPI() eurostat.execute_synpop_extract( ... s3_base_path="s3://bucket/eurostat", ... logger=my_logger ... )
synpop_tools.EurostatAPI.__archive_datapoint(table_name, update_date, s3_base_path)
Copy a Eurostat extract into its dated S3 archive location.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table_name
|
Eurostat table name used by the source CSV. |
required | |
update_date
|
Datetime used to construct the archive filename. |
required | |
s3_base_path
|
Root S3 path containing the |
required |
Returns:
| Type | Description |
|---|---|
|
None. |
Notes
This method uses dbutils.fs.cp and therefore requires a
Databricks runtime with access to the source and archive paths.
synpop_tools.NonEurostatHandler
Base handler for non-Eurostat census data sources.
This class provides a generic interface for handling census data from sources other than Eurostat. It manages file downloads, extraction, and S3 uploads for various country-specific data sources.
Attributes:
| Name | Type | Description |
|---|---|---|
root_path |
str
|
The root directory for data storage. |
data_path |
str
|
The path to the data subdirectory. |
country_code |
str
|
The ISO country code for the data source. |
datapoints |
dict
|
Dictionary mapping datapoint names to their metadata (URL, download pattern, release dates, etc.). |
Note
This is an abstract base class. Specific country implementations should inherit from it and define their own datapoints.
synpop_tools.NonEurostatHandler.__init__(root_path='/Workspace/dame/Synthetic Population')
Initialize the NonEurostatHandler with a root data path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root_path
|
str
|
The root directory for data storage. Defaults to the DAME Synthetic Population Generation path. |
'/Workspace/dame/Synthetic Population'
|
synpop_tools.NonEurostatHandler.set_root_path(path)
Set the root path for data storage and create data directory if needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
The root directory path for data storage. |
required |
synpop_tools.NonEurostatHandler.get_available_datapoints()
Get a list of available datapoint names for this data source.
Returns:
| Name | Type | Description |
|---|---|---|
list |
List of datapoint names that are configured for this source. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If a datapoint name doesn't match its sanitized form. |
synpop_tools.NonEurostatHandler.download_file_from_url(download_url, filename, verbose=False)
Download a file from a URL to the local data path.
Downloads a file from the specified URL and saves it to the data directory with the given filename. Uses streaming to handle large files efficiently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
download_url
|
str
|
The URL to download the file from. |
required |
filename
|
str
|
The name to save the file as (in data_path). |
required |
verbose
|
bool
|
If True, prints confirmation message. Defaults to False. |
False
|
Raises:
| Type | Description |
|---|---|
HTTPError
|
If the download request fails. |
Example
handler.download_file_from_url( ... "https://example.com/data.csv", ... "country-data.csv", ... verbose=True ... )
synpop_tools.NonEurostatHandler.upload_datapoint_to_s3(datapoint, s3_base_path)
Upload a downloaded datapoint to S3 storage.
Moves the local datapoint file from the data directory to the specified S3 path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
The name of the datapoint to upload. |
required |
s3_base_path
|
str
|
The base S3 path where data should be stored. |
required |
Note
Uses dbutils.fs.mv to move the file, which copies it to S3 and removes the local copy.
Example
handler.upload_datapoint_to_s3( ... "population_data.csv", ... "s3://bucket/census/AU" ... )
synpop_tools.NonEurostatHandler.unzip_datapoint(datapoint, filename=None, only_open=False, delete_original=True)
Extract or open a downloaded zip file.
Helper method to unzip a downloaded zip file. If filename is not provided, all files are extracted to the folder. Otherwise, only the specified filename is retained in the root folder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
The name of the datapoint (without .zip extension). |
required |
filename
|
str or int
|
The specific file to extract. If an integer is provided, extracts the file at that index in the zip archive. If None, extracts all files. Defaults to None. |
None
|
only_open
|
bool
|
If True, opens the file in memory without extracting to disk. Defaults to False. |
False
|
delete_original
|
bool
|
If True, deletes the original zip file after extraction. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
|
file or None: If only_open is True, returns the opened file object. Otherwise, returns None. |
Raises:
| Type | Description |
|---|---|
AssertionError
|
If the datapoint is not a zip file type. |
Example
Extract all files
handler.unzip_datapoint("population_data")
Extract specific file by name
handler.unzip_datapoint("population_data", filename="data.csv")
Extract file by index
handler.unzip_datapoint("population_data", filename=0)
synpop_tools.NonEurostatHandler.execute_synpop_extract(s3_base_path, logger=None)
Execute the synpop extract process for non-Eurostat data sources.
Retrieves the latest census data for all configured datapoints, checks for updates against the stored metadata, and uploads new data to S3 if available.
This method: 1. Reads the current metadata from S3 to determine last update dates 2. Iterates through all configured datapoints 3. Checks if new data is available (by comparing release dates) 4. Downloads, extracts, and uploads new data to S3 5. Updates the metadata file
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s3_base_path
|
str
|
The base S3 path where census data should be stored (e.g., 's3://ap-synthetic-population/raw_data/census'). |
required |
logger
|
Logger
|
A logger instance for tracking progress and reporting status. If not provided, logging is disabled. Defaults to None. |
None
|
Raises:
| Type | Description |
|---|---|
Exception
|
If metadata cannot be read or if data retrieval fails. |
Note
- Only datapoints with release dates newer than stored metadata are updated
- Sends Slack notifications on errors via send_slack_notification
- Creates reminders for manual downloads if needed via notify_manual_download
synpop_tools.NonEurostatHandler.notify_manual_download(datapoint, url)
Create a Slack reminder asking an operator to download a datapoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Key into :attr: |
required | |
url
|
Source URL included in the reminder for the operator to open. |
required |
Notes
Delegates to :class:jobs_tools.ReminderScheduler, so the reminder is
persisted in Delta and delivered at-least-once rather than sent inline.
synpop_tools.NonEurostatHandler.__archive_datapoint(datapoint, update_date, s3_base_path)
Copy the current version of a datapoint into a timestamped archive folder.
Keeping the previous version lets an operator revert a bad refresh.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Datapoint folder name below the country prefix. |
required | |
update_date
|
Date used to build the archive folder name, formatted |
required | |
s3_base_path
|
Base S3 prefix containing the per-country datapoint folders. |
required |
Notes
Copies rather than moves, so the live datapoint remains in place for the caller to overwrite.
synpop_tools.GeneralDataSource
Bases: NonEurostatHandler
Retrieve global reference datasets that are not country-specific.
Attributes:
| Name | Type | Description |
|---|---|---|
country_code |
str
|
Metadata key for global datasets, set to
|
datapoints |
dict
|
Dictionary mapping datapoint names to their source URLs, file types, and source release dates. |
The UN source files are retained in their compressed CSV format. The ITU archive is reduced to its data CSV and saved as Parquet.
synpop_tools.GeneralDataSource.__init__(root_path='/Workspace/dame/Synthetic Population')
Initialize the global reference-source configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root_path
|
Local directory used for staging downloaded files. |
'/Workspace/dame/Synthetic Population'
|
synpop_tools.GeneralDataSource.get_datapoint_release_date(datapoint)
Return a source file's last-modified timestamp.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
Configured datapoint name. |
required |
Returns:
| Type | Description |
|---|---|
datetime
|
Timezone-aware source timestamp from the HTTP |
datetime
|
header. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the source does not provide a last-modified timestamp. |
HTTPError
|
If the source cannot be reached successfully. |
synpop_tools.GeneralDataSource.retrieve_datapoint(datapoint, verbose=False)
Download one configured global source file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
Configured datapoint name. |
required |
verbose
|
bool
|
Whether to report the local staging path. |
False
|
The ITU archive contains metadata CSVs in addition to the indicator data. Its configured data CSV is read and written as Parquet; the source archive is then removed. Other source files are retained in their original format.
Returns:
| Type | Description |
|---|---|
bool
|
True after a successful download and optional transformation. |
synpop_tools.GeneralDataSource.process_zip_datapoint(datapoint)
Extract a configured ZIP CSV and write it as a Parquet file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
Configured ZIP datapoint whose metadata specifies an
|
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the archive does not contain exactly one matching data CSV. |
Notes
The source ZIP is removed only after its selected CSV has been successfully converted to Parquet.
synpop_tools.AUDataSource
Bases: NonEurostatHandler
Australian Bureau of Statistics (ABS) data source handler.
This class handles data retrieval from the Australian Bureau of Statistics website. It inherits from NonEurostatHandler and provides country-specific configuration for Australian census and survey data.
Attributes:
| Name | Type | Description |
|---|---|---|
country_code |
str
|
The ISO country code, set to "AU". |
datapoints |
dict
|
Dictionary mapping datapoint names to their metadata including URLs and download patterns. |
Example
au_data = AUDataSource() au_data.execute_synpop_extract("s3://bucket/census")
synpop_tools.AUDataSource.__init__()
Initialize the AUDataSource with ABS data configuration.
Sets up the Australian data source with predefined datapoints for population, education, and internet usage data from ABS.
synpop_tools.AUDataSource.retrieve_datapoint(datapoint, verbose=False)
Retrieve a specific datapoint from the ABS website.
Downloads the data file for the specified datapoint from the ABS website and saves it locally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Name of the datapoint to retrieve; must be a key of
:attr: |
required | |
verbose
|
Print progress messages while resolving the table URL. |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
Always |
synpop_tools.AUDataSource.__get_html(url)
Fetch HTML content from a URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
The URL to fetch content from. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
The HTML content as text. |
synpop_tools.AUDataSource.__get_soup(html)
Parse HTML content into a BeautifulSoup object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
html
|
str
|
The HTML content to parse. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
BeautifulSoup |
The parsed HTML object. |
synpop_tools.AUDataSource.get_datapoint_reference_period(datapoint, verbose=False)
Extract the reference period (year) for a datapoint from the ABS website.
Parses the ABS webpage to find the current reference period/year for the specified datapoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
The name of the datapoint to look up. |
required |
verbose
|
bool
|
If True, prints the release year. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
The reference period year (e.g., "2023"). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the reference period block cannot be found. |
synpop_tools.AUDataSource.get_table_url(datapoint, verbose=False)
Get the download URL for a specific datapoint.
Constructs the download URL by finding the appropriate download link on the ABS webpage based on the current reference period.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
The name of the datapoint to get URL for. |
required |
verbose
|
bool
|
If True, prints the download URL. Defaults to False. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
The full URL to download the datapoint file. |
synpop_tools.AUDataSource.get_datapoint_release_and_next_release_dates(datapoint, verbose=False)
Extract release and next release dates for a datapoint from the ABS website.
Parses the ABS webpage to find the release date and next scheduled release date for the specified datapoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
str
|
The name of the datapoint to look up. |
required |
verbose (bool, optional): If True, prints the dates found. Defaults to False.
Returns:
| Name | Type | Description |
|---|---|---|
tuple |
A tuple of (released_date: str or None, next_release_date: str or None). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the release date section cannot be found. |
synpop_tools.CADataSource
Bases: NonEurostatHandler
Statistics Canada data source handler.
This class handles data retrieval from the Statistics Canada website (StatCan). It inherits from NonEurostatHandler and provides country-specific configuration for Canadian census data.
Attributes:
| Name | Type | Description |
|---|---|---|
country_code |
str
|
The ISO country code, set to "CA". |
datapoints |
dict
|
Dictionary mapping datapoint names to their metadata including product IDs (pid) and data types. |
Example
ca_data = CADataSource() ca_data.execute_synpop_extract("s3://bucket/census")
synpop_tools.CADataSource.__init__()
Initialize the CADataSource with Statistics Canada data configuration.
Sets up the Canadian data source with predefined datapoints for labour force, income, age, and internet usage data from StatCan.
synpop_tools.CADataSource.retrieve_datapoint(datapoint)
Retrieve a specific datapoint from Statistics Canada.
Downloads the data file for the specified datapoint from StatCan, extracts it if needed, and saves it locally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Name of the datapoint to retrieve; must be a key of
:attr: |
required |
Returns:
| Type | Description |
|---|---|
bool
|
Always |
Notes
ZIP datapoints are read into pandas to convert them to Parquet, so this
runs on the driver. The labour-force table is reduced by
:meth:reduce_df_labour first because the raw file is roughly 5 GB.
synpop_tools.CADataSource.__get_pid_table_csv_link(pid)
Get the download link for a Statistics Canada product ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pid
|
str
|
The Statistics Canada product ID. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
The download URL for the CSV file. |
synpop_tools.CADataSource.__get_pid_release_date(pid)
Get the release date for a Statistics Canada product ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pid
|
str
|
The Statistics Canada product ID. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
The release date in ISO format. |
synpop_tools.CADataSource.reduce_df_labour(df)
Reduce the labour force DataFrame to essential columns.
Special method to reduce the labour force DataFrame to only the columns needed for synpop generation, following Villads filtering.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
df
|
DataFrame
|
The full labour force DataFrame. |
required |
Returns:
| Type | Description |
|---|---|
|
pd.DataFrame: The reduced DataFrame with only essential columns. |
synpop_tools.MXDataSource
Bases: NonEurostatHandler
Retrieve and track Mexican SynPop source datapoints.
The handler combines manually downloaded INEGI census tables, an ITU internet-usage archive, and the Correos de México postal-code mapping. Release dates for manual census inputs are estimated on a ten-year cycle.
synpop_tools.MXDataSource.__init__()
Initialize the Mexican data source and its datapoint metadata.
Release and next-release dates are calculated for every configured datapoint during initialization.
synpop_tools.MXDataSource.retrieve_datapoint_release_date(datapoint)
Return estimated release dates for a Mexican datapoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Key from |
required |
Returns:
| Type | Description |
|---|---|
|
Pair |
|
|
surrounding decade boundaries; other inputs use today with no |
|
|
scheduled next release. |
synpop_tools.MXDataSource.retrieve_datapoint(datapoint)
Ensure a Mexican source datapoint is available locally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Key from |
required |
Returns:
| Type | Description |
|---|---|
|
True when the datapoint is available or downloaded; False when a |
|
|
required manual file is missing and a notification was sent. |
Notes
ZIP downloads are extracted and their original archives removed.
The postal-code source uses special_download_postal_codes.
synpop_tools.MXDataSource.special_download_postal_codes()
Download the Correos de México all-state postal-code archive.
Returns:
| Type | Description |
|---|---|
|
None. The ZIP archive is written beneath |
Notes
The source requires ASP.NET form state and a simulated download button POST. On failure, the error is printed and the datapoint is changed to manual-download mode.
synpop_tools.GBDataSource
Bases: NonEurostatHandler
Retrieve and track Great Britain and Northern Ireland SynPop sources.
Supported inputs include ArcGIS GeoJSON services, downloadable spreadsheets and ZIP archives, manually supplied Ofcom data, and paginated Nomis census datasets.
synpop_tools.GBDataSource.__init__(verbose=False)
Initialize the UK data source and its datapoint metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verbose
|
If True, print each datapoint while its release dates are resolved. |
False
|
Notes
Release and next-release dates are calculated for every configured datapoint during initialization.
synpop_tools.GBDataSource.retrieve_datapoint(datapoint, verbose=False)
Retrieve one configured UK datapoint into the local data directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Key from |
required | |
verbose
|
If True, print download or Nomis pagination progress. |
False
|
Returns:
| Type | Description |
|---|---|
|
True after a successful automated retrieval; False when the datapoint |
|
|
requires a manual download and a notification was sent. |
Notes
ArcGIS GeoJSON is converted to a shapefile bundle, ZIP archives are extracted, and Nomis pages are concatenated into a CSV.
synpop_tools.GBDataSource.retrieve_datapoint_release_date(datapoint)
Discover the release schedule for a configured UK datapoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datapoint
|
Key from |
required |
Returns:
| Type | Description |
|---|---|
|
Pair |
|
|
ArcGIS, NISRA, National Records of Scotland, education-statistics, Nomis, |
|
|
or annual Technology Tracker metadata source. |
Raises:
| Type | Description |
|---|---|
Exception
|
If the metadata URL has no supported date handler. |
Notes
Sources without exposed update metadata can fall back to the current
date. Some metadata pages can return None when a release marker is
unavailable.
synpop_tools.GBDataSource.retrieve_nomis_dataset(url, verbose=False)
Download every page of a Nomis CSV dataset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
Nomis URL template containing a |
required | |
verbose
|
If True, print row-range progress. |
False
|
Returns:
| Type | Description |
|---|---|
|
pandas DataFrame containing the concatenated pages. |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If a page request is unsuccessful. |
AssertionError
|
If Nomis returns a non-CSV or empty response. |
Notes
Nomis is queried in blocks of 25,000 rows. RECORD_COUNT from the first
returned row controls pagination.
synpop_tools.Geo2NUTSGetter
Class to get the mapping between geographical codes (postal codes, etc.) and NUTS codes for European countries, using the TERCET files from Eurostat.
The TERCET files are available for download at https://gisco-services.ec.europa.eu/tercet/NUTS-2024/, and contain the mapping between NUTS codes and various geographical codes for each country.
Author: Gino F. Fazzi (gino.franco.fazzi@audienceproject.com)
synpop_tools.Geo2NUTSGetter.__init__(base_path, logger=None, countries=None)
Configure a Geo-to-NUTS TERCET downloader.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_path
|
Destination root for downloaded and processed TERCET files. |
required | |
logger
|
Optional logger receiving download and processing messages. |
None
|
|
countries
|
Optional iterable of country codes. If omitted, the supported default set of European countries is used. |
None
|
synpop_tools.Geo2NUTSGetter._tercet_file_exists(url)
Return whether a TERCET file URL points to a downloadable file.
TERCET sometimes serves transient server/WAF errors for valid files,
especially on HEAD requests. Retryable errors are treated as
inconclusive instead of missing so the download step can use its curl
fallback with retries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Absolute TERCET file URL to probe. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the probe request fails at the transport level. |
Notes
Probes with HEAD first and retries with a streaming GET for statuses
in :attr:TERCET_GET_FALLBACK_STATUS_CODES, since TERCET rejects HEAD
for some valid files.
synpop_tools.Geo2NUTSGetter.download_tercet_files()
Download and process the newest available TERCET mapping for each country.
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If none of the supported TERCET versions exists for a country. |
synpop_tools.Geo2NUTSGetter.cleanup()
Remove the temporary TERCET download directory.
Returns:
| Type | Description |
|---|---|
|
None. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If |
synpop_tools.Geo2NUTSGetter.update_Geo2NUTS(logger=None)
Download, process, and clean up all configured Geo-to-NUTS mappings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
logger
|
Optional logger receiving processing progress. |
None
|
Returns:
| Type | Description |
|---|---|
|
None. |
synpop_tools.Approver
Class to get produce the approval requests for finished Synthetic Populations, and send them to the relevant stakeholders for review.
Author: Gino F. Fazzi (gino.franco.fazzi@audienceproject.com)
synpop_tools.Approver.__init__()
Initialize the Slack approval client.
Notes:
The bot token is loaded from the Databricks dame secret scope, and
approval requests are sent to the configured SynPop approval channel.
synpop_tools.Approver.__construct_payload(approval_id, synpop_id, report_url)
Build the interactive Slack payload for an approval request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
approval_id
|
Unique identifier associated with the approval request. |
required | |
synpop_id
|
Synthetic-population identifier. Its first hyphen-delimited component is displayed as the country code. |
required | |
report_url
|
URL of the report stakeholders should review. |
required |
Returns:
| Type | Description |
|---|---|
|
Slack message payload containing Approve and Reject buttons. Each |
|
|
button carries the approval and synthetic-population identifiers as |
|
|
JSON metadata. |
synpop_tools.Approver.generate_approval_request(synpop_id, report_url)
Post an interactive SynPop approval request to Slack.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
synpop_id
|
Identifier of the synthetic population awaiting approval. Carried through the Slack action payload so the callback can resolve it. |
required | |
report_url
|
Review-report URL included in the Slack message. |
required |
Returns:
| Type | Description |
|---|---|
None
|
The request is posted to Slack rather than returned. |
Notes
The message contains Approve and Reject actions carrying a freshly generated
approval ID together with synpop_id. Authentication uses the bot token
loaded by the class constructor.
synpop_tools.SynPopAPIHandler
Class to handle the API calls for Synthetic Population ingestion and validation.
Author: Gino F. Fazzi (gino.franco.fazzi@audienceproject.com)
synpop_tools.SynPopAPIHandler.__init__(env, token=None, logger=None)
Initialize a SynPop API client for an environment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env
|
API environment accepted by
:func: |
required | |
token
|
Optional bearer token. When omitted, the token is read from the
Databricks |
None
|
|
logger
|
Optional logger retained for callers that need to attach process logging. |
None
|
Raises:
| Type | Description |
|---|---|
Exception
|
If |
Notes
Authentication headers are built during initialization, so constructing this class requires either a token or secret-scope access.
synpop_tools.SynPopAPIHandler.whoami()
Return the identity associated with the configured API bearer token.
Returns:
| Type | Description |
|---|---|
|
JSON-decoded identity response. |
Raises:
| Type | Description |
|---|---|
Exception
|
If the API does not return HTTP 200. |
synpop_tools.SynPopAPIHandler._post_ingest_population(payload)
Submit a population-ingestion payload to the SynPop API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
payload
|
JSON-serializable request body for the population ingestion endpoint. |
required |
Returns:
| Type | Description |
|---|---|
|
JSON-decoded API response. |
Raises:
| Type | Description |
|---|---|
Exception
|
If the ingestion endpoint does not return HTTP 201. |
synpop_tools.SynPopAPIHandler._generate_ingestion_path(country_code, version, date, name)
Build the production S3 path for a formatted population.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
Population country partition. |
required | |
version
|
Population version partition. |
required | |
date
|
Three-element |
required | |
name
|
Population name partition. |
required |
Returns:
| Type | Description |
|---|---|
|
S3 URI below the production |
synpop_tools.SynPopAPIHandler._construct_payload_for_ingestion(country_code, version, date, name)
Build an ingestion payload and ensure its population is formatted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
Population country partition. |
required | |
version
|
Population version partition. |
required | |
date
|
Three-element |
required | |
name
|
Alias and S3 name partition for the ingested population. |
required |
Returns:
| Type | Description |
|---|---|
|
SynPop API ingestion payload containing the S3 location and column |
|
|
metadata. |
Notes
Geographic columns are read from the matching approved metadata. If the formatted ingestion path does not exist, the approved population is formatted and written there before the payload is returned.
synpop_tools.SynPopAPIHandler.ingest_population(country_code, version, date, name=None, force=False, verbose=False)
Register an approved synthetic population with the SynPop API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
Population country code. |
required | |
version
|
Population version and API alias. |
required | |
date
|
Three-element |
required | |
name
|
Optional population name and S3 |
None
|
|
force
|
Re-submit even when a |
False
|
|
verbose
|
Print the resulting population ID and response. |
False
|
Returns:
| Type | Description |
|---|---|
dict
|
JSON-decoded API response for the created population, or the
previously stored response when one exists and |
Raises:
| Type | Description |
|---|---|
Exception
|
If the ingestion endpoint does not return HTTP 201, or if the population contains a column without known API metadata. |
Notes
Writes payload.json and response.json beside the ingested
population in S3. The duplicate check keys on country, version, and date
but not name, so a given partition can only be ingested once unless
force is set.
synpop_tools.SynPopAPIHandler.activate_population(population_id, activation_date)
Activate a synthetic population in the SynPop API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
population_id
|
Population ID returned by the ingestion endpoint. |
required | |
activation_date
|
Activation date string formatted as |
required |
Returns:
| Type | Description |
|---|---|
dict
|
JSON-decoded API response for the activated population. |
Raises:
| Type | Description |
|---|---|
Exception
|
If the activation endpoint does not return HTTP 200. |
synpop_tools.SynPopAPIHandler.get_population(country_code=None, date=None)
Query available synthetic populations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
str | None
|
Optional country code filter. Sent to the API as |
None
|
date
|
str | None
|
Optional population date filter. String formatted date YYYY-MM-DD |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
JSON response from the population query endpoint. |
Raises:
| Type | Description |
|---|---|
Exception
|
If the query endpoint does not return HTTP 200. |
Notes
API reference: http://synthetic-population-prod.dk-prod.ap.priv/api-docs/index.html#/population/getQueriedPopulations
synpop_tools.SynPopAPIHandler.get_population_by_id(population_id)
Retrieve one synthetic population by its API ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
population_id
|
Population ID produced when the population was ingested. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
JSON response describing the requested population. |
Raises:
| Type | Description |
|---|---|
Exception
|
If the endpoint does not return HTTP 200, including when no
population matches |
Notes
API reference: http://synthetic-population-prod.dk-prod.ap.priv/api-docs/index.html#/population/getPopulation
synpop_tools.SynPopAPIHandler._get_column_info(geo_columns, columns_to_include)
Convert population columns into SynPop API column metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geo_columns
|
Geographic column names for this population. Each is declared categorical and marked as a target-granularity column. |
required | |
columns_to_include
|
Population column names to describe. |
required |
Returns:
| Type | Description |
|---|---|
list of dict
|
One entry per column with its |
Raises:
| Type | Description |
|---|---|
Exception
|
If a requested column has no known API metadata. Adding a new population column requires registering it here first. |
synpop_tools.SynPopAPIHandler._get_headers(token)
Build authenticated JSON headers for the SynPop API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
Bearer token to use. When falsy, the token is read from the
Databricks |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Headers containing the JSON content type and the bearer-token authorization value. |
Raises:
| Type | Description |
|---|---|
Exception
|
Re-raises the underlying secrets error if no |
synpop_tools.get_population_by_id(population_id, env='prod', token=None)
Query available synthetic populations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
population_id
|
|
required | |
env
|
|
'prod'
|
|
token
|
|
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict
|
JSON response from the population query endpoint. |
|
NOTE |
Documentation http://synthetic-population-prod.dk-prod.ap.priv/api-docs/index.html#/population/getPopulation
|
|
synpop_tools.get_environment_path_population_api(env)
Return the synthetic-population API base URL for an environment.
Author: Christian Starup (christian@audienceproject.com)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env
|
Target environment. One of |
required |
Returns:
| Type | Description |
|---|---|
str
|
Base URL for the requested environment, with a trailing slash. |
Raises:
| Type | Description |
|---|---|
Exception
|
If |
synpop_tools.format_population_for_engine_upload(population_load_path, population_save_path, country_code, columns_to_include)
Rewrite a Data Science synthetic population into the Engine upload format.
Compared with the Data Science output, the Engine format drops the freq_
column prefix and exposes exactly one column per universe, computed as the sum
of the hard-coded channel columns that make up that universe. The
implementation tolerates any Data Science population version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
population_load_path
|
S3 path of the Parquet synthetic population to read. |
required | |
population_save_path
|
S3 path to overwrite with the reformatted population. |
required | |
country_code
|
Country code driving the minimum-age filter and the geographic column
mapping. |
required | |
columns_to_include
|
Engine column names to emit. Must be a subset of the allowed column list
and must contain |
required |
Returns:
| Type | Description |
|---|---|
None
|
The reformatted population is written to |
Raises:
| Type | Description |
|---|---|
Exception
|
If |
Notes
Writes with mode("overwrite"), so any existing data at
population_save_path is replaced. Validation runs several counting actions
over the population, so this is deliberately not a lazy transformation.
synpop_tools.load_approvals_table(env='prod')
Load the synthetic-population approvals Delta table for an environment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env
|
Environment prefix below the |
'prod'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Spark DataFrame over the approvals Delta table. |
synpop_tools.get_attribute_from_synpop_table(country_code, version, attribute, stage='active', max_date=None)
Return one attribute from the latest eligible synthetic-population row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
Country code identifying the synthetic population. |
required | |
version
|
Population version to select. |
required | |
attribute
|
Approval-table column or derived |
required | |
stage
|
Required lifecycle stage: |
'active'
|
|
max_date
|
Latest allowed release date as a date string or |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
Value of |
Raises:
| Type | Description |
|---|---|
Exception
|
If an argument is invalid or no matching population row is available. |
synpop_tools.write_to_approval_table(step, env, args)
Write an approval workflow event to the approval's Delta table.
Parameters
step:
Workflow step to apply: "decision", "ingestion", or
"activation".
env:
Environment partition used in the approvals-table S3 path.
args:
Values required by the selected step. Decision events require
synpop_id, creation_date, approval_id, decision, and
approved_by; ingestion updates require synpop_id,
population_id, and status; activation updates require synpop_id
and an activation_date formatted as YYYY-MM-DD.
Returns
None The event is persisted to Delta rather than returned.
Raises
ValueError
If step is not one of the three supported workflow steps.
KeyError
If args is missing any argument required by step.
Notes
Decision events are appended to the Delta table. Ingestion and activation
events update matching rows by synpop_id and do not insert unmatched
rows, so an activation for an unknown synpop_id succeeds silently without
changing anything. Requires Spark, Delta Lake, and write access to the target
S3 location.
synpop_tools.push_synthethic_population(country_code, version, approver='', synpop_id='', overwrite=False, debug=False)
Promote the latest reviewed synthetic population to approved storage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
str
|
Country partition of the reviewed population. |
required |
version
|
str
|
Version partition of the reviewed population. |
required |
approver
|
str
|
Approver value recorded in the metadata manifest. |
''
|
synpop_id
|
str
|
Synthetic-population identifier recorded in the manifest. |
''
|
overwrite
|
bool
|
If True, remove existing approved targets before copying. If False, existing targets cause an exception. |
False
|
debug
|
If True, perform discovery and validation without deleting, copying, or writing the manifest. |
False
|
Returns:
| Type | Description |
|---|---|
|
None. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If a required reviewed data or metadata source is missing. |
Exception
|
If an approved destination exists and |
Notes
Only the artifact=synthetic_population data artifact is promoted.
All items in the matching latest metadata partition are copied, and a
manifest.json file is written alongside them. The operation uses
dbutils.fs and production S3 paths.
Author: Christian Starup (christian@audienceproject.com) [Copied from synthetic-population-generation/synpop_general_functions and adapted to use dsr_tools instead of deprecated working_tools_edit]
synpop_tools.load_synpop_survey(country_code, max_date=None)
Load the synthetic-population survey for a country.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
Country whose survey extracts should be searched. |
required | |
max_date
|
Optional inclusive upper bound as an ISO |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Survey responses. Read as Parquet from the |
Raises:
| Type | Description |
|---|---|
Exception
|
If the country has no survey directory, if |
Notes
The two branches return different file formats, so callers that pass
max_date receive all-string CSV columns rather than the typed Parquet
schema returned by the default branch.
synpop_tools.load_demographic_weights(country_code, version, date=None)
Load the demographic weights produced by the latest approved SynPop flow.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
country_code
|
Country whose weights should be loaded. |
required | |
version
|
Population version to resolve. |
required | |
date
|
Optional inclusive upper bound on the population creation date, accepted
as a |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Spark DataFrame of demographic weights for the resolved population. |
Raises:
| Type | Description |
|---|---|
Exception
|
If no active population matches the country, version, and date bound, or
if the resolved population has no |