Skip to end of banner
Go to start of banner

External Data

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Table of contents

 More detailed table of contents

Overview

The Testify API allows you to send sensor data to Testify so that it can be used as part of a checklist. It is designed for companies trying to automate some of the checks in their Testify checklists.

Modes of operation

There are 2 ways to send data to Testify:

  • Registered Devices can send data to Testify at any time and it will be saved by Testify in case it is needed by a checklist. Any mechanism to send HTTP requests can be used here.

  • Public Devices need to be publicly accessible, so that Testify can send a request to it in case its value is needed by a checklist. Any HTTP server with JSON responses can be used here.

Available check types

Regardless if you use Registered Devices or Public Devices, you will need to know what check type you are sending or providing to Testify:

Check Type

Supported format

TextCheck

string in UTF-8 format

NumericCheck

number (including floating point numbers with 12 places before and after the decimal point)

LogicCheck

boolean

SingleChoiceCheck

GUID of single choice option in Testify (string)

MultipleChoiceCheck

GUIDs of multiple choice options in Testify (list of strings)

TestobjectSelection

GUIDs of test objects in Testify (string)

TimeCheck

time in ISO8601 format (string)

DateCheck

date in ISO8601 format (string)

FileCheck

base64-encoded file (string) + mimeType (string) or data URL (string), this can either be a list of files or a single file

PhotoCheck

base64-encoded image (string) + mimeType (string) or data URL (string), this can only be a single photo

Notice that for FileChecks and PhotoChecks, Testify needs to be provided with the MIME type of the photo or the file that was sent to them. This is necessary so that Testify can display the file or photo properly.

Allowed MIME types for FileChecks

File type

MIME type

.pdf

application/pdf

.txt

text/plain

.xml

application/xml

.zip

application/zip

.docx

application/vnd.openxmlformats-officedocument.wordprocessingml.document

.xlsx

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

.doc

application/msword

.xls

application/vnd.ms-excel

Allowed MIME types for PhotoChecks

Photo type

MIME type

.png

image/png

.bmp

text/plain

.gif

image/gif

.jpg

image/jpg

.jpeg

image/jpeg

.tiff

image/tiff

.svg

image/svg+xml

Further reading

Public Devices

Public Devices need to be publicly accessible, so that Testify can send a request to it in case its value is needed by a checklist.

Technology

Any HTTP server with JSON responses can be used here. This means that any public API like weather APIs and others can act as Public Devices.

The structure of this JSON response can be very flexible, however it must be possible to decide which part of the JSON response (e.g. which property) should be used as a check result within Testify by specifying a JSON Path (see chapter "JSON paths").

Important: Make sure that this API is reachable on the Internet (e.g. have a public IP address or domain). Otherwise Testify will not be able to access it. The easiest way to test this is to try accessing this API with a different internet access than the one of your company (e.g. your private mobile phone).

Samples in some commonly used programming languages and frameworks can be found in Public Device Examples.

Connecting the API to Testify

Wheather you created your own API or use an existing one, you have to connect it to Testify . This can be done in the Testify web interface in Devices. If you create a Public Device there, you will need to provide:

  • URL: url of the API

  • HTTP method: what HTTP method should Testify use to make the request to the API. This is GET in most cases.

  • HTTP headers: any HTTP headers that Testify should send along with the request. This might be needed for an API-key.

  • Check type: what type of data you want to make accessible to Testify. For a list of available check types visit Overview.

For any check other than FileChecks or PhotoChecks :

  • JSON path: used to locate the exact value you want to provide to Testify. For more information see "Using JSON paths" below.

If you selected FileCheck or PhotoCheck, you have to use one of the following options instead of the JSON path mentioned above:

  • MIME type: enter the MIME type of the file or photo you want to send manually

  • JSON path to value: JSON path to the value you want to provide to Testify

    OR

  • JSON path to MIME type: JSON path to the MIME type

  • JSON path to value: JSON path to the value you want to provide to Testify

    OR (for FileChecksonly)

  • JSON path to file array: JSON path to the array of FileChecks. This array needs to have the following structure:

    [
        {
        	"value": YOUR_BASE64_STRING,
        	"mimeType": YOUR_MIME_TYPE
        },
        // other array elements here
    ]
    

Using JSON paths

JSON paths are used to extract a specific value from some JSON.

When accessing information from a public device, this JSON path tells Testify what information in the HTTP response it should use.


For example, if we have the following HTTP response:

{
  "firstName": "Max",
  "lastName" : "Mustermann",
  "age"      : 26,
  "address"  : {
    "streetAddress": "Peter-Behrens-Platz 10",
    "city"         : "Linz",
    "postalCode"   : "4020"
  },
  "phoneNumbers": [
    {
      "type"  : "iPhone",
      "number": "0123456789"
    },
    {
      "type"  : "Home",
      "number": "0112233"
    }
  ]
}

