Repository: spyder-ide/spyder

Issue:
TypeError when starting Kite client
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

installed spyder 4.0.1 using "conda update spyder". Had previously installed spyder 4.0.0 using "conda install spyder=4.0.0" and could not get past the starting-to-open state. python is at 3.7.3

### Traceback
```python-traceback
  File "C:\Progra~1\Anaconda3\lib\site-packages\spyder\plugins\completion\kite\client.py", line 108, in get_status
    self.sig_status_response_ready[dict].emit(kite_status)
TypeError: KiteClient.sig_status_response_ready[dict].emit(): argument 1 has unexpected type 'str'
```

## Versions

* Spyder version: 4.0.1 
* Python version: 3.7.3
* Qt version: 5.12.5
* PyQt5 version: 5.12.3
* Operating System: Windows 10

### Dependencies

```
atomicwrites >=1.2.0         :  1.3.0 (OK)
chardet >=2.0.0              :  3.0.4 (OK)
cloudpickle >=0.5.0          :  1.2.2 (OK)
diff_match_patch >=20181111  :  20181111 (OK)
intervaltree                 :  None (OK)
IPython >=4.0                :  7.11.1 (OK)
jedi =0.14.1                 :  0.14.1 (OK)
nbconvert >=4.0              :  5.6.1 (OK)
numpydoc >=0.6.0             :  0.9.2 (OK)
pexpect >=4.4.0              :  4.7.0 (OK)
pickleshare >=0.4            :  0.7.5 (OK)
psutil >=0.3                 :  5.6.7 (OK)
pygments >=2.0               :  2.5.2 (OK)
pylint >=0.25                :  2.4.4 (OK)
pyls >=0.31.2;<0.32.0        :  0.31.4 (OK)
zmq >=17                     :  18.1.1 (OK)
qdarkstyle >=2.7             :  2.7 (OK)
qtawesome >=0.5.7            :  0.6.0 (OK)
qtconsole >=4.6.0            :  4.6.0 (OK)
qtpy >=1.5.0                 :  1.9.0 (OK)
rtree >=0.8.3                :  0.9.3 (OK)
sphinx >=0.6.6               :  2.3.1 (OK)
spyder_kernels >=1.8.1;<2.0.0:  1.8.1 (OK)
watchdog                     :  None (OK)
cython >=0.21                :  None (NOK)
matplotlib >=2.0.0           :  None (NOK)
numpy >=1.7                  :  1.17.3 (OK)
pandas >=0.13.1              :  None (NOK)
scipy >=0.17.0               :  1.3.1 (OK)
sympy >=0.7.3                :  None (NOK)
```



Discussion:
have created a "bare" anaconda environment and reinstalled spyder and now get the following kite-related errors:
File "C:\Progra~1\Anaconda3\envs\bare\lib\site-packages\spyder\app\mainwindow.py", line 3718, in main
mainwindow = run_spyder(app, options, args)
File "C:\Progra~1\Anaconda3\envs\bare\lib\site-packages\spyder\app\mainwindow.py", line 3559, in run_spyder
main.setup()
File "C:\Progra~1\Anaconda3\envs\bare\lib\site-packages\spyder\app\mainwindow.py", line 960, in setup
self.completions.start()
File "C:\Progra~1\Anaconda3\envs\bare\lib\site-packages\spyder\plugins\completion\plugin.py", line 292, in start
client_info['plugin'].start()
File "C:\Progra~1\Anaconda3\envs\bare\lib\site-packages\spyder\plugins\completion\kite\plugin.py", line 144, in start
self.client.start()
File "C:\Progra~1\Anaconda3\envs\bare\lib\site-packages\spyder\plugins\completion\kite\client.py", line 62, in start
self.sig_client_started.emit(self.languages)
TypeError: KiteClient.sig_client_started[list].emit(): argument 1 has unexpected type 'str'
ignore strikeouts; they were created by having a tilde between "Progra" and 1
could you post the output of

```
$ curl -v http://localhost:46624/clientapi/languages
$ curl -v http://localhost:46624/clientapi/status?filetype=python
```
my employer-owned system ended up having "forbidden" messages when running the curl commands, but I did get myself to a workable state. On that system I downgraded Spyder to the latest v3. On my home system I was able to get v4.0.1 working.
It looks like we just need to check the status code of the response and gracefully fail in these sorts of cases @ccordoba12 
@suzannejb, thanks a lot for your information. That was very helpful!
> It looks like we just need to check the status code of the response and gracefully fail in these sorts of cases

@metalogical, it seems this is a firewall issue and I totally agree with your proposed solution. Could you help us with this?
@suzannejb if possible could you post the full output of `curl -v` on your employer-owned machine? In particular, I'm interested in the HTTP status code. I don't see how this could happen unless the status code is 200 for some reason (despite the "forbidden" response)
I am afraid it can't be run on that machine. I didn't see any http status code within all of the error/forbidden messages.

Resolving patch:
diff --git a/spyder/plugins/completion/kite/client.py b/spyder/plugins/completion/kite/client.py
--- a/spyder/plugins/completion/kite/client.py
+++ b/spyder/plugins/completion/kite/client.py
@@ -18,6 +18,7 @@
 import requests
 
 # Local imports
+from spyder.config.base import _
 from spyder.plugins.completion.kite import KITE_ENDPOINTS, KITE_REQUEST_MAPPING
 from spyder.plugins.completion.kite.decorators import class_register
 from spyder.plugins.completion.kite.providers import KiteMethodProviderMixIn
@@ -102,14 +103,30 @@ def _get_status(self, filename):
             url_params = {'filetype': 'python'}
         success, response = self.perform_http_request(
             verb, url, url_params=url_params)
-        return response
+        return success, response
 
     def get_status(self, filename):
         """Get kite status for a given filename."""
-        kite_status = self._get_status(filename)
+        success_status, kite_status = self._get_status(filename)
         if not filename or kite_status is None:
             kite_status = status()
             self.sig_status_response_ready[str].emit(kite_status)
+        elif isinstance(kite_status, TEXT_TYPES):
+            if not success_status:
+                status_str = status(extra_status=' with errors')
+                long_str = _("<code>{error}</code><br><br>"
+                             "Note: If you are using a VPN, "
+                             "please don't route requests to "
+                             "localhost/127.0.0.1 with it").format(
+                                 error=kite_status)
+            else:
+                status_str = status()
+                long_str = kite_status
+            kite_status_dict = {
+                'status': status_str,
+                'short': status_str,
+                'long': long_str}
+            self.sig_status_response_ready[dict].emit(kite_status_dict)
         else:
             self.sig_status_response_ready[dict].emit(kite_status)
 
diff --git a/spyder/plugins/completion/kite/utils/status.py b/spyder/plugins/completion/kite/utils/status.py
--- a/spyder/plugins/completion/kite/utils/status.py
+++ b/spyder/plugins/completion/kite/utils/status.py
@@ -85,12 +85,12 @@ def is_proc_kite(proc):
     return is_kite
 
 
-def status():
+def status(extra_status=''):
     """Kite completions status: not installed, ready, not running."""
     kite_installed, _ = check_if_kite_installed()
     if not kite_installed:
-        return NOT_INSTALLED
+        return NOT_INSTALLED + extra_status
     elif check_if_kite_running():
-        return RUNNING
+        return RUNNING + extra_status
     else:
-        return NOT_RUNNING
+        return NOT_RUNNING + extra_status


Test patch: