How to use SAFE Upload API?
When to use SAFE Application API?
SAFE Application API keeps a copy of your uploaded roster data in the SAFE web app so that you can return to it at any time and analyze the results visually. You should use this API if you want the roster data to be preserved in the SAFE web app.
How to work with the API?
This code snippet is written in C# and it is used to upload roster data to the FRMSC SAFE Application API and get results from the API. The program uses the following libraries:
IdentityModel.Client
Newtonsoft.Json
Safe_API_Demo_Client.Models
System.Text
Here are the steps to follow.
Step 1: Generate a token
Generate a Bearer token to use with this endpoint. Follow the instructions given in How to generate a Bearer token? tutorial to generate a bearer token.
Step 2: Upload the roster data
Follow the instructions below to upload the roster data. This code sends HTTP POST
request to a web API endpoint.
Step 1: Set the variable values
Set the values of apiKey
, accessToken
, rosterCSV
, and clientId
variables.
var apiKey = "[Your_APIKey]";
var apiUrl = "https://web-eu.frmsc.com";
var accessToken = "[Your_Accesstoken]";
var rosterCsv = File.ReadAllText("SampleRosters\\ExampleRosterUpload.csv");
var clientId = "[Your_ClientId]";
You can get apiKey
and clientId
from the web app, and you can get the accessToken
from the previous step.
The rosterCSV
variable is set to read the roster data from a CSV file. Set the parameter value of the File.ReadAllText()
function to the location of the CSV file with the roster data.
Step 2: Initiate request
Create an HTTP client and set the base address to the API URL. Then, create an HTTP request message with the HTTP method set to POST and the endpoint set to /api/UploadRoster
. The request message should also include the authorization
header with the access token.
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(apiUrl);
var request = new HttpRequestMessage(HttpMethod.Post, "/api/UploadRoster");
request.Version = new Version(2, 0);
request.Headers.Add("authorization", $"Bearer {accessToken}");
Step 3: Prepare request body
Create an instance of the UploadRequest
class and sets its properties.
var uploadRequest = new UploadRequest
{
RosterName = "Sample SAFE Application API post",
RosterData = rosterCsv,
Username = clientId,
Key = apiKey,
Overwrite = false
};
The UploadRequest
class has four properties.
RosterName
RosterData
Username
Key
Provide a name for the roster through the RosterName
property. In the following code example, the RosterName
property is set to Sample SAFE Application API post
.
Set the RosterData property to refer to rosterCsv
and the Username
property to clientId
variables. The Key
property must refer to apiKey
.
Leave the Overwrite
property as false
, if you want to create a new roster. To overwrite an existing roster with the same name, set the value of the Overwrite
property to true
.
Step 4: Make the request
Serialize the UploadRequest
object to JSON and set the request message content to the serialized JSON. Send the request message to the API and wait for it to return a roster token.
request.Content = new StringContent(JsonConvert.SerializeObject(uploadRequest), Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
Step 3: Generate result
Follow the instructions below to upload the roster data. This code sends HTTP GET
request to a web API endpoint.
Step 1: Set the variable values
Set the values of rosterToken
and dataKey
variables.
You can get rosterToken
from Step 4: Make the request. The dataKey variable is set to status
initially to ensure that the roster data you uploaded previously was completed successfully. See Step 4: Retry with different dataKey
Step 2: Initiate request
Create a query string using the variables set in Step 1: Set the variable values, including the apiKey
variable. Then, create an HTTP request message with the HTTP method set to GET and the endpoint set to /api/GetResults
. The request message should also include the authorization
header with the access token.
Set the Version property of the HttpRequestMessage
object is set to 2.0
to indicate that the request should use HTTP/2.0
.
var queryString = string.Format("?token={0}&key={1}&dataKey={2}", rosterToken, apiKey, dataKey);
var request = new HttpRequestMessage(HttpMethod.Get, "/api/GetResults" + queryString);
request.Version = new Version(2, 0);
request.Headers.Add("authorization", $"Bearer {accessToken}");
Step 3: Make the request
Use the SendAsync
method of the HttpClient
object to send the request, and the ReadAsStringAsync
method of the HttpContent
object to read the response content as a string.
Step 4: Retry with different dataKey
There are two workflows for this step depending on the response you receive from the previous step.
If the response from the previous step is not completedsuccessfully
, set the value of dataKey
parameter to feedback
in Step 1: Set the variable values and retry sending the request to learn more about the problem.
Resolve any error in the roster data file. Then, return to Step 2: Upload the roster data. Keep the RosterName
same and set the value of Overwrite
field to true
to resubmit the roster data.
If the status is completedsuccessfully
, set the value of dataKey
parameter to the type of result you want to receive and submit. The following values are supported for the dataKey parameter. Send only one value at a time.
- status
- feedback
- hundredpointalertness
- samnperellialertness
- karolinskaalertness
- karolinskaprobability
- vigilancedegradation
- complexreactiondegradation
- percentagemissedresponses
- sleepperiods
- schedule
- timeabovethreshold
- tableofscheduledetailsids
Complete Code
using IdentityModel.Client;
using Newtonsoft.Json;
using Safe_API_Demo_Client.Models;
using System.Text;
namespace Safe_API_Demo_Client
{
public static class UploadApi
{
public static async void Run()
{
var identityUrl = "https://identity-eu.frmsc.com";
var apiUrl = @"https://web-eu.frmsc.com";
var apiKey = "[Your_ApKey]";
var clientId = "[Your_ClientId]";
var clientSecret = "[your_ClientSecret]";
var rosterCsv = File.ReadAllText("SampleRosters\\ExampleRosterUpload.csv");
var accessToken = await Authenticate(identityUrl, clientId, clientSecret, "frmsc_safe_upload_api");
if (accessToken == null) { return; }
var rosterToken = await Upload(apiUrl, apiKey, accessToken, rosterCsv, clientId);
Console.WriteLine("Acquired token: " + rosterToken);
while (await GetResults(apiUrl, apiKey, accessToken, rosterToken, "Status") == "processing")
{
Console.WriteLine("Roster still being processed....");
Thread.Sleep(2000);
}
var feedback = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "Feedback");
Console.WriteLine("Feedback: {0}", feedback);
var schedules = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "TableOfScheduleDetailsIds");
Console.WriteLine("Schedules: {0}", schedules);
Console.WriteLine("Downloading 100pt scale alertness data");
var hundredPointAlertness = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "HundredPointAlertness");
File.WriteAllText("Output\\hundredPointAlertnessData.csv", hundredPointAlertness);
Console.WriteLine("Downloading Samn Perelli scale alertness data");
var samnPerelliAlertness = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "SamnPerelliAlertness");
File.WriteAllText("Output\\samnPerelliAlertnessData.csv", samnPerelliAlertness);
Console.WriteLine("Downloading Karolinska Alertness scale alertness data");
var karolinskaAlertness = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "KarolinskaAlertness");
File.WriteAllText("Output\\karolinskaAlertnessData.csv", karolinskaAlertness);
Console.WriteLine("Downloading Karolinska Probability scale alertness data");
var karolinskaProbability = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "KarolinskaProbability");
File.WriteAllText("Output\\karolinskaProbabilityAlertnessData.csv", karolinskaProbability);
Console.WriteLine("Downloading Vigilance Degradation scale alertness data");
var vigilanceDegradation = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "VigilanceDegradation");
File.WriteAllText("Output\\vigilanceDegradationAlertnessData.csv", vigilanceDegradation);
Console.WriteLine("Downloading Complex Reaction Degradation scale alertness data");
var complexReactionDegradation = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "ComplexReactionDegradation");
File.WriteAllText("Output\\complexReactionDegradationAlertnessData.csv", complexReactionDegradation);
Console.WriteLine("Downloading Percentage Missed Responses scale alertness data");
var percentageMissedResponses = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "PercentageMissedResponses");
File.WriteAllText("Output\\percentageMissedResponses.csv", percentageMissedResponses);
Console.WriteLine("Downloading sleep periods data");
var sleepPeriods = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "SleepPeriods");
File.WriteAllText("Output\\sleepPeriodData.csv", sleepPeriods);
Console.WriteLine("Downloading schedule data");
var schedule = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "Schedule");
File.WriteAllText("Output\\scheduleData.csv", schedule);
Console.WriteLine("Downloading time above threshold data");
var timeAboveThreshold = await GetResults(apiUrl, apiKey, accessToken, rosterToken, "TimeAboveThreshold");
File.WriteAllText("Output\\timeAboveThresholdData.csv", timeAboveThreshold);
}
static async Task<string> Upload(string apiUrl, string apiKey, string accessToken, string rosterCsv, string clientId)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(apiUrl);
var request = new HttpRequestMessage(HttpMethod.Post, "/api/UploadRoster");
request.Version = new Version(2, 0);
request.Headers.Add("authorization", $"Bearer {accessToken}");
var uploadRequest = new UploadRequest
{
RosterName = "Sample roster API post",
RosterData = rosterCsv,
Username = clientId,
Key = apiKey,
Overwrite = false
};
request.Content = new StringContent(JsonConvert.SerializeObject(uploadRequest), Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
static async Task<string> Authenticate(string identityUrl, string clientId, string clientSecret, string scope)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(identityUrl);
var openIdDiscoveryDocument = client.GetDiscoveryDocumentAsync(identityUrl).GetAwaiter().GetResult();
var request = new ClientCredentialsTokenRequest
{
Address = openIdDiscoveryDocument.TokenEndpoint,
ClientId = clientId,
ClientSecret = clientSecret,
Scope = scope
};
var tokenResponse = await client.RequestClientCredentialsTokenAsync(request);
if (tokenResponse != null)
{
return tokenResponse.AccessToken;
}
else
{
Console.WriteLine("Authentication failed");
throw new Exception("Authentication failed");
}
}
static async Task<string> GetResults(string apiUrl, string apiKey, string accessToken, string rosterToken, string dataKey) {
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(apiUrl);
var queryString = string.Format("?token={0}&key={1}&dataKey={2}", rosterToken, apiKey, dataKey);
var request = new HttpRequestMessage(HttpMethod.Get, "/api/GetResults" + queryString);
request.Version = new Version(2, 0);
request.Headers.Add("authorization", $"Bearer {accessToken}");
var response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
}
}