Writing back to BaseSpace

If your application does some procesing where data is generated, you may upload it back to BaseSpace so it can be accessed by the user and other applications.

The process is simple:

  1. Create a new Project or choose an existing Project to write back to, provided that the user has write permission to that Project.

  2. Create a new AppResult within that project or choose an existing AppResult to write back to.

  3. Upload file to the AppResult, each file may be given an optional path.

  4. Mark the AppSession as complete.

Creating or choosing a Project

The first step for writing back is to choose a Project to write back the data to. There are two cases that will occur, either the user will want to write back the data to an existing Project or the user will want to create a new Project to write the data back to.

Writing back to an Existing Project

To write back to an existing Project, the user must be able to give write access to that project. In some cases, either the user owns the Project or has been shared the Project. The owner of a Project will always be able to give write permission to that Project, however if the user is not the owner they may not be able to give write access to the Project.

The app should first check to see if the user is the owner by matching the UserOwnedBy field in the Project response to the user's id. The app can first list all of the Projects a user owns by using the GET: users/current/projects method using a scope of browse global, then the user could choose which Project to write back to.

An app is able to write back to an existing project using the create scope. An app can request create project {id} access to gain create permission to a Project. Also, an app can request create global access to gain create permission to all of the user's current projects that they have the ability to write to. This means that by being granted create global, an app is able to create AppResults within any Project to which the user has write access.

Note: Using create scope, an app is given only create access to the user's data, create does not contain read or browse so these will have to be asked for separately.

Apps can also use the write permission to gain the ability to create resources and upload files in BaseSpace. The write permission includes browse, read, and create access to the Project specified. The user should be redirected to the OAuth dialog with a write project {id} scope. This will allow the app to write to the Project and any Samples or AppResults associated with that Project.

Creating a new Project for write back

The user may want to create a new Project to write all of the data back to. In this case the app will need to request the create projects scope. This scope allows an app to create a Project for a user, and also permission to write into that Project.

To create a Project, please refer to the API Reference for the API method to do so. The only parameter used for Project creation is Name.

The user should be prompted to choose the Name of the new Project. Once the user inputs a Name, the app can use the POST: projects method to create the Project.

Curl Example to Create a Project

curl -v -H "x-access-token: {access token}" \
-X POST \
-d "name=Test Project 1" \
https://api.basespace.illumina.com/v1pre3/projects

If a new Project is created, the app will see a 201 Created. If a Project with that name already exists for that user, a 200 OK is returned instead and the app will need to request create project {id} or write project {id} access to that Project. In either case, the API response for a Project with id 125125 would be:

{
    "Response": {
        "HrefSamples": "v1pre3/projects/125125/samples",
        "HrefAppResults": "v1pre3/projects/125125/appresults",
        "HrefBaseSpaceUI": "https://basespace.illumina.com/project/125125/Test Project 1",
        "Id": "125125",
        "UserOwnedBy": {
            "Id": "1001",
            "Href": "v1pre3/users/1001",
            "Name": "John Doe"
        },
        "Href": "v1pre3/projects/125125",
        "Name": "Test Project 1",
        "DateCreated": "2012-10-03T20:22:16.7838033Z"
    },
    "ResponseStatus": {},
    "Notifications": []
}

Create the AppResult or write to an existing AppResult

Write to an existing AppResult

Writing to an existing AppResult is simple. If the app has already requested write access to the parent Project, the app inherits write access to all of the Samples and AppResults within that Project.

Using the steps above, the app should already have write permission to the Project that the AppResult is in, however to gain write access to the Project or an existing AppResult, the app will need to direct the suer to the OAuth dialog and request write project {id} or write appresult {id} scopes respectively.

Create a new AppResult within a Project

An AppResult may be created within a project your app has WRITE access to. See Obtaining Access Tokens for details.

There is one data parameter that will need to be passed for AppResult creation, this is the Content-Type. Content-Type is the content type of the parameter you are passing, for this you'll have to specify application/json and pass a JSON. In this JSON, you will be able to specify the following parameters:

Defining the JSON fields for the request body

Remember, these parameters are included in the JSON that is being passed in with the AppResult creation:

  • Name: Name of the AppResult (required)
  • Description: Brief decription of the AppResult
  • HrefAppSession: Specifies a location for the AppSession for the new AppResult. This field may only be set if the status parameter of this AppSession is neither complete nor aborted, and also the application field must match. Generally it looks like v1pre3/appsessions/{appsessionid}.
  • References: The References field shows this AppResult's inputs or relationship to other resources in BaseSpace. Multiple References may be added if multiple inputs were used. Within References exist three more parameters.

    • Rel: Using means that some Files were used as input for this AppResult
    • Type: The type of resource that was used as an input to this AppResult. This can be Samples or AppResults.
    • HrefContent: Gives the location of the Type specified above, see the following example

