From 79365221ee520391c5260568750597bf33f6aee8 Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Thu, 25 Jul 2024 11:18:06 +0200 Subject: [PATCH 1/2] services: added record extension registry --- invenio_rdm_records/ext.py | 19 +++++++++++++++++++ invenio_rdm_records/services/config.py | 17 +++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/invenio_rdm_records/ext.py b/invenio_rdm_records/ext.py index be975dd37..f97217fc3 100644 --- a/invenio_rdm_records/ext.py +++ b/invenio_rdm_records/ext.py @@ -102,6 +102,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 +311,24 @@ 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): + # TODO load entry points + self.record_service_registry = {} + self._register_entry_point( + self.record_service_registry, + "invenio_rdm_records.services.record_service_registry", + ) + # Discussed w/Alex + # Interface could be the function itself that modifies the record class and returns it + + 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 From d5a6631cd50f44e3412fa84b0eba2517fc422c14 Mon Sep 17 00:00:00 2001 From: alejandromumo Date: Wed, 13 Nov 2024 17:19:46 +0100 Subject: [PATCH 2/2] chore: cleanup code --- invenio_rdm_records/ext.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/invenio_rdm_records/ext.py b/invenio_rdm_records/ext.py index f97217fc3..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 @@ -312,14 +313,12 @@ def fix_datacite_configs(self, app): app.config[config_item] = str(app.config[config_item]) def init_record_service_registry(self, app): - # TODO load entry points + """Initialize record service registry.""" self.record_service_registry = {} self._register_entry_point( self.record_service_registry, "invenio_rdm_records.services.record_service_registry", ) - # Discussed w/Alex - # Interface could be the function itself that modifies the record class and returns it def _register_entry_point(self, registry, ep_name): """Load entry points into the given registry."""