Source code for qiskit.providers.ibmq.credentials.credentials

# -*- coding: utf-8 -*-

# 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
import warnings

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. 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 ) -> 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. """ self.token = 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 # Normalize proxy urls. self._prepend_protocol_if_needed()
[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: return self.__dict__ == other.__dict__
[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 _prepend_protocol_if_needed(self) -> None: """Prepend the proxy URLs with protocol if needed.""" if 'urls' not in self.proxies: return warning_issued = False for key, url in self.proxies['urls'].items(): colon_pos = url.find(':') if colon_pos < 0 or re.match(r'[0-9]*$', url[colon_pos+1:]): # If colon not found OR everything after colon are digits (i.e. port number). if not warning_issued: warnings.warn("Proxy URLs without protocols (e.g. 'http://') " "will no longer be supported in the future release.", DeprecationWarning, stacklevel=4) warning_issued = True prepend_str = 'http:' if url[:2] != '//': prepend_str += '//' self.proxies['urls'][key] = prepend_str + url
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