oarepo-references

OArepo module for tracking and updating references in Invenio records


License
MIT
Install
pip install oarepo-references==2.0.0a1

Documentation

OArepo references

OArepo module for tracking and updating references in Invenio records

Installation

To use this module in your Invenio application, run the following in your virtual environment:

    pip install oarepo-references

Prerequisites

This module expects a canonical_url field present on your Record model. This field should contain a full canonical url reference to the Record instance, e.g.

class Record(FilesRecord):
    @property
    def canonical_url(self):
        return url_for('invenio_records_rest.recid_item',
                       pid_value=self['pid'], _external=True)

Types of reference

This module considers the following two types of reference that can occur the referencing objects:

Reference by link

Reference to another object is represented in the referencing object's metadata as a canonical_url of the referenced object, e.g:

{
...
  "links": {
    "attachments": "https://example.org/objects/M249/attachments",
    "self": "https://example.org/objects/M249",
    "works": "https://example.org/objects/M249/works"
  }
}

Inlined reference

The actual metadata content of the referenced object are inlined into the referencing object's metadata, e.g:

{
  ...
    "stylePeriod": {
        "id":	123,
        "level": 1,
        "links": {…},
        "path": "/novovek-moderni-doba",
        "slug":	"novovek-moderni-doba",
        "startYear": 1789,
        "title": […],
        "tooltip": ""
    }
}

In the example above, the complete metadata of a certain Taxonomic record are inlined into the stylePeriod field of the referencing object.

Usage

To enable reference tracking on your data model objects, you will need to do the following:

  • Tell Marshmallow, which fields of your marshmallow schema contain references by link by inheriting ReferenceByLinkFieldMixin:
class URLReferenceField(ReferenceByLinkFieldMixin, URL):
    """URL reference marshmallow field."""
  • If your Marshmallow Scheme holds inlined references, you will need to define a custom nested schema for inlined reference contents, that implements ref_url that returns an URL to be used as a reference to the object and inherits from InlineReferenceMixin, like this:
class InlinedReferenceSchema(InlineReferenceMixin, Schema):
    """Inlined reference schema."""
    class Meta:
        unknown = INCLUDE

    def ref_url(self, data):
        return data.get('links').get('self')

    def ref_uuid(self, data):
        return data.get('id', None)
  • Use the reference-enabled field in your Marshmallow schema:
class ExampleReferencesSchema(Schema):
    """Reference to other objects schema."""
    link = URLReferenceField()
    inlined = Nested(InlinedReferenceSchema)
  • Inherit your Record model from the ReferenceEnabledRecordMixin and MarshmallowValidatedRecordMixin. Doing so, will add support for automatic Record updates whenever some reference contained in Record metadata changes:
class ExampleRecord(MarshmallowValidatedRecordMixin,
                    ReferenceEnabledRecordMixin,
                    Record):
    """References enabled example record class."""
    MARSHMALLOW_SCHEMA = ExampleReferencesSchema
    VALIDATE_MARSHMALLOW = True
    VALIDATE_PATCH = True

    @property
    def canonical_url(self):
        return url_for('invenio_records_rest.recid_item',
                       pid_value=self['pid'], _external=True)

Signals

This module will register the following signal handlers on the Invenio Records signals that handle managing of reference records whenever a Record changes:

Invenio Records signal Registered signal handler Description
after_record_insert create_references_record Finds all references to other objects in a Record and creates RecordReference entries for each reference
after_record_update update_references_record Updates all RecordReferences that refer to the updated object and reindexes all referring Records
after_record_delete delete_references_record Deletes all RecordReferences referring to the deleted Record

Module API

You can access all the API functions this module exposes through the current_references proxy. For more info, see api.py.

Tasks

An asynchronous (Celery) tasks could be launched in a group on all objects referring to a certain Record like this:

from oarepo_references.utils import run_task_on_referrers

run_task_on_referrers(referred,
                      task.s(),
                      success_task.s(),
                      error_task.s())

Further documentation is available on https://oarepo-references.readthedocs.io/