-
Notifications
You must be signed in to change notification settings - Fork 33
API Sample Manifest
This part of the API is currently being finalised so details may change from what is presented here. In particular, the information relating to the container
element may vary slightly but the element itself will not be removed.
The following documents the sample manifest API, through which samples are registered with the system. The idea behind the manifests is that the Sanger Institute pre-generates a manifest, prints labels on the tubes or plates, and then ships them to a supplier; the supplier then fills the containers with their samples, fills the details of these samples in the manifest, and sends both of them back to the institute; once received, the sample manifest is uploaded to the system, updating the details of the samples within Sequencescape, and the physical samples are processed by the receiving laboratory.
So the API follows the same flow, in that you:
- Create a manifest with "blank" information
- Update the manifest with the correct information
Printing the labels is left to the client application.
In order to create a sample manifest the client application needs several pieces of information:
- A study, identified by a UUID, through which to create the manifest
- A supplier, identified by a UUID, that will be supplying the samples
- Whether to create a tube or plate manifest
- The number of containers that will be registered (plates are assumed to have 96 wells)
The first two pieces of information can be obtained through the API itself by accessing the appropriate resources, either through searches or by iterating over all records to identify the specific ones required. Once the UUIDs have been obtained they can be safely stored as these will not change.
In the following examples it can be assumed that:
- The study UUID is
22222222-3333-4444-5555-000000000000
- The supplier UUID is
33333333-1111-2222-3333-444444444444
- The API is located at
http://www.example.com/api/1/
The first thing the client needs to do is retrieve the JSON for the study, by performing an HTTP GET request to the study URL, which is, by definition, http://www.example.com/api/1/22222222-3333-4444-5555-000000000000
. The returned JSON will contain, at least, the following elements:
{
"study": {
"sample_manifests": {
"actions": {
"create_for_tubes": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000/sample_manifests/create_for_tubes",
"create_for_plates": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000/sample_manifests/create_for_plates"
}
}
}
}
It should now be obvious that the create_for_tubes
action can be used to create tube manifests, and the create_for_plates
will create plate manifests. Both of these respond to HTTP POST requests, just as a normal create
action would.
So an HTTP POST, with the following JSON in its request body, to the create_for_tubes
action would create a manifest for 5 tubes:
{
"sample_manifest": {
"supplier": "3333333-1111-2222-3333-444444444444",
"count": 5
}
}
Sending the same JSON body to create_for_plates
would create 5 96 well plates, pre-registering 480 samples.
The response from either will contain the JSON for the manifest, first let's examine the common elements:
{
"sample_manifest": {
"actions": {
"read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444",
"update": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444"
},
"study": {
"actions": {
"read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000"
}
},
"supplier": {
"actions": {
"read": "http://www.example.com/api/1/33333333-1111-2222-3333-444444444444"
}
},
"uuid": "00000000-1111-2222-3333-444444444444",
"state": "pending",
"last_errors": null,
"samples": [
{
"container": { ... container specific information here ... },
"sample": { ... sample information here ... }
},
... 5 records in total here (including the one above) ...
]
}
}
It should be obvious that the study
and supplier
relations link to the study and supplier that were used to create the manifest. And it should also be apparent that the top-level actions
element contains the read
and update
actions for the sample manifest itself.
The samples
element is a list of records that identify the container in which a particular sample exists, and the information for the sample itself. The contents of each sample
element conforms to the JSON used by the sample part of the API regardless of whether the manifest is for tubes or plates.
The variations between the two types of manifest come in the contents of the container
element. In the case of a tubes manifest the elements will look like this:
"container": {
"barcode": "NT9999J"
}
For a plate manifest a sample is to be placed in a particular well on a particular plate; therefore the container
element becomes:
"container": {
"position": "A01",
"barcode": "DN1234567T"
}
Here the container is the well at position A01 on the plate identified by the barcode.
To update the sample information the client application must make an HTTP PUT request, with the appropriate JSON body, to the update
action for the sample manifest. The body of the request should be something like this:
{
"sample_manifest": {
"samples": [
{
"uuid": "11111111-2222-3333-4444-000000000001",
"supplier": {
"sample_name": "flurby_wurby_sample",
"measurements": {
"concentration": 10,
"volume": 100
}
}
}
]
}
}
It should be apparent that the samples
element in this JSON is an array of individual sample JSON elements, each one representing the updates that should be performed upon the sample, identified through the UUID. Here, for example, the sample_name
, concentration
and volume
are all being updated for the sample identified by the UUID 11111111-2222-3333-4444-000000000001
.
When updating sample information in this manner the concentration
and volume
fields are required; failure to provide them, for any individual sample being updated, will result in the entire manifest being failed and no samples being updated. concentration
is in nano grams and volume
is in micro litres.
It is not necessary to provide all of the samples in a manifest on any update: only those referenced will be updated. Whilst this means that client applications can make many updates it does lead to a problem when samples have already been updated. For example, consider that Alice creates the manifest and then performs and update of the information for all samples; later Bob wants to update the same manifest: should he be allowed to? In these cases, if Bob wants to override the information provided by Alice, his JSON body should contain the override_previous_manifest
attribute thus:
{
"sample_manifest": {
"override_previous_manifest": true,
"samples": [
{
"uuid": "11111111-2222-3333-4444-000000000001",
"supplier": {
"sample_name": "Bob says this name was wrong",
"measurements": {
"concentration": 10,
"volume": 100
}
}
}
]
}
}