Repository: augerai/a2ml
Issue: "RuntimeError: There is no current event loop in thread X" is thrown when using api w/ a2ml server from django

There might be a threading issue with the asyncio / websocket dependency when calling the api functions like `predict()` from a  webserver such as the django development server.

Here's a sample that's called from a django server:

```python
ctx = Context(debug=True)
a2ml = A2ML(ctx, 'azure')  
prediction = a2ml.predict(None,A2ML_MODEL,AUGER_THRESHOLD,data=dicts)  
```

This will throw an exception like the following:

```
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py”, line 644, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread ‘Thread-13’.
----------------------------------------
Exception happened during processing of request from (‘127.0.0.1’, 54306)
Traceback (most recent call last):
  File “/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py”, line 650, in process_request_thread
    self.finish_request(request, client_address)
  File “/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py”, line 360, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File “/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socketserver.py”, line 720, in __init__
    self.handle()
  File “~/.virtualenvs/venv/lib/python3.7/site-packages/django/core/servers/basehttp.py”, line 171, in handle
    self.handle_one_request()
  File “~/.virtualenvs/venv/lib/python3.7/site-packages/django/core/servers/basehttp.py”, line 179, in handle_one_request
    self.raw_requestline = self.rfile.readline(65537)
  File “/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py”, line 589, in readinto
    return self._sock.recv_into(b)
```

Note that these calls work from a WSGI server like gunicorn.

Changed files:
a2ml/api/utils/remote_runner.py

diff --git a/a2ml/api/utils/remote_runner.py b/a2ml/api/utils/remote_runner.py
index 4bd4e54..c5433a9 100644
--- a/a2ml/api/utils/remote_runner.py
+++ b/a2ml/api/utils/remote_runner.py
@@ -93,17 +93,26 @@ class RemoteRunner(object):
                 params['tmp_file_to_remove'] = uploaded_file
 
             res = self.make_requst(http_verb, path, params)
-            return asyncio.get_event_loop().run_until_complete(self.wait_result(res['data']['request_id'], local_file))
+            return self.get_event_loop().run_until_complete(self.wait_result(res['data']['request_id'], local_file))
         except Exception as exc:
             if self.ctx.debug:
                 import traceback
                 traceback.print_exc()
-            
+
             self.ctx.log(str(exc))
 
-            return {self.provider: {
-                'result': False,
-                'data': str(exc) }}
+            return {
+                self.provider: {
+                    'result': False,
+                    'data': str(exc)
+                }
+            }
+
+    def get_event_loop(self):
+        try:
+            return asyncio.get_event_loop()
+        except RuntimeError:
+            return asyncio.new_event_loop()
 
     def make_requst(self, http_verb, path, params={}):
         method = getattr(requests, http_verb)
@@ -214,7 +223,7 @@ class RemoteRunner(object):
                     print(data['status'] + ':', data['result'])
         elif isinstance(data, Exception):
             if self.ctx.debug:
-                import traceback; 
+                import traceback;
                 traceback.print_exc()
 
             sys.stdout.write('\\b')
@@ -261,9 +270,12 @@ class RemoteRunner(object):
                     done = True
                     break
 
-        if  data.get('result'):           
+        if data.get('result'):
             return data.get('result')
 
-        return {self.provider: {
-            'result': False,
-            'data': "Server error. Please try again..." }}
+        return {
+            self.provider: {
+                'result': False,
+                'data': "Server error. Please try again..."
+            }
+        }