Repository: Qiskit/qiskit

Issue:
credentials failed for qiskit ver 0.6.1
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Informations

- **Qiskit Terra version**: 0.6.1
- **Python version**: 3.7.0
- **Operating system**:MAC OSX 10.13.6 

### What is the current behavior?
After I acquired fresh token from https://quantumexperience.ng.bluemix.net/qx/account/advanced
IBMQ.load_accounts() fails.

### Steps to reproduce the problem
```
from qiskit import IBMQ
myToken='b6abe11442c9a...'
IBMQ.save_account(myToken)
IBMQ.load_accounts()
```
Results with
```
Traceback (most recent call last):
  File "/anaconda3/lib/python3.7/site-packages/qiskit/backends/ibmq/ibmqsingleprovider.py", line 71, in _authenticate
    credentials.verify)
  File "/anaconda3/lib/python3.7/site-packages/IBMQuantumExperience/IBMQuantumExperience.py", line 478, in __init__
    self.req = _Request(token, config=config, verify=verify)
  File "/anaconda3/lib/python3.7/site-packages/IBMQuantumExperience/IBMQuantumExperience.py", line 253, in __init__
    ntlm_credentials=self.ntlm_credentials)
  File "/anaconda3/lib/python3.7/site-packages/IBMQuantumExperience/IBMQuantumExperience.py", line 95, in __init__
    self.obtain_token(config=self.config)
  File "/anaconda3/lib/python3.7/site-packages/IBMQuantumExperience/IBMQuantumExperience.py", line 159, in obtain_token
    raise CredentialsError('error during login: %s' % error_message)
IBMQuantumExperience.IBMQuantumExperience.CredentialsError: error during login: Wrong user or password, check your credentials.
```

### What is the expected behavior?
Would be better if  IBMQ.load_accounts() accepted me. All worked well w/ ver 0.5.


### Suggested solutions





Discussion:
Can you try enable_account or regenerating the token. Your code should work. If you type `IBMQ.stored_accounts()` do you see the account.
@pacomf I can confirm this has happened to me today as well. 
I cant reproduce the bug, i regenerate my APIToken and it works fine using qiskit terra... is it still happening? Can you send me more details?
It happened for about 5 hours on the weekend. However, @nonhermitian could run at the same time and then it started working again. 
Mmmm, maybe an issue with the API... we will investigate it
I will add that, when it happened to me, I could log into some accounts and not others.
Hi @jaygambetta,
your tip helped. IBMQ.stored_accounts() has returned some  old token, not the new one.
Looks like IBMQ.save_account(myToken) is unable to replace token if it exist - I leave it to you to decide if it is a bug or a feature.
My hack around it is to execute first: IBMQ.delete_accounts()
to clear my old token. So this sequence always works:
`
IBMQ.delete_accounts()
myToken='b6abe11442c9a...'
IBMQ.save_account(myToken)
IBMQ.load_accounts()
`
I can move on, closing thus ticket.
Thanks for help
Jan
Let's leave this open and investigate whether there's a bug with `IBMQ.save_account()` re-writing old tokens.
@diego-plan9 can you please have a look?
Yes - thanks @balewski for the information, which is spot on - currently, `IBMQ.save_account()` will just print a warning and do nothing else if old credentials are present:

https://github.com/Qiskit/qiskit-terra/blob/master/qiskit/backends/ibmq/ibmqprovider.py#L140-L143

> Looks like IBMQ.save_account(myToken) is unable to replace token if it exist - I leave it to you to decide if it is a bug or a feature.

Actually ... I can't decide if it is a bug or a feature either! :thinking: In the original draft implementation, the `.save_account()` (`.add_account()` by that time) method was [raising an Exception](https://github.com/Qiskit/qiskit-terra/blob/746245e29c5cadc44dc37851b19a4150b4e86cd8/qiskit/backends/ibmq/ibmqprovider.py#L111) in the case of trying to store a duplicate account. This was later changed to a warning, I'm unsure if by design and as a hard requisite from Jupyter-users needs, or also related to the slight tuning of the method functionality (ie. not authenticating during the call, just storing in disk). So I'm actually de-assigning myself, as probably the rest of the team has a more fresh view of the design decisions related to #1000.

I think we have several options:
* consider that not overwriting and raising a warning is indeed the desired behavior: the main drawback is that the warning might be easy to miss (and was probably the source of confusion in this issue).
* tune the method a bit in order to accept an `overwrite=True` optional parameter or a similar approach: the `credentials` module already has the needed parts in place, the main drawback would be that we touch a bit the public API.
* be a bit more restrictive and promote the warning back to an exception: it might affect users running the method twice and already used to not raising a warning (ie. maybe notebook users).

One way or the other, I think we need to make sure that the flow for updating an existing stored token is a bit smoother than the delete-save workaround proposed by @balewski, as it seems a relatively common use case.

From external user perspective:

It happens rather often  that the ibmq_16_melbourne or even sometimes ibmqx4 does not accept the job, throws some 'general error', despite your web-page says both hardwares are operational.
Then, it is natural to (wrongly?) guess perhaps my token is invalid.
Then, I'd ask for a new token and try to use it - hoping it will help.
For such train of though  the natural solution  is assume 'user knows what he wants'. If user wants to replace the token by calling save_account(), just replace it. You can issue a warning that there was an old token (still valid), but why not just replace token each time user calls IBMQ.save_account(myToken) ?
Would this have any negative effect on your end? 
Thanks
Jan
I think save_account should not raise an exception. Overwriting is not bad behavior. Similar to overwriting a key in a dict or something. Should just work.
@ajavadia is there an update.
Hi,
there is some inconsistency between the devices status you show here:
https://quantumexperience.ng.bluemix.net/qx/account/advanced
and actual avaliability.
At this moment, both ibmqx4 and ibmq_16_melbourne are reported to work.

