-
Notifications
You must be signed in to change notification settings - Fork 216
Query programs by name and search #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 39 commits
07460d7
85be645
7413496
3c282e1
d2cc513
f733ee0
b26f544
17d1f47
610e8a0
ad53714
7be7a77
bf87cae
5a1d7c2
b9933c9
830ddfc
ebacbee
d48e892
0ab06e6
c188a14
8d287d9
861cf00
af309c7
ea04aa8
fca5a98
0bc0bca
6671b7d
851caa2
d33595e
5e827fe
d0ac07e
2a479ae
079a88e
7186f5a
4bf740e
21ec9a2
fac7775
7688814
162576b
3f48cea
b9746c1
cbb5d63
4b9a3eb
9669bd2
764b8cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -632,6 +632,7 @@ def pprint_programs( | |
| self, | ||
| refresh: bool = False, | ||
| detailed: bool = False, | ||
| name: Optional[str] = "", | ||
| limit: int = 20, | ||
| skip: int = 0, | ||
| ) -> None: | ||
|
|
@@ -641,11 +642,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: | ||
|
|
@@ -658,7 +660,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. | ||
|
|
||
|
|
@@ -667,35 +673,30 @@ 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. | ||
|
|
||
| Returns: | ||
| A list of runtime programs. | ||
| """ | ||
| already_retrieved = False | ||
| if skip is None: | ||
| skip = 0 | ||
| 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 | ||
| ) | ||
| program_page = response.get("programs", []) | ||
| # count is the total number of programs that would be returned if | ||
| # there was no limit or skip | ||
| count = response.get("count", 0) | ||
| for prog_dict in program_page: | ||
| program = self._to_program(prog_dict) | ||
| self._programs[program.program_id] = program | ||
| if len(self._programs) == count: | ||
| # Stop if there are no more programs returned by the server. | ||
| break | ||
| offset += len(program_page) | ||
| if not self._programs or (refresh and not name): | ||
| self._programs = self._retrieve_programs() | ||
| already_retrieved = True | ||
| if limit is None: | ||
| limit = len(self._programs) | ||
| if name: | ||
| matched_programs = [] | ||
| if refresh and not already_retrieved: | ||
| matched_programs = list(self._retrieve_programs(name).values()) | ||
| else: | ||
| for program in list(self._programs.values()): | ||
| if program.name == name: | ||
| matched_programs.append(program) | ||
| return matched_programs[skip : limit + skip] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally have problems to understand this deeply nested code because filtering by name either happens on the client-, or on the server-side. In the most likely path where a user runs I suggest to make the following simplifications
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is also a good approach - originally we wanted to minimize the number of API calls, and just use the cache for every call after the first one that didn't specifically set |
||
| return list(self._programs.values())[skip : limit + skip] | ||
|
|
||
| def program(self, program_id: str, refresh: bool = False) -> RuntimeProgram: | ||
|
|
@@ -729,6 +730,35 @@ def program(self, program_id: str, refresh: bool = False) -> RuntimeProgram: | |
|
|
||
| return self._programs[program_id] | ||
|
|
||
| def _retrieve_programs(self, name: str = "") -> Dict[str, RuntimeProgram]: | ||
| """Make an API call to fetch programs. | ||
|
|
||
| Args: | ||
| name: Name of the program. | ||
|
|
||
| Returns: | ||
| A dict of ``RuntimeProgram`` instances, keyed by program name. | ||
| """ | ||
| programs = {} | ||
| current_page_limit = 20 | ||
| offset = 0 | ||
| while True: | ||
| response = self._api_client.list_programs( | ||
| 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 | ||
| # there was no limit or skip | ||
| count = response.get("count", 0) | ||
| for prog_dict in program_page: | ||
| program = self._to_program(prog_dict) | ||
| programs[program.program_id] = program | ||
| if len(programs) == count: | ||
| # Stop if there are no more programs returned by the server. | ||
| break | ||
| offset += len(program_page) | ||
| return programs | ||
|
daka1510 marked this conversation as resolved.
Outdated
|
||
|
|
||
| def _to_program(self, response: Dict) -> RuntimeProgram: | ||
| """Convert server response to ``RuntimeProgram`` instances. | ||
|
|
||
|
|
||
| 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way, this change is not backward-compatible. Users may rely on the order of the positional arguments (limit, skip). An easy way to fix that is to add the optional name parameter at the end.