Skip to content
This repository has been archived by the owner on May 10, 2023. It is now read-only.

tutorial 11: no such command 'records'. #74

Open
diegodelemos opened this issue May 13, 2020 · 5 comments
Open

tutorial 11: no such command 'records'. #74

diegodelemos opened this issue May 13, 2020 · 5 comments
Labels

Comments

@diegodelemos
Copy link
Member

Problem
Tutorial 11 relies on creating records with references using the invenio records CLI. However, Invenio-Records CLI has been remove in version 1.3.0.

Solution
Modify tutorial to enable the creation of linked records through the REST API.

@ppanero
Copy link
Member

ppanero commented May 13, 2020

To use the REST API, we would have to change the loaders, since the author field is not defined

diegodelemos pushed a commit to topless/training that referenced this issue May 15, 2020
* blocker: `pipenv run invenio records` was removed from `invenio-records` reform STEP 5
  - markdown lint
  - ES7 mappings
  - child of inveniosoftware#50

* Added warning (addresses inveniosoftware#74).
diegodelemos pushed a commit to topless/training that referenced this issue May 15, 2020
* blocker: `pipenv run invenio records` was removed from `invenio-records` reform STEP 5
  - markdown lint
  - ES7 mappings
  - child of inveniosoftware#50

* Added warning (addresses inveniosoftware#74).
diegodelemos pushed a commit to topless/training that referenced this issue May 15, 2020
* blocker: `pipenv run invenio records` was removed from `invenio-records` reform STEP 5
  - markdown lint
  - ES7 mappings
  - child of inveniosoftware#50

* Added warning (addresses inveniosoftware#74).
@ZedThree
Copy link

ZedThree commented Jul 8, 2022

How exactly do the loaders need to be changed? Is it it just the author field needs adding to records.marshmallow.json.MetadataSchemaV1? What kind of field should it be?

Presumably there's also something that needs doing to the deposit form to find and link the authors?

@ZedThree
Copy link

A minimal change to create the record using the REST API appears to be:

modified   my_site/records/marshmallow/json.py
@@ -8,7 +8,7 @@
 """JSON Schemas."""
 
 from invenio_jsonschemas import current_jsonschemas
-from invenio_records_rest.schemas import Nested, StrictKeysMixin
+from invenio_records_rest.schemas import Nested, StrictKeysMixin, RecordMetadataSchemaJSONV1
 from invenio_records_rest.schemas.fields import DateString, GenFunction, \
     PersistentIdentifier, SanitizedUnicode
 from marshmallow import fields, missing, validate
@@ -54,7 +54,7 @@ class ContributorSchemaV1(StrictKeysMixin):
     email = fields.Email()
 
 
-class MetadataSchemaV1(StrictKeysMixin):
+class MetadataSchemaV1(RecordMetadataSchemaJSONV1):
     """Schema for the record metadata."""
 
     id = PersistentIdentifier()

Which allows creation with:

curl -k --header Content-Type: application/json \
  --request POST \
  --data {"author": { "$ref": "https://my-site.com/api/resolver/author/1" }, \
     "title": "Invenio is awesome", "contributors": [{"name": "Kent, Clark"}], \
    "owner": 1}
  https://127.0.0.1:5000/api/records/?prettyprint=1

If I'm understanding how this works correctly, StrictKeysMixin will fail because author is not defined in MetadataSchemaV1, while RecordMetadataSchemaJSONV1 just passes along any keys it doesn't recognise.

However, retrieving the record doesn't include the author in the REST API:

$ curl -ks https://localhost:5000/api/records/2?prettyprint=1
{
  "id": "2", 
  "links": {
    "files": "https://localhost:5000/api/records/2/files", 
    "self": "https://localhost:5000/api/records/2"
  }, 
  "metadata": {
    "contributors": [
      {
        "name": "Kent, Clark"
      }
    ], 
    "id": "2", 
    "owner": 1, 
    "pid": "2", 
    "title": "Invenio is awesome"
  }, 
  "revision": 0, 
  "updated": "2022-07-11T09:42:17.536711+00:00"

and in the web view, author is there but it doesn't get resolved:
image

So, has this just moved the problem onto the mapping? Sticking a print(record) into record_jsonresolver, I can see that it is correctly resolving the author when the record is retrieved via the REST API, though not through the web interface.

@ZedThree
Copy link

Further investigation reveals that searching for author.name in /api/records/ works with the above change, it's just the serialisation where it disappears.

I looked into that further, and the author reference does get resolved when access via REST, but marshmallow removes it, I guess because it's not in MetadataSchemaV1. The web interface doesn't call the resolver at all.

I've been looking at invenio-app-ils as an example that has links between data models, and I can't see how that handles anything differently, except for the change I suggest above.

Is this the expected behaviour?

@ZedThree
Copy link

I think I have something working, I'm just not sure if it's sensible:

modified   my_site/records/config.py
@@ -66,6 +66,7 @@ RECORDS_UI_ENDPOINTS = dict(
         route='/records/<pid_value>',
         template='records/record.html',
         record_class='invenio_records_files.api:Record',
+        view_imp="my_site.records.views:record_view",
     ),
     recid_previewer=dict(
         pid_type='recid',
modified   my_site/records/marshmallow/json.py
@@ -63,6 +63,7 @@ class MetadataSchemaV1(StrictKeysMixin):
     publication_date = DateString()
     contributors = Nested(ContributorSchemaV1, many=True, required=True)
     owner = fields.Integer()
+    author = fields.Dict()
     _schema = GenFunction(
         attribute="$schema",
         data_key="$schema",
modified   my_site/records/views.py
@@ -12,6 +12,7 @@ from os.path import splitext
 
 from flask import Blueprint
 from invenio_previewer.proxies import current_previewer
+from invenio_records_ui.views import default_view_method
 
 blueprint = Blueprint(
     'my_site_records',
@@ -46,3 +47,6 @@ def select_preview_file(files):
     except KeyError:
         pass
     return selected
+
+def record_view(pid, record, template=None, **kwargs):
+    return default_view_method(pid, record.replace_refs(), template, **kwargs)

Instead of using RecordMetadataSchemaJSONV1, we still use StrictKeysMixin, but add a field for the author that's just fields.Dict(), so we don't need to define its schema. This allows us to both create a record with an author reference, and also allows us to view the resolved author in the record REST API.

The other half is to add a custom view that just calls the default view but passes record.replace_refs() which resolves the references.

If this seems like a sensible solution, I'd be happy to make a PR adding this to the tutorial. If not, I'd really appreciate some pointers on how to fix this properly!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants