diff --git a/.github/workflows/notebook-local-verify.yaml b/.github/workflows/notebook-local-verify.yaml new file mode 100644 index 000000000..5e82f277d --- /dev/null +++ b/.github/workflows/notebook-local-verify.yaml @@ -0,0 +1,38 @@ +name: Notebook LocalProvider tests + +on: + pull_request: + branches: [ main ] + +jobs: + tests: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.9' + - name: patch notebooks + shell: bash + run: | + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/examples/02_qaoa.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/examples/01_vqe.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/experimental/running_programs_using_decorators.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/experimental/manage_data_directory.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/experimental/file_download.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/02_arguments_and_results.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/04_distributed_workloads.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/05_retrieving_past_results.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/03_dependencies.ipynb + sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/01_running_program.ipynb + - name: install dependencies + shell: bash + run: pip install client/ && pip install nbmake pytest + - name: Run basic notebooks + shell: bash + run: IN_TEST=True pytest --nbmake docs/getting_started/basic/ + - name: Run experimental notebooks + shell: bash + run: IN_TEST=True pytest --nbmake docs/getting_started/experimental/ + diff --git a/client/quantum_serverless/core/job.py b/client/quantum_serverless/core/job.py index b1efd9738..f7f0ad3a0 100644 --- a/client/quantum_serverless/core/job.py +++ b/client/quantum_serverless/core/job.py @@ -256,6 +256,10 @@ def get(self, job_id) -> Optional["Job"]: def list(self, **kwargs) -> List["Job"]: return [job["job"] for job in list(self._jobs.values())] + def filtered_logs(self, job_id: str, **kwargs): + """Return filtered logs.""" + raise NotImplementedError + def run( self, program: QiskitPattern, @@ -362,7 +366,7 @@ def run_existing( # pylint: disable=too-many-locals def get_programs(self, **kwargs): """Returns list of programs.""" - raise NotImplementedError + return self._patterns class GatewayJobClient(BaseJobClient): diff --git a/client/quantum_serverless/core/provider.py b/client/quantum_serverless/core/provider.py index a636e0e7e..9e0c7e3d9 100644 --- a/client/quantum_serverless/core/provider.py +++ b/client/quantum_serverless/core/provider.py @@ -30,6 +30,7 @@ import logging import warnings import os.path +import os from dataclasses import dataclass from typing import Optional, List, Dict, Any, Union @@ -608,6 +609,7 @@ def __init__(self): """ super().__init__("local-provier") self.client = LocalJobClient() + self.in_test = os.getenv("IN_TEST") def run( self, @@ -629,3 +631,39 @@ def get_jobs(self, **kwargs) -> List[Job]: def upload(self, program: QiskitPattern): return self.client.upload(program) + + def widget(self): + """Widget for information about provider and jobs.""" + return Widget(self).show() + + def get_programs(self, **kwargs) -> List[QiskitPattern]: + return self.client.get_programs(**kwargs) + + def files(self) -> List[str]: + if self.in_test: + logging.warning("files method is not implemented in LocalProvider.") + return [] + raise NotImplementedError("files method is not implemented in LocalProvider.") + + def file_upload(self, file: str): + if self.in_test: + logging.warning("file_upload method is not implemented in LocalProvider.") + return + raise NotImplementedError("files method is not implemented in LocalProvider.") + + def file_download( + self, + file: str, + target_name: Optional[str] = None, + download_location: str = "./", + ): + if self.in_test: + logging.warning("file_download method is not implemented in LocalProvider.") + return None + raise NotImplementedError("files method is not implemented in LocalProvider.") + + def file_delete(self, file: str): + if self.in_test: + logging.warning("file_delete method is not implemented in LocalProvider.") + return None + raise NotImplementedError("files method is not implemented in LocalProvider.") diff --git a/client/requirements.txt b/client/requirements.txt index 9b75c16b8..b9799c117 100644 --- a/client/requirements.txt +++ b/client/requirements.txt @@ -3,6 +3,7 @@ requests>=2.31.0 importlib-metadata>=5.2.0 qiskit>=0.45.2 qiskit-ibm-runtime>=0.18.0 +qiskit-ibm-provider>=0.8.0 # TODO: make sure ray node and notebook node have the same version of cloudpickle cloudpickle==2.2.1 tqdm>=4.65.0