The API will parse through the JSON and set these parameters in the response for this AppResult automatically. This form of input easily shows which Samples were taken as input to this AppResult (as shown in the following example.)

When an AppResult is created, the AppSessionId parameter may be passed with an id to specify an AppSession id. If it is not passed, the AppSession is automatically created. This allows you to connect the new AppResult with others by specifying an existing AppSession Id, such as the one that was given to your application when it was triggered. There are two requirements for specifying an AppSessionId; the AppSession status must be neither complete nor aborted and the application must match the one specified in the AppSession.

If you don't provide the AppSessionId parameter, an AppSession is created for you automatically (a reference to is returned from within the app result response).

Note that multiple AppResults may be created and connected through one AppSessionId. This means that a user may run an application on multiple files and receive separate AppResults under one AppSession, this then provides a way of grouping many AppResults together by the AppSession id.

Naming AppResults

When naming an AppResult, ensure that the name is meaningful for the User as the name of the AppResult will be displayed in the UI. The name could be the based on the names of the input Sample(s), AppResult(s), or Project(s) but should provide the user with enough information to understand which analyses were done to produce this result.

Note: An AppResult should always contain References if data from BaseSpace was used as input. Multiple Samples or AppResults may be used as input to an app, in which case multiple References would be added. References should no longer be used, this information can be passed using the {app_name}.inputs.appresults and {app_name}.inputs.samples via the Properties API.

Curl example to create the AppResult

curl -v -H "x-access-token: {access token} \
-H "Content-Type: application/json" \
-X POST 
-d {
       "Name":"My AppResult",
       "Description":"My App Description"
       "HrefAppSession":"v1pre3/appsessions/{appsessionId}",
       "References":[
          {
             "Rel":"using",
             "HrefContent":"v1pre3/samples/1100"
          }
       ]
    } \
https://api.basespace.illumina.com/v1pre3/projects/{ProjectId}/appresults

If successful, a 201 Created is returned with a JSON app result object.

HTTP/1.1 201 Created
Content-Type: application/json
Date: Fri, 11 May 2012 10:23:46 GMT

{
   Response:{
      Description:"My App Description",
      HrefFiles:"v1pre3/appresults/9675/files",
      AppSession:{
         Id:"0480cbb3c56135f3f2265f6437ceadf0",
         Href:"v1pre3/appsessions/0480cbb3c56135f3f2265f6437ceadf0",
         UserCreatedBy:{
            Id:"1001",
            Href:"v1pre3/users/1001",
            Name:"John Smith"
         },
         Status:"Complete",
         StatusSummary:"",
         DateCreated:"2012-02-14T07:00:52.0000000"
      },
      References:[
         {
            Rel:"Using",
            Type:"Sample",
            Href:"v1pre3/samples/1100",
            HrefContent:"v1pre3/samples/1100",
            Content:{
               Id:"37037",
               Href:"v1pre3/samples/1100",
               UserOwnedBy:{
                  Id:"1001",
                  Href:"v1pre3/users/1001",
                  Name:"John Smith"
               },
               Name:"NA18507",
               SampleId:"ID 1",
               Status:"Complete",
               StatusSummary:"",
               DateCreated:"2012-02-14T15:04:52.0000000"
            }
         }
      ],
      Id:"9675",
      Href:"v1pre3/appresults/9675",
      UserOwnedBy:{
         Id:"1001",
         Href:"v1pre3/users/1001",
         Name:"John Doe"
      },
      Name:"My AppResult",
      Status:"Running",
      StatusSummary:"",
      DateCreated:"2012-06-01T16:12:00.0000000"
   },
   ResponseStatus:{

   },
   Notifications:[

   ]
}

If you get a 403 Forbidden response then you don't have WRITE permission to the project with this access_token. You may ask the user for WRITE permission to this project using the OAuthV2 workflow.

Upload files

You may upload as few or many files as you need for this app result. Provide the name of the file with the query parameter name. If your data has a directory structure, you may preserve it by using the directory query parameter. Note that a Content-Type header is required and you should take care to provide the appropriate value for each file you're uploading. When downloading the file, this same Content-Type will be returned. Alternatively, the Multi-Part file upload API may be used.

Curl example to upload files

curl -v -H "x-access-token: {access token} \
-d @MyFile.vcf \    
-H "Content-Type: application/octet-stream" \
https://api.basespace.illumina.com/v1pre3/appresults/6797791/files?name=myfile.vcf\&directory=some/path

