The following steps outline how to upload attachments via the API. It is assumed that collection object attachments are being created for a new collection object resource. Additionally, the steps required to create an attachment for an existing resource are mentioned at the end. Code snippets for Node.js are provided.
Additionally, it is assumed that authentication cookie has been obtained as described in the API demo:
Step 1 - Getting asset specifics from the backend
Before a file is uploaded to the asset server, specify generated token
and attachmentlocation
that defines specs of the upload to the asset server are needed.
To generate this, use the attachment_gw/get_upload_params/
endpoint which
takes in the filename as a query parameter and returns the token
and
attachmentlocation
.
The code snippet:
const {attachmentlocation, token} = await fetch("http://localhost/attachment_gw/get_upload_params/?filename=FILENAME", {
"headers": {
"accept": "application/json",
"accept-language": "en-US,en",
"sec-ch-ua": "\"Brave\";v=\"113\", \"Chromium\";v=\"113\", \"Not-A.Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"sec-gpc": "1",
"cookie": COOKIE,
"Referer": "http://localhost/specify/view/collectionobject/new/",
"Referrer-Policy": "strict-origin-when-cross-origin"
},
"body": null,
"method": "GET"
}).then((response)=>response.json());
Step 2 - Uploading file to the asset server
Next, the file is POSTed to the asset server as formData. To do so, formData
instance needs to be created with some specific specs.
Node.js provides external library form-data
which can be used along with fetch as:
var FormData = require('form-data');
var fs = require('fs');
var formData = new FormData();
formData.append('file', FILENAME);
formData.append('token', token);
formData.append('store', attachmentlocation);
formData.append('type', 'O');
formData.append('coll', COLLECTION);
await fetch("http://ASSET_SERVER_URL/fileupload", {
"headers": "POST",
"body": formData
})
Step 3 - Making an attachment resource.
Define a new attachment resources using the following JSON format:
const attachmentResource0 = {
"ordinal": 0,
"attachment": {
"attachmentlocation": attachmentlocation,
"mimetype": mimeType,
"origfilename": FILENAME,
"title": FILENAME,
"ispublic": true,
"tableid": TABLEID
}
}
Step 4 - Post request for collection object
Define a Collection Object Resource with collectionobjectattachments
as
an array of attachments JSON defined previously. For example, if a new collection object
is created with one collection object attachment, then the final JSON representation of collection object
will look like:
const collectionobjectResource = {
"collection": "/api/specify/collection/4/",
"catalognumber": "#########",
"altcatalognumber": null,
"cataloger": "/api/specify/agent/1514/",
"reservedtext": null,
"text2": null,
"guid": null,
"determinations": [],
"preparations": [],
"collectionobjectattachments": [attachmentResource0],
"dnasequences": [],
"collectionobjectcitations": []
}
POSTing this JSON to /api/specify/collectionobject/
as following will create a new collection object with one new attachment.
await fetch("http://localhost/api/specify/collectionobject/", {
"headers": {
"accept": "application/json",
"accept-language": "en-US,en",
"content-type": "application/json",
"sec-ch-ua": "\"Brave\";v=\"113\", \"Chromium\";v=\"113\", \"Not-A.Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"sec-gpc": "1",
"x-csrftoken": CSRFTOKEN,
"cookie": COOKIE,
"Referer": "http://localhost/specify/view/collectionobject/new/",
"Referrer-Policy": "strict-origin-when-cross-origin"
},
"body": JSON.stringify(collectionobjectResource),
"method": "POST"
});
If more than one attachment needs to created for a new collection object (say 3), then follow steps
1 through 3 to get three new attachment resources attachmentResource0
, attachmentResource1
, attachmentResource2
and the new collectionobject resource will then be:
const collectionobjectResourceMultipleAttachments = {
"collection": "/api/specify/collection/4/",
"catalognumber": "#########",
"altcatalognumber": null,
"cataloger": "/api/specify/agent/1514/",
"reservedtext": null,
"text2": null,
"guid": null,
"determinations": [],
"preparations": [],
"collectionobjectattachments": [attachmentResource0, attachmentResource1, attachmentResource2],
"dnasequences": [],
"collectionobjectcitations": []
}
POSTind this resource similar to before will create a new collection object with three new
attachments.
Attachments to existing resources:
If the attachments need to be created for an existing resource, fetch that resource first using the /api/specify/{table}/{id}
endpoint
and then append new attachments (after step 3) to the {table}attachments
list, and then PUT this resource