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
- 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
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:
- The image should be either of format jpeg or png.
- 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: For jpeg: Example: |
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:
- {‘status’: 411, ‘message’: ‘LC-ERR-0033 : Max Allowed Single Image Size 5 MB.’}
- {‘status’: 411, ‘message’: ‘LC-ERR-0034 : Only jpeg and png type images allowed.’}
- {‘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:
|
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:
- Get Token when username and password are sent and are authenticated.
- Send an image for DR processing.
- Ping the api every 90 seconds for the status of the request sent.
- 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);