Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
07460d7
query programs by name
kt474 Nov 17, 2021
85be645
refactor cache logic
kt474 Nov 17, 2021
7413496
Merge branch 'main' into query-program-name
rathishcholarajan Nov 23, 2021
3c282e1
Merge branch 'main' into query-program-name
rathishcholarajan Nov 23, 2021
d2cc513
Merge branch 'main' into query-program-name
kt474 Nov 29, 2021
f733ee0
fix lint
kt474 Nov 29, 2021
b26f544
update tests
kt474 Nov 29, 2021
17d1f47
Merge branch 'main' into query-program-name
rathishcholarajan Nov 29, 2021
610e8a0
refactor programs cache
kt474 Nov 30, 2021
ad53714
fix lint
kt474 Nov 30, 2021
7be7a77
Merge branch 'main' into query-program-name
kt474 Nov 30, 2021
bf87cae
unrelated lint fix
kt474 Nov 30, 2021
5a1d7c2
Merge branch 'query-program-name' of https://github.com/Qiskit/qiskit…
kt474 Nov 30, 2021
b9933c9
Merge branch 'main' into query-program-name
rathishcholarajan Dec 1, 2021
830ddfc
Merge branch 'main' into query-program-name
rathishcholarajan Dec 1, 2021
ebacbee
update cache logic
kt474 Dec 2, 2021
d48e892
Merge branch 'main' into query-program-name
rathishcholarajan Dec 2, 2021
0ab06e6
update cache logic
kt474 Dec 5, 2021
c188a14
Merge branch 'main' into query-program-name
kt474 Dec 5, 2021
8d287d9
Update qiskit_ibm_runtime/ibm_runtime_service.py
kt474 Dec 7, 2021
861cf00
update retrieve programs method
kt474 Dec 7, 2021
af309c7
refactor logic
kt474 Dec 8, 2021
ea04aa8
Merge branch 'main' into query-program-name
kt474 Dec 16, 2021
fca5a98
Merge branch 'main' into query-program-name
kt474 Jan 4, 2022
0bc0bca
Merge branch 'main' into query-program-name
kt474 Jan 5, 2022
6671b7d
add tests back in
kt474 Jan 5, 2022
851caa2
Merge branch 'main' into query-program-name
kt474 Jan 6, 2022
d33595e
Merge branch 'main' into query-program-name
kt474 Jan 7, 2022
5e827fe
fix list programs test
kt474 Jan 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions qiskit_ibm_runtime/api/clients/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,19 @@ def __init__(
)
self.api = Runtime(self._session)

def list_programs(self, limit: int = None, skip: int = None) -> Dict[str, Any]:
def list_programs(
self, name: str = "", limit: int = None, skip: int = None
) -> Dict[str, Any]:
"""Return a list of runtime programs.

Args:
limit: The number of programs to return.
skip: The number of programs to skip.

name: Name of the program.
Returns:
A list of runtime programs.
"""
return self.api.list_programs(limit, skip)
return self.api.list_programs(name, limit, skip)

