Repository: Qiskit/qiskit

Issue:
Calling IBMQ.load_accounts() twice should give warning, not exception
<!-- ⚠️ 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**: latest master
- **Python version**: 3.7 
- **Operating system**: OSX

### What is the current behavior?
Calling `IBMQ.load_accounts()` twice gives an Exception.  However, in notebooks, it is common to just run multiple cells (or whole notebooks) repeatedly.  Raising an exception breaks this convenient workflow.  A similar issue, #673 , was raised and corrected, previously.


### Steps to reproduce the problem


### What is the expected behavior?



### Suggested solutions
Make repeated calls to `IBMQ.load_accounts()` give a warning instead.




Discussion:
This issue was not fixed in #962.  A new Exception is now raised if `IBMQ.load_accounts()` is called twice:

```python

IBMQAccountError: 'Credentials are already in use'
```

Resolving patch:
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
@@ -7,6 +7,7 @@
 
 """Provider for remote IBMQ backends with admin features."""
 
+import warnings
 from collections import OrderedDict
 
 from qiskit.backends import BaseProvider
@@ -93,9 +94,6 @@ def add_account(self, token, url=QE_URL, **kwargs):
             **kwargs (dict):
                 * proxies (dict): Proxy configuration for the API.
                 * verify (bool): If False, ignores SSL certificates errors
-
-        Raises:
-            IBMQAccountError: if the credentials are already in use.
         """
         credentials = Credentials(token, url, **kwargs)
 
@@ -104,12 +102,12 @@ def add_account(self, token, url=QE_URL, **kwargs):
         stored_credentials = read_credentials_from_qiskitrc()
 
         if credentials.unique_id() in stored_credentials.keys():
-            raise IBMQAccountError('Credentials are already stored')
-
-        self._append_account(credentials)
+            warnings.warn('Credentials are already stored')
+        else:
+            self._append_account(credentials)
 
-        # Store the credentials back to disk.
-        store_credentials(credentials)
+            # Store the credentials back to disk.
+            store_credentials(credentials)
 
     def remove_account(self, token, url=QE_URL, **kwargs):
         """Remove an account from the session and from disk.
@@ -199,8 +197,7 @@ def load_accounts(self, **kwargs):
         3. in the `qiskitrc` configuration file
 
         Raises:
-            IBMQAccountError: if attempting to load previously loaded accounts,
-                    or if no credentials can be found.
+            IBMQAccountError: if no credentials are found.
         """
         # Special handling of the credentials filters.
         credentials_filter = {}
@@ -223,14 +220,11 @@ def _append_account(self, credentials):
 
         Returns:
             IBMQSingleProvider: new single-account provider.
-
-        Raises:
-            IBMQAccountError: if the provider could not be appended.
         """
         # Check if duplicated credentials are already in use. By convention,
         # we assume (hub, group, project) is always unique.
         if credentials.unique_id() in self._accounts.keys():
-            raise IBMQAccountError('Credentials are already in use')
+            warnings.warn('Credentials are already in use.')
 
         single_provider = IBMQSingleProvider(credentials, self)
         self._accounts[credentials.unique_id()] = single_provider


Test patch:
diff --git a/test/python/test_registration.py b/test/python/test_registration.py
--- a/test/python/test_registration.py
+++ b/test/python/test_registration.py
@@ -67,9 +67,6 @@ def test_use_duplicate_credentials(self):
         with custom_qiskitrc(), mock_ibmq_provider():
             qiskit.IBMQ.use_account('QISKITRC_TOKEN')
 
-            with self.assertRaises(QISKitError):
-                qiskit.IBMQ.use_account('QISKITRC_TOKEN')
-
             self.assertEqual(len(qiskit.IBMQ._accounts), 1)
 
     def test_store_credentials(self):
@@ -106,10 +103,6 @@ def test_store_duplicate_credentials(self):
         with custom_qiskitrc(), mock_ibmq_provider():
             qiskit.IBMQ.add_account('QISKITRC_TOKEN')
 
-            with self.assertRaises(QISKitError):
-                # Note they are considered the same, as they have the same url.
-                qiskit.IBMQ.use_account('QISKITRC_TOKEN2')
-
             # Compare the session accounts with the ones stored in file.
             loaded_accounts = read_credentials_from_qiskitrc()
             self.assertEqual(len(qiskit.IBMQ._accounts), 1)
diff --git a/test/python/test_wrapper.py b/test/python/test_wrapper.py
--- a/test/python/test_wrapper.py
+++ b/test/python/test_wrapper.py
@@ -65,6 +65,7 @@ def test_register_twice(self, qe_token, qe_url):
             qiskit.wrapper.register(qe_token, qe_url)
         self.assertCountEqual(initial_providers, registered_providers())
 
+    @requires_qe_access
     def test_register_bad_credentials(self):
         """Test registering a provider with bad credentials."""
         initial_providers = registered_providers()