And we want to get the value iPhone we can use the following JSON path:

$.phoneNumbers[0].type

In the simplest case you might have a response like this:

{
 	"temperature": 3.14159
}

And we would get the value 3.14159 like this:

$.temperature

For more information on this concept visit https://jsonpath.com/ .

Public Device Examples

The purpose of this example is to setup a HTTP server that returns "Hello world". This server is then connected to Testify.

C#

using System.Text.Json;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () =>
{
    return JsonSerializer.Serialize(new
    {
        text = "Hello world"
    });
});

app.Run();

Note:

  • This example is done using a C# Minimal API for simplicity, but similar functionality can also be achieved when using a more traditional ASP.NET API with controllers.

Python

from flask import Flask
app = Flask(__name__)

@app.route("/")
def get_data():
    return {
        "text": "Hello world"
    }

if __name__ == "__main__":
    app.run()

Note:

  • This example uses flask which is a lightweight web framework. It can be installed with pip install Flask.

  • The last if is unnecessary if the python script is run with the command flask run. However, this takes more steps to setup which is why it hasn't been done here. For more information visit https://www.twilio.com/blog/how-run-flask-application . The script above works by simply running py FILENAME.py as you would expect.

Javascript

import express from "express";
const app = express();

app.get("/", (req, res) => {
    res.json({
        "text": "Hello world"
    });
})

app.listen(3000, () => {
    console.log("Listening on port 3000");
});

Note:

  • This example uses express, which can be installed with npm install express.

Connecting the API to Testify

In order to make the "Hello World"-API that we created above accessible to Testify, we need to create a Public Device in the Testify web interface with the following options:

  • URL: depends on where you run your server

  • HTTP method: GET

  • HTTP headers: None

  • Check type: TextCheck

  • JSON path: $.text

Other check types

Depending on the check type, you need to send to provide data in a different format.

Registered Devices

Registered Devices can send data to Testify at any time and it will be saved by Testify in case it is needed by a checklist.

Technology

The API is a public HTTP endpoint that accepts JSON data. Therefore any programming or scripting language capable of sending HTTP requests can be used to send data to the API.

Samples in some commonly used programming languages can be found in Registered Device Examples.

Access

The API is accessible at the following URL: https://externaldatastore.azurewebsites.net/api/device/CHECK_TYPE where CHECK_TYPE is the CheckType you want to send data for.

Authentication

You must include a deviceId with every API request. This deviceId can be created with the Testify web interface in Devices.

Request structure

There are 3 ways to add the deviceId to your HTTP request. Therefore, there are 3 different ways your HTTP request might look.

deviceId in Query-String

Add ?deviceId=YOUR_DEVICE_ID to the end of your request url.

POST https://externaldatastore.azurewebsites.net/api/device/CHECK_TYPE?deviceId=YOUR_DEVICE_ID HTTP/1.1
Content-Type: application/json

{
    "value": YOUR_VALUE
} 

deviceId as a HTTP-Header

Add a deviceId HTTP-Header with the value of YOUR_DEVICE_ID.

POST https://externaldatastore.azurewebsites.net/api/device/CHECK_TYPE HTTP/1.1
Content-Type: application/json
deviceId: YOUR_DEVICE_ID

{
    "value": YOUR_VALUE
}

deviceId in the HTTP-Body

Add a deviceId property to the JSON in the HTTP body.

POST https://externaldatastore.azurewebsites.net/api/device/CHECK_TYPE HTTP/1.1
Content-Type: application/json

{
    "value": YOUR_VALUE,
    "deviceId": YOUR_DEVICE_ID
}

Note:

  • value is the actual value that you want to send to the API. This varies depending on the check type.

Custom timestamp

By default Testify uses the timestamp of the HTTP request as a creationDate. However, if the time you get data from your sensor and the time you send it to the API vary, you might consider adding a creationDate manually.

POST https://externaldatastore.azurewebsites.net/api/device/CHECK_TYPE?deviceId=YOUR_DEVICE_ID HTTP/1.1
Content-Type: application/json

{
    "value": YOUR_VALUE,
    "creationDate": YOUR_CUSTOM_CREATION_DATE
}

Adding MIME types to the Request

For FileChecks and PhotoChecks you need to add the MIME type to the request. There are 2 ways to do that:

With an additional property

The easiest way is to add the property valueMimeType to the http request and specify the appropriate MIME type there.

POST https://externaldatastore.azurewebsites.net/api/device/CHECK_TYPE?deviceId=YOUR_DEVICE_ID HTTP/1.1
Content-Type: application/json

