KCWorks Architecture

InvenioRDM’s Layered Architecture

InvenioRDM employs a layered architecture with:

  1. Data layer

    • Low-level data storage and retrieval.

      • Primarily SQLAlchemy model classes.

    • High-level data API classes that provide a Pythonic interface to the data layer.

      • Validate data before storing it.

  2. Service layer

    • Retrieves and modifies data from the data layer, either for a view or for another service.

      • Providing abstract CRUD methods for operating on the data layer’s API classes.

      • Providing abstracted “result items” and “result lists”

    • Enforces permission and access control policies.

  3. View layer

    • Consists of

      • Flask views (registered as Blueprints)

      • rendering either

        • Jinja2 templates to produce HTML

        • JSON to produce API responses

      • in some cases, React components embedded in the Jinja2 templates

        • These are rendered on the client side

        • Data is passed from the Jinja2 templates to the React components via HTML data attributes

InvenioRDM Services

An InvenioRDM service is a class that provides methods for interacting with the data layer. The business logic of the service is usually delegated to one or more component classes, which are called during the service’s methods.

Service Classes

BaseService

The base Service class is defined in invenio_records_resources.services.base.Service. It defines methods for:

  • Getting the service ID

    • id(self): Return the id of the service from config.

  • Permissions checking

    • permission_policy(self, action_name, **kwargs): Factory for a permission policy instance.

    • check_permission(self, identity, action_name, **kwargs): Check a permission against the identity.

    • require_permission(self, identity, action_name, **kwargs): Require a specific permission from the permission policy.

  • Handling service components

    • components(self): Return initialized instances of the service’s component classes.

    • run_components(self, action, *args, **kwargs): Run components for a given action.

  • Producing result items and lists

    • result_item(self, *args, **kwargs): Create a new instance of the resource unit, i.e. whatever the service provides.

    • result_list(self, *args, **kwargs): Create a new list of resource units. In some cases this is a simple iterable of resource units, but in other cases it is a more complex object that includes additional data.

RecordService

Services dealing with InvenioRDM records of some kind (e.g. records, drafts, communities, etc.) inherit from the RecordService class defined in invenio_records_resources.services.records.service. This class adds:

  • properties and methods related to the service’s related data-layer API class

    • A schema property that returns a ServiceSchemaWrapper instance.

    • A record_cls property that returns the record class for the service.

    • A links_item_tpl property that returns a LinksTemplate instance for constructing links to a resource unit.

    • An expandable_fields property that returns a list of expandable fields for the service’s data-layer API class.

  • Methods for creating searches

    • create_search(self, identity, record_cls, search_opts, permission_action="read", preference=None, extra_filter=None, versioning=True): Instantiate a search class.

    • search_records(self, identity, params, **kwargs): A low-level method to create an OpenSearch DSL instance for searching records.

    • search(self, identity, params=None, search_preference=None, expand=False, **kwargs): A high-level method to search for records matching the querystring.

    • scan(self, identity, params=None, search_preference=None, expand=False, **kwargs): A high-level method to perform a rolling “scroll” search for records matching the querystring. (This is used for searching through large numbers of records, since OpenSearch will not return more than 10,000 records at a time.)

  • Methods for indexing records

    • reindex(self, identity, params=None, search_preference=None, search_query=None, extra_filter=None, **kwargs): A high-level method to reindex records matching the query parameters.

    • rebuild_index(self, identity, uow=None): A high-level method to reindex all records managed by this service.

  • CRUD methods

    • create(self, identity, data, uow=None, expand=False): Create a record.

    • exists(self, identity, id_): Check if the record exists and user has permission. (Does not use the search index.)

    • read(self, identity, id_, expand=False, action="read"): Retrieve a record. (Does not use the search index.)

    • read_many(self, identity, ids, expand=False, action="read"): Retrieve multiple records using the search index.

    • read_all(self, identity, params=None, search_preference=None, expand=False, **kwargs): Retrieve all records matching the query parameters using the search index.

    • update(self, identity, id_, data, uow=None, expand=False): Update a record.

    • delete(self, identity, id_, uow=None): Delete a record.

  • Helper methods for record management

    • check_revision_id(self, record, expected_revision_id): Validate the given revision_id with current record’s one.

    • on_relation_update(self, identity, record_type, records_info, notif_time, limit=100): Handles the update of a related field record when the related field is updated.

Augmented RecordService

