Netra API Developer Documentation

Netra API 1.0

Disclaimer.The Netra.AI API  is intended to help qualified healthcare professionals with the analysis of the human retina. When using Netra API, the user must be aware of the following:

  • Netra.AI is not intended to diagnose, treat, cure, or prevent diabetic retinopathy or any other disease;
  • Netra.AI is to be used as an ancillary tool by qualified eye care professionals;
  • Leben makes no claims as to the effectiveness of Netra.AI to treat or prevent any medical condition;
  • Netra.AI is designed to be used with images from a fundus camera approved by the relevant regulatory authorities, e.g. CE in Europe, FDA in the United States;
  • User should ensure that the fundus camera is well maintained and is free of dust or other particles or reflections in the image that may appear as artifacts on a retinal image, and might cause any potential misinterpretation of such image; and
  • User should ensure that Netra API and any other software used to visualize retinal images is used in an appropriate viewing environment, e.g. optimal lighting and free of distraction, so that details in the image may be appropriately viewed.

Fundus image quality

  • Posterior pole
  • Macula centered color fundus image with 45 degree FOV with a clear view of optic disc.
  • No shadows or reflections
  • Main vessels clearly visible
  • Image in focus with clear and sharp view of retinal anatomy
  • No external artifacts, reflections, flashes in the image
  • Right exposure, without blown out or dark underexposed areas

Requirements for fundus cameras

  • Field of view: min 45° to max 50° 
  • Type of image capture: Full color image
  • ISO 10940:2009
  • CE-marking (for EU): 93/42/EEC (Medical Device Directive)
  • Minimum resolution 1.3 MP(1280 x 1024 pixels) and maximum file size 5 MB

Netra API supports JPEG , PNG , TIFF and DICOM (Coming soon) Image format .

Exclusion

    1. Cataract, Other Corneal or Vitreous abnormalities that can impede a clear view of retina

 

How to get started

Get in touch with us to discuss

Contact Us

List of API Endpoints

Get Token The token is used for image upload, getting status and getting result for Netra API.

URL: https://api.netra.ai/v1/getToken

HTTP Method: POST

Note: DR – Diabetic Retinopathy

Input

Property

Description

username

Username to access API

password Password to access API
apiRequestType

DIAB_RETINA = Access DR API

Output JSON

Property Description
status 200 – Successful

500 – Error in API

411 – API Specific error

token Token to be used for later transactions. Valid for 2 hours.
remaining Remaining API Credits
validUpto Token Valid Until – UTC unix timestamp
message Message text if there is an error.

Sample Output JSON:

{‘status’: 200, ‘token’: ‘LMoXQtXJ8Y1lJrOYD1O7r5FHPlKWbqgzhwals7scTePBHePdCw8FwZQYgM7k’, ‘remaining’: 100, ‘validUpto’: 1517613274139}

Upload Image For Netra.AI Analysis: Send an image to Netra API for DR Analysis

URL: https://api.netra.ai/v1/doAnalysis

HTTP Method: POST

Conditions:

  1. The image should be either of format jpeg or png.
  2. The image should be less than or equal to 5 MB.

Input

Property Description
token API Token obtained using getToken
image Base64 format image Data

Prepend image information into base64 string

For png:
data:image/png;base64,

For jpeg:
data:image/jpeg;base64,

Example:
data:image/jpeg;base64,/9asdfdsjfdslfeafdsaedd

imageName Basename of the image to be sent.
bulkImgLabel Optional – Label to identify a set of images as one group.
imageLocPath Optional – Path to the file in local machine.

Output JSON

Property Description
status 200 – Successful

500 – Error in API

411 – API Specific error

jobId JobId to keep track of the request.
jobStatus Status of the job when uploaded.
remaining Remaining API Credits
message Message text if there is an error.