def program_create(
self,
Expand Down
10 changes: 7 additions & 3 deletions qiskit_ibm_runtime/api/rest/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,22 @@ def program_job(self, job_id: str) -> "ProgramJob":
"""
return ProgramJob(self.session, job_id)

def list_programs(self, limit: int = None, skip: int = None) -> Dict[str, Any]:
def list_programs(
self, name: str = "", limit: int = None, skip: int = None
) -> Dict[str, Any]:
"""Return a list of runtime programs.

Args:
limit: The number of programs to return.
skip: The number of programs to skip.

name: Name of the program.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we move this before limit and skip, just to maintain parameter order?

Returns:
A list of runtime programs.
"""
url = self.get_url("programs")
payload: Dict[str, int] = {}
payload: Dict[str, Union[int, str]] = {}
if name:
payload["name"] = name
if limit:
payload["limit"] = limit
if skip:
Expand Down
19 changes: 16 additions & 3 deletions qiskit_ibm_runtime/ibm_runtime_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,7 @@ def pprint_programs(
self,
refresh: bool = False,
detailed: bool = False,
name: Optional[str] = "",
limit: int = 20,
skip: int = 0,
) -> None:
Expand All @@ -809,11 +810,12 @@ def pprint_programs(
refresh: If ``True``, re-query the server for the programs. Otherwise
return the cached value.
detailed: If ``True`` print all details about available runtime programs.
name: Only retrieve programs with the exact program name given.
limit: The number of programs returned at a time. Default and maximum
value of 20.
skip: The number of programs to skip.
"""
programs = self.programs(refresh, limit, skip)
programs = self.programs(refresh, name, limit, skip)
for prog in programs:
print("=" * 50)
if detailed:
Expand All @@ -826,7 +828,11 @@ def pprint_programs(
print(f" Description: {prog.description}")

def programs(
self, refresh: bool = False, limit: int = 20, skip: int = 0
self,
refresh: bool = False,
name: Optional[str] = "",
limit: int = 20,
skip: int = 0,
) -> List[RuntimeProgram]:
"""Return available runtime programs.

Expand All @@ -835,6 +841,7 @@ def programs(
Args:
refresh: If ``True``, re-query the server for the programs. Otherwise
return the cached value.
name: Only retrieve programs with the exact program name given.
limit: The number of programs returned at a time. ``None`` means no limit.
skip: The number of programs to skip.

Expand All @@ -843,13 +850,19 @@ def programs(
"""
if skip is None:
skip = 0
if name:
for program in list(self._programs.values())[skip : limit + skip]:
if program.name == name:
self._programs[program.program_id] = program
else:
del self._programs[program.program_id]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. We should loop through all programs in self._programs.
  2. If we find a program with given name then we should add it to a temporary list.
  3. After we find all programs with the given name, we should then apply limit and skip on the temporary list and immediately return it.

All this local filtering should happen only if refresh is not set to True and self._programs is non empty.

We shouldn’t delete programs from self._programs since it’s usually lot of info that’ll have to be refetched from sever.

if not self._programs or refresh:
self._programs = {}
current_page_limit = 20
offset = 0
while True:
response = self._api_client.list_programs(
limit=current_page_limit, skip=offset
name=name, limit=current_page_limit, skip=offset
)
program_page = response.get("programs", [])
# count is the total number of programs that would be returned if
Expand Down
8 changes: 8 additions & 0 deletions releasenotes/notes/query-program-name-22b97d6b4c5731d2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
upgrade:
- |
The ``name`` parameter has been added to
:meth:`qiskit_ibm_runtime.IBMRuntimeService.programs` and
:meth:`qiskit_ibm_runtime.IBMRuntimeService.pprint_programs`
which can be used to filter by a specific program name. The
``name`` given must be an exact match with an actual program name.
9 changes: 6 additions & 3 deletions test/ibm/runtime/fake_runtime_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,15 @@ def set_final_status(self, final_status):
"""Set job status to passed in final status instantly."""
self._final_status = final_status

def list_programs(self, limit, skip):
def list_programs(self, name, limit, skip):
"""List all programs."""
programs = []
for prog in self._programs.values():
programs.append(prog.to_dict())
return {"programs": programs[skip : limit + skip], "count": len(self._programs)}
if not name:
programs.append(prog.to_dict())
if name == prog.to_dict()["name"]:
programs.append(prog.to_dict())
return {"programs": programs[skip : limit + skip], "count": len(programs)}

def program_create(
self,
Expand Down
10 changes: 10 additions & 0 deletions test/ibm/runtime/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,16 @@ def test_list_programs(self):
all_ids = [prog.program_id for prog in programs]
self.assertIn(program_id, all_ids)

def test_filter_programs_with_program_name(self):
"""Test filter programs with the program name"""
program_id = self._upload_program(name="qiskit-test-sample")
programs = self.service.programs(name="qiskit-test-sample")
all_ids = [prog.program_id for prog in programs]
self.assertIn(program_id, all_ids)
programs = self.service.programs(name="qiskit-test")
all_ids = [prog.program_id for prog in programs]
self.assertNotIn(program_id, all_ids)

def test_list_programs_with_limit_skip(self):
"""Test listing programs with limit and skip."""
program_1 = self._upload_program()
Expand Down
10 changes: 10 additions & 0 deletions test/ibm/runtime/test_runtime_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ def test_list_programs(self):
found = True
self.assertTrue(found, f"Program {self.program_id} not found!")

def test_filter_programs_with_program_name(self):
"""Test filter programs with program name."""
program_id = self._upload_program(name="qiskit-test-sample")
programs = self.service.programs(name="qiskit-test-sample")
all_ids = [prog.program_id for prog in programs]
self.assertIn(program_id, all_ids)
programs = self.service.programs(name="qiskit-test")
all_ids = [prog.program_id for prog in programs]
self.assertNotIn(program_id, all_ids)

def test_list_programs_with_limit_skip(self):
"""Test listing programs with limit and skip."""
self._upload_program()
Expand Down