The invenio_drafts_resources package then overrides this with a RecordService class that adds (a) a distinction between published and draft records, (b) record versioning and a parent-child record relationship, and (c) file attachments to service records. This adds the following properties and methods to the RecordService class:

  • Properties and methods for draft records

    • draft_cls(self): Return the record class for the service.

    • draft_files(self): Return the draft files service for the service.

    • draft_indexer(self): A factory for creating an indexer instance.

    • search_drafts(self, identity, params=None, search_preference=None, expand=False, extra_filter=None, **kwargs): Search for draft records matching the querystring.

    • read_draft(self, identity, id_, expand=False): Retrieve a draft record.

    • update_draft(self, identity, id_, data, revision_id=None, uow=None, expand=False): Replace a draft.

    • edit(self, identity, id_, uow=None, expand=False): Creates a new revision of a draft or a draft for an existing published record.

    • publish(self, identity, id_, uow=None, expand=False): Publishes a draft record.

    • delete_draft(self, identity, id_, revision_id=None, uow=None): Deletes a draft record. (Defaults to a soft delete, so the record is not actually deleted from the database or search index until a later cleanup operation.)

    • validate_draft(self, identity, id_, ignore_field_permissions=False): Validate a draft.

    • cleanup_drafts(self, timedelta, uow=None, search_gc_deletes=60): Hard delete of soft deleted drafts.

  • Properties and methods for files

    • files(self): Return the files service for the service.

    • import_files(self, identity, id_, uow=None): Import files from previous record version.

  • Properties and methods for versions and parent records

    • schema_parent(self): Return the parent schema for the service.

    • search_versions(self, identity, id_, params=None, search_preference=None, expand=False, permission_action="read", **kwargs): Search for record’s versions.

    • read_latest(self, identity, id_, expand=False): Retrieve the latest version of a record.

    • new_version(self, identity, id_, uow=None, expand=False): Creates a new version of a record. This overridden RecordService class also modifies the CRUD methods to enforce a workflow in which records are only modified via their draft records. This involves overriding:

  • update(self, identity, id_, data, uow=None, expand=False): Now raises a NotImplementedError error.

  • create(self, identity, data, uow=None, expand=False): Now creates a draft record.

  • rebuild_index(self, identity): Now reindexes all draft records (instances of draft API class) as well as all published records (instances of record API class) and skips soft-deleted records.

RDMRecordService

The invenio_rdm_records package provides an RDMRecordService class that inherits from the RecordService class and adds:

  • Additional properties for accessing subservices

    • access: Return the access service for the service.

    • pids: Return the PIDs service for the service.

    • review: Return the review service for the service.

  • Methods for embargo handling

    • lift_embargo(self, identity, _id, uow=None): Lifts an embargo from the record and draft (if exists).

    • scan_expired_embargos(self, identity): Scan for records with an expired embargo.

  • Properties and methods for file quota handling

    • schema_quota: Return the schema for quota information.

    • set_quota(self, identity, id_, data, files_attr="files", uow=None): Set the quota values for a record.

    • set_user_quota(self, identity, id_, data, uow=None): Set the user files quota.

  • Properties and methods for deletion of published records

    • schema_tombstone: Return the schema for tombstone information.

    • delete_record(self, identity, id_, data, expand=False, uow=None, revision_id=None): Re-introduces soft-deletion of published records (which were previously removed by the RecordService class).

    • update_tombstone(self, identity, id_, data, expand=False, uow=None): Update the tombstone information for the (soft) deleted record.

    • cleanup_record(self, identity, id_, uow=None): Clean up a (soft) deleted record.

    • restore_record(self, identity, id_, expand=False, uow=None): Restore a record that has been (soft) deleted.

    • mark_record_for_purge(self, identity, id_, expand=False, uow=None): Mark a (soft) deleted record for purge.

    • unmark_record_for_purge(self, identity, id_, expand=False, uow=None): Remove the mark for deletion from a record, returning it to deleted state.

    • purge_record(self, identity, id_, uow=None): Purge a record that has been marked.

  • Overridden methods to add deletion-related functionality

    • read(self, identity, id_, expand=False, action="read", include_deleted=False): Adds an include_deleted argument to the read method, and a check for the read_deleted permission if it is set to True.

    • read_draft(self, identity, id_, expand=False): Prevents reading a draft if there is a published deleted record. (410 response.)

    • search(self, identity, params=None, search_preference=None, expand=False, extra_filter=None, **kwargs): Adds a “read_deleted” permission action to the search method.

    • search_drafts(self, identity, params=None, search_preference=None, expand=False, extra_filter=None, **kwargs): Adds a filter to exclude soft-deleted records from the search results.

    • search_versions(self, identity, id_, params=None, search_preference=None, expand=False, permission_action="read", **kwargs): Adds a “read_deleted” permission action to the search method.

  • Additional overridden methods for other functionality

    • publish(self, identity, id_, uow=None, expand=False): Adds a check prior to the original publish method to allow enforcement of a config setting that requires a community to be present on a record before it can be published.

    • update_draft(self, identity, id_, data, revision_id=None, uow=None, expand=False): Adds a check prior to the original update_draft method to allow enforcement of a config setting that prevents a record from being restricted after the grace period.

  • Additional new methods for other functionality

    • expandable_fields: Expands the communities field to return community details.

    • oai_result_item(self, identity, oai_record_source): Get a result item from a record source in the OAI server.

    • scan_versions(self, identity, id_, params=None, search_preference=None, expand=False, permission_action="read_deleted", **kwargs): Search for record’s versions using a “scroll” search.

Service Configuration

A service configuration is an object that provides the service with its configuration. It is passed to the service’s constructor when it is instantiated during the Flask app initialization.

The service configuration is defined in the service’s config attribute.

