Uploading a 3D model file via the API

I am using the Python omeka_s_tools module to attach a media file to an item using the Omeka S API. My code successfully attaches a JPEG to an existing item, but when I try attaching a .glb 3D model file, the file is uploaded, but the resulting file within files/original on the server has the extension “.bin” instead of “.glb” and it does not render on the item page. (We are using the ModelViewer module to render the 3D images.)

I am not doing anything to tell Omeka the MIME type of the file when I upload. Does this matter? I am pretty sure that our Apache does not know what a “.glb” file is anyway.

I’m not sure whether the problem is to do with how I am uploading the file using the API, or whether there is something missing in ModelViewer which means that .glb file upload via the API results in a .bin file being saved.

Note that uploading a “.glb” file manually in the Omeka admin interface works fine. When I check the metadata about the media using the API, the only difference I can see between the version uploaded via API and the version attached manually is the filename extension. In both cases the o:media-type is application/octet-stream.

Here is the code I am using to upload the two files:

from omeka_s_tools.api import OmekaAPIClient

omeka_base = 'https://server.host.name.here/omeka-s'

omeka = OmekaAPIClient(
    api_url = f"{omeka_base}/api",
    key_identity = 'xxxxxxxxxxxxx',
    key_credential = 'yyyyyyyyyyyyyyy'
    )


def attach_media(id, file):
    media = {
        "@context": f"{omeka_base}/api-context",
        "@type": "o:Media",
        "o:is_public": True,
        "o:ingester": "upload",
        "o:renderer": "file",
        "o:item": {
            "@id": f"{omeka_base}/api/items/{id}",
            "o:id": id
        },
        "o:source": file
    }

    omeka.add_media_to_item(id, file, media)


attach_media(28097, '3DModels/JPEG_example_flower.jpg')
attach_media(28097, '3DModels/Wansunt_P1971_6_1_104.glb')

Well, this is weird. I found an old posting about how to upload files using Python which happens to have been written by @wragge who is the author of the Omeka S Tools Python library. By following his example I have managed to upload a “.glb” file successfully using this code. Note that the final line deliberately gives the MIME type of the file incorrectly as image/jpg which proves that the MIME type declared does not matter at all in terms of determining the file extension to use when saving.

I’m rather surprised. I will have to check the omeka_s_tools code next to see what the differences are!

import requests
import json

omeka_base = 'https://server.host.name.here/omeka-s'

auth = {
    'key_identity': 'xxxxxxxxxx',
    'key_credential': 'yyyyyyyyyyyy'
    }

session = requests.Session()


def attach_media(id, file, type):
    media = {
        "o:ingester": "upload",
        "o:item": {
            "@id": f"{omeka_base}/api/items/{id}",
            "o:id": id
        },
        "file_index": "0"
    }

    files = [
        ('data', (None, json.dumps(media), 'application/json')),
        ('file[0]', (file, open(file, 'rb'), type))
        ]

    res = session.post(f"{omeka_base}/api/media", params=auth, files=files)


attach_media(28090, '3DModels/JPEG_example_flower.jpg', 'image/jpg')
attach_media(28090, '3DModels/Wansunt_P1971_6_1_104.glb', 'image/jpeg')

At any rate, it proves it is nothing to do with the ModelViewer module.