API Reference¶
- class nightingale.config.Publishing(publisher, base_uri, version='', publisher_uid='', publisher_scheme='', publisher_uri='', license='', publicationPolicy='')[source]¶
Bases:
object- Parameters:
- class nightingale.config.Mapping(file, ocid_prefix, selector, force_publish=False, codelists=None, milestone_lookup_sql=None, split_milestone_codes=False, codelist_passthrough_paths=())[source]¶
Bases:
object- Parameters:
- milestone_lookup_sql: str | None = None¶
SQL query to load milestone code metadata. Must return
code,titleanddescriptioncolumns. Used to enrich milestones with titles and descriptions, and to identify known codes for deduplication.
- split_milestone_codes: bool = False¶
Whether to split space-separated milestone codes into individual milestone objects. When enabled, a value like
"CA AT AU"in the milestone code field produces three separate milestones. Requires the source data to encode multiple codes in a single field; do not enable if milestone codes can legitimately contain spaces.
- class nightingale.config.Config(datasource, mapping, publishing, output)[source]¶
Bases:
object- Parameters:
datasource (Datasource)
mapping (Mapping)
publishing (Publishing)
output (Output)
- datasource: Datasource¶
- publishing: Publishing¶
- class nightingale.loader.DataLoader(config, connection=None)[source]¶
Bases:
objectLoad data from a database using a SQL query.
- nightingale.mapper.LARGE_RELEASE_ROW_THRESHOLD = 500000¶
Log a progress message every this many rows, and report releases that meet or exceed this row count.
- nightingale.mapper.SLOW_RELEASE_SECONDS = 18000¶
Report releases that take longer than this many seconds to process.
- class nightingale.mapper.OCDSDataMapper(config, writer=None)[source]¶
Bases:
objectMaps data from a source to the OCDS format.
- Parameters:
config (Config) – Configuration object containing settings for the mapper.
writer (DataWriter | None)
- transform_data(data, mapping, codelists=None)[source]¶
Transform the input data to the OCDS format.
- Parameters:
data (list[dict[Any, Any]]) – List of input data dictionaries.
mapping (MappingTemplate) – Mapping configuration object.
codelists (CodelistsMapping | None)
- Returns:
List of transformed release dictionaries.
- Return type:
- transform_row(input_data, mapping_config, flattened_schema, result=None, array_counters=None, codelists=None, curr_release_dates=None)[source]¶
Transform a single row of input data to the OCDS format.
- Parameters:
input_data (dict[Any, Any]) – Dictionary of input data.
mapping_config (MappingTemplate) – Mapping configuration object.
flattened_schema (dict[str, Any]) – Flattened schema dictionary.
result (dict, optional) – Existing result dictionary to update.
array_counters (dict | None)
codelists (CodelistsMapping | None)
- Returns:
Transformed row dictionary.
- Return type:
- make_release_id(curr_row)[source]¶
Generate and set a unique ID for the release based on its content.
- Parameters:
curr_row (dict) – The current release row dictionary.
- Return type:
None
- tag_initiation_type(curr_row)[source]¶
Tag the initiation type of the release as ‘tender’ if applicable.
- Parameters:
curr_row (dict) – The current release row dictionary.
- Return type:
None
- generate_tags(release_data)[source]¶
Generate the release tag(s) based on the current release data, without considering prior releases.
Exclude ‘update’ tags, ‘cancellation’ tags and the ‘compiled’ tag.
- Parameters:
release_data – The current release data (dict).
- Returns:
A list of tags (list of str).
- Return type:
None
- nightingale.mapper.find_array_element_by_id(current, array_element_id)[source]¶
Find the first dictionary in a list that contains the given ‘id’ value.
If no dictionary with the matching ‘id’ is found, return the last dictionary in the list.
- Parameters:
current – List[Dict], a list of dictionaries to search.
array_element_id – Any, the target ‘id’ value to search for.
- Returns:
Dict, the dictionary with the matching ‘id’ value, or the last dictionary if not found.
- Examples:
>>> dict_list = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}, {'id': 3, 'name': 'Charlie'}] >>> find_array_element_by_id(dict_list, 2) {'id': 2, 'name': 'Bob'}
>>> find_array_element_by_id(dict_list, 4) {'id': 3, 'name': 'Charlie'}
>>> find_array_element_by_id(dict_list, 3) {'id': 3, 'name': 'Charlie'}
>>> find_array_element_by_id([], 1) is None True
- class nightingale.mapping_template.v09.MappingTemplate(config)[source]¶
Bases:
object
- class nightingale.codelists.CodelistsMapping(config)[source]¶
Bases:
object
- class nightingale.publisher.DataPublisher(config, mapping)[source]¶
Bases:
objectPacks array of releases into a release package.
- Parameters:
config (Publishing)
- produce_uri()[source]¶
Produce a URI for the package based on the given date.
- Returns:
The produced URI.
- Return type:
- nightingale.writer.new_name(package)[source]¶
Generate a new name for the package based on its published date.
- class nightingale.writer.DataWriter(config)[source]¶
Bases:
objectWrites release package to disk.
- Parameters:
config (Output)
- make_dirs()[source]¶
Create the necessary directories for storing the release package.
- Returns:
The base directory path.
- Return type:
- start_package_stream(package_metadata)[source]¶
Start a streaming write session, write package metadata and prepare for releases.
- Parameters:
package_metadata (dict)
- Return type:
None
- stream_release(release)[source]¶
Write a single release to the open package file stream.
- Parameters:
release (dict)
- Return type:
None
- nightingale.util.is_new_array(array_counters, child_path, array_key, array_value, array_path)[source]¶
Check if a new array should be created based on the given parameters.
- Parameters:
- Returns:
True if a new array should be created, False otherwise.
- Return type:
>>> array_counters = {'/object/field2/array_field': '1'} >>> child_path = '/id' >>> array_key = 'id' >>> array_value = '2' >>> array_path = '/object/field2/array_field' >>> is_new_array(array_counters, child_path, array_key, array_value, array_path) True
>>> array_counters = {'/object/field2/array_field': '1'} >>> child_path = '/id' >>> array_key = 'id' >>> array_value = '1' >>> array_path = '/object/field2/array_field' >>> is_new_array(array_counters, child_path, array_key, array_value, array_path) False
>>> array_counters = {'/object/field2/array_field': '1'} >>> child_path = '/name' >>> array_key = 'name' >>> array_value = 'example' >>> array_path = '/object/field2/array_field' >>> is_new_array(array_counters, child_path, array_key, array_value, array_path) False
- nightingale.util.group_contiguous_mappings(mapping_list)[source]¶
Group mapping items by contiguous blocks: group consecutive items that share the same block.
- nightingale.util.sort_group_by_parent_and_id(group)[source]¶
Sort a contiguous group of mapping items so that ‘/id’ paths come first within each parent.
Split the group into subgroups that share the same parent (i.e. everything before the final ‘/’). Then, for each subgroup, sort so that any item whose path ends with ‘/id’ comes first. The sorted subgroups are then concatenated in the original order.
- exception nightingale.exceptions.NightingaleError[source]¶
Bases:
ExceptionBase class for exceptions from within this package.
- exception nightingale.exceptions.StreamNotStartedError[source]¶
Bases:
NightingaleErrorRaised when a streaming method is called before start_package_stream().