Upload a file using REST API

Hello !
How to upload a file using API? I tried to follow [Omeka 2 documentation] (http://omeka.readthedocs.io/en/latest/Reference/api/resources/files.html) but I get this error:
{"errors":{"error":"The API does not support the \u0022files\u0022 resource."}}

//Base URL
$apiUrl="http://localhost/omeka-s/api";
$apiUrl.="/files";
$apiUrl.="?key_identity=XXX&key_credential=YYY";

$data = [];
$data['data']=$item; //$item is JSon string got from GET request using API
$data['test_file'] = new CURLFile('test.txt','text/plain','myFile');

$options=[
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POSTFIELDS => $data,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => ['Content-Type: multipart/form-data']
];

$ch = curl_init($apiUrl);
curl_setopt_array($ch, $options);
$result=curl_exec($ch);
curl_close($ch);

var_dump($result);

Is my code wrong or Omeka S does not support file upload via REST API yet?

I got it working like this:


> curl -F 'file[0]=@/home/store/img.jpg' -F 'data={"o:ingester": "upload", "file_index": "0", "o:item": {"o:id": "11"}}' 'http://localhost:8080/api/media?key_identity=hTHRcFByROlLsO5X2On9orAAwIrKqx6E&key_credential=Zcks0DyoYDGv0ZIyYxscuD5ATYoNZz6L'

This adds image to an item 11.

1 Like

Than you for your help.
Indeed, using ‘/media’ instead of ‘/files’ seems to be better. However I still have an issue: the result is now only false.
My PHP file and the curl command you give return the same result false without other explanation.

I just tried to change o:id value and file_index value.

Can you explain me how to correctly set JSon properties and values, please?

Note that file must be in array:
file[0]=@/your_file
not
file=@/your_file

Otherwise you get false.

Yes, I’ve seen, but it does not work anyway (return ‘false’).
My command:

curl -F 'file[0]=@/home/pols12/java0.log' -F 'data={"o:ingester": "upload", "file_index": "0", "o:item": {"o:id": "8"}}' 'http://localhost/omeka-s/api/media?key_identity=XXX&key_credential=YYY'

Strange, I tried with your curl and it worked. If you can make other queries to that address normally, then I have no idea what could be wrong.

How stupid I am!

I have solved my problem: the ‘log’ file extension was not in ‘allowed file extension’ list (in admin settings). My bad!
Thank you a lot for your help! :slight_smile:

So, this is my well-working PHP code:

$apiUrl="http://localhost/omeka-s/api";
$apiUrl.="/media";
$apiUrl.="?key_identity=XXX&key_credential=YYY";

$data = [];
$itemId=7;
$array=[
    "o:ingester"=> "upload",
    "file_index"=> "0",
    "o:item"=> ["o:id" => $itemId] 
    ];
$data['data']=json_encode($array);
$data['file[0]'] = new CURLFile('test.txt','text/plain','newFileName');
// Note that the value must be a string, not an array (CURLFile objects are
//automatically parsed into String) so you must set the key as 'file[0]'

$options=[
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POSTFIELDS => $data,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_HTTPHEADER => ['Content-Type: multipart/form-data']
    ];

$ch = curl_init($apiUrl);
curl_setopt_array($ch, $options);
$result=curl_exec($ch);
curl_close($ch);

var_dump($result);

Ah, I see. A little bit more detailed error message from Omeka would be handy :slight_smile:

Yes, there’s a problem at work here causing just the “false” return. We should be returning a more understandable error in this case, and we’re looking into why that’s not the case.

This problem (of the error not being properly reported through the API) is now fixed in the develop branch, and so will be fixed in the next beta release.

2 Likes

Great, thanks!

Reports nicely:
{"errors":{"upload":["Error ingesting \u0022Aleo-Regular.woff\u0022. Cannot store files with the media type \u0022application\/octet-stream\u0022.","Error ingesting \u0022Aleo-Regular.woff\u0022. Cannot store files with the resolved extension \u0022woff\u0022."]}}

However, I can upload files like “model.wapiti” and csv files even though they are not listed in allowed extensions?

What’s happening with CSV probably is that we’re detecting that it’s a plain text file and further detecting that .txt is the preferred extension for text/plain, and .txt is in the allowed list. If you look at the file we actually stored, I believe you’ll see that the extension was changed to .txt when we stored it.

There may be a bug at play here as well though… the extension guessing system is really in place to get some extension when one isn’t provided… it shouldn’t be making these kinds of changes.