All service configurations inherit from the ServiceConfig class, which is defined in invenio_records_resources.services.base.config. They include at least:

  • service_id: The ID of the service.

  • permission_policy_cls: The permission policy class to use for the service.

  • result_item_cls: The result item class to use for the service.

  • result_list_cls: The result list class to use for the service.

This is expanded in a RecordServiceConfig class by the invenio_records_resources package to add:

  • record_cls: The record class to use for the service.

  • indexer_cls: The indexer class to use for the service.

  • indexer_queue_name: The name of the task queue to be used by the service’s indexer.

  • index_dumper: The dumper to be used for serializing records to be indexed by OpenSearch.

  • relations: The inverse relation mapping for the service, defining which fields relate to which record type.

  • search: The search configuration for the service. (This is a SearchOptions instance.)

  • schema: The schema to be used when validating the service’s records.

  • links_item: The template for creating url links for the service’s result items.

  • links_search: The template for creating url links for the service’s search endpoints.

  • components: A list of components that will be used by the service.

It is further expanded in an overridden RecordServiceConfig class by the invenio_drafts_resources package to add:

  • draft_cls: The draft record class to use for the service.

  • draft_indexer_cls: The indexer class to use for the service’s draft records.

  • draft_indexer_queue_name: The name of the task queue to be used by the service’s draft records indexer.

  • schema_parent: The schema used to valid parent records for the service.

  • search_drafts: A search class for searching for draft records.

  • search_versions: A search class for searching for record versions.

  • default_files_enabled: Whether files are enabled by default for the service.

  • default_media_files_enabled: Whether media files are enabled by default for the service.

  • lock_edit_published_files: Whether to lock editing of published files for the service.

  • links_search_drafts: The template for creating url links for the service’s search drafts endpoint.

  • links_search_versions: The template for creating url links for the service’s search versions endpoint.

The RDMRecordServiceConfig class adds the following additional configuration attributes:

  • max_files_count: The maximum number of files that can be attached to a record.

  • file_links_list: The list of file links for the service.

  • schema_access_settings: The schema for access settings.

  • schema_secret_link: The schema for secret links.

  • schema_grant: The schema for grants.

  • schema_grants: The schema for grants.

  • schema_request_access: The schema for request access.

  • schema_tombstone: The schema for tombstone.

  • schema_quota: The schema for quota.

Additional common configration attributes are added by inheriting from additional mixin classes.

Attaching configuration to the service

The service config class can be passed to the service’s constructor when it is instantiated during the Flask app initialization (i.e., in the init_app() method of the extension):

service = MyService(config=MyServiceConfig)

Alternatively, if the service config class inherits from the ConfiguratorMixin class, the service and its config class can be initialized like this:

service = MyService(MyServiceConfig.build(app))

File service configuration

The FileConfigMixin class (defined in invenio_records_resources.services.records.components.files) adds config class attributes for: ????

  • _files_attr_key: The attribute key for the files field.

  • _files_data_key: The attribute key for the files data.

  • _files_bucket_attr_key: The attribute key for the files bucket.

  • _files_bucket_id_attr_key: The attribute key for the files bucket ID.

Search configuration

SearchOptionsMixin

This mixin class (defined in invenio_records_resources.services.base.config) adds config class attributes for:

  • facets: The search facet definitions for searches on the service’s resource.

  • sort_options: The sort options for searches on the service’s resource.

  • sort_default: The default sort option for searches on the service’s resource.

  • sort_default_no_query: The default sort option for searches on the service’s resource when no query is present.

  • available_sort_options: The available sort options for searches on the service’s resource.

  • query_parser_cls: The query parser class to use in constructing searches on the service’s resource.

SearchConfig

The SearchConfig class (defined in invenio_records_resources.services.base.config) defines the search configuration that will be used to interface with OpenSearch.

FromConfigSearchOptions

The FromConfigSearchOptions class (defined in invenio_records_resources.services.base.config) is used to load search configuration from app config variables. In the service’s config class, it is used like this:

Loading configuration from app config variables

The FromConfig class (defined in invenio_records_resources.services.base.config) is used to load configuration from app config variables. In the service’s config class, it is used like this:

class MyServiceConfig(ServiceConfig):
    foo = FromConfig("FOO", default=1)

In the app config, the config variable is defined like this:

FOO = 2

When the service is instantiated, the FromConfig class will load the config variable from the app config and assign it to the foo attribute.

Service Components

A service component is a class that provides methods that shadow the service’s methods. When a service method is called, it passes the call through each of the service’s components (using the Service.run_components() method), allowing each component to perform additional processing before the result is returned. If the service component includes a method with the same name as the service method that is being called, its matching method will be called. During this call, the component method is passed the service method’s arguments and keyword arguments, and the service method’s modified versions of these arguments are passed on to the next component. Once all the service’s components have been called, the result is returned to the service method, which returns the final result or performs the final action.

BaseServiceComponent

The BaseServiceComponent class (defined in invenio_records_resources.services.base.components) is the base class for all service components. It provides a uow property that returns the Unit of Work manager.