However,. when I try to submit my circuit using  Qiskit ver: 0.6.1 I get the error below for either.

Got a 400 code response to https://quantumexperience.ng.bluemix.net/api/Jobs?access_token=VCgYWnMUUBaYeT5gSmGO14cX93Foo4rccsLUVvIjf3bwYEZNjxlDcRmPArS2wZ25: {"error":{"status":400,"message":"Generic error","code":"GENERIC_ERROR"}}

Note, my token is correct, because I can submit the circuit to your simulator
 'backend': 'ibmq_qasm_simulator',
 'jobId2': '1814808',
 'startTime': '2018-11-09 17:53:28'}

Can you have a look ?
Thanks
Jan

Resolving patch:
diff --git a/qiskit/backends/ibmq/credentials/_configrc.py b/qiskit/backends/ibmq/credentials/_configrc.py
--- a/qiskit/backends/ibmq/credentials/_configrc.py
+++ b/qiskit/backends/ibmq/credentials/_configrc.py
@@ -9,6 +9,7 @@
 Utilities for reading and writing credentials from and to configuration files.
 """
 
+import warnings
 import os
 from ast import literal_eval
 from collections import OrderedDict
@@ -116,15 +117,17 @@ def store_credentials(credentials, overwrite=False, filename=None):
             location is used (`HOME/.qiskit/qiskitrc`).
 
     Raises:
-        QISKitError: If credentials already exists and overwrite=False; or if
-            the account_name could not be assigned.
+        QISKitError: if the account_name could not be assigned.
     """
     # Read the current providers stored in the configuration file.
     filename = filename or DEFAULT_QISKITRC_FILE
     stored_credentials = read_credentials_from_qiskitrc(filename)
 
+    # Check if duplicated credentials are already stored. By convention,
+    # we assume (hub, group, project) is always unique.
     if credentials.unique_id() in stored_credentials and not overwrite:
-        raise QISKitError('Credentials already present and overwrite=False')
+        warnings.warn('Credentials already present. Set overwrite=True to overwrite.')
+        return
 
     # Append and write the credentials to file.
     stored_credentials[credentials.unique_id()] = credentials
diff --git a/qiskit/backends/ibmq/credentials/credentials.py b/qiskit/backends/ibmq/credentials/credentials.py
--- a/qiskit/backends/ibmq/credentials/credentials.py
+++ b/qiskit/backends/ibmq/credentials/credentials.py
@@ -22,7 +22,7 @@ class Credentials(object):
     """IBM Q account credentials.
 
     Note that, by convention, two credentials that have the same hub, group
-    and token (regardless of other attributes) are considered equivalent.
+    and project (regardless of other attributes) are considered equivalent.
     The `unique_id()` returns the unique identifier.
     """
 
diff --git a/qiskit/backends/ibmq/ibmqprovider.py b/qiskit/backends/ibmq/ibmqprovider.py
--- a/qiskit/backends/ibmq/ibmqprovider.py
+++ b/qiskit/backends/ibmq/ibmqprovider.py
@@ -116,7 +116,7 @@ def enable_account(self, token, url=QE_URL, **kwargs):
 
         self._append_account(credentials)
 
-    def save_account(self, token, url=QE_URL, **kwargs):
+    def save_account(self, token, url=QE_URL, overwrite=False, **kwargs):
         """Save the account to disk for future use.
 
         Login into Quantum Experience or IBMQ using the provided credentials,
@@ -127,20 +127,13 @@ def save_account(self, token, url=QE_URL, **kwargs):
             token (str): Quantum Experience or IBM Q API token.
             url (str): URL for Quantum Experience or IBM Q (for IBM Q,
                 including the hub, group and project in the URL).
+            overwrite (bool): overwrite existing credentials.
             **kwargs (dict):
                 * proxies (dict): Proxy configuration for the API.
                 * verify (bool): If False, ignores SSL certificates errors
         """
         credentials = Credentials(token, url, **kwargs)
-
-        # Check if duplicated credentials are already stored. By convention,
-        # we assume (hub, group, project) is always unique.
-        stored_credentials = read_credentials_from_qiskitrc()
-
-        if credentials.unique_id() in stored_credentials.keys():
-            warnings.warn('Credentials are already stored.')
-        else:
-            store_credentials(credentials)
+        store_credentials(credentials, overwrite=overwrite)
 
     def active_accounts(self):
         """List all accounts currently in the session.


Test patch:
diff --git a/test/python/ibmq/test_registration.py b/test/python/ibmq/test_registration.py
--- a/test/python/ibmq/test_registration.py
+++ b/test/python/ibmq/test_registration.py
@@ -9,6 +9,7 @@
 """
 Test the registration and credentials features of the wrapper.
 """
+import warnings
 import os
 from contextlib import contextmanager
 from tempfile import NamedTemporaryFile
@@ -179,10 +180,12 @@ def test_store_credentials_overwrite(self):
 
         with custom_qiskitrc():
             store_credentials(credentials)
+            # Cause all warnings to always be triggered.
+            warnings.simplefilter("always")
             # Attempt overwriting.
-            with self.assertRaises(QISKitError) as context_manager:
+            with warnings.catch_warnings(record=True) as w:
                 store_credentials(credentials)
-            self.assertIn('already present', str(context_manager.exception))
+                self.assertIn('already present', str(w[0]))
 
             with no_file('Qconfig.py'), no_envs(), mock_ibmq_provider():
                 # Attempt overwriting.