API Overview
The Application Program Interface (API) provides a REST type architecture providing a simple, scalable interface to the core functionality of the TotalQA platform. It allows:
- Remote access to data in the TotalQA database for custom analyses.
- Ability to push data remotely into the TotalQA database
The motivation for creating an API interface is to handle situations such as:
- I am a clinical user. I am doing some analysis on my QA data that goes beyond the built-in analyses that Image Owl provides. I would like to easily import specific data from TotalQA into my custom analysis application.
- I am a clinical user in an academic or research setting. I have developed a number of custom image processing routines that are very specific to my needs. I would like to have an API toolkit from IO that would allow me to directly send the data to TotalQA automatically.
- I am a manufacturer of QA hardware or software. I would like to provide database tools on cloud infrastructure to my customers to send information from my systems to TotalQA without waiting for a lengthy development cycle. I would like to be able to have my engineers easily put together a software component to accomplish this.
API Workflow
In order to communicate with the API, the following steps must be followed.
- Generate an API key within TotalQA.
- Use the key to request an access token for the API
- Use the returned access token to use HTTP methods to communicate with the API (GET, POST, PATCH, etc)
Generating an API Key
Y
You must have administrative rights to generate API keys.
- In your TotalQA account, navigate to the "Manage - Application Programmer Interface" page.
- Click the +Add Token button and enter a descriptive name for your key.
A key will be generated and displayed on the main API page. You may generate multiple keys for your account. Each key must have a unique label.
- Click on the icon to the right of the key to copy to the clipboard.
Modifying API Keys
To modify an existing API key click on the Edit button next to the key and provide a new unique label. If you hover over the Edit button with the cursor, it will say Modify token. Note that the label is used when requesting access tokens to the service so changing the label may break existing code requesting access.
Deleting API Keys
To delete an API key click the Delete button next to the key. Note that any code using the key will not function once it is deleted.
Requesting an Access Token
The base URL for all API calls to TotalQA is https://tqa.imageowl.com/api/rest. In order to make a call to receive an access token. In order to request access to the API service send a POST request to tqa.imageowl.com/api/rest/oauth with the JSON body:
{
"client_id": "The descriptive id you set up above",
"client_secret": "The generated key string",
"grant_type": "client_credentials"
}
Note: the ID will be a concatenation of a number and the label you assigned. Copy the entire label (e.g 180:API_Connection)
MATLAB Example
%% Get the Access Token using the API Key we generated %this is the basic information needed r.client_id = 'label you provided'; r.client_secret = 'generated key'; r.grant_type = 'client_credentials'; %...make the request options = weboptions('MediaType','application/json','RequestMethod','post'); tokenRequestResponse = webwrite('https://tqa.imageowl.com/api/rest/oauth',r,options); %...display the authorization disp('The response to the access request'); disp(tokenRequestResponse);
Python Example
This example uses the Python requests package.
import json import requests class tqa_Connect: def demo(self): payload = {"client_id": "Your API Label", "client_secret": "Your API Key", "grant_type": "client_credentials" } r = requests.post('https://tqa.imageowl.com/api/rest/oauth',data = payload) print 'Status Code:',r.status_code j = r.json() accessToken = j['access_token'] print 'Access Token: ',j['access_token'] tqa_Connect().demo()
R Example
This example uses the R httr package.
library(httr) url <- 'http://tqa.imageowl.com/api/rest/oauth' body <- list(client_id = 'Your API Label', client_secret= 'Your API Key',grant_type = 'client_credentials') # get the access token in a respone r <- POST(url, body = body, encode = "form") tqa_token <- content(r,"parsed") # look at access token str(tqa_token)
C# (.NET) example
We need to establish some basic data contract classes to make the JSON formatting easier.
For some discussion using Data Contracts in .NET see Using Data Contracts and How to use HttpClient to post JSON data
For the request.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Net.Http.Headers; using System.Runtime.Serialization; namespace TQA_API_Demo { [DataContract] public class AccessRequest { [DataMember(Name = "client_id")] public String ClientID { get; set; } [DataMember(Name = "client_secret")] public String ClientSecret { get; set; } [DataMember(Name = "grant_type")] public String GrantType { get; set; } } }
And to store the response
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Net.Http.Headers; using System.Runtime.Serialization; namespace TQA_API_Demo { [DataContract] public class accessRequestResponseData { [DataMember(Name = "access_token")] public String AccessToken { get; set; } [DataMember (Name= "expires_in")] public int ExpiresIn { get; set; } } }
And then the call to get the access token.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Net.Http.Headers; using Newtonsoft.Json; // uses the Json.NET assembly a freely available JSON library using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.IO; namespace TQA_API_Demo { class Program { static void Main() { RunAsync().Wait(); } static async Task RunAsync() { using (var client = new HttpClient()) { // TODO - Send HTTP requests Uri baseAddress = new Uri("https://tqa.imageowl.com/"); client.BaseAddress = baseAddress; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var accessRequestData = new AccessRequest() { ClientID = "Your API Label", ClientSecret = "Your API Key", GrantType = "client_credentials" }; //HTTP get the access token HttpResponseMessage response = await client.PostAsJsonAsync("api/rest/oauth", accessRequestData); if (response.IsSuccessStatusCode) { accessRequestResponseData responseData = await response.Content.ReadAsAsync<accessRequestResponseData>(); Console.WriteLine("{0}\t{1}",responseData.AccessToken,responseData.ExpiresIn); } Console.ReadLine(); } } } }
Detailed API call formats
Detailed information on API calls can be found at http://tqa.imageowl.com/api/documentation/TqaAPI-v1. In general, the raw tab contains the most in-depth information and examples of each call.
Calling HTTP Methods on the TotalQA API
Once you have an access token you can make HTTP requests to the API. API tokens expire in 1 hour from their creation.
Each API request will be made to a different URL in the API.
All API requests will include the same header information:
- Content-Type => application/json,
- Accept => application/json,
- Authorization => Bearer AccessTokenThatYouCopied
POST and PATCH requests will generally require a JSON formatted body be passed in the request.
GET Example with MATLAB
Continuing from the MATLAB example above to get the the Access token
%% Setup the options to do the various gets options = weboptions('RequestMethod','get',... 'ContentType','json',... 'KeyName','Authorization',... 'KeyValue',['Bearer ',tokenRequestResponse.access_token]); disp(''); disp('The options I need to pass for GET requests'); disp(options); %% Get the sites i have in my account disp('The sites I have in my account'); data= webread(... 'https://tqa.imageowl.com/api/rest/sites',... 'Accept','application/json',... options); tblSites = struct2table(data.sites) %% What are the machine IDs associated with the first site in my account? disp('What are the machine IDs associated with the first site in my account?'); firstID = data.sites(1).id; machineData = webread(... ['https://tqa.imageowl.com/api/rest/machines?site=',int2str(firstID)],... 'Accept','application/json',... options); tblMachine = struct2table(machineData.machines,'AsArray',true)
GET Example with Python
A more complete example building on the Python example above that includes a GET call.
import json import requests class tqa_Connect: def demo(self): payload = {"client_id": "Your API Label", "client_secret": "Your API Key", "grant_type": "client_credentials" } r = requests.post('https://tqa.imageowl.com/api/rest/oauth',data = payload) print 'Status Code:',r.status_code j = r.json() accessToken = j['access_token'] print 'Access Token: ',j['access_token'] bearerToken = 'Bearer ' + accessToken url = "https://tqa.imageowl.com/api/rest/sites" headers = { 'authorization': bearerToken, 'content-type': "application/json", 'accept': "application/json", } response = requests.request("GET", url, headers=headers) print json.dumps(response.json(), indent=4, sort_keys=True) tqa_Connect().demo()
GET Example with R
A more complete example building on the R example above that includes a GET call.
library(httr) url <- 'http://tqa.imageowl.com/api/rest/oauth' body <- list(client_id = 'Your API Label', client_secret= 'Your API Key',grant_type = 'client_credentials') # get the access token in a respone r <- POST(url, body = body, encode = "form") tqa_token <- content(r,"parsed") authorization <- paste('Bearer',tqa_token$access_token) accept <- 'application/json' tqa_headers <- c(Authorization= authorization,Accept = accept) siteUrl <- 'https://tqa.imageowl.com/api/rest/sites' s <- GET(siteUrl,add_headers(.headers = tqa_headers)) sites <- content(s,"parsed") str(sites)
GET Example with C#
A complete example building on the C# example above that includes a GET call.
A utility class to hold the site information when it is returned.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Net.Http.Headers; using System.Runtime.Serialization; namespace TQA_API_Demo { [DataContract] public class Site { [DataMember(Name= "id")] public int ID { get; set; } [DataMember(Name= "name")] public String Name { get; set; } [DataMember(Name= "notes")] public String Notes { get; set; } [DataMember(Name = "ownerId")] public int OwnerID { get; set; } [DataMember(Name = "machineIds")] public List<int> MachineIds { get; set; } [DataMember(Name = "userIds")] public List<int> UserIds { get; set; } } [DataContract] public class SiteList { [DataMember(Name = "sites")] public List<Site> Sites { get; set; } } }
And now we use the access token to get the site information
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http; using System.Net.Http.Headers; using Newtonsoft.Json; // uses the Json.NET assembly a freely available JSON library using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.IO; namespace TQA_API_Demo { class Program { static void Main() { RunAsync().Wait(); } static async Task RunAsync() { using (var client = new HttpClient()) { // TODO - Send HTTP requests Uri baseAddress = new Uri("https://tqadev.imageowl.com/"); client.BaseAddress = baseAddress; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var accessRequestData = new AccessRequest() { ClientID = "141:Webinar", ClientSecret = "42d1a2b2277bbafc906b2a60744f2fb231757cef06df6e231a779093000b3e03", GrantType = "client_credentials" }; //HTTP get the access token HttpResponseMessage response = await client.PostAsJsonAsync("api/rest/oauth", accessRequestData); if (response.IsSuccessStatusCode) { accessRequestResponseData responseData = await response.Content.ReadAsAsync<accessRequestResponseData>(); Console.WriteLine("{0}\t{1}",responseData.AccessToken,responseData.ExpiresIn); //Now that we have the access code let's get some data about the sites HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "api/rest/sites"); requestMessage.Headers.Add("Authorization", "Bearer " + responseData.AccessToken); response = await client.SendAsync(requestMessage); string responseAsString = await response.Content.ReadAsStringAsync(); //prettify Console.WriteLine(FormatJSON(responseAsString)); //turn the response into a list of Site objects DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(SiteList)); MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(responseAsString)); var obj = (SiteList)ser.ReadObject(stream); Console.WriteLine("ID\tName\tMachine Ids\tUser Ids"); foreach (Site s in obj.Sites) { Console.WriteLine("{0}\t{1}\t{2}\t{3}", s.ID, s.Name, string.Join(",", s.MachineIds.ToArray()), string.Join(",", s.UserIds.ToArray())); } } Console.ReadLine(); } } private static string FormatJSON(string json) { dynamic parsedJson = JsonConvert.DeserializeObject(json); return JsonConvert.SerializeObject(parsedJson, Formatting.Indented); } } }
MATLAB Wrapper for TotalQA API
A complete MATLAB wrapper for TotalQA is available on GitHub (TQAConnector). The wrapper simplifies calls using MATLAB to the REST API and helps with some tasks that can be challenging even for experienced MATLAB experts.
Comments
0 comments
Please sign in to leave a comment.