Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Changelog

- `QAMExecutionResult` now includes `execution_duration_microseconds`, providing the amount of time
a job held exclusive hardware access. (@randall-fulton, #1436)

- Upgrade `qcs-api-client` so that clients can specify a QCS account on their profile, which `qcs-api-client` will in turn use to set `X-QCS-ACCOUNT-{ID/TYPE}` headers on outgoing QCS requests, most notably during engagement creation. (@erichulburd, #1439)

### Bugfixes

Expand Down
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ lark = "^0.11.1"
rpcq = "^3.10.0"
networkx = "^2.5"
importlib-metadata = { version = "^3.7.3", python = "<3.8" }
qcs-api-client = ">=0.8.1,<0.21.0"
qcs-api-client = ">=0.20.12,<0.21.0"
retry = "^0.9.2"

# latex extra
Expand Down
2 changes: 2 additions & 0 deletions pyquil/api/_quantum_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,8 @@ def get_qc(
:param compiler_timeout: Time limit for compilation requests, in seconds.
:param execution_timeout: Time limit for execution requests, in seconds.
:param client_configuration: Optional client configuration. If none is provided, a default one will be loaded.
For more information on setting up QCS credentials, see documentation for using the QCS CLI:
[https://docs.rigetti.com/qcs/guides/using-the-qcs-cli#configuring-credentials].
:param endpoint_id: Optional quantum processor endpoint ID, as used in the `QCS API Docs`_.
:param engagement_manager: Optional engagement manager. If none is provided, a default one will be created.

Expand Down
50 changes: 49 additions & 1 deletion test/unit/test_quantum_computer.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import itertools
import random
from test.unit.utils import DummyCompiler
from typing import cast

import networkx as nx
import numpy as np
import pytest
import respx

from pyquil import Program, list_quantum_computers
from pyquil.api import QCSClientConfiguration
from pyquil.api._quantum_computer import (
QuantumComputer,
_check_min_num_trials_for_symmetrized_readout,
Expand All @@ -23,6 +23,7 @@
_symmetrization,
get_qc,
)
from pyquil.api._qpu import QPU
from pyquil.api._qvm import QVM
from pyquil.experiment import Experiment, ExperimentSetting
from pyquil.experiment._main import _pauli_to_product_state
Expand All @@ -32,6 +33,7 @@
from pyquil.pyqvm import PyQVM
from pyquil.quantum_processor import NxQuantumProcessor
from pyquil.quilbase import Declare, MemoryReference
from qcs_api_client.client import QCSAccountType, QCSClientConfiguration
from qcs_api_client.models.instruction_set_architecture import InstructionSetArchitecture
from rpcq.messages import ParameterAref

Expand Down Expand Up @@ -849,3 +851,49 @@ def test_get_qc_endpoint_id(client_configuration: QCSClientConfiguration, qcs_as
qc = get_qc("test", endpoint_id="test-endpoint")

assert qc.qam._qpu_client._endpoint_id == "test-endpoint"


@respx.mock
def test_get_qc_with_group_account(client_configuration: QCSClientConfiguration, qcs_aspen8_isa: InstructionSetArchitecture):
"""
Assert that a client may specify a ``QCSClientConfigurationSettingsProfile`` representing a QCS group
account and create a group account engagement via headers.
"""
respx.get(
url=f"{client_configuration.profile.api_url}/v1/quantumProcessors/test/instructionSetArchitecture",
).respond(json=qcs_aspen8_isa.to_dict())

group_profile = client_configuration.profile.copy()
group_profile.account_id = "group0"
group_profile.account_type = QCSAccountType.group
client_configuration.settings.profiles["my-group-profile"] = group_profile
client_configuration.profile_name = "my-group-profile"
qc = get_qc("test", endpoint_id="test-endpoint", client_configuration=client_configuration)

assert isinstance(qc, QuantumComputer)
quantum_computer = cast(QuantumComputer, qc)
assert isinstance(quantum_computer.qam, QPU)
qpu = cast(QPU, quantum_computer.qam)
engagement_manager = qpu._qpu_client._engagement_manager

respx.post(
url=f"{client_configuration.profile.api_url}/v1/engagements",
headers__contains={
'X-QCS-ACCOUNT-ID': 'group0',
'X-QCS-ACCOUNT-TYPE': QCSAccountType.group.value,
},
).respond(json={
'address': 'address',
'endpointId': 'endpointId',
'quantumProcessorId': 'quantumProcessorId',
'userId': 'userId',
'expiresAt': '01-01-2200T00:00:00Z',
'credentials': {
'clientPublic': 'faux',
'clientSecret': 'faux',
'serverPublic': 'faux',
}
})

engagement = engagement_manager.get_engagement(quantum_processor_id='test')
assert 'faux' == engagement.credentials.client_public