KCWorks Architecture¶
InvenioRDM’s Layered Architecture¶
InvenioRDM employs a layered architecture with:
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.
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.
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 aServiceSchemaWrapper
instance.A
record_cls
property that returns the record class for the service.A
links_item_tpl
property that returns aLinksTemplate
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 overriddenRecordService
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 aNotImplementedError
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 theRecordService
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 aninclude_deleted
argument to the read method, and a check for theread_deleted
permission if it is set toTrue
.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 thecommunities
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 aSearchOptions
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 aread_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 theupdate
method from the earlierMetadataComponent
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 topids
, a separate field)media_files
(if not present indata
)custom_fields
(if not present indata
)
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 instancebucket_id
: The ID for the bucket used to store files for the RDMRecord instancecreated
: 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 deletedis_draft
: Whether the RDMRecord instance is a draftis_published
: Whether the RDMRecord instance has been publishedmedia_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 apid_value
property which is shared by all versions of the record (both draft and published). It also has anobject_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 |
---|---|
|
Method to clear record data |
|
Method to clear None values |
|
Method to commit changes |
|
Method to copy record |
|
Method to create record |
|
Method to delete record |
|
Method to serialize record |
|
JSON reference flag |
|
Dictionary method |
|
Dictionary get method |
|
Method to retrieve record |
|
Method to retrieve multiple records |
|
Dictionary items method |
|
Dictionary keys method |
|
Method to deserialize record |
|
Method to patch record |
|
Dictionary pop method |
|
Dictionary popitem method |
|
Method to replace references |
|
Method to revert changes |
|
Revision identifier |
|
Method to send signals |
|
Dictionary setdefault method |
|
Method to undelete record |
|
Method to update record |
|
Method to validate record |
|
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 (aCommunity
object).entries
: A list ofCommunity
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 |
---|---|---|
|
|
The |
|
|
Any validation errors |
|
|
The expand options for the record |
|
|
The fields resolver for the record |
|
|
The identity for the record |
|
|
The links template for the record |
|
|
The nested links item for the record |
|
|
The object for the record |
|
|
The underlying api-level |
|
|
The schema for the record |
|
|
The service for the record |
|
|
The record data represented as a dictionary. This is the same dictionary returned by the |
|
|
Any validation errors |
|
|
Permission checks |
|
|
The record identifier |
|
|
Related URLs. The same as the |
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 |
---|---|---|
|
|
The underlying api-level |
|
|
The record data as a dictionary |
|
|
Any validation errors |
|
|
Permission checks |
|
|
The record identifier |
|
|
Related URLs. The same as the |
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.