{
    "value": {
    	"value": YOUR_BASE64_STRING,
    	"mimeType": YOUR_MIME_TYPE
    }
}

With a data URL

Another way to add the MIME type to the request is to use a data URL instead of standard base64-string.

Data urls are essentially base64-strings with MIME-types attached to them. For example:

data:YOUR_MIME_TYPE;base64,YOUR_BASE64_STRING

So with this data URL, your request could look like this:

POST https://externaldatastore.azurewebsites.net/api/device/CHECK_TYPE?deviceId=YOUR_DEVICE_ID HTTP/1.1
Content-Type: application/json

{
    "value": {
    	"value": YOUR_DATA_URL
    }
}

Note:

  • CHECK_TYPE is either FileCheck or PhotoCheck

  • YOUR_BASE64_STRING is the base64-representation of the file or image you want to send

  • YOUR_MIME_TYPE is one of the allowed MIME types listed in Overview

Response status codes

After sending data to the Testify API, you can look at the HTTP status code of the response to determine wheater your request was successful or failed. If a request failed, status codes can provide additional information on why it failed.

HTTP Status Code

Explanation

201 - Created

Everything worked as expected.

400 - Bad Request

Some required parameters are not provided.

401 - Unauthorized

The provided deviceId doesn't seem to exist.

422 - Unprocessable Entity

The shape of the JSON body isn't right or the mime type doesn't match the file or photo that was sent

Registered Device Examples

This simple example sends the string "Hello world" to the Testify API as a TextCheck.

C#

HttpClient client = new HttpClient();

string url = "https://externaldatastore.azurewebsites.net/api/device/TextCheck?deviceId=YOUR_DEVICE_ID";
object payload = new { value = "Hello world" };

HttpContent httpContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var result = await client.PostAsync(url, httpContent);

Console.WriteLine(result.StatusCode);

Note:

  • The HttpClient should only be instantiated once (don't create a new one if you have to make multiple requests).

  • client.PostAsync is an asynchronous method which allows other code to run while we wait for the response. However, here we want to work with the result immidiately after the POST request, which is why await is used to force the program to wait for the response. In other scenarios (e.g. when having multiple API calls), removing await can lead to better performance.

Python

import requests

url = "https://externaldatastore.azurewebsites.net/api/device/TextCheck?deviceId=YOUR_DEVICE_ID"
payload = { "value": "Hello world" }

response = requests.post(url = url, json = payload, headers={"Content-Type": "application/json"})

print(response.status_code)

Note:

  • The library requests has to be installed for this to work. It can be installed using pip install requests.

Javascript

let url = "https://externaldatastore.azurewebsites.net/api/device/TextCheck?deviceId=YOUR_DEVICE_ID";
let payload = { "value": "Hello world" };

fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload)
}).then((response) => {
    console.log(response.status);
})

Note:

  • When Javascript is run in a browser fetch is available by default. However, if we want to run it in Node.js we have to install it first by running npm install node-fetch and importing it at the top of our file with import fetch from "node-fetch".

  • fetch returns a Promise, which can be handled with then like in the example above or with async/await. For more information visit https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/async_function .

Curl

curl -X POST -i -H "Content-Type: application/json" -d "{\"value\": \"Hello world\"}" https://externaldatastore.azurewebsites.net/api/device/TextCheck?deviceId=YOUR_DEVICE_ID

Note for all of the examples above:

  • YOUR_DEVICE_ID needs to be replaced with your specific deviceId. Information on how to get this can be found at [Authentication in Registered Devices](Registered Devices.md).

Other authentication methods

If you don't want to add your deviceId as a query parameter at the end of the url like in the example above, you can also use one of the following two approaches:

deviceId as a HTTP-Header

deviceId is added as a HTTP header with the value of YOUR_DEVICE_ID.

HttpContent httpContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
httpContent.Headers.Add("deviceId", YOUR_DEVICE_ID);
response = requests.post(url = url, json = payload, headers={
    "Content-Type": "application/json",
    "deviceId": YOUR_DEVICE_ID
})
fetch(url, {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "deviceId": YOUR_DEVICE_ID
    },
    body: JSON.stringify(payload)
}).then((response) => {
    console.log(response.status);
});

deviceId in the HTTP-Body

deviceId is added in the payload of the HTTP request.

object payload = new {
    value = YOUR_VALUE,
    deviceId = YOUR_DEVICE_ID
});
payload = { 
    "value": YOUR_VALUE, 
    "deviceId": YOUR_DEVICE_ID
}
let payload = { 
    "value": YOUR_VALUE, 
    "deviceId": YOUR_DEVICE_ID
};

Other check types