This class is overridden by the ServiceComponent class (defined in invenio_records_resources.services.base.components.base), which adds the following methods:

  • create(self, identity, **kwargs): Perform additional processing while creating an item of the service’s resource.

  • read(self, identity, **kwargs): Perform additional processing while retrieving an item of the service’s resource.

  • update(self, identity, **kwargs): Perform additional processing while updating an item of the service’s resource.

  • delete(self, identity, **kwargs): Perform additional processing while deleting an item of the service’s resource.

  • search(self, identity, search, params, **kwargs): Perform additional processing while searching for items of the service’s resource.

The invenio_drafts_resources package overrides the ServiceComponent class to add methods matching the overridden RecordService methods for draft records and versioning.

  • read_draft(self, identity, draft=None): Retrieve a draft record.

  • update_draft(self, identity, data=None, record=None, errors=None): Update a draft record.

  • delete_draft(self, identity, draft=None, record=None, force=False): Delete a draft record.

  • edit(self, identity, draft=None, record=None): Edit a record.

  • new_version(self, identity, draft=None, record=None): Create a new version of a record.

  • publish(self, identity, draft=None, record=None): Publish a draft record.

  • import_files(self, identity, draft=None, record=None): Import files from previous record version.

  • post_publish(self, identity, record=None, is_published=False): Post publish handler.

RecordService Components

The invenio_records_resources package provides the following components for the RecordService class:

  • DataServiceComponent (create, update): Adds data to the record.

  • BaseRecordFilesComponent (create, update):

    • Handles enabling/disabling files for a record.

    • Handles setting the default preview file for a record.

  • MetadataComponent (create, update): Adds metadata to the new/updated record from the input data.

  • RelationsComponent (read): Dereferences a record’s related fields in order to provide the data from the related records in a read result.

  • ChangeNotificationsComponent (update): Emits a change notification for the updated record.

The invenio_drafts_resources package provides additional components for the RecordService class:

  • an overridden BaseRecordFilesComponent class that adds methods for ???

  • DraftFilesComponent: Handles files for draft records.

  • DraftMediaFilesComponent: Handles media files for draft records.

  • DraftMetadataComponent: Handles metadata for draft records.

  • PIDComponent (create, delete_draft): Handles registration of PIDs for draft records.

  • an overridden RelationsComponent class that adds a read_drafts method

The invenio_rdm_records package provides additional components for the RDMRecordService class:

  • AccessComponent(create, update_draft, publish, edit, new_version): Handles access settings for records.

  • an overridden MetadataComponent class (create, update_draft, publish, edit, new_version): Adds metadata to the new/updated record from the input data. (Removes the update method from the earlier MetadataComponent class.)

  • CustomFieldsComponent(create, update_draft, publish, edit, new_version): Adds custom fields to the metadata of a record.

  • PIDsComponent(create, update_draft, delete_draft, publish, edit, new_version, delete_record, restore_record): Handles PIDs for records.

  • ParentPIDsComponent(create, publish, delete_record, restore_record): Handles parent PIDs for records.

  • RecordDeletionComponent(delete_record, update_tombstone, restore_record, mark_record, unmark_record, purge_record): Handles deletion of records.

  • RecordFilesProcessorComponent(publish, lift_embargo): Handles file processing for records.

  • ReviewComponent(create, delete_draft, publish): Handles reviews for records.

  • SignalComponent(publish): Triggers signals on publish.

  • ContentModerationComponent(publish): Creates a moderation request if the user is not verified.

RDMRecordService Components

The invenio_rdm_records package draws its list of components from the RDM_RECORDS_SERVICE_COMPONENTS config variable. The default list is defined in the DefaultRecordsComponents class (defined in invenio_rdm_records.services.config) and currently includes:.

[
    MetadataComponent,
    CustomFieldsComponent,
    AccessComponent,
    DraftFilesComponent,
    DraftMediaFilesComponent,
    RecordFilesProcessorComponent,
    RecordDeletionComponent,
    # for the internal `pid` field
    PIDComponent,
    # for the `pids` field (external PIDs)
    PIDsComponent,
    ParentPIDsComponent,
    RelationsComponent,
    ReviewComponent,
    ContentModerationComponent,
]

Note that the order of the components in the list is important, since the components are called in the order they are listed and some components depend on the results of previous components.

InvenioRDM Record Objects

API-level Record Objects

PersistentIdentifier (invenio_records.api.PersistentIdentifier)

An object representing a persistent identifier for a record. It has the following properties:

  • pid_value: The value of the persistent identifier.

  • pid_type: The type of the persistent identifier.

  • status: The status of the persistent identifier.

  • obj_type: The type of the object the persistent identifier is for.

  • object_uuid: The UUID of the database object the persistent identifier is for.

RDMDraft (invenio_rdm_records.records.api.RDMDraft)

The RDMDraft object is a subclass of the Record object (defined in invenio_records.api.Record) and includes all of the submitted metadata values, along with the keys:

  • $schema

  • id

  • created

  • updated

  • revision_id

  • version_id

  • pid (as opposed to pids, a separate field)

  • media_files (if not present in data)

  • custom_fields (if not present in data)

Its dict has the following shape (these values are available by key and also as dot properties):

