qcs 0.26.1

High level interface for running Quil on a QPU
Documentation
import datetime
import os
from typing import List

import pytest
from _pytest.config import Config
from _pytest.config.argparsing import Parser
from _pytest.nodes import Item

from qcs_sdk.client import QCSClient
from qcs_sdk.qpu.api import APIExecutionOptions, APIExecutionOptionsBuilder, ExecutionOptions
from qcs_sdk.qpu.isa import InstructionSetArchitecture
from qcs_sdk.qvm import QVMClient
from qcs_sdk.compiler.quilc import QuilcClient


TEST_ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
TEST_CONFIG_DIR = os.path.join(TEST_ROOT_DIR, "./_qcs_config")
TEST_FIXTURE_DIR = os.path.join(TEST_ROOT_DIR, "./_fixtures")


def pytest_addoption(parser: Parser):
    parser.addoption("--with-qcs-session", action="store_true", default=False, help="Run tests that require proper user config authentication.")
    parser.addoption("--with-qcs-execution", action="store_true", default=False, help="Run tests that require qpu execution.")


def pytest_configure(config: Config):
    config.addinivalue_line("markers", "qcs_session: mark test as requiring authentication + authorization.")
    config.addinivalue_line("markers", "not_qcs_session: mark test as requiring no authentication + authorization.")
    config.addinivalue_line("markers", "qcs_execution: mark test as requiring qpu execution.")


def pytest_collection_modifyitems(config: Config, items: List[Item]):
    with_qcs_session = config.getoption("--with-qcs-session")
    with_qcs_execution = config.getoption("--with-qcs-execution")

    if not with_qcs_session:
        os.environ["QCS_SETTINGS_FILE_PATH"] = os.path.join(TEST_CONFIG_DIR, "settings.toml")
        os.environ["QCS_SECRETS_FILE_PATH"] = os.path.join(TEST_CONFIG_DIR, "secrets.toml")

    skip_not_sess = pytest.mark.skip(reason="requires --with-qcs-session pytest option to be false.")
    skip_sess = pytest.mark.skip(reason="requires --with-qcs-session pytest option to be true.")
    skip_exec = pytest.mark.skip(reason="requires --with-qcs-execution pytest option to be true.")

    for item in items:
        if not with_qcs_session:
            if "qcs_session" in item.keywords:
                item.add_marker(skip_sess)
        else:
            if "not_qcs_session" in item.keywords:
                item.add_marker(skip_not_sess)

        if not with_qcs_execution:
            if "qcs_execution" in item.keywords:
                item.add_marker(skip_exec)


def _read_fixture(relpath: str) -> str:
    with open(os.path.join(TEST_FIXTURE_DIR, relpath)) as f:
        contents = f.read()
    return contents


@pytest.fixture
def quantum_processor_id() -> str:
    return os.getenv("TEST_LIVE_QUANTUM_PROCESSOR_ID", "Ankaa-3")


@pytest.fixture
def aspen_m_3_isa() -> InstructionSetArchitecture:
    return InstructionSetArchitecture.from_raw(_read_fixture("./aspen-m-3.json"))


@pytest.fixture
def device_2q() -> str:
    return _read_fixture("./device-2q.json")


@pytest.fixture
def native_bitflip_program() -> str:
    return """
DECLARE ro BIT[1]
RX(pi) 0
MEASURE 0 ro[0]
"""


@pytest.fixture
def bell_program() -> str:
    return """
DECLARE ro BIT[2]
X 0
CNOT 0 1
MEASURE 0 ro[0]
MEASURE 1 ro[1]
"""


@pytest.fixture
def qvm_http_client() -> QVMClient:
    return QVMClient.new_http(QCSClient.load().qvm_url)


@pytest.fixture
def quilc_rpcq_client() -> QuilcClient:
    return QuilcClient.new_rpcq(QCSClient.load().quilc_url)


@pytest.fixture(scope="session")
def live_qpu_access(request: pytest.FixtureRequest) -> bool:
    return (
        request.config.getoption("--with-qcs-execution") is not None
        and request.config.getoption("--with-qcs-execution") is not False
    )


@pytest.fixture
def execution_timeout() -> datetime.timedelta:
    return datetime.timedelta(seconds=60)


@pytest.fixture
def api_execution_options(execution_timeout: datetime.timedelta) -> APIExecutionOptions:
    return APIExecutionOptions(timeout=execution_timeout)


@pytest.fixture
def execution_options(
    execution_timeout: datetime.timedelta,
    api_execution_options: APIExecutionOptions
) -> ExecutionOptions:
    return ExecutionOptions(
        timeout=execution_timeout,
        api_options=api_execution_options
    )