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

Query programs by name #194

Closed
wants to merge 58 commits into from
Closed
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
464192f
Remove version field from runtime program (#152)
rathishcholarajan Oct 18, 2021
abb98d0
Rename isPublic to is_public when creating or reading runtime program…
rathishcholarajan Oct 18, 2021
31fdd4b
Update programId to program_id when running program (#139)
renier Oct 18, 2021
0d5ebf8
Add support to view program update date (#160)
rathishcholarajan Oct 18, 2021
767afeb
Upload runtime program using 'data' field (#157)
rathishcholarajan Oct 19, 2021
24dfa95
Read programs from "programs" array in response (#161)
rathishcholarajan Oct 19, 2021
79cd9bd
Remove version field from runtime program (#152)
rathishcholarajan Oct 18, 2021
45ab0b2
Rename isPublic to is_public when creating or reading runtime program…
rathishcholarajan Oct 18, 2021
faff4e2
Update programId to program_id when running program (#139)
renier Oct 18, 2021
bcc27fb
Add support to view program update date (#160)
rathishcholarajan Oct 18, 2021
866d045
Upload runtime program using 'data' field (#157)
rathishcholarajan Oct 19, 2021
eda2a51
Read programs from "programs" array in response (#161)
rathishcholarajan Oct 19, 2021
ab33b52
Pass program as base64 string to update (#168)
rathishcholarajan Oct 21, 2021
a8fe605
Accept JSON schema as program metadata (#158)
rathishcholarajan Oct 25, 2021
1b26e0b
Merge branch 'runtime-release-q4' of https://github.com/Qiskit-Partne…
kt474 Oct 26, 2021
df4eb81
Pass program params as object (#171)
rathishcholarajan Oct 27, 2021
e3e4315
Fix integration tests
rathishcholarajan Oct 27, 2021
f5712bc
Merge branch 'runtime-release-q4' of https://github.com/Qiskit-Partne…
kt474 Oct 28, 2021
0f95825
Use count to reduce one last extra call to API (#172)
rathishcholarajan Oct 28, 2021
b532b14
Allow updating runtime metadata in place (#188)
jyu00 Oct 29, 2021
c1065f0
Merge branch 'runtime-release-q4' of https://github.com/Qiskit-Partne…
kt474 Nov 1, 2021
f5b4e54
Remove version field from runtime program (#152)
rathishcholarajan Oct 18, 2021
93a2b85
Rename isPublic to is_public when creating or reading runtime program…
rathishcholarajan Oct 18, 2021
966d42a
Update programId to program_id when running program (#139)
renier Oct 18, 2021
031fc25
Add support to view program update date (#160)
rathishcholarajan Oct 18, 2021
1561a9b
Upload runtime program using 'data' field (#157)
rathishcholarajan Oct 19, 2021
b656ece
Read programs from "programs" array in response (#161)
rathishcholarajan Oct 19, 2021
8fb3669
Pass program as base64 string to update (#168)
rathishcholarajan Oct 21, 2021
74472c5
Accept JSON schema as program metadata (#158)
rathishcholarajan Oct 25, 2021
ee76158
Pass program params as object (#171)
rathishcholarajan Oct 27, 2021
da52271
Fix integration tests
rathishcholarajan Oct 27, 2021
f3033b8
Use count to reduce one last extra call to API (#172)
rathishcholarajan Oct 28, 2021
aea236b
Allow updating runtime metadata in place (#188)
jyu00 Oct 29, 2021
e71b402
Merge branch 'runtime-release-q4' of https://github.com/Qiskit-Partne…
kt474 Nov 2, 2021
f72a108
wip program name query
kt474 Nov 2, 2021
4102480
Allow filtering runtime jobs by program ID (#193)
rathishcholarajan Nov 4, 2021
8e8bcb3
Allow runtime program authors to retrieve program data (#174)
kt474 Nov 4, 2021
9dbbeb6
Merge branch 'runtime-release-q4' into program-name-query
kt474 Nov 4, 2021
90484cc
add test case, refactor logic
kt474 Nov 4, 2021
07f0d53
Update cache after updating program (#196)
rathishcholarajan Nov 5, 2021
304387c
Merge branch 'runtime-release-q4' into program-name-query
rathishcholarajan Nov 5, 2021
91e4ba8
add integration test
kt474 Nov 5, 2021
b458efc
update doc strings
kt474 Nov 5, 2021
4b48ec0
Update releasenotes/notes/query-program-name-823e8e7cfef44f50.yaml
kt474 Nov 5, 2021
87a5429
Update test/ibm/runtime/test_runtime.py
kt474 Nov 5, 2021
1d6e8ff
Update test/ibm/runtime/test_runtime.py
kt474 Nov 5, 2021
005a5d4
Update test/ibm/runtime/test_runtime_integration.py
kt474 Nov 5, 2021
15655ec
Update test/ibm/runtime/test_runtime_integration.py
kt474 Nov 5, 2021
35a9879
Update test/ibm/runtime/test_runtime_integration.py
kt474 Nov 5, 2021
8b01221
Update test/ibm/runtime/test_runtime.py
kt474 Nov 5, 2021
8133076
Allow filtering runtime jobs by provider (#197)
kt474 Nov 8, 2021
bbcf7b5
Merge branch 'runtime-release-q4' into program-name-query
rathishcholarajan Nov 8, 2021
7f474e9
Update qiskit_ibm/api/rest/runtime.py
rathishcholarajan Nov 8, 2021
4522d9b
Support pagination for retrieving runtime programs (#170)
kt474 Nov 8, 2021
b40df0f
Merge branch 'runtime-release-q4' into program-name-query
kt474 Nov 8, 2021
d35b56f
update program name
kt474 Nov 8, 2021
a960d8e
Merge branch 'main' into program-name-query
kt474 Nov 10, 2021
caa749a
Merge branch 'main' into program-name-query
kt474 Nov 12, 2021
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
84 changes: 49 additions & 35 deletions qiskit_ibm/api/clients/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"""Client for accessing IBM Quantum runtime service."""

import logging
from typing import List, Dict, Union, Optional
from typing import Any, List, Dict, Union, Optional

from qiskit_ibm.credentials import Credentials
from qiskit_ibm.api.session import RetrySession
Expand All @@ -39,40 +39,35 @@ def __init__(
**credentials.connection_parameters())
self.api = Runtime(self._session)

def list_programs(self) -> List[Dict]:
def list_programs(self, name: str) -> Dict[str, Any]:
"""Return a list of runtime programs.

Args:
name: Name of the program.

Returns:
A list of quantum programs.
"""
kt474 marked this conversation as resolved.
Show resolved Hide resolved
return self.api.list_programs()
return self.api.list_programs(name)

def program_create(
self,
program_data: bytes,
program_data: str,
name: str,
description: str,
max_execution_time: int,
is_public: Optional[bool] = False,
version: Optional[str] = None,
backend_requirements: Optional[Dict] = None,
parameters: Optional[Dict] = None,
return_values: Optional[List] = None,
interim_results: Optional[List] = None
spec: Optional[Dict] = None
) -> Dict:
"""Create a new program.

Args:
name: Name of the program.
program_data: Program data.
program_data: Program data (base64 encoded).
description: Program description.
max_execution_time: Maximum execution time.
is_public: Whether the program should be public.
version: Program version.
backend_requirements: Backend requirements.
parameters: Program parameters.
return_values: Program return values.
interim_results: Program interim results.
spec: Backend requirements, parameters, interim results, return values, etc.

Returns:
Server response.
Expand All @@ -81,9 +76,7 @@ def program_create(
program_data=program_data,
name=name,
description=description, max_execution_time=max_execution_time,
is_public=is_public, version=version, backend_requirements=backend_requirements,
parameters=parameters, return_values=return_values,
interim_results=interim_results
is_public=is_public, spec=spec
)

def program_get(self, program_id: str) -> Dict:
Expand All @@ -97,17 +90,6 @@ def program_get(self, program_id: str) -> Dict:
"""
return self.api.program(program_id).get()

def program_get_data(self, program_id: str) -> Dict:
"""Return a specific program and its data.

Args:
program_id: Program ID.

Returns:
Program information, including data.
"""
return self.api.program(program_id).get_data()

def set_program_visibility(self, program_id: str, public: bool) -> None:
"""Sets a program's visibility.

Expand All @@ -127,7 +109,7 @@ def program_run(
program_id: str,
credentials: Credentials,
backend_name: str,
params: str,
params: Dict,
image: str
) -> Dict:
"""Run the specified program.
Expand Down Expand Up @@ -155,14 +137,32 @@ def program_delete(self, program_id: str) -> None:
"""
self.api.program(program_id).delete()

def program_update(self, program_id: str, program_data: str) -> None:
def program_update(
self,
program_id: str,
program_data: str = None,
name: str = None,
description: str = None,
max_execution_time: int = None,
spec: Optional[Dict] = None
) -> None:
"""Update a program.

Args:
program_id: Program ID.
program_data: Program data.
program_data: Program data (base64 encoded).
name: Name of the program.
description: Program description.
max_execution_time: Maximum execution time.
spec: Backend requirements, parameters, interim results, return values, etc.
"""
self.api.program(program_id).update(program_data)
if program_data:
self.api.program(program_id).update_data(program_data)

if any([name, description, max_execution_time, spec]):
self.api.program(program_id).update_metadata(
name=name, description=description,
max_execution_time=max_execution_time, spec=spec)

def job_get(self, job_id: str) -> Dict:
"""Get job data.
Expand All @@ -177,19 +177,33 @@ def job_get(self, job_id: str) -> Dict:
logger.debug("Runtime job get response: %s", response)
return response

def jobs_get(self, limit: int = None, skip: int = None, pending: bool = None) -> Dict:
def jobs_get(
self,
limit: int = None,
skip: int = None,
pending: bool = None,
program_id: str = None,
hub: str = None,
group: str = None,
project: str = None
) -> Dict:
"""Get job data for all jobs.

Args:
limit: Number of results to return.
skip: Number of results to skip.
pending: Returns 'QUEUED' and 'RUNNING' jobs if True,
returns 'DONE', 'CANCELLED' and 'ERROR' jobs if False.
program_id: Filter by Program ID.
hub: Filter by hub - hub, group, and project must all be specified.
group: Filter by group - hub, group, and project must all be specified.
project: Filter by project - hub, group, and project must all be specified.

Returns:
JSON response.
"""
return self.api.jobs_get(limit=limit, skip=skip, pending=pending)
return self.api.jobs_get(limit=limit, skip=skip, pending=pending,
program_id=program_id, hub=hub, group=group, project=project)

def job_results(self, job_id: str) -> str:
"""Get the results of a program job.
Expand Down
128 changes: 77 additions & 51 deletions qiskit_ibm/api/rest/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from .base import RestAdapterBase
from ..session import RetrySession
from ...runtime.utils import RuntimeEncoder

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -54,65 +55,54 @@ def program_job(self, job_id: str) -> 'ProgramJob':
"""
return ProgramJob(self.session, job_id)

def list_programs(self) -> List[Dict]:
def list_programs(self, name: str) -> Dict[str, Any]:
"""Return a list of runtime programs.

Args:
name: Name of the program.

Returns:
JSON response.
"""
kt474 marked this conversation as resolved.
Show resolved Hide resolved
url = self.get_url('programs')
return self.session.get(url).json()
payload: Dict[str, Union[str]] = {}
rathishcholarajan marked this conversation as resolved.
Show resolved Hide resolved
if name:
payload['name'] = name
response = self.session.get(url, params=payload).json()
return response

def create_program(
self,
program_data: bytes,
program_data: str,
name: str,
description: str,
max_execution_time: int,
is_public: Optional[bool] = False,
version: Optional[str] = None,
backend_requirements: Optional[Dict] = None,
parameters: Optional[Dict] = None,
return_values: Optional[List] = None,
interim_results: Optional[List] = None
spec: Optional[Dict] = None
) -> Dict:
"""Upload a new program.

Args:
program_data: Program data.
program_data: Program data (base64 encoded).
name: Name of the program.
description: Program description.
max_execution_time: Maximum execution time.
is_public: Whether the program should be public.
version: Program version.
backend_requirements: Backend requirements.
parameters: Program parameters.
return_values: Program return values.
interim_results: Program interim results.
spec: Backend requirements, parameters, interim results, return values, etc.

Returns:
JSON response.
"""
url = self.get_url('programs')
data = {'name': name,
'cost': str(max_execution_time),
'description': description.encode(),
'max_execution_time': max_execution_time,
'isPublic': is_public}
if version is not None:
data['version'] = version
if backend_requirements:
data['backendRequirements'] = json.dumps(backend_requirements)
if parameters:
data['parameters'] = json.dumps({"doc": parameters})
if return_values:
data['returnValues'] = json.dumps(return_values)
if interim_results:
data['interimResults'] = json.dumps(interim_results)

files = {'program': (name, program_data)} # type: ignore[dict-item]
response = self.session.post(url, data=data, files=files).json()
return response
payload = {'name': name,
'data': program_data,
'cost': max_execution_time,
'description': description,
'is_public': is_public}
if spec is not None:
payload['spec'] = spec
data = json.dumps(payload)
return self.session.post(url, data=data).json()

def program_run(
self,
Expand All @@ -121,7 +111,7 @@ def program_run(
group: str,
project: str,
backend_name: str,
params: str,
params: Dict,
image: str
) -> Dict:
"""Execute the program.
Expand All @@ -140,25 +130,38 @@ def program_run(
"""
url = self.get_url('jobs')
payload = {
'programId': program_id,
'program_id': program_id,
'hub': hub,
'group': group,
'project': project,
'backend': backend_name,
'params': [params],
'params': params,
'runtime': image
}
data = json.dumps(payload)
data = json.dumps(payload, cls=RuntimeEncoder)
return self.session.post(url, data=data).json()

def jobs_get(self, limit: int = None, skip: int = None, pending: bool = None) -> Dict:
def jobs_get(
self,
limit: int = None,
skip: int = None,
pending: bool = None,
program_id: str = None,
hub: str = None,
group: str = None,
project: str = None
) -> Dict:
"""Get a list of job data.

Args:
limit: Number of results to return.
skip: Number of results to skip.
pending: Returns 'QUEUED' and 'RUNNING' jobs if True,
returns 'DONE', 'CANCELLED' and 'ERROR' jobs if False.
program_id: Filter by Program ID.
hub: Filter by hub - hub, group, and project must all be specified.
group: Filter by group - hub, group, and project must all be specified.
project: Filter by project - hub, group, and project must all be specified.

Returns:
JSON response.
Expand All @@ -171,6 +174,10 @@ def jobs_get(self, limit: int = None, skip: int = None, pending: bool = None) ->
payload['offset'] = skip
if pending is not None:
payload['pending'] = 'true' if pending else 'false'
if program_id:
payload['program'] = program_id
if all([hub, group, project]):
payload['provider'] = f"{hub}/{group}/{project}"
return self.session.get(url, params=payload).json()

def logout(self) -> None:
Expand Down Expand Up @@ -211,15 +218,6 @@ def get(self) -> Dict[str, Any]:
url = self.get_url('self')
return self.session.get(url).json()

def get_data(self) -> Dict[str, Any]:
"""Return program information, including data.

Returns:
JSON response.
"""
url = self.get_url('data')
return self.session.get(url).json()

def make_public(self) -> None:
"""Sets a runtime program's visibility to public."""
url = self.get_url('public')
Expand All @@ -239,15 +237,43 @@ def delete(self) -> None:
url = self.get_url('self')
self.session.delete(url)

def update(self, program_data: str) -> None:
"""Update a program.
def update_data(self, program_data: str) -> None:
"""Update program data.

Args:
program_data: Program data.
program_data: Program data (base64 encoded).
"""
url = self.get_url("data")
self.session.put(url, data=program_data,
headers={'Content-Type': 'text/plain'})
headers={'Content-Type': 'application/octet-stream'})

def update_metadata(
self,
name: str = None,
description: str = None,
max_execution_time: int = None,
spec: Optional[Dict] = None
) -> None:
"""Update program metadata.

Args:
name: Name of the program.
description: Program description.
max_execution_time: Maximum execution time.
spec: Backend requirements, parameters, interim results, return values, etc.
"""
url = self.get_url("self")
payload: Dict = {}
if name:
payload["name"] = name
if description:
payload["description"] = description
if max_execution_time:
payload["cost"] = max_execution_time
if spec:
payload["spec"] = spec

self.session.patch(url, json=payload)


class ProgramJob(RestAdapterBase):
Expand Down
Loading