diff --git a/mqss_client/__init__.py b/mqss_client/__init__.py index 974202c..851ac84 100644 --- a/mqss_client/__init__.py +++ b/mqss_client/__init__.py @@ -1,6 +1,12 @@ """MQSS Client package""" -from .job import CircuitJobRequest, HamiltonianJobRequest, JobStatus, Result +from .job import ( + CircuitJobRequest, + HamiltonianJobRequest, + JobStatus, + PennylaneJobRequest, + Result, +) from .mqss_client import MQSSClient from .resource_info import ResourceInfo @@ -11,4 +17,5 @@ "HamiltonianJobRequest", "JobStatus", "Result", + "PennylaneJobRequest", ] diff --git a/mqss_client/job.py b/mqss_client/job.py index 7df49b0..171d31d 100644 --- a/mqss_client/job.py +++ b/mqss_client/job.py @@ -66,6 +66,27 @@ def to_json_dict(self) -> dict: } +@dataclass +class PennylaneJobRequest(JobRequest): + """Class to hold Pennylane job information""" + + resource_name: str + circuits: str + circuit_format: str + shots: int + no_modify: bool + + def to_json_dict(self) -> dict: + """Convert PennylaneJobRequest to JSON dictionary""" + return { + "resource_name": self.resource_name, + "circuit": self.circuits, + "circuit_format": self.circuit_format, + "shots": self.shots, + "no_modify": self.no_modify, + } + + @dataclass class Result: """Result Class to hold counts""" diff --git a/mqss_client/mqss_client.py b/mqss_client/mqss_client.py index a825a37..8a4089d 100644 --- a/mqss_client/mqss_client.py +++ b/mqss_client/mqss_client.py @@ -8,7 +8,14 @@ from typing import Dict, Optional, Union from .hpc_client import HPCOffloadClient -from .job import CircuitJobRequest, HamiltonianJobRequest, JobRequest, JobStatus, Result +from .job import ( + CircuitJobRequest, + HamiltonianJobRequest, + JobRequest, + JobStatus, + PennylaneJobRequest, + Result, +) from .resource_info import ResourceInfo from .rest_client import RESTClient @@ -56,6 +63,11 @@ def submit_job(self, job_request: JobRequest) -> str: "hamiltonian_job", job_request.to_json_dict(), ) + elif isinstance(job_request, PennylaneJobRequest): + rsp_json = self.client.post( + "pennylane_job", + job_request.to_json_dict(), + ) else: raise ValueError("Invalid job request type") @@ -73,6 +85,8 @@ def cancel_job(self, uuid: str, job_type: JobRequest) -> None: self.client.delete(f"job/{uuid}") elif isinstance(job_type, HamiltonianJobRequest): self.client.delete(f"hamiltonian_job/{uuid}") + elif isinstance(job_type, PennylaneJobRequest): + self.client.delete(f"pennylane_job/{uuid}") else: raise ValueError("Invalid job request type") @@ -82,6 +96,8 @@ def job_status(self, uuid: str, job_type: JobRequest) -> JobStatus: rsp_json = self.client.get(f"job/{uuid}/status") elif isinstance(job_type, HamiltonianJobRequest): rsp_json = self.client.get(f"hamiltonian_job/{uuid}/status") + elif isinstance(job_type, PennylaneJobRequest): + rsp_json = self.client.get(f"pennylane_job/{uuid}/status") else: raise ValueError("Invalid job request type") @@ -98,6 +114,8 @@ def job_result(self, uuid: str, job_type: JobRequest) -> Optional[Result]: result_json = self.client.get(f"job/{uuid}/result") elif isinstance(job_type, HamiltonianJobRequest): result_json = self.client.get(f"hamiltonian_job/{uuid}/result") + elif isinstance(job_type, PennylaneJobRequest): + result_json = self.client.get(f"pennylane_job/{uuid}/result") else: raise ValueError("Invalid job request type") diff --git a/test/mocks.py b/test/mocks.py index 1684a33..c5a337f 100644 --- a/test/mocks.py +++ b/test/mocks.py @@ -20,9 +20,11 @@ # For job endpoints "job": {"jobs": ["mock-uuid-12345"]}, "hamiltonian_job": {"jobs": ["mock-uuid-12345"]}, + "pennylane_job": {"jobs": ["mock-uuid-12345"]}, # Status endpoints "job/mock-uuid-12345/status": {"status": "PENDING"}, "hamiltonian_job/mock-uuid-12345/status": {"status": "PENDING"}, + "pennylane_job/mock-uuid-12345/status": {"status": "PENDING"}, # Result endpoints "job/mock-uuid-12345/result": { "result": '{"00": 500, "11": 500}', @@ -36,6 +38,12 @@ "timestamp_submitted": "2023-04-14 10:00:00.123456", "timestamp_scheduled": "2023-04-14 10:05:00.123456", }, + "pennylane_job/mock-uuid-12345/result": { + "result": '{"00": 500, "11": 500}', + "timestamp_completed": "2023-04-14 10:15:30.123456", + "timestamp_submitted": "2023-04-14 10:00:00.123456", + "timestamp_scheduled": "2023-04-14 10:05:00.123456", + }, } @@ -63,7 +71,9 @@ def mock_receive(queue_name): method = message_data.get("method", "") # Handle POST requests for job creation - if (request_path in ["job", "hamiltonian_job"]) and method == "POST": + if ( + request_path in ["job", "hamiltonian_job", "pennylane_job"] + ) and method == "POST": return json.dumps({"uuid": "mock-uuid-12345"}) # Handle GET requests using the shared data diff --git a/test/mqss_client_tests_base.py b/test/mqss_client_tests_base.py index 2000c96..360972b 100644 --- a/test/mqss_client_tests_base.py +++ b/test/mqss_client_tests_base.py @@ -5,6 +5,7 @@ HamiltonianJobRequest, JobStatus, MQSSClient, + PennylaneJobRequest, ResourceInfo, Result, ) @@ -44,6 +45,18 @@ def hamiltonian_job_request(resource_name): ) +@pytest.fixture +def pennylane_job_request(resource_name): + """Fixture to create a pennylane job request""" + return PennylaneJobRequest( + resource_name=resource_name, + circuits=get_qasm(), + circuit_format="qasm", + shots=1000, + no_modify=False, + ) + + class BaseMQSSClientTests: """Base class for MQSS client tests.""" @@ -105,6 +118,14 @@ def test_submit_hamiltonian_job( assert job_id is not None client.cancel_job(job_id, hamiltonian_job_request) + def test_submit_pennylane_job( + self, client: MQSSClient, pennylane_job_request + ) -> None: + """Test submitting a Pennylane job.""" + job_id = client.submit_job(pennylane_job_request) + assert job_id is not None + client.cancel_job(job_id, pennylane_job_request) + def test_job_status( self, client: MQSSClient, circuit_job_request, monkeypatch ) -> None: diff --git a/test/test_mqss_client_live.py b/test/test_mqss_client_live.py index 64be5f0..11e67dd 100644 --- a/test/test_mqss_client_live.py +++ b/test/test_mqss_client_live.py @@ -58,6 +58,13 @@ def test_submit_hamiltonian_job( hamiltonian_job_request.resource_name = online_resource_name(client) return super().test_submit_hamiltonian_job(client, hamiltonian_job_request) + def test_submit_pennylane_job( + self, client: MQSSClient, pennylane_job_request + ) -> None: + """Test submitting a Pennylane job.""" + pennylane_job_request.resource_name = online_resource_name(client) + return super().test_submit_pennylane_job(client, pennylane_job_request) + def test_job_status( self, client: MQSSClient, circuit_job_request, monkeypatch ) -> None: diff --git a/test/test_mqss_client_mock.py b/test/test_mqss_client_mock.py index afec0f6..2d36fd9 100644 --- a/test/test_mqss_client_mock.py +++ b/test/test_mqss_client_mock.py @@ -9,10 +9,16 @@ BaseMQSSClientTests, circuit_job_request, hamiltonian_job_request, + pennylane_job_request, resource_name, ) -__all__ = ["circuit_job_request", "hamiltonian_job_request", "resource_name"] +__all__ = [ + "circuit_job_request", + "hamiltonian_job_request", + "resource_name", + "pennylane_job_request", +] @pytest.mark.mock