fairdm.contrib.contributors.utils.transforms#
Data transformation utilities for contributors.
This module provides bidirectional transformations between Contributor objects and various external metadata formats (DataCite, Schema.org, CSL-JSON, ORCID, ROR, etc.).
Module Contents#
Classes#
Base class for bidirectional contributor data transformations. |
|
Bidirectional transformation for DataCite Metadata Schema 4.4. |
|
Bidirectional transformation for Schema.org JSON-LD format. |
|
Bidirectional transformation for CSL-JSON (Citation Style Language) format. |
|
Bidirectional transformation for ORCID Public API v3.0 data. |
|
Bidirectional transformation for ROR (Research Organization Registry) API data. |
Functions#
Export contributor as DataCite JSON. |
|
Export contributor as Schema.org JSON-LD. |
|
Export contributor as CSL-JSON. |
|
Import CSL-JSON data as Contributor. |
API#
- class BaseTransform#
Base class for bidirectional contributor data transformations.
Provides utilities for converting between external data formats and Contributor model instances. Subclasses should implement:
export(): Convert Contributor → external format
import_data(): Convert external format → Contributor
- dictget(data: dict | list, path: list, default: Any = '') Any#
Navigate nested data structures using a path list.
Safely retrieves values from deeply nested dictionaries or lists.
Args: data: Nested dictionary or list structure path: List of keys/indices to navigate (e.g., [“person”, “name”, 0]) default: Value to return if path doesn’t exist
Returns: The value at the specified path, or default if not found
Example: >>> data = {“person”: {“names”: [{“given”: “John”}]}} >>> self.dictget(data, [“person”, “names”, 0, “given”]) ‘John’
- abstractmethod export(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export a Contributor instance to external format.
Args: contributor: The Contributor instance to export
Returns: dict: Data in the external format
Raises: NotImplementedError: Subclasses must implement this method
- abstractmethod import_data(data: dict, instance: fairdm.contrib.contributors.models.Contributor | None = None, save: bool = True) fairdm.contrib.contributors.models.Contributor#
Import external format data into a Contributor instance.
Args: data: External format data dictionary instance: Existing Contributor to update (creates new if None) save: Whether to save the instance to the database
Returns: Contributor: The created or updated Contributor instance
Raises: NotImplementedError: Subclasses must implement this method
- validate(data: dict) bool#
Validate that data conforms to the expected format.
Args: data: Data to validate
Returns: bool: True if valid, False otherwise
- class DataCiteTransform#
Bases:
fairdm.contrib.contributors.utils.transforms.BaseTransformBidirectional transformation for DataCite Metadata Schema 4.4.
Converts between Contributor objects and DataCite creator/contributor format. See: https://schema.datacite.org/meta/kernel-4.4/
- export(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export Contributor to DataCite creator/contributor format.
Args: contributor: Person or Organization instance
Returns: dict: DataCite-formatted contributor metadata
- import_data(data: dict, instance: fairdm.contrib.contributors.models.Contributor | None = None, save: bool = True) fairdm.contrib.contributors.models.Contributor#
Import DataCite creator/contributor data into a Contributor.
Args: data: DataCite formatted contributor data instance: Existing Contributor to update (creates new if None) save: Whether to save to database
Returns: Contributor: Created or updated instance
- class SchemaOrgTransform#
Bases:
fairdm.contrib.contributors.utils.transforms.BaseTransformBidirectional transformation for Schema.org JSON-LD format.
Converts between Contributor objects and Schema.org Person/Organization types. See: https://schema.org/Person and https://schema.org/Organization
- export(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export Contributor to Schema.org JSON-LD format.
Args: contributor: Person or Organization instance
Returns: dict: Schema.org formatted data
- import_data(data: dict, instance: fairdm.contrib.contributors.models.Contributor | None = None, save: bool = True) fairdm.contrib.contributors.models.Contributor#
Import Schema.org Person/Organization data into a Contributor.
Args: data: Schema.org formatted data instance: Existing Contributor to update (creates new if None) save: Whether to save to database
Returns: Contributor: Created or updated instance
- class CSLJSONTransform#
Bases:
fairdm.contrib.contributors.utils.transforms.BaseTransformBidirectional transformation for CSL-JSON (Citation Style Language) format.
Converts between Contributor objects and CSL-JSON author/contributor format. See: https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html
- export(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export Contributor to CSL-JSON author format.
Args: contributor: Contributor instance
Returns: dict: CSL-JSON formatted author object
- import_data(data: dict, instance: fairdm.contrib.contributors.models.Contributor | None = None, save: bool = True) fairdm.contrib.contributors.models.Contributor#
Import CSL-JSON author data into a Contributor.
Args: data: CSL-JSON formatted author data instance: Existing Contributor to update (creates new if None) save: Whether to save to database
Returns: Contributor: Created or updated instance
- class ORCIDTransform#
Bases:
fairdm.contrib.contributors.utils.transforms.BaseTransformBidirectional transformation for ORCID Public API v3.0 data.
Converts between Person objects and ORCID API response format. See: https://info.orcid.org/documentation/integration-guide/orcid-record/
- static fetch_from_api(orcid_id: str) dict#
Fetch public data for a given ORCID ID from the ORCID Public API.
Args: orcid_id: The ORCID identifier of the researcher
Returns: dict: The JSON response from the ORCID API
Raises: requests.RequestException: If the API request fails
Example: data = ORCIDTransform.fetch_from_api(“0000-0002-1825-0097”)
- export(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export Person to ORCID API format.
Note: This creates a minimal ORCID-compatible structure for Person data. The full ORCID record has many more fields.
Args: contributor: Person instance (Organizations not supported)
Returns: dict: ORCID-formatted person data
Raises: TypeError: If contributor is not a Person instance
- import_data(data: dict, instance: fairdm.contrib.contributors.models.Person | None = None, save: bool = True) fairdm.contrib.contributors.models.Person#
Import ORCID API data into a Person instance.
Args: data: ORCID API response data instance: Existing Person to update (creates new if None) save: Whether to save to database
Returns: Person: Created or updated Person instance
- classmethod update_or_create(orcid: str, force: bool = False, **kwargs) tuple[fairdm.contrib.contributors.models.Person, bool]#
Update an existing Person or create a new one using ORCID data.
Attempts to find a Person matching the provided kwargs or with an identifier value matching the given ORCID. If found and not recently synced (or force=True), updates the Person with latest ORCID API data. If not found, creates a new Person.
Args: orcid: The ORCID identifier to fetch data for force: If True, always fetch and update from ORCID API **kwargs: Additional lookup parameters for finding an existing Person
Returns: tuple: (Person object, created boolean)
Example: person, created = ORCIDTransform.update_or_create(“0000-0002-1825-0097”)
- classmethod get_or_create(orcid: str) tuple[fairdm.contrib.contributors.models.Person, bool]#
Retrieve a Person instance matching the given ORCID.
If no match is found, a Person instance is created by fetching data from the ORCID Public API.
Args: orcid: The ORCID identifier to search for or create a Person with
Returns: tuple: (Person instance, created boolean)
Example: person, created = ORCIDTransform.get_or_create(“0000-0002-1825-0097”)
- class RORTransform#
Bases:
fairdm.contrib.contributors.utils.transforms.BaseTransformBidirectional transformation for ROR (Research Organization Registry) API data.
Converts between Organization objects and ROR API response format. Records are read in version 2 of ROR’s schema. See: https://ror.readme.io/v2/docs/data-structure
- static clean_ror_id(ror_id_or_link: str) str#
Extract ROR ID from URL or return as-is.
Args: ror_id_or_link: ROR ID or full URL
Returns: str: Clean ROR ID without URL prefix
- static fetch_from_api(ror_id: str) dict#
Fetch public data for a given ROR ID from the ROR API.
Args: ror_id: The ROR identifier of the organization (URL or ID)
Returns: dict: The JSON response from the ROR API
Raises: requests.RequestException: If the API request fails
Example: data = RORTransform.fetch_from_api(“https://ror.org/00x0x0x”)
- export(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export Organization to ROR API format.
Note: This creates a minimal ROR-compatible structure for Organization data. The full ROR record has many more fields.
Args: contributor: Organization instance (Person not supported)
Returns: dict: ROR-formatted organization data
Raises: TypeError: If contributor is not an Organization instance
- import_data(data: dict, instance: fairdm.contrib.contributors.models.Organization | None = None, save: bool = True) fairdm.contrib.contributors.models.Organization#
Import ROR API data into an Organization instance.
Args: data: ROR API response data instance: Existing Organization to update (creates new if None) save: Whether to save to database
Returns: Organization: Created or updated Organization instance
- display_name(data: dict) str#
Return the name ROR displays for the organization in a ROR record.
Args: data: ROR API response data
Returns: str: The display name, or an empty string when the record has none
- import_location(data: dict, org: fairdm.contrib.contributors.models.Organization) None#
Set the organization’s city, country and location from a ROR record.
Nothing is changed when the record names no place.
Args: data: ROR API response data org: The Organization to update; it is not saved
- classmethod update_or_create(ror_id: str, force: bool = False, **kwargs) tuple[fairdm.contrib.contributors.models.Organization, bool]#
Update an existing Organization or create a new one using ROR data.
Attempts to find an Organization matching the provided kwargs or with an identifier value matching the given ROR ID. If found and not recently synced (or force=True), updates the Organization with latest ROR API data. If not found, creates a new Organization.
Args: ror_id: The ROR identifier to fetch data for force: If True, always fetch and update from ROR API **kwargs: Additional lookup parameters for finding an existing Organization
Returns: tuple: (Organization object, created boolean)
Example: org, created = RORTransform.update_or_create(“https://ror.org/00x0x0x”)
- classmethod get_or_create(ror_id: str) tuple[fairdm.contrib.contributors.models.Organization, bool]#
Retrieve an Organization instance matching the given ROR ID.
If no match is found, an Organization instance is created by fetching data from the ROR API.
Args: ror_id: The ROR identifier to search for or create an Organization with
Returns: tuple: (Organization instance, created boolean)
Example: org, created = RORTransform.get_or_create(“https://ror.org/00x0x0x”)
- contributor_to_datacite(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export contributor as DataCite JSON.
- contributor_to_schema_org(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export contributor as Schema.org JSON-LD.
- contributor_to_csljson(contributor: fairdm.contrib.contributors.models.Contributor) dict#
Export contributor as CSL-JSON.
- csljson_to_contributor(data: dict, save: bool = True) fairdm.contrib.contributors.models.Contributor#
Import CSL-JSON data as Contributor.