{
'$schema': 'local://records/record-v6.0.0.json',
'pid': {
    'pk': 88,
    'pid_type': 'recid',
    'status': 'N',
    'obj_type': 'rec'
},
'id': '9f06s-7d583',
'files': {
    'enabled': True
},
'media_files': {
    'enabled': True
},
'metadata': {
    'resource_type': {'id': 'image-photograph'},
    'creators': [
        {'person_or_org': {
            'type': 'personal',
            'given_name': 'Troy',
            'family_name': 'Brown',
            'name': 'Brown, Troy'}
        },
        {'person_or_org': {
            'type': 'organizational',
            'name': 'Troy Inc.'}
        }
    ],
    'title': 'A Romans story',
    'publisher': 'Acme Inc',
    'publication_date': '2020-06-01'
},
'custom_fields': {},
'access': {
    'record': 'public',
    'files': 'public'
},
'pids': {}
}

The RDMDraft also has the following properties:

  • ‘bucket’,

  • ‘bucket_id’,

  • ‘created’,

  • ‘dumper’,

  • ‘expires_at’,

  • ‘fork_version_id’,

  • ‘format_checker’,

  • ‘has_draft’,

  • ‘index’,

  • ‘is_deleted’,

  • ‘is_draft’,

  • ‘is_published’,

  • ‘media_bucket’,

  • ‘media_bucket_id’,

  • ‘model’,

  • ‘model_cls’,

  • ‘parent’,

  • ‘parent_record_cls’,

  • ‘revision_id’,

  • ‘revisions’,

  • ‘schema’,

  • ‘status’,

  • ‘updated’,

  • ‘validator’,

  • ‘versions’,

  • ‘versions_model_cls’

And the following methods (among others, including standard dict methods)

  • ‘cleanup_drafts’,

  • ‘clear’,

  • ‘clear_none’,

  • ‘commit’,

  • ‘copy’,

  • ‘dumps’,

  • ‘get_latest_by_parent’,

  • ‘get_record’,

  • ‘get_records’,

  • ‘get_records_by_parent’,

  • ‘items’,

  • ‘keys’,

  • ‘loads’,

  • ‘new_version’,

  • ‘register’,

  • ‘relations’,

  • ‘revert’,

  • ‘send_signals’,

  • ‘undelete’,

  • ‘validate’,

Creating an RDMDraft object

The RDMDraft object can be created by calling the create method on the RDMDraft class. This method takes a dictionary of data to be used to create the record and returns an RDMDraft object.

draft = RDMDraft.create({
    "metadata": {
        "title": "My Title",
        "description": "My Description"
    }
})

RDMRecord (invenio_rdm_records.records.api.RDMRecord)

The RDMRecord object is a subclass of the Record object (defined in invenio_records.api.Record).

The RDMRecord object has the following metadata properties that are available as dot properties and by key.

  • access

  • custom_fields

  • deletion_status

  • errors

  • files

  • id

  • media_files

  • metadata

  • pids

One additional key, $schema, is not available as a dot property. It provides the name of the schema used to validate the RDMRecord instance prior to publication. The actual schema object is stored in the schema property.

The object also has the following properties that are not part of the metadata and cannot be accessed by key:

  • bucket: The bucket object used to store files for the RDMRecord instance

  • bucket_id: The ID for the bucket used to store files for the RDMRecord instance

  • created: The date and time the RDMRecord instance was created

  • ‘dumper’: The dumper class for serializing RDMRecord instances to JSON (e.g., for search indexing)

  • ‘enable_jsonref’: Whether to enable JSON references ????

  • ‘format_checker’: The format checker for the RDMRecord class

  • ‘index’: The OpenSearch index for the RDMRecord class

  • is_deleted: Whether the RDMRecord instance has been deleted

  • is_draft: Whether the RDMRecord instance is a draft

  • is_published: Whether the RDMRecord instance has been published

  • media_bucket_id: The ID for the bucket used to store media files for the RDMRecord instance

  • ‘model’: The SQLAlchemy model instance providing the ORM object for the RDMRecord instance

  • ‘model_cls’: The SQLAlchemy model class providing the ORM for the RDMRecord class

  • ‘next_latest_published_record_by_parent’: The next latest published record (published version) that shares the same parent record

  • parent: The parent record for the RDMRecord instance

  • ‘pid’: The PIDs for the RDMRecord instance. This is a PersistentIdentifier object with a pid_value property which is shared by all versions of the record (both draft and published). It also has an object_uuid property which is the unique UUID for the database record behind this version of the record.

  • ‘relations’: The ORM relations for the RDMRecord instance

  • ‘revisions’: The revisions for the RDMRecord instance

  • ‘schema’: The schema used to validate the RDMRecord instance prior to publication

  • ‘revision_id’: The revision ID for the RDMRecord instance

  • ‘stats’: The stats for the RDMRecord instance

  • ‘status’: The status of the RDMRecord instance (“draft”, “published”, “deleted”, etc.)

  • tombstone

  • ‘updated’: The updated date for the RDMRecord instance

  • ‘validator’: The validator for the RDMRecord class

  • ‘versions’: The versions for the RDMRecord instance

  • ‘versions_model_cls’: The SQLAlchemy model class providing the ORM for the versions record

