diff --git a/invenio_rdm_records/ext.py b/invenio_rdm_records/ext.py index be975dd37..36597ef46 100644 --- a/invenio_rdm_records/ext.py +++ b/invenio_rdm_records/ext.py @@ -16,6 +16,7 @@ from flask import Blueprint from flask_iiif import IIIF from flask_principal import identity_loaded +from importlib_metadata import entry_points from invenio_records_resources.resources.files import FileResource from . import config @@ -102,6 +103,7 @@ def __init__(self, app=None): def init_app(self, app): """Flask application initialization.""" self.init_config(app) + self.init_record_service_registry(app) self.init_services(app) self.init_resource(app) app.extensions["invenio-rdm-records"] = self @@ -310,6 +312,22 @@ def fix_datacite_configs(self, app): if config_item in app.config: app.config[config_item] = str(app.config[config_item]) + def init_record_service_registry(self, app): + """Initialize record service registry.""" + self.record_service_registry = {} + self._register_entry_point( + self.record_service_registry, + "invenio_rdm_records.services.record_service_registry", + ) + + def _register_entry_point(self, registry, ep_name): + """Load entry points into the given registry.""" + for ep in set(entry_points(group=ep_name)): + ext_name = ep.name + callback = ep.load() + assert callable(callback) + registry.setdefault(ext_name, callback) + def finalize_app(app): """Finalize app. diff --git a/invenio_rdm_records/services/config.py b/invenio_rdm_records/services/config.py index 160071860..febb9adf1 100644 --- a/invenio_rdm_records/services/config.py +++ b/invenio_rdm_records/services/config.py @@ -102,6 +102,7 @@ StatusParam, ) from .sort import VerifiedRecordsSortParam +from werkzeug.utils import cached_property def is_draft_and_has_review(record, ctx): @@ -396,8 +397,20 @@ def expand(self, obj, context): class RDMRecordServiceConfig(RecordServiceConfig, ConfiguratorMixin): """RDM record draft service config.""" - # Record and draft classes - record_cls = FromConfig("RDM_RECORD_CLS", default=RDMRecord) + @cached_property + def record_cls(self): + """Record class.""" + cfg_cls = self._app.config.get("RDM_RECORD_CLS", RDMRecord) + exts = getattr( + self._app.extensions["invenio-rdm-records"], "record_service_registry", {} + ) + new_cls = cfg_cls + for name, _ext in exts.items(): + tmp = _ext(self._app, new_cls) + assert type(tmp) == type(cfg_cls), f"Invalid record type. Expected: {type(cfg_cls)}, got: {type(tmp)}" + new_cls = tmp + return new_cls + draft_cls = FromConfig("RDM_DRAFT_CLS", default=RDMDraft) # Schemas