Depending on the check type, the value you send to the API has to be of a certain type (see Available check types in Overview). Here are some examples using all the different check types in different programming languages.

TextCheck

string text = "Hello";
text = "Hello"
let text = "Hello";

NumericCheck

double number = 3.14159;
number = 3.14159
let number = 3.14159;

LogicCheck

bool logic = false;
logic = False
let logic = false;

SingleChoiceCheck

Here you need to provide the GUID of the choice from the single choice check that we want to select.

string singleChoice = "e0607e71-56c6-4a62-9112-ce0eab4cdcf5";
single_choice = "e0607e71-56c6-4a62-9112-ce0eab4cdcf5"
let singleChoice = "e0607e71-56c6-4a62-9112-ce0eab4cdcf5";

MultipleChoiceCheck

Here you need to provide the GUID of the choices from the multiple choice check that we want to select.

string[] multipleChoices = new string[] { "e0607e71-56c6-4a62-9112-ce0eab4cdcf5", "e0607e71-56c6-4a62-9112-ce0eab4cdcf3" };
multiple_choices = ["e0607e71-56c6-4a62-9112-ce0eab4cdcf5", "e0607e71-56c6-4a62-9112-ce0eab4cdcf3"]
let multipleChoices = ["e0607e71-56c6-4a62-9112-ce0eab4cdcf5", "e0607e71-56c6-4a62-9112-ce0eab4cdcf3"];

TestobjectSelection

Here you need to provide the GUID of the test objects you want to select.

string[] testObject = new string[] { "e0607e71-56c6-4a62-9112-ce0eab4cdcf5", "e0607e71-56c6-4a62-9112-ce0eab4cdc32" };
test_object = ["e0607e71-56c6-4a62-9112-ce0eab4cdcf5", "e0607e71-56c6-4a62-9112-ce0eab4cdc32"]
let testObject = ["e0607e71-56c6-4a62-9112-ce0eab4cdcf5", "e0607e71-56c6-4a62-9112-ce0eab4cdc32"];

TimeCheck

If you use language that doesn't allow you to create a Timeonly datatype (Javascript) or where the serializer doesn't support the Timeonly type yet (C#), you have 2 options:

  • Create a normal Date (Javascript) or DateTime (C#) object and enter random values for the date (the date will be ignored by the Testify API).

  • Send a string representation of the time you want.

DateTime time = new DateTime(1970, 1, 1, 20, 15, 33, 0);
string timeAsString = "20:15:33";
time = datetime.time(20, 15, 33, 0).__str__()
let time = new Date(1970, 1, 1, 20, 15, 33, 0);
let timeAsString = "20:15:33";

DateCheck

DateTime date = new DateTime(2021, 12, 24);
date = datetime.date(2021, 12, 24).__str__()
let date = new Date(2021, 12, 24);

FileCheck

FileChecks are somewhat different from other checks:

  • You can send multiple files with one request (notice that a list of objects is used).

  • You have to provide a mime type for every file. For a list of all allowed mime types visit Allowed MIME types for FileChecks.

string fileDataBase64 = Convert.ToBase64String(File.ReadAllBytes("./assets/file.zip"));
object[] fileDataList = new[] {
    new
    {
        value = fileDataBase64,
        mimeType = "application/zip"
    }
};
file_data = open("./assets/file.zip", "rb").read()
file_data_base64 = base64.b64encode(file_data).decode("utf-8") # .decode("utf-8") so that it's a string
file_data_list = [
    {
        "value": file_data_base64,
        "mimeType": "application/zip"
    }
]
let fileDataBase64 = await fs.readFile("./assets/file.zip", { encoding: 'base64' });
let fileDataList = [
    {
        "value": fileDataBase64,
        "mimeType": "application/zip"
    }
];

PhotoCheck

Photo are somewhat different from other checks, as you have to provide a mime type for every photo you send to the API. For a list of all allowed mime types visit Allowed MIME types for PhotoChecks.

string photoDataBase64 = Convert.ToBase64String(File.ReadAllBytes("./assets/photo.png"));
object photoDataObject = new
{
    value = photoDataBase64,
    mimeType = "image/png"
};
photo_data = open("./assets/photo.png", "rb").read()
photo_data_base64 = base64.b64encode(photo_data).decode("utf-8") # .decode("utf-8") so that it's a string
photo_data_object = {
    "value": photo_data_base64,
    "mimeType": "image/png"
}
let photoDataBase64 = await fs.readFile("./assets/photo.png", { encoding: 'base64' });
let photoDataObject = {
    "value": photoDataBase64,
    "mimeType": "image/png"
};

Notice that we don't use a list here like we do with FileChecks.

For the functionality in Testify, key users can find more information at Equipment or Messmittel.

  • No labels