Source code for qiskit.providers.ibmq.credentials.credentials
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2018.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""Represent IBM Quantum Experience account credentials."""
import re
from typing import Dict, Tuple, Optional, Any
from requests_ntlm import HttpNtlmAuth
from .hubgroupproject import HubGroupProject
REGEX_IBMQ_HUBS = (
'(?P<prefix>http[s]://.+/api)'
'/Hubs/(?P<hub>[^/]+)/Groups/(?P<group>[^/]+)/Projects/(?P<project>[^/]+)'
)
"""str: Regex that matches an IBM Quantum Experience URL with hub information."""
TEMPLATE_IBMQ_HUBS = '{prefix}/Network/{hub}/Groups/{group}/Projects/{project}'
"""str: Template for creating an IBM Quantum Experience URL with hub/group/project information."""
[docs]class Credentials:
"""IBM Quantum Experience account credentials and preferences.
Note:
By convention, two credentials that have the same hub, group,
and project are considered equivalent, regardless of other attributes.
"""
def __init__(
self,
token: str,
url: str,
websockets_url: Optional[str] = None,
hub: Optional[str] = None,
group: Optional[str] = None,
project: Optional[str] = None,
proxies: Optional[Dict] = None,
verify: bool = True,
services: Optional[Dict] = None,
access_token: Optional[str] = None,
preferences: Optional[Dict] = None,
default_provider: Optional[HubGroupProject] = None
) -> None:
"""Credentials constructor.
Args:
token: IBM Quantum Experience API token.
url: IBM Quantum Experience URL.
websockets_url: URL for websocket server.
hub: The hub to use.
group: The group to use.
project: The project to use.
proxies: Proxy configuration.
verify: If ``False``, ignores SSL certificates errors.
services: Additional services for this account.
access_token: IBM Quantum access token.
preferences: Application preferences. Used for dictating preferred
action in services like the `ExperimentService`.
default_provider: Default provider to use.
"""
self.token = token
self.access_token = access_token
(self.url, self.base_url,
self.hub, self.group, self.project) = _unify_ibmq_url(
url, hub, group, project)
self.websockets_url = websockets_url
self.proxies = proxies or {}
self.verify = verify
self.preferences = preferences or {}
self.default_provider = default_provider
# Initialize additional service URLs.
services = services or {}
self.extractor_url = services.get('extractorsService', None)
self.experiment_url = services.get('resultsDB', None)
self.runtime_url = services.get('runtime', None)
[docs] def is_ibmq(self) -> bool:
"""Return whether the credentials represent an IBM Quantum Experience account."""
return all([self.hub, self.group, self.project])
def __eq__(self, other: object) -> bool:
if not isinstance(other, Credentials):
return False
return (self.token == other.token) & (self.unique_id() == other.unique_id())
[docs] def unique_id(self) -> HubGroupProject:
"""Return a value that uniquely identifies these credentials.
By convention, two credentials that have the same hub, group,
and project are considered equivalent.
Returns:
A ``HubGroupProject`` instance.
"""
return HubGroupProject(self.hub, self.group, self.project)
[docs] def connection_parameters(self) -> Dict[str, Any]:
"""Construct connection related parameters.
Returns:
A dictionary with connection-related parameters in the format
expected by ``requests``. The following keys can be present:
``proxies``, ``verify``, and ``auth``.
"""
request_kwargs = {
'verify': self.verify
}
if self.proxies:
if 'urls' in self.proxies:
request_kwargs['proxies'] = self.proxies['urls']
if 'username_ntlm' in self.proxies and 'password_ntlm' in self.proxies:
request_kwargs['auth'] = HttpNtlmAuth(
self.proxies['username_ntlm'],
self.proxies['password_ntlm']
)
return request_kwargs
def _unify_ibmq_url(
url: str,
hub: Optional[str] = None,
group: Optional[str] = None,
project: Optional[str] = None
) -> Tuple[str, str, Optional[str], Optional[str], Optional[str]]:
"""Return a new-style set of credential values (url and hub parameters).
Args:
url: URL for IBM Quantum Experience.
hub: The hub to use.
group: The group to use.
project: The project to use.
Returns:
A tuple that consists of ``url``, ``base_url``, ``hub``, ``group``,
and ``project``, where
* url: The new-style IBM Quantum Experience URL that contains
the hub, group, and project names.
* base_url: Base URL that does not contain the hub, group, and
project names.
* hub: The hub to use.
* group: The group to use.
* project: The project to use.
"""
# Check if the URL is "new style", and retrieve embedded parameters from it.
regex_match = re.match(REGEX_IBMQ_HUBS, url, re.IGNORECASE)
base_url = url
if regex_match:
base_url, hub, group, project = regex_match.groups()
else:
if hub and group and project:
# Assume it is an IBMQ URL, and update the url.
url = TEMPLATE_IBMQ_HUBS.format(prefix=url, hub=hub, group=group,
project=project)
else:
# Cleanup the hub, group and project, without modifying the url.
hub = group = project = None
return url, base_url, hub, group, project