[GeoNetwork-users] Update metadata record through records API using Python

Due to using the wrong email alias this wasn't delivered back to the
mailing list as intended earlier.

Thanks so much for your help Jo, it's working! I got it to work with your
pointers using the "batchediting" path. I'll try to be as concise as
possible:

class MetaDataRecord:
    def __init__(self) -> None:
        # You need to set
        self.portal = 'http://localhost:8080'
        self.catalogue_user = 'my_gn_user_account'
        self.catalogue_password = 'some_secret'
        self.record_id = '00000000-0000-0000-0000-000000000000'

    def update(self, version: str) -> None:
        session = requests.Session()
        session.auth = HTTPBasicAuth(self.catalogue_user,
self.catalogue_password)

        # Start an authenticated post to fetch the XSFR-TOKEN
        me_url = self.portal + '/srv/eng/info?type=me'
        session.post(me_url)
        session.headers.update({'X-XSRF-TOKEN': session.cookies.get('XSRF-
TOKEN')})

        # Do the actual login
        login_response = session.post(me_url)
        assert login_response.status_code == 200, f"Error authenticating
with server {self.portal}: " \
                                                  f"response
{login_response.status_code}"

        params = {
            'uuids': [self.record_id],
            'bucket': 'be101',
            'updateDateStamp': True,
        }
        session.headers.update({'Content-Type': 'application/json'})
        session.headers.update({'Accept': 'application/json'})
        update_url = f"{self.portal}/geonetwork/
api/0.1/records/batchediting"
        # Take care here: non-matched xpaths are not exactly easy to debug
        edition_xpath = '/mdb:MD_Metadata/mdb:identificationInfo/mri:MD_
DataIdentification/mri:citation/cit:CI_Citation/cit:
edition/gco:CharacterString'

        payload = json.dumps([{"xpath": edition_xpath, "value": version}])
        response = session.put(url=update_url, params=params, data=payload)

        assert response.status_code == 201, f'Error updating record: status
code {response.status_code}'

I hope this brings across the gist of the operation. Please check whether
the xpath matches for your purpose: we use the 'edition' metadata element
to store our data version info (perhaps there is a better one, but this is
fine I guess).

There was one thing I noticed though: you need to pay exceptional care to
what the response json contains. Whether you try to update existing or
non-existing xpaths, it will give you a 201 response regardless. Inspection
of the response json on having some kind of content is prudent. A
successful update will contain something like:

"metadataInfos":{"150":[{"message":"Metadata updated.","date":"2020-10-
16T15:27:37"}]}

amongst a host of other keys and values. On a bad xpath, you will get
something like
"metadataInfos":{}
So an empty 'metadataInfos' value for a mismatched xpath. So apart from the
response status assertion, you may want to parse the response json and
check that the 'metadataInfos' value contains at least one key.

Kind regards and all the kudos to Jo,
Rein