# Copyright (C) 2023 qBraid
#
# This file is part of the qBraid-SDK
#
# The qBraid-SDK is free software released under the GNU General Public License v3
# or later. You can redistribute and/or modify it under the terms of the GPL v3.
# See the LICENSE file in the project root or <https://www.gnu.org/licenses/gpl-3.0.html>.
#
# THERE IS NO WARRANTY for the qBraid-SDK, as per Section 15 of the GPL v3.
"""
Module for configuring provider credentials and authentication.
"""
from abc import ABC, abstractmethod
from typing import List
from qbraid._qdevice import QDEVICE, QDEVICE_TYPES
[docs]
class QbraidDeviceNotFoundError(Exception):
"""Exception raised when no device could be found."""
class QuantumProvider(ABC):
"""
This class is responsible for managing the interactions and
authentications with various Quantum services.
"""
@abstractmethod
def save_config(self):
"""Save the current configuration."""
@abstractmethod
def get_devices(self):
"""Return a list of backends matching the specified filtering."""
@abstractmethod
def get_device(self, vendor_device_id: str):
"""Return quantum device corresponding to the specified device ID."""
[docs]
class QbraidProvider(QuantumProvider):
"""
This class is responsible for managing the interactions and
authentications with the AWS and IBM Quantum services.
Attributes:
aws_access_key_id (str): AWS access key ID for authenticating with AWS services.
aws_secret_access_key (str): AWS secret access key for authenticating with AWS services.
qiskit_ibm_token (str): IBM Quantum token for authenticating with IBM Quantum services.
"""
[docs]
def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, qiskit_ibm_token=None):
"""
Initializes the QbraidProvider object with optional AWS and IBM Quantum credentials.
Args:
aws_access_key_id (str, optional): AWS access key ID. Defaults to None.
aws_secret_access_key (str, optional): AWS secret access token. Defaults to None.
qiskit_ibm_token (str, optional): IBM Quantum token. Defaults to None.
"""
self._aws_provider = self._get_aws_provider(aws_access_key_id, aws_secret_access_key)
self._ibm_provider = self._get_ibm_provider(qiskit_ibm_token)
def save_config(self):
raise NotImplementedError
def _get_aws_provider(self, aws_access_key_id, aws_secret_access_key):
if "braket.aws.aws_device.AwsDevice" not in QDEVICE_TYPES:
return None
from qbraid.providers.aws import BraketProvider # pylint: disable=import-outside-toplevel
try:
return BraketProvider(aws_access_key_id, aws_secret_access_key)
except Exception: # pylint: disable=broad-exception-caught
return None
def _get_ibm_provider(self, qiskit_ibm_token):
if "qiskit_ibm_provider.ibm_backend.IBMBackend" not in QDEVICE_TYPES:
return None
from qbraid.providers.ibm import QiskitProvider # pylint: disable=import-outside-toplevel
try:
return QiskitProvider(qiskit_ibm_token)
except Exception: # pylint: disable=broad-exception-caught
return None
def _get_ibm_runtime(self, qiskit_ibm_token):
if "qiskit_ibm_runtime.ibm_backend.IBMBackend" not in QDEVICE_TYPES:
return None
from qbraid.providers.ibm import QiskitRuntime # pylint: disable=import-outside-toplevel
try:
return QiskitRuntime(qiskit_ibm_token)
except Exception: # pylint: disable=broad-exception-caught
return None
def get_devices(self) -> List[QDEVICE]:
"""Return a list of backends matching the specified filtering.
Returns:
list[QDEVICE]: a list of Backends that match the filtering
criteria.
"""
devices = []
for provider in [self._aws_provider, self._ibm_provider]:
if provider is not None:
devices += provider.get_devices()
return devices
def get_device(self, vendor_device_id: str) -> QDEVICE:
"""Return quantum device corresponding to the specified device ID.
Returns:
QDEVICE: the quantum device corresponding to the given ID
Raises:
QbraidDeviceNotFoundError: if no device could be found
"""
if vendor_device_id.startswith("ibm") or vendor_device_id.startswith("simulator"):
if self._ibm_provider is not None:
return self._ibm_provider.get_device(vendor_device_id)
if vendor_device_id.startswith("arn:aws"):
if self._aws_provider is not None:
return self._aws_provider.get_device(vendor_device_id)
raise QbraidDeviceNotFoundError(f"Device {vendor_device_id} not found.")