The RDMRecord class also has methods for operating on RDMRecord instance objects. These include:

  • ‘create’,

  • ‘get_latest_by_parent’,

  • ‘get_latest_published_by_parent’,

  • ‘get_record’,

  • ‘get_records’,

  • ‘get_records_by_parent’,

The RDMRecord object also has methods that perform actions on the record. These include:

  • ‘clear’,

  • ‘clear_none’,

  • ‘commit’,

  • ‘copy’,

  • ‘delete’,

  • ‘dumps’,

  • ‘has_draft’,

  • ‘loads’,

  • ‘parent’,

  • ‘parent_record_cls’,

  • ‘patch’,

  • ‘pop’,

  • ‘popitem’,

  • ‘publish’,

  • ‘register’,

  • ‘replace_refs’,

  • ‘revert’,

  • ‘send_signals’,

  • ‘setdefault’,

  • ‘undelete’,

  • ‘update’,

  • ‘validate’,

Since the RDMRecord object can present values as if it were a dictionary, it also has the following methods:

  • ‘keys’

  • ‘items’

  • ‘values’,

  • ‘fromkeys’,

  • ‘get’,

RDMParent (invenio_rdm_records.records.api.RDMParent)

The RDMParent object is the parent record for an RDMRecord instance. It is a subclass of the Record object (defined in invenio_records.api.Record). Note that parent records never exist without a child record. They do not represent any particular record state, but rather are used to link records together.

The RDMParent object has the following properties containing record metadata that appears in the parent field of an RDMRecord or RDMDraft instance:

| Property | Accessible by key | Description | |———-|————-| | access | Yes | Access control settings. The value is a ParentRecordAccess object with grants, links, owned_by, owner, and settings properties (among others). | | communities | Yes | Associated communities. The value is a invenio_communities.records.records.systemfields.communities.manager.CommunitiesRelationManager object with ids, default, and entries properties. (No values are accessible by key.) | | created | No | Creation timestamp | | id | Yes | Record identifier | | metadata | No | Record metadata | | pids | Yes | Public-facing persistent identifiers, including the primary DOI | | updated | No | Last updated timestamp |

The object instance also has the key $schema which is not accessible as a dot property. It provides the name of the schema used to validate the RDMRecord instance prior to publication. The actual schema object is stored in the schema property.

The RDMParent object also has the following properties that are not part of the metadata and are not included in the parent field of an RDMRecord or RDMDraft instance:

| dumper | Serialization dumper | | format_checker | Format validation checker | | is_deleted | Deletion status flag | | is_verified | Verification status flag | | model | Database model instance | | model_cls | Database model class | | permission_flags | Permission settings | | pid | Internal persistent identifier, a UUID for the parent record. | | review | Review information | | revisions | Revision history | | schema | JSON schema | | validator | Validation handler |

The RDMParent object also has the following methods:

Property

Description

clear

Method to clear record data

clear_none

Method to clear None values

commit

Method to commit changes

copy

Method to copy record

create

Method to create record

delete

Method to delete record

dumps

Method to serialize record

enable_jsonref

JSON reference flag

fromkeys

Dictionary method

get

Dictionary get method

get_record

Method to retrieve record

get_records

Method to retrieve multiple records

items

Dictionary items method

keys

Dictionary keys method

loads

Method to deserialize record

patch

Method to patch record

pop

Dictionary pop method

popitem

Dictionary popitem method

replace_refs

Method to replace references

revert

Method to revert changes

revision_id

Revision identifier

send_signals

Method to send signals

setdefault

Dictionary setdefault method

undelete

Method to undelete record

update

Method to update record

validate

Method to validate record

values

Dictionary values method

Community (invenio_communities.communities.records.api.Community)

The Community class is the api-level object for a community. It is a subclass of the Record object (defined in invenio_records.api.Record).

Unlike some Record object types, the Community object does not expose most its values as dictionary keys. But it exposes several dot properties. Some of these provide the data that is included in the serialized and projected forms of the community’s data (in the search index and service layer responses):

  • ‘access’

  • ‘children’

  • ‘created’

  • ‘custom_fields’

  • ‘deletion_status’

  • ‘files’

  • ‘id’

  • ‘is_deleted’

  • ‘is_verified’

  • ‘metadata’

  • ‘parent’

  • ‘pid’

  • ‘slug’

  • ‘theme’

  • ‘updated’

Other properties are provided for internal manipulation and management of the Community object:

  • ‘bucket’

  • ‘bucket_id’

  • ‘dumper’

  • ‘format_checker’

  • ‘index’

  • ‘model’

  • ‘model_cls’

  • ‘relations’

  • ‘revision_id’

  • ‘revisions’

  • ‘schema’

  • ‘tombstone’

  • ‘validator’

