Objects are the primary resource to actually hold the data you upload.
In any case, Objects need at least a Project that acts as the root of their hierarchy. However, this project does not have to be the direct parent, but objects can also be attached below a collection or a dataset by specifying the latter as the parent during creation.
If you don't know how to create other hierarchical resources you should read the previous chapters on how to use the Project API, Collection API and/or Dataset API.
Initialize Object
The first step is to initialize an Object.
This creates an Object in Aruna with a status of Initializing which marks it as a Staging Object.
As long as an Object is in the staging area data can be uploaded to it.
Hash validation
If you provide a SHA256 and/or MD5 hash with the initializing of an Object it will be automatically validated by
the DataProxy after the data upload has been finished. This ensures that the upload was successful and complete.
Required permissions
This request requires at least APPEND permission on the parent resource in which the Object is to be created.
Info
Names are unique within each hierarchy (e.g. you cannot create Objects with the same name inside the same Collection)
// Create tonic/ArunaAPI request to create a new Objectletrequest=CreateObjectRequest{name:"aruna.png".to_string(),title:"Aruna Logo".to_string(),description:"My demo Object".to_string(),key_values:vec![],relations:vec![],data_class:DataClass::Publicasi32,hashes:vec![Hash{alg:Hashalgorithm::Sha256asi32,hash:"5839942d4f1e706fee33d0837617163f9368274a72b2b7e89d3b0877f390fc33".to_string(),}],metadata_license_tag:"CC-BY-4.0".to_string(),data_license_tag:"CC-BY-4.0".to_string(),parent:Some(Parent::ProjectId("<project-id>".to_string())),authors:vec![],};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.create_object(init_request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 910111213141516171819202122232425
# Create tonic/ArunaAPI request to create a new Objectrequest=CreateObjectRequest(name="aruna.png",title="Aruna Logo",description="My demo Object",key_values=[],relations=[],data_class=DataClass.DATA_CLASS_PUBLIC,project_id="<project-id>",collection_id="<collection-id>",dataset_id="<dataset-id>",hashes=[Hash(alg=Hashalgorithm.HASHALGORITHM_SHA256,hash="5839942d4f1e706fee33d0837617163f9368274a72b2b7e89d3b0877f390fc33")],metadata_license_tag="CC-BY-4.0",data_license_tag="CC-BY-4.0",authors=[])# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.CreateObject(request=request)# Do something with the responseprint(f'{response}')
Upload data to a Staging Object
After initializing an Object you can request an upload url with the object id you received from the initialization.
Data then can be uploaded through the received url to the Aruna DataProxy.
If the data associated with the Object is greater than 5 Gigabytes you have to request a multipart upload and chunk your data in parts which are at most 5 Gigabytes in size.
You also have to request an upload url for each part individually.
S3 Presigned download URL
You can also generate presigned URLs on your own for the specific Aruna DataPoxy you want to upload the Object data to.
Required permissions
Requesting an upload URL needs at least APPEND permissions on the Object's Collection or the Project under which the Collection is registered.
Single part upload
Info
Single part upload automatically starts the finishing process of the respective Object once the upload has been finished to make it available.
1234567
# Native JSON request to request an upload url for single part upload
curl-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XGEThttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{object-id}/upload
# Native JSON request to upload single part data through the generated DataProxy upload url
curl-XPUT-T<path-to-local-file><upload-url>
// Create tonic/ArunaAPI request to request an upload url for single part uploadletget_request=GetUploadUrlRequest{object_id:"<object-id>".to_string(),multipart:false,part_number:1,};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.get_upload_url(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);letupload_url=response.url;// Upload local file to the generated upload URLletpath=Path::new("/path/to/local/file");letfile=std::fs::File::open(path).await.unwrap();letclient=reqwest::Client::new();letstream=FramedRead::new(file,BytesCodec::new());letbody=Body::wrap_stream(stream);// Send the request to the upload urlletresponse=client.put(upload_url).body(body).send().await.unwrap();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 9101112131415161718192021
# Create tonic/ArunaAPI request to request an upload url for single part uploadrequest=GetUploadURLRequest(object_id="<object-id>",multipart=False,part_number=1)# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.GetUploadURL(request=request)# Do something with the responseprint(f'{response}')upload_url=response.url# Upload local file to the generated upload URLfile_path="/path/to/local/file"headers={'Content-type':'application/octet-stream'}upload_response=requests.put(upload_url,data=open(file_path,'rb'),headers=headers)# Do something with the responseprint(f'{upload_response}')
Multipart upload
For each uploaded part of the multipart upload you will receive a so called ETag in the response header which has to be saved with the correlating part number for the Object finishing.
Numbers of upload parts start with 1, not 0.
Multipart uploads have to be finished manually as the DataProxy cannot know or guess how many parts will be uploaded in total.
Tip
Upload of parts from multipart upload can be uploaded parallel.
Warning
If the data is stored in an S3 endpoint individual parts of multipart upload have to be at least 5MiB in size (5242880 bytes) or the Object finishing will fail. This limitation is part of the official S3 multipart upload specification.
1234567
# Native JSON request to request an upload url for specific part of multipart upload
curl-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XGET'https://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{object-id}/upload?multipart=true&partNumber=<part-number>'# Upload multipart data with native JSON requests through the generated DataProxy upload urls
curl-XPUT-T<path-to-local-file><upload-url>
1 2 3 4 5 6 7 8 9101112131415
// Create tonic/ArunaAPI to request an upload url for specific part of multipart uploadletrequest=GetUploadUrlRequest{object_id:"<object-id>".to_string(),multipart:true,part_number:<part-number>asi32,};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.get_upload_url(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 9101112
# Create tonic/ArunaAPI request to request an upload url for specific part of multipart uploadrequest=GetUploadURLRequest(object_id="<object-id>",multipart=True,part_number=<part-number>)# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.GetUploadURL(request=request)# Do something with the responseprint(f'{response}')
Multipart upload example
1 2 3 4 5 6 7 8 910111213141516
OBJECT_ID=<staging-object-id>
# Loop over all file parts, request an upload url, upload the data and display ETag with its part numberforiin"Dummy_Archive.tar.gz.aa",1"Dummy_Archive.tar.gz.ab",2"Dummy_Archive.tar.gz.ac",3"Dummy_Archive.tar.gz.ad",4;doIFS=",";# Split input at commaset--$i;# Convert the "tuple" into the param args $1 $2 ...PART_FILE=$1PART_NUM=$2UPLOAD_URL=$(curl-s-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XGET"https://<URL-to-Aruna-instance-API-endpoint>/v2/objects/${OBJECT_ID}/upload?multipart=true&partNumber=${PART_NUM}"|jq-r'.url')ETAG=$(curl-XPUT-T${PART_FILE}-i"${UPLOAD_URL}"|grepetag)echo-e"\nPart: ${PART_NUM}, ETag: ${ETAG}\n"done
letmutfile=tokio::fs::File::open("/path/to/local/file").await.unwrap();// File handleletmutremaining_bytes:usize=file.metadata().await.unwrap().len()asusize;// File size in bytesletmutupload_part_counter:i64=0;letmutcompleted_parts:Vec<CompletedPart>=Vec::new();constUPLOAD_BUFFER_SIZE:usize=1024*1024*50;// 50MiB chunksletmutbuffer_size=UPLOAD_BUFFER_SIZE;// Variable buffer size for looploop{// Increment part numberupload_part_counter+=1;// Set buffer sizeifremaining_bytes<UPLOAD_BUFFER_SIZE{buffer_size=remaining_bytes;}// Fill buffer with bytes from fileletmutdata_buf=vec![0u8;buffer_size];letsuccessful_read=file.read_exact(&mutdata_buf).await;matchsuccessful_read{Ok(bytes)=>bytes,Err(_)=>file.read_to_end(&mutdata_buf).await.unwrap(),};// Create tonic/ArunaAPI request to request an upload url for multipart upload partletupload_url=object_client.get_upload_url(GetUploadUrlRequest{object_id:object_id.to_string(),multipart:true,part_number:upload_part_counterasi32,}).await.unwrap().into_inner().url;// Upload buffer content to upload url and parse ETag from response headerletclient=reqwest::Client::new();letresponse=client.put(upload_url).body(data_buf).send().await.unwrap();letetag_raw=response.headers().get("ETag").unwrap().as_bytes();letetag=std::str::from_utf8(etag_raw).unwrap().to_string();// Collect ETag with corresponding part numbercompleted_parts.push(CompletedPart{etag:etag,part:upload_part_counter,});// Update the amount of remaining bytes for the next loopremaining_bytes-=buffer_size;ifremaining_bytes==0{break;}}// Retain the completed parts for usage in the FinishObjectRequestprintln!("{:#?}",completed_parts);
CHUNK_SIZE=1024*1024*50;# 50MiB chunksfile_path="/path/to/local/file"headers={'Content-type':'application/octet-stream'}# Arbitrary binary data uploadcompleted_parts=[]# Open file and return a streamwithopen(file_path,'rb')asfile_in:fori,data_chunkinenumerate(read_file_chunks(file_in,CHUNK_SIZE)):# (1)# Create tonic/ArunaAPI request to request an upload url for multipart upload partget_request=GetUploadURLRequest(object_id="<object-id>",multipart=True,part_number=i+1)# Send the request to the Aruna instance gRPC endpointget_response=client.object_client.GetUploadURL(request=get_request)# Extraxt download url from responseupload_url=get_response.url# Upload file content chunk to upload urlupload_response=requests.put(upload_url,data=data_chunk,headers=headers)# Parse ETag from response headeretag=str(upload_response.headers["etag"].replace("\"",""))# Collect ETag with corresponding part numbercompleted_parts.append(CompletedPart(etag=etag,part=i+1))# Retain the completed parts for usage in the FinishObjectRequestprint(f'{completed_parts}')
This function returns a generator with byte chunks of the specified file:
1 2 3 4 5 6 7 8 91011121314
defread_file_chunks(file_object,chunk_size=5242880):""" Generator to read set chunk sizes of a file object. Args: file_object: Open file handle chunk_size: Size of chunk to read (Default: 5MiB) Returns: Generator with file content bytes in chunk size """whileTrue:data=file_object.read(chunk_size)ifnotdata:breakyielddata
Finish Object
Finishing the Object transfers it from the staging area into production i.e. makes it available.
From this moment the Object is generally available for other functions than Get Object.
On success the response will contain the finished Object analog to the response content of a .
When to finish an Object?
Object finishing is only needed in the following cases:
Object created/updated without upload
Object created/updated with multipart upload
Single part upload automatically starts the finishing process of the associated Object once the data upload has been finished and validated.
Object hashes
SHA256 and MD5 hash sums are always calculated automatically for the content of the object and added to the object, so they do not have to be explicitly specified when finishing. Currently Aruna only supports SHA256 and MD5 but the list can be extended if the demand arises.
So, in the future further hashes of the object can be specified, which are also added to the object. However, these hashes are not validated against the content of the object.
Required permissions
This request requires at least APPEND permission on the parent resource in which the Object is to be created.
// Create tonic/ArunaAPI to finish a multipart upload Objectletrequest=FinishObjectStagingRequest{object_id:"<object-id>".to_string(),content_len:123456,hashes:vec![Hash{alg:Hashalgorithm::Sha256asi32,hash:"5839942d4f1e706fee33d0837617163f9368274a72b2b7e89d3b0877f390fc33".to_string(),},// Other additional hashes can be added here],completed_parts:vec![CompletedPart{etag:"6bcf86bed8807b8e78f0fc6e0a53079d-1".to_string(),part:1,},CompletedPart{etag:"d41d8cd98f00b204e9800998ecf8427e-2".to_string(),part:2,},CompletedPart{...}],};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.finish_object_staging(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
# Create tonic/ArunaAPI to finish a multipart upload Objectrequest=FinishObjectStagingRequest(object_id="<object-id>",content_len=123456hashes=[Hash(alg=Hashalgorithm.HASHALGORITHM_SHA256,hash="5839942d4f1e706fee33d0837617163f9368274a72b2b7e89d3b0877f390fc33")],completed_parts=[CompletedPart(etag="6bcf86bed8807b8e78f0fc6e0a53079d-1",part=1),CompletedPart(etag="d41d8cd98f00b204e9800998ecf8427e-2",part=2),CompletedPart(...)],)# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.FinishObjectStaging(request=request)# Do something with the responseprint(f'{response}')
Get Object(s)
Fetch information on finished or staging Objects via their unique id.
You can also fetch information on multiple Objects with a single request. In this case the permission requeirements apply to each Object individually.
Required permissions
This request requires at least READ permissions on the Object or one of its parent resources.
1234
# Native JSON request to fetch information of a single Object
curl-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XGEThttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{object-id}
1234
# Native JSON request to fetch information of multiple Objects in a single request
curl-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XGET'https://<URL-to-Aruna-instance-API-endpoint>/v2/objects?objectIds={object-id-01}&objectIds={object-id-02}'
1 2 3 4 5 6 7 8 910111213
// Create tonic/ArunaAPI request to fetch information of a single Objectletrequest=GetObjectRequest{object_id:"<object-id>".to_string()};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.get_object(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 91011121314151617
// Create tonic/ArunaAPI request to fetch information of multiple Objects in a single requestletrequest=GetObjectsRequest{object_ids:vec!["<object-id-01>".to_string(),"<object-id-02>".to_string(),"<...>".to_string(),]};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.get_objects(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 910
# Create tonic/ArunaAPI request to to fetch information of an objectrequest=GetObjectRequest(object_id="<object-id>")# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.GetObject(request=request)# Do something with the responseprint(f'{response}')
1 2 3 4 5 6 7 8 91011121314
# Create tonic/ArunaAPI request to to fetch information of an objectrequest=GetObjectsRequest(object_ids=["<object-id-01>","<object-id-02>","<...>",])# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.GetObjects(request=request)# Do something with the responseprint(f'{response}')
Download Object data
To download the data associated with an Object you have to request a download url.
S3 Presigned download URL
You can also generate presigned URLs on your own for the specific Aruna DataPoxy you want to download the Object data from.
Required permissions
This request requires at least READ permissions on the Object or one of its parent resources.
1234567
# Native JSON request to fetch the download URL of an Object
curl-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XGEThttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{object-id}/download
# Download the data with the provided remote file name
curl-J-O-XGET<received-download-url>
// Create tonic/ArunaAPI request to fetch the download URL of an Objectletrequest=GetDownloadUrlRequest{object_id:"<object-id>".to_string()};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.get_download_url(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);letdownload_url=response.url;// Send GET request to download urlletresponse=reqwest::get(download_url).await.unwrap();// Only proceed if response status is okifresponse.status()!=StatusCode::OK{panic!("Get request for file download failed.");}// Set default filename to "object.<object-id>"letmutfile_name=format!("object.{}",response.url().path_segments().unwrap().last().unwrap());// Try to extract filename from download url query parameterforeleminresponse.url().query_pairs(){ifelem.0=="filename"{file_name=elem.1.to_string();}}// Create local filelettarget_path=Path::new("/tmp").join();letmuttarget_file=File::create(target_path).unwrap();// Write response content to fileletmutcontent=Cursor::new(response.bytes().await.unwrap());copy(&mutcontent,&muttarget_file).unwrap();
# Create tonic/ArunaAPI request to fetch an Objects download urldownload_url_request=GetDownloadURLRequest(object_id="<object-id>")# Send the request to the Aruna instance gRPC endpointdownload_url_response=client.object_client.GetDownloadURL(request=download_url_request)# Extract download url from responsedownload_url=download_url_response.url.url# Try to extract filename from download url query parameterparsed_url=urlparse(download_url)local_filename=parse_qs(parsed_url.query)['filename'][0]iflocal_filenameisNone:local_filepath=os.path.join("/tmp",f'object.{object_id}')else:local_filepath=os.path.join("/tmp",local_filename)# Send GET request to download urlwithrequests.get(download_url,stream=True)asr:r.raise_for_status()//Writeresponsecontentinchunkstolocalfilewithopen(local_filepath,'wb')asf:forchunkinr.iter_content(chunk_size=8192):# Chunk size can be adaptedf.write(chunk)
Update Object
Objects can still be updated after finishing.
Depending on the fields to be updated a new revision of the Object gets created.
You can check if the returned Object is a new revision through the response paramater new_revision.
Operations which are updated "in-place":
Description modification
Key-value adding
Dataclass relaxing
Parent modification
AllRightsReserved license update
Operations which always trigger the creation of a new revision:
force_revision == true in the request
Name update
Key-value removal
Object hashes modification
License update with the exception of AllRightsReserved
A new revision Object always has the status Initializing analog to the initial creation of an Object.
In the same way, the Object must be finished either through a single part data upload or a manual finish request to set its status to Available.
Required permissions
This request requires at least WRITE permissions on the Object or one of its parent resources.
# Native JSON request to update the title of an Object in-place
curl-d' { "title": "Updated Title" }'\-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XPOSThttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{object-id}/title
1 2 3 4 5 6 7 8 91011121314151617
# Native JSON request to add an author to an Object in-place
curl-d' { "addAuthors": [ { "firstName": "John", "lastName": "Doe", "email": "john.doe@example.com", "orcid": "0000-0002-1825-0097", "id": "<user-id-if-registered>" } ], "removeAuthors": [] }'\-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XPOSThttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{object-id}/authors
1 2 3 4 5 6 7 8 91011121314151617181920212223
// Create tonic/ArunaAPI request to update the description of an Object in-placeletadd_request=UpdateObjectRequest{object_id:"<object-id>".to_string(),name:None,description:Some("Updated demo Object".to_string()),add_key_values:vec![],remove_key_values:vec![],data_class:DataClass::Publicasi32,hashes:vec![<old-hashes>],force_revision:false,metadata_license_tag:None,data_license_tag:None,parent:None,};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.update_object(add_request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
// Create tonic/ArunaAPI request to add a key-value to an Object in-placeletadd_request=UpdateObjectRequest{object_id:"<object-id>".to_string(),name:None,description:None,add_key_values:vec![KeyValue{key:"LabelKey".to_string(),value:"LabelValue".to_string(),variant:KeyValueVariant::Labelasi32,}],remove_key_values:vec![],data_class:DataClass::Publicasi32,hashes:vec![<old-hashes>],force_revision:false,metadata_license_tag:None,data_license_tag:None,parent:None,};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.update_object(add_request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 91011121314
// Create tonic/ArunaAPI request to update the title of an Object in-placeletadd_request=UpdateObjectTitleRequest{object_id:"<object-id>".to_string(),title:"Updated Title",};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.update_object_title(add_request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 9101112131415161718192021
// Create tonic/ArunaAPI request to add an author to an Objectletrequest=UpdateObjectAuthorsRequest{object_id:"<object-id>".to_string(),add_authors:vec![Author{first_name:"John".to_string(),last_name:"Doe".to_string(),email:"john.doe@example.com".to_string(),orcid:"0000-0002-1825-0097".to_string(),id:"<user-id-if-registered>".to_string(),}],remove_authors:vec![],};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.update_object_authors(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 910111213141516171819202122
# Create tonic/ArunaAPI request to update the description of an Object in-placerequest=UpdateObjectRequest(object_id="<object-id>",name="<old-name>",description="Updated demo Object",add_key_values=[],remove_key_values=[],data_class=DataClass.DATA_CLASS_PUBLIC,project_id="<old-project-id",collection_id="<old-collection-id",dataset_id="<old-dataset-id",hashes=[<old-hashes>],force_revision=False,metadata_license_tag:"<old-license-tag>",data_license_tag:"<old-license-tag>",)# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.UpdateObject(request=request)# Do something with the responseprint(f'{response}')
# Create tonic/ArunaAPI request to add a key-value to an Object in-placerequest=UpdateObjectRequest(object_id="<object-id>",name="<old-name>",description="<old-description>",add_key_values=[KeyValue(key="LabelKey",value="LabelValue",variant=KeyValueVariant.KEY_VALUE_VARIANT_LABEL)],remove_key_values=[],data_class=DataClass.DATA_CLASS_PUBLIC,project_id="<old-project-id",collection_id="<old-collection-id",dataset_id="<old-dataset-id",hashes=[<old-hashes>],force_revision=False,metadata_license_tag:"<old-license-tag>",data_license_tag:"<old-license-tag>",)# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.UpdateObject(request=request)# Do something with the responseprint(f'{response}')
1 2 3 4 5 6 7 8 91011
# Create tonic/ArunaAPI request to update the title of a Datasetrequest=UpdateObjectTitleRequest(object_id="<object-id>",title="Updated Title")# Send the request to the Aruna instance gRPC endpointresponse=client.dataset_client.UpdateObjectTitle(request=request)# Do something with the responseprint(f'{response}')
1 2 3 4 5 6 7 8 9101112131415161718
# Create tonic/ArunaAPI request to add an author to a Datasetrequest=UpdateObjectAuthorsRequest(object_id="<object-id>",add_authors=[Author(first_name="John",last_name="Doe",email="john.doe@example.com",orcid="0000-0002-1825-0097",user_id="<user-id-if-registered")],remove_authors=[])# Send the request to the Aruna instance gRPC endpointresponse=client.dataset_client.UpdateObjectAuthors(request=request)# Do something with the responseprint(f'{response}')
Update which creates a new revision
If a new revision of an Object gets created it basically gets cloned with the specified updates applied.
As already mentioned in the general Object update introduction, the newly created Object must be finished in order for it to have its status set from Initializing to Available.
// Create tonic/ArunaAPI request to update the description of an Object in-placeletrequest=UpdateObjectRequest{object_id:"<object-id>".to_string(),name:Some("aruna_updated.png".to_string()),description:None,add_key_values:vec![],remove_key_values:vec![],data_class:DataClass::Publicasi32,hashes:vec![<old-hashes>],force_revision:true,// (1)metadata_license_tag:None,data_license_tag:None,parent:None,};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.update_object(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);letrevision_object=response.object.unwrap();// Create tonic/ArunaAPI request to finish the new Object revisionletrequest=FinishObjectStagingRequest{object_id:revision_object.id,content_len:revision_object.content_len,hashes:revision_object.hashes,completed_parts:[],};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.finish_object_staging(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
Could also be left false since the name change alone triggers the creation of a new revision.
# Create tonic/ArunaAPI request to update an objects descriptionrequest=UpdateObjectRequest(object_id="<object-id>",name="<old-name>",description="Updated demo Object",add_key_values=[],remove_key_values=[],data_class=DataClass.DATA_CLASS_PUBLIC,project_id="<old-project-id",collection_id="<old-collection-id",dataset_id="<old-dataset-id",hashes=[],force_revision=False,metadata_license_tag="<old-license-tag>",data_license_tag="<old-license-tag>",)# Send the request to the Aruna instance gRPC endpointupdate_response=client.object_client.UpdateObject(request=request)# Do something with the responseprint(f'{update_response}')letrevision_object=response.object# Create tonic/ArunaAPI request to finish a single part upload staging objectrequest=FinishObjectStagingRequest(object_id=revision_object.id,content_len=revision_object.content_len,hashes=revision_object.hashes,completed_parts=[],)# Send the request to the Aruna instance gRPC endpointfinish_response=client.object_client.FinishObjectStaging(request=request)# Do something with the responseprint(f'{finish_response}')
# Native JSON request to re-upload the modified dataNEW_REVISION_ID=$(curl-d' { "name": "aruna_updated.png", "description": "<old-description>", "addKeyValues": [], "removeKeyValues": [], "dataClass": "<old-data-class>", "projectId": "<old-project-id>", "collectionId": "<old-collection-id>", "datasetId": "<old-dataset-id>", "hashes": [<old-hashes>], "forceRevision": true, "metadataLicenseTag": "<old-license-tag>", "dataLicenseTag": "<old-license-tag>" }'\-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XPOSThttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{object-id}|jq-r'.object.id')# Native JSON request to request an upload url for single part upload
curl-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XGEThttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/{NEW_REVISION_ID}/upload
# Native JSON request to upload single part data through the generated DataProxy upload url
curl-XPUT-T<path-to-local-file><upload-url>
# Request to finish the updated object only needed in case of no upload or multipart upload
// Create tonic/ArunaAPI request to re-upload the modified dataletrequest=UpdateObjectRequest{object_id:"<object-id>".to_string(),name:Some("aruna_updated.png".to_string()),description:None,add_key_values:vec![],remove_key_values:vec![],data_class:DataClass::Publicasi32,hashes:vec![<old-hashes>],force_revision:true,metadata_license_tag:None,data_license_tag:None,parent:None,};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.update_object(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);letrevision_object=response.object.unwrap();// Create tonic/ArunaAPI request to request an upload url for single part uploadletget_request=GetUploadUrlRequest{object_id:revision_object.id,multipart:false,part_number:1,};// Send the request to the Aruna instance gRPC endpointletget_response=object_client.get_upload_url(get_request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",get_response);letupload_url=get_response.url;// Upload local file to the generated upload URLletpath=Path::new("/path/to/local/file");letfile=std::fs::File::open(path).await.unwrap();letclient=reqwest::Client::new();letstream=FramedRead::new(file,BytesCodec::new());letbody=Body::wrap_stream(stream);// Send the request to the upload urlletupload_response=client.put(upload_url).body(body).send().await.unwrap();// Do something with the responseprintln!("{:#?}",upload_response);// Request to finish a staging object only needed in case of no upload or multipart upload
# Create tonic/ArunaAPI request to re-upload the modified datarequest=UpdateObjectRequest(object_id="<object-id>",name="aruna_updated.",description="<old-description>",add_key_values=[],remove_key_values=[],data_class=DataClass.DATA_CLASS_PUBLIC,project_id="<old-project-id",collection_id="<old-collection-id",dataset_id="<old-dataset-id",hashes=[],force_revision=False,metadata_license_tag="<old-license-tag>",data_license_tag="<old-license-tag>",)# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.UpdateObject(request=request)# Do something with the responseprint(f'{response}')revision_object=response.object# Create tonic/ArunaAPI request to request an upload url for single part uploadrequest=GetUploadURLRequest(object_id=revision_object.id,multipart=False,part_number=1)# Send the request to the Aruna instance gRPC endpointget_response=client.object_client.GetUploadURL(request=request)# Do something with the responseprint(f'{get_response}')upload_url=get_response.url.url# Upload updated local file to the generated upload URLfile_path="/path/to/updated/local/file"headers={'Content-type':'application/octet-stream'}upload_response=requests.put(upload_url,data=open(file_path,'rb'),headers=headers)# Do something with the response (e.g. check status if was successful)print(f'{upload_response}')# Request to finish a staging object only needed in case of no upload or multipart upload
Delete Object
Objects can also be deleted again according to the FAIR guidelines.
Info
Deletion does not remove the Object from the database, but sets the status of the Object "DELETED".
This means that deleted objects or individually deleted revisions of objects do not simply disappear, but a tombstone of the deleted resource remains.
Required permissions
This request requires at least ADMIN permissions on the Object or one of its parent resources.
12345678
# Native JSON request to delete an Object
curl-d' { "withRevisions": "false" }'\-H'Authorization: Bearer <AUTH_TOKEN>'\-H'Content-Type: application/json'\-XDELETEhttps://<URL-to-Aruna-instance-API-endpoint>/v2/objects/<object-id>
1 2 3 4 5 6 7 8 91011121314
// Create tonic/ArunaAPI request to delete an Objectletrequest=DeleteObjectRequest{object_id:"<object-id>".to_string(),with_revisions:false,};// Send the request to the Aruna instance gRPC endpointletresponse=object_client.delete_object(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",response);
1 2 3 4 5 6 7 8 91011
# Create tonic/ArunaAPI request to delete an Objectrequest=DeleteObjectRequest(object_id="<object-id>",with_revisions=False)# Send the request to the Aruna instance gRPC endpointresponse=client.object_client.DeleteObject(request=request)# Do something with the responseprint(f'{response}')