Creating and modifying hierarchical metadata programmatically with Cantemo Portal

As of Cantemo Portal 2.2, we can now create hierarchical metadata fields in the system. Obviously when we have large data sets, this may be uncomfortable to do by hand. Luckily, there is a REST API that allows us to create, delete, and update metadata hierarchies.

To get IDs on fields we know are hierarchy fields, call this

curl -H accept:application/json -u admin:admin http://<cantemoserver>/API/v2/metadata-schema/fields/<hierarchy_portal_mf_id>/hierarchy/ | python -m json.tool

That’ll dump out JSON for you

{
    "meta": {
        "first_on_page": 1,
        "has_next": false,
        "has_other_pages": false,
        "has_previous": false,
        "hits": 1,
        "last_on_page": 1,
        "next": 2,
        "page": 1,
        "pages": 1,
        "previous": 0,
        "results_per_page": 100
    },
    "objects": [
        {
            "display_type": "LOOKUP",
            "external_id": null,
            "id": 1,
            "label": "Root Field Label",
            "level": 0,
            "name": "Root Field Name",
            "parent_id": null,
            "path": []
        }
    ]
}

Now I know my ID and I can get children on the root ID

curl -H accept:application/json -u admin:admin http://<cantemoserver>/API/v2/metadata-schema/fields/<hierarchy_portal_mf_id>/hierarchy/1/children/ | python -m json.tool

Which gives me all the children on that node

{
    "meta": {
        "first_on_page": 1,
        "has_next": false,
        "has_other_pages": false,
        "has_previous": false,
        "hits": 69,
        "last_on_page": 69,
        "next": 2,
        "page": 1,
        "pages": 1,
        "previous": 0,
        "results_per_page": 100
    },
    "object": {
        "display_type": "LOOKUP",
        "external_id": null,
        "id": 1,
        "label": "Root Field Label",
        "level": 0,
        "name": "Root Field Name",
        "parent_id": null,
        "path": []
    },
    "objects": [
        {
            "display_type": "LOOKUP",
            "external_id": null,
            "id": 505,
            "label": "Child 1 Label",
            "level": 1,
            "name": "Child 1 Name",
            "parent_id": 1,
            "path": [
                {
                    "id": 1,
                    "label": "Root Field Label",
                    "name": "Root Field Name"
                }
            ]
        },
        {
            "display_type": "LOOKUP",
            "external_id": null,
            "id": 5,
            "label": "Child 2 Label",
            "level": 1,
            "name": "Child 2 Name",
            "parent_id": 1,
            "path": [
                {
                    "id": 1,
                    "label": "Root Field Label",
                    "name": "Root Field Name"
                }
            ]
        }
    }
}

Now that I know a bunch of node IDs, I can post in to create a new one

curl -X POST -H content-type:application/json -H accept:application/json -u admin:admin http://<cantemoserver>/API/v2/metadata-schema/fields/<hierarchy_portal_mf_id>/hierarchy/ --data-binary '{"name":"test","label":"test","parent_id":1}' | python -m json.tool

Which again gives me a success JSON (or an error if you mess up)

{
    "display_type": "LOOKUP",
    "external_id": null,
    "id": 2075,
    "label": "test",
    "level": 1,
    "name": "test",
    "parent_id": 1,
    "path": [
        {
            "id": 1,
            "label": "Root Field Label",
            "name": "Root Field Name"
        }
    ]
}

If you want to update an existing node rather than create one, you use the PUT method on that node ID itself.

curl -X POST -H content-type:application/json -H accept:application/json -u admin:admin http://<cantemoserver>/API/v2/metadata-schema/fields/<hierarchy_portal_mf_id>/hierarchy/2075/ --data-binary '{"name":"test2","label":"test2","parent_id":1}' | python -m json.tool

On success, this also returns the JSON of my node with its updated information (or an error if I screwed up)

{
    "display_type": "LOOKUP",
    "external_id": null,
    "id": 2075,
    "label": "test2",
    "level": 1,
    "name": "test2",
    "parent_id": 1,
    "path": [
        {
            "id": 1,
            "label": "Root Field Label",
            "name": "Root Field Name"
        }
    ]
}