Sample Output JSON:

  1. {‘status’: 411, ‘message’: ‘LC-ERR-0033 : Max Allowed Single Image Size 5 MB.’}
  2. {‘status’: 411, ‘message’: ‘LC-ERR-0034 : Only jpeg and png type images allowed.’}
  3. {‘status’: 200, ‘jobId’: ‘LaHkZVkSRkHpSdIoA8hgo97BrT47vrZL6FhUX2XqG26RhBxW3luvEjSfAnwPPrR5f2K2xd’, ‘jobStatus’: ‘QUEUED’, ‘remaining’: 43110}

Get Job Status : Get status of your request using jobId.

URL: https://api.netra.ai/v1/getStatus

HTTP Method: POST

Input

Property Description
token API Token obtained using getToken
jobId JobId to for the request.

Output Json

Property Description
status 200 – Successful

500 – Error in API

411 – API Specific error

jobId JobId to keep track of the request.
jobStatus Status of the job when uploaded.
remaining Remaining API Credits
message Message text if there is an error.

Sample Output JSON:

a) {‘status’: 200, ‘jobId’: ‘rCSiWGrp4bhOw7AntwlbI9LbaAe2KDIsOb3tvPNoEz2MSF6hW0PumXvGcHTkpVzC4YMjhO’,’statusJob’: ‘QUEUED’’,}

b) {‘status’: 200, ‘jobId’: ‘sk1eD8xw6FfbVLNuuXfTH4UcmguHZrov39mFNG6si071xq7oRdG8r3wKKuaiUlySA8n4Rv’, ‘status’: ‘COMPLETED’}

Get Result for DR Analysis: This will give the result of the DR analysis.

URL: https://api.netra.ai/v1/getResult

HTTP Method: POST

Input

Property Description
token API Token obtained using getToken
jobId JobId for the request.

Output JSON

Property Description
status 200 – Successful

500 – Error in API

411 – API Specific error

jobId JobId for the request.
usedOn Time Used – UTC unix timestamp
usedBy Used By
statusJob Status of the request
result Result of Netra DR Analysis:

a) eyeOrNot – Whether image is fundus retina.

b) imageQuality – Whether image is gradable.

a) drYes – Whether DR present or not.

b) referrableDR – Whether Referable DR.

lesionBbox Lesion info and corresponding bbox data.

Bbox format: [x1, y1, x2, y2]

Lesions shown:

  1. Deep Hemorrhage
  2. Drusen
  3. Cotton-wool Spot
  4. Superficial Hemorrhage
  5. Hard Exudate
message Message text if there is an error.

Sample Output JSON:

a) {‘status’: 200, ‘jobId’: ‘b579a73a688c4dd9beyn3oIeb730057701ec52f7c324db6bf0c9fa01c9527bdETsS7Q’, ‘usedOn’: ‘1516820982075236’, ‘usedBy’: ‘username’, ‘statusJob’: ‘COMPLETED’, ‘result’: ‘{“drYes”:”Detected”,”referrableDR”:”YES”,”imageQuality”:”Gradable Image”,”eyeOrNot”:”YES”}”lesionBbox”:[{“bbox”:”[959,729,1042,812]”,”lesionType”:”Deep Hemorrhage”},{“bbox”:”[795,850,870,932]”,”lesionType”:”Hard Exudate”},{“bbox”:”[524,972,572,1052]”,”lesionType”:”Deep Hemorrhage”}]’}

b) {‘status’: 200, ‘jobId’: ‘8b53d4cfd1ddyc7e226eb0bfab8c889913d60d8af04c4a83b3ecfe50d308a1fbt18tu0’, ‘usedOn’: ‘1514859444682135’, ‘usedBy’: ‘username’, ‘statusJob’: ‘ERROR’, ‘message’: ‘LC-ERR-0035 : Please contact Leben Care Support Team.’}

Sample Code Python: The sample code below does the following:

  1. Get Token when username and password are sent and are authenticated.
  2. Send an image for DR processing.
  3. Ping the api every 90 seconds for the status of the request sent.
  4. When the request completes or error is thrown, get the result and display.

 

config_testing.py

fileToProcess=”/path/to/image/sampleRetina.jpeg”;

