Skip to content
Snippets of Python code you may find useful to connect to the NuraLogix DeepAffex API
Python
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
dfxsnippets
.gitignore
LICENSE.txt
README.md
default.config
measure.py
setup.py

README.md

DFX API Python Snippets

This repository contains snippets of Python code you may find useful to connect to the NuraLogix DeepAffex API

Getting started

  • Create and activate your python3.6 environment and run pip install .

  • Get payload files(payload, metadata, properties) from the DFX SDK and save them in a directory

  • In a shell, run:

    python measure.py "studyID received from Nuralogix" \
                      "Token from registration/login process"
                      "your directory above" \
                      --restUrl="base REST url to the DFX API" \
                      --wsUrl="base Websocket url to the DFX API" \
                      --outputDir="directory for results" \
                      --connectionMethod="Websocket"

Let's take a look at measure.py

First we import what we need:

import asyncio  # For async operations
import argparse # For parsing arguments

# The followings are the libraries we made in the dfxsnippets directory
# Refer to each .md files of them for detailed description
from dfxsnippets.createMeasurement import createMeasurement
from dfxsnippets.subscribeResults import subscribeResults
from dfxsnippets.addData import addData
from dfxsnippets.websocketHelper import WebsocketHandler

Then, we parse the command line to set up the studyId, token, restUrl, websocketUrl, the input directory to the payload files, output directory, connection method (can only be "REST" or "Websocket"),

parser = argparse.ArgumentParser()

parser.add_argument("studyID", help="StudyID")
parser.add_argument("token", help="user or device token")
parser.add_argument("payloadDir", help="Directory of payload files")
parser.add_argument("--restUrl", help="DFX API REST url", default="https://qa.api.deepaffex.ai:9443")
parser.add_argument("--wsUrl", help="DFX API Websocket url", default="wss://qa.api.deepaffex.ai:9080")
parser.add_argument("--outputDir", help="Directory for received files", default=None)
parser.add_argument("--connectionMethod", help="Connection method", choices=["REST", "Websocket"], default="REST")

args = parser.parse_args()

studyID = args.studyID
token = args.token
rest_url = args.restUrl
ws_url = args.wsUrl
conn_method = args.connectionMethod
input_directory = args.payloadDir
output_directory = args.outputDir

Then, we create the eventloop which manages all the async tasks, as well as a list of async tasks:

loop = asyncio.get_event_loop()
tasks = []

and a WebsocketHandler object for handling websockets:

websocketobj = WebsocketHandler(token, ws_url)

Now, we must establish the websocket connection. Note that this must be done first as not doing so will return errors. However, it needs to time out after a few seconds in case of a failure, so we handle it as follows:

tasks.append(loop.create_task(websocketobj.connect_ws()))
wait_tasks = asyncio.wait(tasks, timeout=10)
loop.run_until_complete(wait_tasks)

We then create a Measurement and get it's measurementID

createmeasurementObj = createMeasurement(studyID, token, rest_url)
measurementID = createmeasurementObj.create()

Then, we create an addData object which prepares the data to be sent from the input_directory. If the connection method is 'REST' then pass in None for websocketobj.

if conn_method == 'REST':
    adddataObj = addData(measurementID, token, rest_url, None, input_directory)
else:
    adddataObj = addData(measurementID, token, rest_url, websocketobj, input_directory)

Then, we create a subscribeResults object which prepares the subscribeResults request

subscriberesultsObj = subscribeResults(
    measurementID, token, websocketobj, adddataObj.num_chunks, out_folder=output_directory)

Add the adddataObj.sendAsync() and subscribeResults.subscribe() method to an async task list:

tasks.append(loop.create_task(adddataObj.sendAsync()))
tasks.append(loop.create_task(subscriberesultsObj.subscribe()))

Since the event loop has already been started when doing websocketobj.connect_ws(), it will just run the remaining tasks in order asynchronously.

In this process, whenever the sendAsyncs are awaiting for I/O operation to finish, the event loop will try to switch context to the next async task that is not awaiting, which is the subscribeResults.subscribe() in our case.

At this point, once the event loop has finished all the chunks in addData.sendAsync(), we ask the eventloop to keep running until the subscribeResults.subscribe() finishes, which will return when all chunks results are received, in the task list to finish.

wait_tasks = asyncio.wait(tasks)
loop.run_until_complete(wait_tasks)

At the end, we need to close the websocket connection and close the event loop:

loop.run_until_complete(websocketobj.handle_close())
loop.close()
You can’t perform that action at this time.