Skip to content
This repository has been archived by the owner on Jun 17, 2024. It is now read-only.

Commit

Permalink
feat: Finalized integration and acceptance tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Wagner committed Dec 30, 2022
1 parent 1feac5a commit 3bce5e6
Show file tree
Hide file tree
Showing 17 changed files with 386 additions and 203 deletions.
5 changes: 3 additions & 2 deletions planqk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
def base_url():
return os.environ.get('PLANQK_QUANTUM_BASE_URL', 'https://quantum-engine.platform.planqk.de')


# TODO read always from env first even if token provided

logger = logging.getLogger(__name__)


def _dict_values_to_string(obj_values_dict: dict):
for key in obj_values_dict:
obj_value = obj_values_dict[key]
Expand All @@ -24,7 +26,6 @@ def _dict_values_to_string(obj_values_dict: dict):
obj_values_dict[key] = str_value



class PlanqkClient(object):

def __init__(self, credentials: DefaultCredentialsProvider):
Expand All @@ -44,7 +45,7 @@ def submit_job(self, job) -> dict:
headers["Content-Type"] = "application/json"

job_dict = job.toDict()
_dict_values_to_string(job_dict.get("meta_data"))
_dict_values_to_string(job_dict.get("metadata"))

response = requests.post(f'{base_url()}/jobs', json=job_dict, headers=headers)
if not response:
Expand Down
2 changes: 2 additions & 0 deletions planqk/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ class PlanqkClientError(PlanqkError):

class CredentialUnavailableError(PlanqkError):
pass

# TODO exception handling in tests
46 changes: 20 additions & 26 deletions planqk/planqk_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

DEFAULT_TIMEOUT = 300 # Default timeout for waiting for job to complete


class ErrorData(object):
def __init__(self, code: str, message: str):
self.code = code
Expand Down Expand Up @@ -31,14 +32,15 @@ def _update_job_details(self,
input_data: str = None,
name: str = None,
input_params: object = None,
meta_data: dict[str, str] = None,
metadata: dict[str, str] = None,
output_data_format: str = None,
output_data: object = None,
status: str = None,
creation_time: str = None,
begin_execution_time: str = None,
end_execution_time: str = None,
cancellation_time: str = None,
tags: list[str] = [],
error_data: ErrorData = None):