jobStatusApiUrl=’https://api.netra.ai/v1/getStatus’;

jobResultApiUrl=’https://api.netra.ai/v1/getResult’;

getApiTokenUrl=’https://api.netra.ai/v1/getToken’;

imageUploadApiUrl=’https://api.netra.ai/v1/doAnalysis’;

usernameForGetToken=’username’;

passForGetToken=’password’;

bulkImageLabel=’testLabelBulkImg’;

 

sendImageGetResultForApiDoc.py

import json

import requests

import base64

import os;

import sys;

import mimetypes;

import time;

sys.path.append(os.getcwd());

from config.config_testing import fileToProcess;

from config.config_testing import imageUploadApiUrl;

from config.config_testing import getApiTokenUrl;

from config.config_testing import jobResultApiUrl;

from config.config_testing import jobStatusApiUrl;

from config.config_testing import usernameForGetToken;

from config.config_testing import passForGetToken;

from config.config_testing import bulkImageLabel;

dataForToken = { ‘username’ : usernameForGetToken,

‘password’ : passForGetToken,

‘apiRequestType’: ‘DIAB_RETINA’

};

r_token = requests.post(getApiTokenUrl, data=dataForToken)

dataForToken = r_token.json();

tokenForApi = ”;

if (dataForToken[“status”] != 200) :

print(dataForToken[“message”]);

sys.exit(0);

else :

tokenForApi = dataForToken[“token”];

try :

basenameOfFile = os.path.basename(fileToProcess);

prepend_info = ‘data:%s;base64’ % mimetypes.guess_type(fileToProcess)[0];

with open(fileToProcess, “rb”) as image_file:

imageData = base64.urlsafe_b64encode(image_file.read()).decode(“utf-8”)

imageData = ‘%s,%s’ % (prepend_info, imageData)

dataForImgUpload = {

‘image’ : imageData,

‘imageName’ : basenameOfFile,

‘bulkImgLabel’ : bulkImageLabel,

‘token’ : tokenForApi,

‘imageLocPath’ : fileToProcess

}

r_img = requests.post(imageUploadApiUrl, data=dataForImgUpload)

dataFromImgUpload = r_img.json()

print(dataFromImgUpload);

if dataFromImgUpload[‘status’] == 200 :

dataForStatusAndResult = {

‘jobid’ : dataFromImgUpload[‘jobId’],

‘token’ : tokenForApi

}

## This controls the maximum execution time of the program in your local machine.

## Set to 30 mins

maxAllowedTimeForExec = 30;

totalTimeExecuted = 0;

while True :

try :

r_status = requests.post(jobStatusApiUrl, data=dataForStatusAndResult)

dataFromStatus = r_status.json();

print(dataFromStatus);

if dataFromStatus[‘status’] == 200 :

if (dataFromStatus[‘statusJob’] == ‘COMPLETED’ or dataFromStatus[‘statusJob’] == ‘ERROR’ or dataFromStatus[‘statusJob’] == ‘HOLD’ ) :

break;

## Break on max allowed time

if totalTimeExecuted > (30 * 60) :

break;

## Sleep for 90 seconds before sending another request

sleepTime = 90;

totalTimeExecuted = totalTimeExecuted + sleepTime;

print(“Sleeping for “, sleepTime);

time.sleep(sleepTime);

else :

print(dataFromStatus);

break;

except requests.exceptions.ConnectionError :

time.sleep(3);

continue;

if (dataFromStatus[‘statusJob’] == ‘COMPLETED’ or dataFromStatus[‘statusJob’] == ‘ERROR’ or dataFromStatus[‘statusJob’] == ‘HOLD’) :

r_result = requests.post(jobResultApiUrl, data=dataForStatusAndResult)

dataFromResult = r_result.json();

print(dataFromResult);

else :

print(“Image Upload Status : “, dataFromImgUpload[‘status’], dataFromImgUpload[‘message’]);

except Exception as ex :

print(ex);

Log in with your credentials

Forgot your details?