Skip to content

Commit 301356b

Browse files
committed
Reintroduce delete_job (Qiskit#2541)
* Reintroduce delete_job * Add release note
1 parent b3be564 commit 301356b

File tree

4 files changed

+64
-1
lines changed

4 files changed

+64
-1
lines changed

qiskit_ibm_runtime/qiskit_runtime_service.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,25 @@ def jobs(
11561156

11571157
return [self._decode_job(job) for job in job_responses]
11581158

1159+
def delete_job(self, job_id: str) -> None:
1160+
"""Delete a runtime job.
1161+
1162+
Note that this operation cannot be reversed.
1163+
1164+
Args:
1165+
job_id: ID of the job to delete.
1166+
1167+
Raises:
1168+
RuntimeJobNotFound: The job doesn't exist.
1169+
IBMRuntimeError: Method is not supported.
1170+
"""
1171+
try:
1172+
self._active_api_client.job_delete(job_id)
1173+
except RequestsApiError as ex:
1174+
if ex.status_code == 404:
1175+
raise RuntimeJobNotFound(f"Job not found: {ex.message}") from None
1176+
raise IBMRuntimeError(f"Failed to delete job: {ex}") from None
1177+
11591178
def usage(self) -> dict[str, Any]:
11601179
"""Return usage information for the current active instance.
11611180
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The ``delete_job()`` method has been reintroduced.

test/integration/test_job.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@
1515
import random
1616
import time
1717

18+
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
19+
1820
from qiskit_ibm_runtime.exceptions import (
1921
RuntimeInvalidStateError,
22+
RuntimeJobNotFound,
2023
)
2124

2225
from ..ibm_test_case import IBMIntegrationJobTestCase
2326
from ..decorators import run_integration_test, production_only
2427
from ..serialization import (
2528
SerializableClass,
2629
)
27-
from ..utils import cancel_job_safe, wait_for_status
30+
from ..utils import bell, cancel_job_safe, get_real_device, wait_for_status
2831

2932

3033
class TestIntegrationJob(IBMIntegrationJobTestCase):
@@ -84,6 +87,35 @@ def test_cancel_job_done(self, service):
8487
with self.assertRaises(RuntimeInvalidStateError):
8588
job.cancel()
8689

90+
@run_integration_test
91+
def test_delete_job(self, service):
92+
"""Test deleting a job."""
93+
self.skipTest("Deleting jobs not supported on IBM Quantum Platform.")
94+
sub_tests = ["DONE"]
95+
for status in sub_tests:
96+
with self.subTest(status=status):
97+
job = self._run_program(service)
98+
wait_for_status(job, status)
99+
service.delete_job(job.job_id())
100+
with self.assertRaises(RuntimeJobNotFound):
101+
service.job(job.job_id())
102+
103+
@run_integration_test
104+
@production_only
105+
def test_delete_job_queued(self, service):
106+
"""Test deleting a queued job."""
107+
self.skipTest("Deleting jobs not supported on IBM Quantum Platform.")
108+
real_device_name = get_real_device(service)
109+
real_device = service.backend(real_device_name)
110+
pm = generate_preset_pass_manager(optimization_level=1, target=real_device.target)
111+
isa_circuit = pm.run([bell()])
112+
_ = self._run_program(service, circuits=isa_circuit, backend=real_device_name)
113+
job = self._run_program(service, circuits=isa_circuit, backend=real_device_name)
114+
wait_for_status(job, "QUEUED")
115+
service.delete_job(job.job_id())
116+
with self.assertRaises(RuntimeJobNotFound):
117+
service.job(job.job_id())
118+
87119
@run_integration_test
88120
def test_job_status(self, service):
89121
"""Test job status."""

test/unit/test_jobs.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from qiskit_ibm_runtime.constants import API_TO_JOB_ERROR_MESSAGE
2323
from qiskit_ibm_runtime.exceptions import (
2424
RuntimeJobFailureError,
25+
RuntimeJobNotFound,
2526
RuntimeJobMaxTimeoutError,
2627
RuntimeInvalidStateError,
2728
)
@@ -147,6 +148,16 @@ def test_wait_for_final_state(self, service):
147148
job.wait_for_final_state()
148149
self.assertEqual("DONE", job.status())
149150

151+
@run_cloud_fake
152+
def test_delete_job(self, service):
153+
"""Test deleting a job."""
154+
params = {"param1": "foo"}
155+
job = run_program(service=service, inputs=params)
156+
self.assertTrue(job.job_id())
157+
service.delete_job(job.job_id())
158+
with self.assertRaises(RuntimeJobNotFound):
159+
service.job(job.job_id())
160+
150161
@run_cloud_fake
151162
def test_instance_limit_warning(self, service):
152163
"""Test emitting a warning if instance usage has been reached."""

0 commit comments

Comments
 (0)