The Community object also provides the following methods:

  • ‘clear’

  • ‘clear_none’

  • ‘commit’

  • ‘copy’

  • ‘create’

  • ‘delete’

  • ‘dumps’

  • ‘enable_jsonref’

  • ‘fromkeys’

  • ‘get’

  • ‘items’

  • ‘keys’

  • ‘loads’

  • ‘patch’

  • ‘pop’

  • ‘popitem’

  • ‘replace_refs’

  • ‘revert’

  • ‘send_signals’

  • ‘setdefault’

  • ‘undelete’

  • ‘update’

  • ‘validate’

  • ‘values’

CommunitiesRelationManager (invenio_communities.records.records.systemfields.communities.manager.CommunitiesRelationManager)

The CommunitiesRelationManager object is the manager for the communities field of the RDMParent object. It exposes dot properties including:

  • default: The default community for the record (a Community object).

  • entries: A list of Community objects.

  • ids: A list of community IDs (string UUIDs, not slugs).

Service-level Response Objects

RecordItem (invenio_records_resources.services.records.results.RecordItem)

The RecordItem object is the service-level response object for a record, used for individual results from the RDMRecordService. It is returned by service methods like current_rdm_records_service.read() or current_rdm_records_service.search().

The RecordItem object has the following properties:

Property

Type

Description

_data

dict

The _data property does not return the same dictionary as the to_dict() method. It appears to be None for published records.

_errors

list

Any validation errors

_expand

dict

The expand options for the record

_fields_resolver

dict

The fields resolver for the record

_identity

dict

The identity for the record

_links_tpl

dict

The links template for the record

_nested_links_item

dict

The nested links item for the record

_obj

dict

The object for the record

_record

invenio_rdm_records.records.api.RDMRecord

The underlying api-level RDMRecord record object

_schema

dict

The schema for the record

_service

invenio_rdm_records.services.RDMRecordService

The service for the record

data

dict

The record data represented as a dictionary. This is the same dictionary returned by the to_dict() method.

errors

list

Any validation errors

has_permissions_to

dict

Permission checks

id

str

The record identifier

links

dict

Related URLs. The same as the links property of the _record object and the “links” value of the data dictionary.

The RecordItem object also has the to_dict() method, which returns a representation of the record as a dictionary. For a published record, the to_dict() method returns a dictionary with the following shape:

{'access': {'embargo': {'active': False, 'reason': None},
            'files': 'public',
            'record': 'public',
            'status': 'metadata-only'},
 'created': '2025-03-19T20:49:34.391191+00:00',
 'custom_fields': {},
 'deletion_status': {'is_deleted': False, 'status': 'P'},
 'files': {'count': 0,
           'enabled': False,
           'entries': {},
           'order': [],
           'total_bytes': 0},
 'id': 'q2cae-anf51',
 'is_draft': False,
 'is_published': True,
 'links': {'access': 'https://localhost/api/records/q2cae-anf51/access',
           'access_grants': 'https://localhost/api/records/q2cae-anf51/access/grants',
           'access_groups': 'https://localhost/api/records/q2cae-anf51/access/groups',
           'access_links': 'https://localhost/api/records/q2cae-anf51/access/links',
           'access_request': 'https://localhost/api/records/q2cae-anf51/access/request',
           'access_users': 'https://localhost/api/records/q2cae-anf51/access/users',
           'archive': 'https://localhost/api/records/q2cae-anf51/files-archive',
           'archive_media': 'https://localhost/api/records/q2cae-anf51/media-files-archive',
           'communities': 'https://localhost/api/records/q2cae-anf51/communities',
           'communities-suggestions': 'https://localhost/api/records/q2cae-anf51/communities-suggestions',
           'doi': 'https://handle.stage.datacite.org/10.17613/q2cae-anf51',
           'draft': 'https://localhost/api/records/q2cae-anf51/draft',
           'files': 'https://localhost/api/records/q2cae-anf51/files',
           'latest': 'https://localhost/api/records/q2cae-anf51/versions/latest',
           'latest_html': 'https://localhost/records/q2cae-anf51/latest',
           'media_files': 'https://localhost/api/records/q2cae-anf51/media-files',
           'parent': 'https://localhost/api/records/hkz47-g3q07',
           'parent_doi': 'https://localhost/doi/10.17613/hkz47-g3q07',
           'parent_html': 'https://localhost/records/hkz47-g3q07',
           'requests': 'https://localhost/api/records/q2cae-anf51/requests',
           'reserve_doi': 'https://localhost/api/records/q2cae-anf51/draft/pids/doi',
           'self': 'https://localhost/api/records/q2cae-anf51',
           'self_doi': 'https://localhost/doi/10.17613/q2cae-anf51',
           'self_html': 'https://localhost/records/q2cae-anf51',
           'self_iiif_manifest': 'https://localhost/api/iiif/record:q2cae-anf51/manifest',
           'self_iiif_sequence': 'https://localhost/api/iiif/record:q2cae-anf51/sequence/default',
           'versions': 'https://localhost/api/records/q2cae-anf51/versions'},
 'media_files': {'count': 0,
                 'enabled': False,
                 'entries': {},
                 'order': [],
                 'total_bytes': 0},
 'metadata': {'creators': [{'person_or_org': {'family_name': 'Brown',
                                              'given_name': 'Troy',
                                              'name': 'Brown, Troy',
                                              'type': 'personal'}},
                           {'person_or_org': {'name': 'Troy Inc.',
                                              'type': 'organizational'}}],
              'publication_date': '2020-06-01',
              'publisher': 'Acme Inc',
              'resource_type': {'id': 'image-photograph',
                                'title': {'en': 'Photo'}},
              'title': 'A Romans story'},
 'parent': {'access': {'grants': [],
                       'links': [],
                       'owned_by': {'user': '1'},
                       'settings': {'accept_conditions_text': None,
                                    'allow_guest_requests': False,
                                    'allow_user_requests': False,
                                    'secret_link_expiration': 0}},
            'communities': {'default': '00c10e5a-cfb6-4c4d-ab7e-3894b5930181',
                            'entries': [{'access': {'member_policy': 'open',
                                                    'members_visibility': 'public',
                                                    'record_policy': 'open',
                                                    'review_policy': 'open',
                                                    'visibility': 'public'},
                                         'children': {'allow': False},
                                         'created': '2025-03-19T20:49:33.284511+00:00',
                                         'custom_fields': {},
                                         'deletion_status': {'is_deleted': False,
                                                             'status': 'P'},
                                         'id': '00c10e5a-cfb6-4c4d-ab7e-3894b5930181',
                                         'links': {},
                                         'metadata': {'curation_policy': 'Curation '
                                                                         'policy',
                                                      'description': 'A '
                                                                     'description',
                                                      'organizations': [{'name': 'Organization '
                                                                                 '1'}],
                                                      'page': 'Information for '
                                                              'my community',
                                                      'title': 'My Community',
                                                      'type': {'id': 'event'},
                                                      'website': 'https://my-community.com'},
                                         'revision_id': 2,
                                         'slug': 'my-community',
                                         'updated': '2025-03-19T20:49:33.452355+00:00'}],
                            'ids': ['00c10e5a-cfb6-4c4d-ab7e-3894b5930181']},
            'id': 'hkz47-g3q07',
            'pids': {'doi': {'client': 'datacite',
                             'identifier': '10.17613/hkz47-g3q07',
                             'provider': 'datacite'}}},
 'pids': {'doi': {'client': 'datacite',
                  'identifier': '10.17613/q2cae-anf51',
                  'provider': 'datacite'},
          'oai': {'identifier': 'oai:https://localhost:q2cae-anf51',
                  'provider': 'oai'}},
 'revision_id': 3,
 'stats': {'all_versions': {'data_volume': 0.0,
                            'downloads': 0,
                            'unique_downloads': 0,
                            'unique_views': 0,
                            'views': 0},
           'this_version': {'data_volume': 0.0,
                            'downloads': 0,
                            'unique_downloads': 0,
                            'unique_views': 0,
                            'views': 0}},
 'status': 'published',
 'updated': '2025-03-19T20:49:34.451290+00:00',
 'versions': {'index': 1, 'is_latest': True, 'is_latest_draft': True}}

