Skip to content

Commit

Permalink
Bump iqm-client dependency (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
hay-k authored Aug 10, 2022
1 parent 20fd551 commit 0340cca
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
Changelog
=========

Version 0.4
=============

- Bump iqm-client dependency to 5.0
- Remind the user to login before using operations requiring authentication

Version 0.3
=============

Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ install_requires =
jsonschema >= 4.6.0
requests >= 2.26.0
pydantic >= 1.8.2, < 2.0
cirq-iqm >= 6.0, < 7.0
iqm-client >= 4.1, < 5.0
cirq-iqm >= 7.0, < 8.0
iqm-client >= 5.0, < 6.0

# Require a specific Python version, e.g. Python 2.7 or >= 3.4
python_requires = ~= 3.9
Expand Down
26 changes: 20 additions & 6 deletions src/cortex_cli/cortex_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

import cirq_iqm
import click
from cirq_iqm.iqm_sampler import serialize_circuit, serialize_qubit_mapping
from cirq_iqm.iqm_sampler import serialize_circuit
from iqm_client.iqm_client import Circuit, IQMClient

from cortex_cli import __version__
Expand All @@ -47,6 +47,7 @@
USERNAME = ''
REFRESH_PERIOD = 3*60 # in seconds


class ClickLoggingHandler(logging.Handler):
"""Simple log handler using click's echo function."""
def __init__(self):
Expand All @@ -56,10 +57,12 @@ def __init__(self):
def emit(self, record):
click.echo(self.format(record))


logger = logging.getLogger('cortex_cli')
logger.addHandler(ClickLoggingHandler())
logger.setLevel(logging.INFO)


def _setLogLevelByVerbosity(verbose: bool) -> int:
"""Sets logger log level to DEBUG if verbose is True, to INFO otherwise.
Args:
Expand All @@ -73,6 +76,7 @@ def _setLogLevelByVerbosity(verbose: bool) -> int:
logger.setLevel(logging.INFO)
return logging.INFO


def _validate_path(ctx: click.Context, param: object, path: str) -> str:
"""Callback for CLI prompt. If needed, confirmation to overwrite is prompted.
Expand Down Expand Up @@ -105,12 +109,14 @@ def _validate_path(ctx: click.Context, param: object, path: str) -> str:
continue
return new_path


@click.group()
@click.version_option(__version__)
def cortex_cli() -> None:
"""Interact with an IQM quantum computer with Cortex CLI."""
return


@cortex_cli.command()
@click.option(
'--config-file',
Expand Down Expand Up @@ -195,6 +201,7 @@ def auth() -> None:
"""Manage authentication."""
return


@auth.command()
@click.option(
'--config-file',
Expand Down Expand Up @@ -233,6 +240,7 @@ def status(config_file, verbose) -> None:
else:
click.echo(f'Token manager: {click.style("NOT RUNNING", fg="red")}')


@auth.command()
@click.option(
'--config-file',
Expand Down Expand Up @@ -307,6 +315,7 @@ def login( #pylint: disable=too-many-arguments
daemonize_token_manager(refresh_period, config)
logger.info('Token manager started.')


@auth.command()
@click.option(
'--config-file',
Expand Down Expand Up @@ -375,12 +384,12 @@ def logout(config_file: str, keep_tokens: str, force: bool) -> None:
logger.info('Logout aborted.')



@cortex_cli.group()
def circuit() -> None:
"""Execute your quantum circuits with Cortex CLI."""
return


@circuit.command()
@click.argument('filename')
def validate(filename:str) -> None:
Expand Down Expand Up @@ -489,17 +498,22 @@ def run( #pylint: disable=too-many-arguments, too-many-locals
logger.debug('\nInput circuit:\n%s', input_circuit)

if qubit_mapping is not None:
qubit_mapping = serialize_qubit_mapping(json.load(qubit_mapping))
qubit_mapping = json.load(qubit_mapping)

if settings is not None:
settings = json.load(settings)

# run the circuit on the backend
if no_auth:
iqm_client = IQMClient(url, settings)
iqm_client = IQMClient(url)
else:
iqm_client = IQMClient(url, settings, tokens_file = tokens_file)
job_id = iqm_client.submit_circuits([input_circuit], qubit_mapping, shots=shots)
iqm_client = IQMClient(url, tokens_file=tokens_file)
job_id = iqm_client.submit_circuits(
[input_circuit],
qubit_mapping=qubit_mapping,
shots=shots,
settings=settings
)
results = iqm_client.wait_for_results(job_id)
iqm_client.close()
except Exception as ex:
Expand Down
5 changes: 3 additions & 2 deletions tests/circuit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

valid_circuit_qasm = os.path.join(resources_path(), 'valid_circuit.qasm')
qubit_mapping_path = os.path.join(resources_path(), 'qubit_mapping.json')
qasm_qubit_mapping_path = os.path.join(resources_path(), 'qubit_mapping_qasm.json')
settings_path = os.path.join(resources_path(), 'settings.json')


Expand Down Expand Up @@ -130,7 +131,7 @@ def test_circuit_run_valid_qasm_circuit(credentials, config_dict, tokens_dict):
result = CliRunner().invoke(cortex_cli,
['circuit', 'run', valid_circuit_qasm,
'--config-file', 'config.json',
'--qubit-mapping', qubit_mapping_path,
'--qubit-mapping', qasm_qubit_mapping_path,
'--settings', settings_path,
'--url', base_url,
'--no-auth'])
Expand Down Expand Up @@ -164,7 +165,7 @@ def test_circuit_run_valid_json_circuit(credentials, config_dict, tokens_dict):

def test_circuit_run_valid_json_circuit_default_settings_no_qubit_mapping(credentials, config_dict, tokens_dict):
"""
Tests that ``circuit run`` succeeds with valid qasm circuit and no qubit mapping.
Tests that ``circuit run`` succeeds with valid json circuit and no qubit mapping.
"""
base_url = credentials['base_url']
expect_jobs_requests(base_url)
Expand Down
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@

existing_run = UUID('3c3fcda3-e860-46bf-92a4-bcc59fa76ce9')


def resources_path():
"""Get path to tests/resources directory from current location"""
return os.path.join(os.path.dirname(os.path.realpath(__file__)), 'resources')


@pytest.fixture()
def credentials():
"""Sample credentials for logging in"""
Expand All @@ -49,20 +51,23 @@ def credentials():
'password': 'some_password',
}


@pytest.fixture
def config_dict():
"""Reads and parses config file into a dictionary"""
config_file = os.path.join(resources_path(), 'config.json')
with open(config_file, 'r', encoding='utf-8') as file:
return json.loads(file.read())


@pytest.fixture
def tokens_dict():
"""Reads and parses tokens file into a dictionary"""
tokens_file = os.path.join(resources_path(), 'tokens.json')
with open(tokens_file, 'r', encoding='utf-8') as file:
return json.loads(file.read())


@pytest.fixture()
def mock_environment_vars_for_backend(credentials):
"""
Expand Down Expand Up @@ -220,9 +225,11 @@ def expect_os_kill(pid:int, signal = signal.SIGTERM, result:bool = True):
"""
when(os).kill(pid, signal).thenReturn(result)


def expect_check_pid(pid:int, result:bool = True):
expect_os_kill(pid, 0, result)


def expect_kill_by_pid(pid:int, result:bool = True):
expect_check_pid(pid, result = result)
expect_os_kill(pid, result = result)
4 changes: 4 additions & 0 deletions tests/resources/qubit_mapping_qasm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"q_0": "QB1",
"q_1": "QB2"
}
5 changes: 4 additions & 1 deletion tests/resources/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"settings": {},
"subtrees": {
"QB1": {},
"QB2": {}
"QB2": {},
"QB3": {},
"QB4": {},
"QB5": {}
}
}

0 comments on commit 0340cca

Please sign in to comment.