If successful, a 201 Created is returned with a JSON file object.

HTTP/1.1 201 Created
Content-Type: application/json
Date: Fri, 11 May 2012 10:47:21 GMT

{
  "Response":{
    "HrefContent":"v1pre3/files/1401400/content",
    "Id":"1401400",
    "Href":"v1pre3/files/1401400",
    "Name":"MyFile.vcf",
    "ContentType":"application/octet-stream",
    "Size":176418,
    "Path":"some/path/MyFile.vcf",
    "DateCreated":"2012-05-11T10:47:17.0000000"
  },
  "ResponseStatus":{},
  "Notifications":[]
}

Mark the AppSession as complete

To complete file upload and AppResult creation, you will need to mark the status of the AppSession Complete. The status of the AppResult is inherited from the AppSession. The user will be able to see files uploaded in the API before the session is marked as Complete, the status is more for grouping. The AppSession id will need to be found to mark the AppSession as complete. To find the AppSession, first find the AppResult which the AppSession modified or created. When the AppResult is called, it will have an AppSession response parameter. Under this parameter is listed an Id, which is the AppSession id which will be used to change the status to complete, and the current AppSession id should not be complete already.

To retrieve the AppSession in an AppResult with an AppResult id of 9675:

GET https://api.basespace.illumina.com/v1pre3/appresults/9675
{
   Response:{
      Description:"My App Description",
      HrefFiles:"v1pre3/appresults/9675/files",
      AppSession:{
         Id:"0480cbb3c56135f3f2265f6437ceadf0",
         Href:"v1pre3/appsessions/0480cbb3c56135f3f2265f6437ceadf0",
         UserCreatedBy:{
            Id:"1001",
            Href:"v1pre3/users/1001",
            Name:"John Smith"
         },
         Status:"Complete",
         StatusSummary:"",
         DateCreated:"2012-02-14T07:00:52.0000000"
      },
      References:[
         {
            Rel:"Using",
            Type:"Sample",
            Href:"v1pre3/samples/1100",
            HrefContent:"v1pre3/samples/1100",
            Content:{
               Id:"37037",
               Href:"v1pre3/samples/1100",
               UserOwnedBy:{
                  Id:"1001",
                  Href:"v1pre3/users/1001",
                  Name:"John Smith"
               },
               Name:"NA18507",
               SampleId:"ID 1",
               Status:"Complete",
               StatusSummary:"",
               DateCreated:"2012-02-14T15:04:52.0000000"
            }
         }
      ],
      Id:"9675",
      Href:"v1pre3/appresults/9675",
      UserOwnedBy:{
         Id:"1001",
         Href:"v1pre3/users/1001",
         Name:"John Doe"
      },
      Name:"My AppResult",
      Status:"Running",
      StatusSummary:"",
      DateCreated:"2012-06-01T16:12:00.0000000"
   },
   ResponseStatus:{

   },
   Notifications:[

   ]
}

The app session id for this AppResult is 0480cbb3c56135f3f2265f6437ceadf0.

When you're finished uploading, you'll want to set the AppSession status to 'complete'. You should call POST: appsessions/{id} with the status changes. This will apply the status for all AppResults associated with that AppSession. More information about AppSession status can be found in the API Reference.

Along with the above statuses, your application may provide a quick summary of what is currently happening. With the statussummary field, you may provide a 128 character summary that will be displayed for the user next to the status. If it's helpful, you may update this multiple times (within a reasonable limit) to describe the ongoing processing.

AppSessions in the Running status will change to the TimedOut status and will not display for the User in the UI after 72 hours if the status of the AppSession is not changed to Complete in that time. Please ensure that the AppSession is changed to the Complete status so that it displays for the user.

Curl example to mark AppSession as complete

curl -v -H "x-access-token: {access token}" \
-d "status=complete" \
-d "statussummary=Processing and file upload complete." \
https://api.basespace.illumina.com/v1pre3/appsessions/9d2cac1f2d908dbf82b9583e072f6b47

If successful, a 200 OK is returned with a JSON app result object.

HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 30 Aug 2012 9:30:46 GMT

{
  "Response":{
    "References": [],
    "Id":"9d2cac1f2d908dbf82b9583e072f6b47",
    "Href":"v1pre3/appsessions/9d2cac1f2d908dbf82b9583e072f6b47",
    "UserCreatedBy":{
      "Id":"74074",
      "Href":"v1pre3/users/74074",
      "Name":"John Doe"
    },
    "Status":"Complete",
    "StatusSummary":"Processing and file upload complete.",
    "DateCreated":"2012-08-21T05:43:17.0000000"
  },
  "ResponseStatus":{},
  "Notifications":[]
}