CommunityItem (invenio_communities.records.api.CommunityItem)

The CommunityItem object is the service-level response object for a community. It is returned by service methods like current_communities.service.read() or current_communities.service.search().

The CommunityItem object has the following properties:

Property

Type

Description

_record

invenio_communities.records.api.Community

The underlying api-level Community record object

data

dict

The record data as a dictionary

errors

list

Any validation errors

has_permissions_to

dict

Permission checks

id

str

The record identifier

links

dict

Related URLs. The same as the links property of the _record object and the “links” value of the data dictionary.

Its data property is a dictionary identical to the to_dict() method’s return value. It has the following shape:

{
    'id': '6bcba8b1-f967-4175-9557-c71dea07c8e7',
    'created': '2025-03-19T19:18:48.550894+00:00',
    'updated': '2025-03-19T19:18:48.643023+00:00',
    'links': {
        'featured': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/featured',
        'self': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7',
        'self_html': 'https://localhost/collections/my-community',
        'settings_html': 'https://localhost/collections/my-community/settings',
        'logo': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/logo',
        'rename': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/rename',
        'members': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/members',
        'public_members': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/members/public',
        'invitations': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/invitations',
        'requests': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/requests',
        'records': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/records',
        'membership_requests': 'https://localhost/api/communities/6bcba8b1-f967-4175-9557-c71dea07c8e7/membership-requests'
    },
    'revision_id': 2,
    'slug': 'my-community',
    'metadata': {
        'title': 'My Community',
        'description': 'A description',
        'curation_policy': 'Curation policy',
        'page': 'Information for my community',
        'type': {
            'id': 'event',
            'title': {'en': 'Event'}
        },
        'website': 'https://my-community.com',
        'organizations': [{'name': 'Organization 1'}]
    },
    'access': {
        'visibility': 'public',
        'members_visibility': 'public',
        'member_policy': 'open',
        'record_policy': 'open',
        'review_policy': 'open'
    },
    'custom_fields': {},
    'deletion_status': {
        'is_deleted': False,
        'status': 'P'
    },
    'children': {'allow': False}
}

Its to_dict() method returns a dictionary with the same shape as the data property.