self.job_id = job_id
Expand All @@ -48,34 +50,34 @@ def _update_job_details(self,
self.input_params = input_params
self.provider_id = provider_id
self.target = target
self.meta_data = meta_data
self.metadata = metadata
self.output_data = output_data
self.output_data_format = output_data_format
self.status = status
self.creation_time = creation_time
self.begin_execution_time = begin_execution_time
self.end_execution_time = end_execution_time
self.cancellation_time = cancellation_time
self.tags = tags
self.error_data = error_data
# self.tags = kwargs.get('tags', None) TODO qiskit specific?

def _json_dict_to_params(self, job_details_dict):
return dict(provider_id=job_details_dict['providerId'],
return dict(provider_id=job_details_dict['provider_id'],
target=job_details_dict['target'],
input_data_format=job_details_dict['inputDataFormat'],
job_id=self.job_id,
input_data_format=job_details_dict['input_data_format'],
job_id=job_details_dict['id'],
input_data=job_details_dict.get('input_data_format', None),
name=job_details_dict.get('name', None),
input_params=job_details_dict.get('inputParams', None),
input_params=job_details_dict.get('input_params', None),
metadata=job_details_dict.get('metadata', None),
output_data_format=job_details_dict.get('outputDataFormat', None),
output_data=job_details_dict.get('outputData', None),
output_data_format=job_details_dict.get('output_data_format', None),
output_data=job_details_dict.get('output_data', None),
status=job_details_dict.get('status', None),
creation_time=job_details_dict.get('creationTime', None),
begin_execution_time=job_details_dict.get('beginExecutionTime', None),
end_execution_time=job_details_dict.get('endExecutionTime', None),
cancellation_time=job_details_dict.get('cancellationTime', None),
error_data=job_details_dict.get('errorData', None))
creation_time=job_details_dict.get('creation_time', None),
begin_execution_time=job_details_dict.get('begin_execution_time', None),
end_execution_time=job_details_dict.get('end_execution_time', None),
cancellation_time=job_details_dict.get('cancellation_time', None),
error_data=job_details_dict.get('error_data', None))

def wait_until_completed(
self,
Expand Down Expand Up @@ -103,7 +105,7 @@ def wait_until_completed(

logger.debug(
f"Waiting for job {self.id},"
+ f"it is in status '{self.details.status}'"
+ f"it is in status '{self.status}'"
)
if print_progress:
print(".", end="", flush=True)
Expand All @@ -119,7 +121,6 @@ def wait_until_completed(
def has_completed(self) -> bool:
"""Check if the job has completed."""

# TODO maybe we just use qiskit states here already
return (
self.status == "Succeeded"
or self.status == "Failed"
Expand All @@ -128,16 +129,10 @@ def has_completed(self) -> bool:

def refresh(self):
job_details_dict = self._client.get_job(self.job_id)

self._update_job_details(**self._json_dict_to_params(job_details_dict))

# def status(self):
# """Return the status of the job, among the values of ``JobStatus``."""
# self.refresh()
# return self.status

def cancel(self):
self._planqk_client.cancel_job(self.job_id())
self._client.cancel_job(self.job_id)

def get_results(self, timeout_secs: float = DEFAULT_TIMEOUT) -> dict:
if self.output_data is not None:
Expand All @@ -160,9 +155,8 @@ def get_results(self, timeout_secs: float = DEFAULT_TIMEOUT) -> dict:

def toDict(self) -> dict:
# Create dict and remove private fields
return { key: value for key, value in vars(self).items() if not key.startswith('_') }
return {key: value for key, value in vars(self).items() if not key.startswith('_')}

@property
def id(self):
return self.job_id


13 changes: 1 addition & 12 deletions planqk/qiskit/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
from qiskit.providers import ProviderV1 as Provider

from planqk.client import PlanqkClient
from planqk.planqk_job import PlanqkJob
from planqk.credentials import DefaultCredentialsProvider
from planqk.qiskit.provider_impls.azure.planqk_azure_provider import PlanqkAzureQuantumProvider
from planqk.qiskit.providers.azure.planqk_azure_provider import PlanqkAzureQuantumProvider

logger = logging.getLogger(__name__)

Expand All @@ -31,18 +30,8 @@ def backends(self, name=None, **kwargs):
for provider in self._providers:

for backend in provider.backends(name, **kwargs):
#TODO if azure provider
#planqk_azure_backend = type("PlanQKAzureBackend", (AzureBackendProxy, type(backend),), {}) backend.configuration()
#planqk_azure_backend_obj = planqk_azure_backend(backend.name(), provider)
backends.append(backend)
#TODO


# jo = dir(backends[0])
#
# new_class = type("NewClassName", (type(backends[0]),), {"new_method": chuck})
# inst = new_class("name", "provider")
# inst.new_method() dir(inst)
return backends


Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from planqk.client import PlanqkClient
from planqk.planqk_job import PlanqkJob
from planqk.qiskit.provider_impls.azure.planqk_azure_job import PlanqkAzureJob
from planqk.qiskit.providers.azure.planqk_azure_job import PlanqkAzureJob

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -71,7 +71,7 @@ def run(self, circuit, **kwargs):
input_data_format=input_data_format,
output_data_format=output_data_format,
input_params=input_params,
meta_data=metadata,
metadata=metadata,
**kwargs
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from azure.quantum.qiskit.backends import *

from planqk.client import PlanqkClient
from planqk.qiskit.provider_impls.azure.planqk_azure_backend import PlanqkAzureBackend
from planqk.qiskit.provider_impls.azure.planqk_target_factory import PlanqkTargetFactory
from planqk.qiskit.providers.azure.planqk_azure_backend import PlanqkAzureBackend
from planqk.qiskit.providers.azure.planqk_target_factory import PlanqkTargetFactory

QISKIT_USER_AGENT = "azure-quantum-qiskit"

Expand Down
Empty file added tests/acceptance/__init__.py
Empty file.
Loading

0 comments on commit 3bce5e6

Please sign in to comment.