ionq_core

A client library for accessing IonQ Cloud Platform API

 1# SPDX-FileCopyrightText: 2026 IonQ, Inc.
 2# SPDX-License-Identifier: Apache-2.0
 3# @generated
 4
 5"""A client library for accessing IonQ Cloud Platform API"""
 6
 7from . import exceptions, extensions, gates, ionq_client, pagination, polling, session
 8from .client import AuthenticatedClient, Client  # noqa: F401
 9from .exceptions import *  # noqa: F403
10from .extensions import *  # noqa: F403
11from .gates import *  # noqa: F403
12from .ionq_client import *  # noqa: F403
13from .pagination import *  # noqa: F403
14from .polling import *  # noqa: F403
15from .session import *  # noqa: F403
16from .types import UNSET, Unset  # noqa: F401
17
18__all__ = sorted(
19    {
20        "exceptions",
21        "extensions",
22        "gates",
23        "ionq_client",
24        "pagination",
25        "polling",
26        "session",
27        "AuthenticatedClient",
28        "Client",
29        "UNSET",
30        "Unset",
31        *exceptions.__all__,
32        *extensions.__all__,
33        *gates.__all__,
34        *ionq_client.__all__,
35        *pagination.__all__,
36        *polling.__all__,
37        *session.__all__,
38    }
39)
class APIConnectionError(ionq_core.IonQError):
58class APIConnectionError(IonQError):
59    """Raised when a connection to the IonQ API cannot be established.
60
61    This covers DNS resolution failures, refused connections, and other
62    network-level errors. The original ``httpx`` exception is chained
63    via ``__cause__``.
64    """

Raised when a connection to the IonQ API cannot be established.

This covers DNS resolution failures, refused connections, and other network-level errors. The original httpx exception is chained via __cause__.

class APIError(ionq_core.IonQError):
 75class APIError(IonQError):
 76    """Raised when the IonQ API returns an HTTP error response (4xx or 5xx).
 77
 78    Attributes:
 79        status_code: The HTTP status code.
 80        body: The parsed response body (``dict`` if JSON, ``str`` otherwise,
 81            or ``None`` if the body could not be read).
 82        message: A human-readable error message extracted from the response,
 83            or a default ``"HTTP <status>"`` string.
 84        request_id: The ``x-request-id`` header from the response, useful for
 85            contacting IonQ support about a specific request.
 86    """
 87
 88    def __init__(
 89        self,
 90        status_code: int,
 91        body: dict | str | None = None,
 92        message: str | None = None,
 93        *,
 94        request_id: str | None = None,
 95    ) -> None:
 96        self.status_code = status_code
 97        self.body = body
 98        self.request_id = request_id
 99        self.message = message or f"HTTP {status_code}"
100        super().__init__(self.message)

Raised when the IonQ API returns an HTTP error response (4xx or 5xx).

Attributes:
  • status_code: The HTTP status code.
  • body: The parsed response body (dict if JSON, str otherwise, or None if the body could not be read).
  • message: A human-readable error message extracted from the response, or a default "HTTP <status>" string.
  • request_id: The x-request-id header from the response, useful for contacting IonQ support about a specific request.
APIError( status_code: int, body: dict | str | None = None, message: str | None = None, *, request_id: str | None = None)
 88    def __init__(
 89        self,
 90        status_code: int,
 91        body: dict | str | None = None,
 92        message: str | None = None,
 93        *,
 94        request_id: str | None = None,
 95    ) -> None:
 96        self.status_code = status_code
 97        self.body = body
 98        self.request_id = request_id
 99        self.message = message or f"HTTP {status_code}"
100        super().__init__(self.message)
status_code
body
request_id
message
class APITimeoutError(ionq_core.APIConnectionError):
67class APITimeoutError(APIConnectionError):
68    """Raised when a request to the IonQ API times out.
69
70    Inherits from `APIConnectionError` so that catching connection errors
71    also catches timeouts.
72    """

Raised when a request to the IonQ API times out.

Inherits from APIConnectionError so that catching connection errors also catches timeouts.

@runtime_checkable
class AsyncEventHook(typing.Protocol):
76@runtime_checkable
77class AsyncEventHook(Protocol):
78    """Async counterpart of `EventHook` for the async client path.
79
80    Implement this protocol and pass instances via
81    `ClientExtension.async_event_hooks`.
82    """
83
84    async def on_request(self, request: httpx.Request) -> None:
85        """Called after the request is built but before it is sent.
86
87        Args:
88            request: The outgoing HTTP request.
89        """
90        ...
91
92    async def on_response(self, request: httpx.Request, response: httpx.Response) -> None:
93        """Called after a response is received.
94
95        Args:
96            request: The original HTTP request.
97            response: The HTTP response.
98        """
99        ...

Async counterpart of EventHook for the async client path.

Implement this protocol and pass instances via ClientExtension.async_event_hooks.

AsyncEventHook(*args, **kwargs)
1953def _no_init_or_replace_init(self, *args, **kwargs):
1954    cls = type(self)
1955
1956    if cls._is_protocol:
1957        raise TypeError('Protocols cannot be instantiated')
1958
1959    # Already using a custom `__init__`. No need to calculate correct
1960    # `__init__` to call. This can lead to RecursionError. See bpo-45121.
1961    if cls.__init__ is not _no_init_or_replace_init:
1962        return
1963
1964    # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`.
1965    # The first instantiation of the subclass will call `_no_init_or_replace_init` which
1966    # searches for a proper new `__init__` in the MRO. The new `__init__`
1967    # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent
1968    # instantiation of the protocol subclass will thus use the new
1969    # `__init__` and no longer call `_no_init_or_replace_init`.
1970    for base in cls.__mro__:
1971        init = base.__dict__.get('__init__', _no_init_or_replace_init)
1972        if init is not _no_init_or_replace_init:
1973            cls.__init__ = init
1974            break
1975    else:
1976        # should not happen
1977        cls.__init__ = object.__init__
1978
1979    cls.__init__(self, *args, **kwargs)
async def on_request(self, request: httpx.Request) -> None:
84    async def on_request(self, request: httpx.Request) -> None:
85        """Called after the request is built but before it is sent.
86
87        Args:
88            request: The outgoing HTTP request.
89        """
90        ...

Called after the request is built but before it is sent.

Arguments:
  • request: The outgoing HTTP request.
async def on_response(self, request: httpx.Request, response: httpx.Response) -> None:
92    async def on_response(self, request: httpx.Request, response: httpx.Response) -> None:
93        """Called after a response is received.
94
95        Args:
96            request: The original HTTP request.
97            response: The HTTP response.
98        """
99        ...

Called after a response is received.

Arguments:
  • request: The original HTTP request.
  • response: The HTTP response.
@define
class AuthenticatedClient:
142@define
143class AuthenticatedClient:
144    """A Client which has been authenticated for use on secured endpoints
145
146    The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
147
148        ``base_url``: The base URL for the API, all requests are made to a relative path to this URL
149
150        ``cookies``: A dictionary of cookies to be sent with every request
151
152        ``headers``: A dictionary of headers to be sent with every request
153
154        ``timeout``: The maximum amount of a time a request can take. API functions will raise
155        httpx.TimeoutException if this is exceeded.
156
157        ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
158        but can be set to False for testing purposes.
159
160        ``follow_redirects``: Whether or not to follow redirects. Default value is False.
161
162        ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
163
164
165    Attributes:
166        raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
167            status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
168            argument to the constructor.
169        token: The token to use for authentication
170        prefix: The prefix to use for the Authorization header
171        auth_header_name: The name of the Authorization header
172    """
173
174    raise_on_unexpected_status: bool = field(default=False, kw_only=True)
175    _base_url: str = field(alias="base_url")
176    _cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
177    _headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
178    _timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
179    _verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl")
180    _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
181    _httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
182    _client: httpx.Client | None = field(default=None, init=False)
183    _async_client: httpx.AsyncClient | None = field(default=None, init=False)
184
185    token: str = field(repr=False)
186    prefix: str = "Bearer"
187    auth_header_name: str = "Authorization"
188
189    def with_headers(self, headers: dict[str, str]) -> "AuthenticatedClient":
190        """Get a new client matching this one with additional headers"""
191        if self._client is not None:
192            self._client.headers.update(headers)
193        if self._async_client is not None:
194            self._async_client.headers.update(headers)
195        return evolve(self, headers={**self._headers, **headers})
196
197    def with_cookies(self, cookies: dict[str, str]) -> "AuthenticatedClient":
198        """Get a new client matching this one with additional cookies"""
199        if self._client is not None:
200            self._client.cookies.update(cookies)
201        if self._async_client is not None:
202            self._async_client.cookies.update(cookies)
203        return evolve(self, cookies={**self._cookies, **cookies})
204
205    def with_timeout(self, timeout: httpx.Timeout) -> "AuthenticatedClient":
206        """Get a new client matching this one with a new timeout configuration"""
207        if self._client is not None:
208            self._client.timeout = timeout
209        if self._async_client is not None:
210            self._async_client.timeout = timeout
211        return evolve(self, timeout=timeout)
212
213    def set_httpx_client(self, client: httpx.Client) -> "AuthenticatedClient":
214        """Manually set the underlying httpx.Client
215
216        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
217        """
218        self._client = client
219        return self
220
221    def get_httpx_client(self) -> httpx.Client:
222        """Get the underlying httpx.Client, constructing a new one if not previously set"""
223        if self._client is None:
224            self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
225            self._client = httpx.Client(
226                base_url=self._base_url,
227                cookies=self._cookies,
228                headers=self._headers,
229                timeout=self._timeout,
230                verify=self._verify_ssl,
231                follow_redirects=self._follow_redirects,
232                **self._httpx_args,
233            )
234        return self._client
235
236    def __enter__(self) -> "AuthenticatedClient":
237        """Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
238        self.get_httpx_client().__enter__()
239        return self
240
241    def __exit__(self, *args: Any, **kwargs: Any) -> None:
242        """Exit a context manager for internal httpx.Client (see httpx docs)"""
243        self.get_httpx_client().__exit__(*args, **kwargs)
244
245    def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "AuthenticatedClient":
246        """Manually set the underlying httpx.AsyncClient
247
248        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
249        """
250        self._async_client = async_client
251        return self
252
253    def get_async_httpx_client(self) -> httpx.AsyncClient:
254        """Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
255        if self._async_client is None:
256            self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
257            self._async_client = httpx.AsyncClient(
258                base_url=self._base_url,
259                cookies=self._cookies,
260                headers=self._headers,
261                timeout=self._timeout,
262                verify=self._verify_ssl,
263                follow_redirects=self._follow_redirects,
264                **self._httpx_args,
265            )
266        return self._async_client
267
268    async def __aenter__(self) -> "AuthenticatedClient":
269        """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
270        await self.get_async_httpx_client().__aenter__()
271        return self
272
273    async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
274        """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
275        await self.get_async_httpx_client().__aexit__(*args, **kwargs)

A Client which has been authenticated for use on secured endpoints

The following are accepted as keyword arguments and will be used to construct httpx Clients internally:

base_url: The base URL for the API, all requests are made to a relative path to this URL

cookies: A dictionary of cookies to be sent with every request

headers: A dictionary of headers to be sent with every request

timeout: The maximum amount of a time a request can take. API functions will raise httpx.TimeoutException if this is exceeded.

verify_ssl: Whether or not to verify the SSL certificate of the API server. This should be True in production, but can be set to False for testing purposes.

follow_redirects: Whether or not to follow redirects. Default value is False.

httpx_args: A dictionary of additional arguments to be passed to the httpx.Client and httpx.AsyncClient constructor.

Attributes:
  • raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a status code that was not documented in the source OpenAPI document. Can also be provided as a keyword argument to the constructor.
  • token: The token to use for authentication
  • prefix: The prefix to use for the Authorization header
  • auth_header_name: The name of the Authorization header
AuthenticatedClient( base_url: str, token: str, prefix: str = 'Bearer', auth_header_name: str = 'Authorization', *, raise_on_unexpected_status: bool = False, cookies: dict[str, str] = NOTHING, headers: dict[str, str] = NOTHING, timeout: httpx.Timeout | None = None, verify_ssl: str | bool | ssl.SSLContext = True, follow_redirects: bool = False, httpx_args: dict[str, typing.Any] = NOTHING)
35def __init__(self, base_url, token, prefix=attr_dict['prefix'].default, auth_header_name=attr_dict['auth_header_name'].default, *, raise_on_unexpected_status=attr_dict['raise_on_unexpected_status'].default, cookies=NOTHING, headers=NOTHING, timeout=attr_dict['_timeout'].default, verify_ssl=attr_dict['_verify_ssl'].default, follow_redirects=attr_dict['_follow_redirects'].default, httpx_args=NOTHING):
36    self.raise_on_unexpected_status = raise_on_unexpected_status
37    self._base_url = base_url
38    if cookies is not NOTHING:
39        self._cookies = cookies
40    else:
41        self._cookies = __attr_factory__cookies()
42    if headers is not NOTHING:
43        self._headers = headers
44    else:
45        self._headers = __attr_factory__headers()
46    self._timeout = timeout
47    self._verify_ssl = verify_ssl
48    self._follow_redirects = follow_redirects
49    if httpx_args is not NOTHING:
50        self._httpx_args = httpx_args
51    else:
52        self._httpx_args = __attr_factory__httpx_args()
53    self._client = attr_dict['_client'].default
54    self._async_client = attr_dict['_async_client'].default
55    self.token = token
56    self.prefix = prefix
57    self.auth_header_name = auth_header_name

Method generated by attrs for class AuthenticatedClient.

raise_on_unexpected_status: bool
token: str
prefix: str
auth_header_name: str
def with_headers(self, headers: dict[str, str]) -> AuthenticatedClient:
189    def with_headers(self, headers: dict[str, str]) -> "AuthenticatedClient":
190        """Get a new client matching this one with additional headers"""
191        if self._client is not None:
192            self._client.headers.update(headers)
193        if self._async_client is not None:
194            self._async_client.headers.update(headers)
195        return evolve(self, headers={**self._headers, **headers})

Get a new client matching this one with additional headers

def with_cookies(self, cookies: dict[str, str]) -> AuthenticatedClient:
197    def with_cookies(self, cookies: dict[str, str]) -> "AuthenticatedClient":
198        """Get a new client matching this one with additional cookies"""
199        if self._client is not None:
200            self._client.cookies.update(cookies)
201        if self._async_client is not None:
202            self._async_client.cookies.update(cookies)
203        return evolve(self, cookies={**self._cookies, **cookies})

Get a new client matching this one with additional cookies

def with_timeout(self, timeout: httpx.Timeout) -> AuthenticatedClient:
205    def with_timeout(self, timeout: httpx.Timeout) -> "AuthenticatedClient":
206        """Get a new client matching this one with a new timeout configuration"""
207        if self._client is not None:
208            self._client.timeout = timeout
209        if self._async_client is not None:
210            self._async_client.timeout = timeout
211        return evolve(self, timeout=timeout)

Get a new client matching this one with a new timeout configuration

def set_httpx_client(self, client: httpx.Client) -> AuthenticatedClient:
213    def set_httpx_client(self, client: httpx.Client) -> "AuthenticatedClient":
214        """Manually set the underlying httpx.Client
215
216        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
217        """
218        self._client = client
219        return self

Manually set the underlying httpx.Client

NOTE: This will override any other settings on the client, including cookies, headers, and timeout.

def get_httpx_client(self) -> httpx.Client:
221    def get_httpx_client(self) -> httpx.Client:
222        """Get the underlying httpx.Client, constructing a new one if not previously set"""
223        if self._client is None:
224            self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
225            self._client = httpx.Client(
226                base_url=self._base_url,
227                cookies=self._cookies,
228                headers=self._headers,
229                timeout=self._timeout,
230                verify=self._verify_ssl,
231                follow_redirects=self._follow_redirects,
232                **self._httpx_args,
233            )
234        return self._client

Get the underlying httpx.Client, constructing a new one if not previously set

def set_async_httpx_client( self, async_client: httpx.AsyncClient) -> AuthenticatedClient:
245    def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "AuthenticatedClient":
246        """Manually set the underlying httpx.AsyncClient
247
248        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
249        """
250        self._async_client = async_client
251        return self

Manually set the underlying httpx.AsyncClient

NOTE: This will override any other settings on the client, including cookies, headers, and timeout.

def get_async_httpx_client(self) -> httpx.AsyncClient:
253    def get_async_httpx_client(self) -> httpx.AsyncClient:
254        """Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
255        if self._async_client is None:
256            self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
257            self._async_client = httpx.AsyncClient(
258                base_url=self._base_url,
259                cookies=self._cookies,
260                headers=self._headers,
261                timeout=self._timeout,
262                verify=self._verify_ssl,
263                follow_redirects=self._follow_redirects,
264                **self._httpx_args,
265            )
266        return self._async_client

Get the underlying httpx.AsyncClient, constructing a new one if not previously set

class AuthenticationError(ionq_core.APIError):
103class AuthenticationError(APIError):
104    """Raised on ``401 Unauthorized``.
105
106    Typically means the API key is missing, invalid, or revoked.
107    """

Raised on 401 Unauthorized.

Typically means the API key is missing, invalid, or revoked.

class BadRequestError(ionq_core.APIError):
124class BadRequestError(APIError):
125    """Raised on ``400 Bad Request``.
126
127    The request body or query parameters failed server-side validation.
128    Inspect ``body`` for details.
129    """

Raised on 400 Bad Request.

The request body or query parameters failed server-side validation. Inspect body for details.

@define
class Client:
 16@define
 17class Client:
 18    """A class for keeping track of data related to the API
 19
 20    The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
 21
 22        ``base_url``: The base URL for the API, all requests are made to a relative path to this URL
 23
 24        ``cookies``: A dictionary of cookies to be sent with every request
 25
 26        ``headers``: A dictionary of headers to be sent with every request
 27
 28        ``timeout``: The maximum amount of a time a request can take. API functions will raise
 29        httpx.TimeoutException if this is exceeded.
 30
 31        ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
 32        but can be set to False for testing purposes.
 33
 34        ``follow_redirects``: Whether or not to follow redirects. Default value is False.
 35
 36        ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
 37
 38
 39    Attributes:
 40        raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
 41            status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
 42            argument to the constructor.
 43    """
 44    raise_on_unexpected_status: bool = field(default=False, kw_only=True)
 45    _base_url: str = field(alias="base_url")
 46    _cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
 47    _headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
 48    _timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
 49    _verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl")
 50    _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
 51    _httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
 52    _client: httpx.Client | None = field(default=None, init=False)
 53    _async_client: httpx.AsyncClient | None = field(default=None, init=False)
 54
 55    def with_headers(self, headers: dict[str, str]) -> "Client":
 56        """Get a new client matching this one with additional headers"""
 57        if self._client is not None:
 58            self._client.headers.update(headers)
 59        if self._async_client is not None:
 60            self._async_client.headers.update(headers)
 61        return evolve(self, headers={**self._headers, **headers})
 62
 63    def with_cookies(self, cookies: dict[str, str]) -> "Client":
 64        """Get a new client matching this one with additional cookies"""
 65        if self._client is not None:
 66            self._client.cookies.update(cookies)
 67        if self._async_client is not None:
 68            self._async_client.cookies.update(cookies)
 69        return evolve(self, cookies={**self._cookies, **cookies})
 70
 71    def with_timeout(self, timeout: httpx.Timeout) -> "Client":
 72        """Get a new client matching this one with a new timeout configuration"""
 73        if self._client is not None:
 74            self._client.timeout = timeout
 75        if self._async_client is not None:
 76            self._async_client.timeout = timeout
 77        return evolve(self, timeout=timeout)
 78
 79    def set_httpx_client(self, client: httpx.Client) -> "Client":
 80        """Manually set the underlying httpx.Client
 81
 82        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
 83        """
 84        self._client = client
 85        return self
 86
 87    def get_httpx_client(self) -> httpx.Client:
 88        """Get the underlying httpx.Client, constructing a new one if not previously set"""
 89        if self._client is None:
 90            self._client = httpx.Client(
 91                base_url=self._base_url,
 92                cookies=self._cookies,
 93                headers=self._headers,
 94                timeout=self._timeout,
 95                verify=self._verify_ssl,
 96                follow_redirects=self._follow_redirects,
 97                **self._httpx_args,
 98            )
 99        return self._client
100
101    def __enter__(self) -> "Client":
102        """Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
103        self.get_httpx_client().__enter__()
104        return self
105
106    def __exit__(self, *args: Any, **kwargs: Any) -> None:
107        """Exit a context manager for internal httpx.Client (see httpx docs)"""
108        self.get_httpx_client().__exit__(*args, **kwargs)
109
110    def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "Client":
111        """Manually set the underlying httpx.AsyncClient
112
113        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
114        """
115        self._async_client = async_client
116        return self
117
118    def get_async_httpx_client(self) -> httpx.AsyncClient:
119        """Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
120        if self._async_client is None:
121            self._async_client = httpx.AsyncClient(
122                base_url=self._base_url,
123                cookies=self._cookies,
124                headers=self._headers,
125                timeout=self._timeout,
126                verify=self._verify_ssl,
127                follow_redirects=self._follow_redirects,
128                **self._httpx_args,
129            )
130        return self._async_client
131
132    async def __aenter__(self) -> "Client":
133        """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
134        await self.get_async_httpx_client().__aenter__()
135        return self
136
137    async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
138        """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
139        await self.get_async_httpx_client().__aexit__(*args, **kwargs)

A class for keeping track of data related to the API

The following are accepted as keyword arguments and will be used to construct httpx Clients internally:

base_url: The base URL for the API, all requests are made to a relative path to this URL

cookies: A dictionary of cookies to be sent with every request

headers: A dictionary of headers to be sent with every request

timeout: The maximum amount of a time a request can take. API functions will raise httpx.TimeoutException if this is exceeded.

verify_ssl: Whether or not to verify the SSL certificate of the API server. This should be True in production, but can be set to False for testing purposes.

follow_redirects: Whether or not to follow redirects. Default value is False.

httpx_args: A dictionary of additional arguments to be passed to the httpx.Client and httpx.AsyncClient constructor.

Attributes:
  • raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a status code that was not documented in the source OpenAPI document. Can also be provided as a keyword argument to the constructor.
Client( base_url: str, *, raise_on_unexpected_status: bool = False, cookies: dict[str, str] = NOTHING, headers: dict[str, str] = NOTHING, timeout: httpx.Timeout | None = None, verify_ssl: str | bool | ssl.SSLContext = True, follow_redirects: bool = False, httpx_args: dict[str, typing.Any] = NOTHING)
32def __init__(self, base_url, *, raise_on_unexpected_status=attr_dict['raise_on_unexpected_status'].default, cookies=NOTHING, headers=NOTHING, timeout=attr_dict['_timeout'].default, verify_ssl=attr_dict['_verify_ssl'].default, follow_redirects=attr_dict['_follow_redirects'].default, httpx_args=NOTHING):
33    self.raise_on_unexpected_status = raise_on_unexpected_status
34    self._base_url = base_url
35    if cookies is not NOTHING:
36        self._cookies = cookies
37    else:
38        self._cookies = __attr_factory__cookies()
39    if headers is not NOTHING:
40        self._headers = headers
41    else:
42        self._headers = __attr_factory__headers()
43    self._timeout = timeout
44    self._verify_ssl = verify_ssl
45    self._follow_redirects = follow_redirects
46    if httpx_args is not NOTHING:
47        self._httpx_args = httpx_args
48    else:
49        self._httpx_args = __attr_factory__httpx_args()
50    self._client = attr_dict['_client'].default
51    self._async_client = attr_dict['_async_client'].default

Method generated by attrs for class Client.

raise_on_unexpected_status: bool
def with_headers(self, headers: dict[str, str]) -> Client:
55    def with_headers(self, headers: dict[str, str]) -> "Client":
56        """Get a new client matching this one with additional headers"""
57        if self._client is not None:
58            self._client.headers.update(headers)
59        if self._async_client is not None:
60            self._async_client.headers.update(headers)
61        return evolve(self, headers={**self._headers, **headers})

Get a new client matching this one with additional headers

def with_cookies(self, cookies: dict[str, str]) -> Client:
63    def with_cookies(self, cookies: dict[str, str]) -> "Client":
64        """Get a new client matching this one with additional cookies"""
65        if self._client is not None:
66            self._client.cookies.update(cookies)
67        if self._async_client is not None:
68            self._async_client.cookies.update(cookies)
69        return evolve(self, cookies={**self._cookies, **cookies})

Get a new client matching this one with additional cookies

def with_timeout(self, timeout: httpx.Timeout) -> Client:
71    def with_timeout(self, timeout: httpx.Timeout) -> "Client":
72        """Get a new client matching this one with a new timeout configuration"""
73        if self._client is not None:
74            self._client.timeout = timeout
75        if self._async_client is not None:
76            self._async_client.timeout = timeout
77        return evolve(self, timeout=timeout)

Get a new client matching this one with a new timeout configuration

def set_httpx_client(self, client: httpx.Client) -> Client:
79    def set_httpx_client(self, client: httpx.Client) -> "Client":
80        """Manually set the underlying httpx.Client
81
82        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
83        """
84        self._client = client
85        return self

Manually set the underlying httpx.Client

NOTE: This will override any other settings on the client, including cookies, headers, and timeout.

def get_httpx_client(self) -> httpx.Client:
87    def get_httpx_client(self) -> httpx.Client:
88        """Get the underlying httpx.Client, constructing a new one if not previously set"""
89        if self._client is None:
90            self._client = httpx.Client(
91                base_url=self._base_url,
92                cookies=self._cookies,
93                headers=self._headers,
94                timeout=self._timeout,
95                verify=self._verify_ssl,
96                follow_redirects=self._follow_redirects,
97                **self._httpx_args,
98            )
99        return self._client

Get the underlying httpx.Client, constructing a new one if not previously set

def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> Client:
110    def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "Client":
111        """Manually set the underlying httpx.AsyncClient
112
113        **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
114        """
115        self._async_client = async_client
116        return self

Manually set the underlying httpx.AsyncClient

NOTE: This will override any other settings on the client, including cookies, headers, and timeout.

def get_async_httpx_client(self) -> httpx.AsyncClient:
118    def get_async_httpx_client(self) -> httpx.AsyncClient:
119        """Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
120        if self._async_client is None:
121            self._async_client = httpx.AsyncClient(
122                base_url=self._base_url,
123                cookies=self._cookies,
124                headers=self._headers,
125                timeout=self._timeout,
126                verify=self._verify_ssl,
127                follow_redirects=self._follow_redirects,
128                **self._httpx_args,
129            )
130        return self._async_client

Get the underlying httpx.AsyncClient, constructing a new one if not previously set

@attrs.frozen
class ClientExtension:
102@attrs.frozen
103class ClientExtension:
104    """Declarative configuration bundle for downstream SDK integration.
105
106    All fields are optional. Pass an instance to `IonQClient` via the
107    ``extension`` parameter to customize client behavior.
108
109    Attributes:
110        user_agent_token: Extra token appended to the ``User-Agent`` header
111            (e.g. ``"my-sdk/1.0"``).
112        default_headers: Headers merged into every request.
113        event_hooks: Sync `EventHook` instances invoked on every request.
114        async_event_hooks: Async `AsyncEventHook` instances invoked on
115            every async request.
116        retryable_status_codes: HTTP status codes that should trigger a retry.
117            Overrides the default set (429, 500, 502, 503, 520-529).
118        max_retries: Maximum retry attempts. Overrides the default of 2.
119        timeout: Request timeout. Overrides the default of 60 seconds.
120        transport_wrapper: Callable that wraps the sync transport, useful for
121            adding middleware (e.g. caching, tracing).
122        async_transport_wrapper: Callable that wraps the async transport.
123        error_mapper: Callable that maps exceptions raised by the transport
124            to downstream-specific exception types. Return the original
125            exception to leave it unchanged.
126        debug_hooks: If ``True``, hook exceptions are re-raised instead of
127            being logged and suppressed. Useful during development.
128    """
129
130    user_agent_token: str | None = None
131    default_headers: dict[str, str] = attrs.Factory(dict)
132    event_hooks: tuple[EventHook, ...] = ()
133    async_event_hooks: tuple[AsyncEventHook, ...] = ()
134    retryable_status_codes: frozenset[int] | None = None
135    max_retries: int | None = None
136    timeout: httpx.Timeout | None = None
137    transport_wrapper: Callable[[httpx.BaseTransport], httpx.BaseTransport] | None = None
138    async_transport_wrapper: Callable[[httpx.AsyncBaseTransport], httpx.AsyncBaseTransport] | None = None
139    error_mapper: Callable[[Exception], Exception] | None = None
140    debug_hooks: bool = False

Declarative configuration bundle for downstream SDK integration.

All fields are optional. Pass an instance to IonQClient via the extension parameter to customize client behavior.

Attributes:
  • user_agent_token: Extra token appended to the User-Agent header (e.g. "my-sdk/1.0").
  • default_headers: Headers merged into every request.
  • event_hooks: Sync EventHook instances invoked on every request.
  • async_event_hooks: Async AsyncEventHook instances invoked on every async request.
  • retryable_status_codes: HTTP status codes that should trigger a retry. Overrides the default set (429, 500, 502, 503, 520-529).
  • max_retries: Maximum retry attempts. Overrides the default of 2.
  • timeout: Request timeout. Overrides the default of 60 seconds.
  • transport_wrapper: Callable that wraps the sync transport, useful for adding middleware (e.g. caching, tracing).
  • async_transport_wrapper: Callable that wraps the async transport.
  • error_mapper: Callable that maps exceptions raised by the transport to downstream-specific exception types. Return the original exception to leave it unchanged.
  • debug_hooks: If True, hook exceptions are re-raised instead of being logged and suppressed. Useful during development.
ClientExtension( user_agent_token: str | None = None, default_headers: dict[str, str] = NOTHING, event_hooks: tuple[EventHook, ...] = (), async_event_hooks: tuple[AsyncEventHook, ...] = (), retryable_status_codes: frozenset[int] | None = None, max_retries: int | None = None, timeout: httpx.Timeout | None = None, transport_wrapper: Callable[[httpx.BaseTransport], httpx.BaseTransport] | None = None, async_transport_wrapper: Callable[[httpx.AsyncBaseTransport], httpx.AsyncBaseTransport] | None = None, error_mapper: Callable[[Exception], Exception] | None = None, debug_hooks: bool = False)
48def __init__(self, user_agent_token=attr_dict['user_agent_token'].default, default_headers=NOTHING, event_hooks=attr_dict['event_hooks'].default, async_event_hooks=attr_dict['async_event_hooks'].default, retryable_status_codes=attr_dict['retryable_status_codes'].default, max_retries=attr_dict['max_retries'].default, timeout=attr_dict['timeout'].default, transport_wrapper=attr_dict['transport_wrapper'].default, async_transport_wrapper=attr_dict['async_transport_wrapper'].default, error_mapper=attr_dict['error_mapper'].default, debug_hooks=attr_dict['debug_hooks'].default):
49    _setattr = _cached_setattr_get(self)
50    _setattr('user_agent_token', user_agent_token)
51    if default_headers is not NOTHING:
52        _setattr('default_headers', default_headers)
53    else:
54        _setattr('default_headers', __attr_factory_default_headers())
55    _setattr('event_hooks', event_hooks)
56    _setattr('async_event_hooks', async_event_hooks)
57    _setattr('retryable_status_codes', retryable_status_codes)
58    _setattr('max_retries', max_retries)
59    _setattr('timeout', timeout)
60    _setattr('transport_wrapper', transport_wrapper)
61    _setattr('async_transport_wrapper', async_transport_wrapper)
62    _setattr('error_mapper', error_mapper)
63    _setattr('debug_hooks', debug_hooks)

Method generated by attrs for class ClientExtension.

user_agent_token: str | None
default_headers: dict[str, str]
event_hooks: tuple[EventHook, ...]
async_event_hooks: tuple[AsyncEventHook, ...]
retryable_status_codes: frozenset[int] | None
max_retries: int | None
timeout: httpx.Timeout | None
transport_wrapper: Callable[[httpx.BaseTransport], httpx.BaseTransport] | None
async_transport_wrapper: Callable[[httpx.AsyncBaseTransport], httpx.AsyncBaseTransport] | None
error_mapper: Callable[[Exception], Exception] | None
debug_hooks: bool
@runtime_checkable
class EventHook(typing.Protocol):
47@runtime_checkable
48class EventHook(Protocol):
49    """Protocol for observing HTTP requests and responses (sync).
50
51    Implement this protocol and pass instances via
52    `ClientExtension.event_hooks` to receive callbacks on every request.
53
54    Hook exceptions are logged and suppressed by default. Set
55    ``debug_hooks=True`` on `ClientExtension` to re-raise them instead.
56    """
57
58    def on_request(self, request: httpx.Request) -> None:
59        """Called after the request is built but before it is sent.
60
61        Args:
62            request: The outgoing HTTP request.
63        """
64        ...
65
66    def on_response(self, request: httpx.Request, response: httpx.Response) -> None:
67        """Called after a response is received.
68
69        Args:
70            request: The original HTTP request.
71            response: The HTTP response. The body has already been read.
72        """
73        ...

Protocol for observing HTTP requests and responses (sync).

Implement this protocol and pass instances via ClientExtension.event_hooks to receive callbacks on every request.

Hook exceptions are logged and suppressed by default. Set debug_hooks=True on ClientExtension to re-raise them instead.

EventHook(*args, **kwargs)
1953def _no_init_or_replace_init(self, *args, **kwargs):
1954    cls = type(self)
1955
1956    if cls._is_protocol:
1957        raise TypeError('Protocols cannot be instantiated')
1958
1959    # Already using a custom `__init__`. No need to calculate correct
1960    # `__init__` to call. This can lead to RecursionError. See bpo-45121.
1961    if cls.__init__ is not _no_init_or_replace_init:
1962        return
1963
1964    # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`.
1965    # The first instantiation of the subclass will call `_no_init_or_replace_init` which
1966    # searches for a proper new `__init__` in the MRO. The new `__init__`
1967    # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent
1968    # instantiation of the protocol subclass will thus use the new
1969    # `__init__` and no longer call `_no_init_or_replace_init`.
1970    for base in cls.__mro__:
1971        init = base.__dict__.get('__init__', _no_init_or_replace_init)
1972        if init is not _no_init_or_replace_init:
1973            cls.__init__ = init
1974            break
1975    else:
1976        # should not happen
1977        cls.__init__ = object.__init__
1978
1979    cls.__init__(self, *args, **kwargs)
def on_request(self, request: httpx.Request) -> None:
58    def on_request(self, request: httpx.Request) -> None:
59        """Called after the request is built but before it is sent.
60
61        Args:
62            request: The outgoing HTTP request.
63        """
64        ...

Called after the request is built but before it is sent.

Arguments:
  • request: The outgoing HTTP request.
def on_response(self, request: httpx.Request, response: httpx.Response) -> None:
66    def on_response(self, request: httpx.Request, response: httpx.Response) -> None:
67        """Called after a response is received.
68
69        Args:
70            request: The original HTTP request.
71            response: The HTTP response. The body has already been read.
72        """
73        ...

Called after a response is received.

Arguments:
  • request: The original HTTP request.
  • response: The HTTP response. The body has already been read.
def IonQClient( *, api_key: str | None = None, base_url: str = 'https://api.ionq.co/v0.4', max_retries: int | None = None, timeout: httpx.Timeout | None = None, additional_user_agent: str | None = None, extension: ClientExtension | None = None, **kwargs) -> AuthenticatedClient:
 40def IonQClient(
 41    *,
 42    api_key: str | None = None,
 43    base_url: str = DEFAULT_BASE_URL,
 44    max_retries: int | None = None,
 45    timeout: httpx.Timeout | None = None,
 46    additional_user_agent: str | None = None,
 47    extension: ClientExtension | None = None,
 48    **kwargs,
 49) -> AuthenticatedClient:
 50    """Create an authenticated IonQ API client.
 51
 52    This is the recommended entry point for using the library. It handles
 53    authentication, retry configuration, User-Agent construction, and transport
 54    setup for both sync and async usage.
 55
 56    Args:
 57        api_key: IonQ API key. If not provided, reads the ``IONQ_API_KEY``
 58            environment variable.
 59        base_url: API base URL. Defaults to the IonQ production API.
 60        max_retries: Maximum retry attempts for transient errors (429, 5xx).
 61            Defaults to 2. Set to 0 to disable retries.
 62        timeout: Request timeout as an ``httpx.Timeout`` instance. Defaults to
 63            60 seconds with a 10-second connect timeout.
 64        additional_user_agent: Extra token appended to the User-Agent header,
 65            useful for identifying calling applications.
 66        extension: A `ClientExtension` bundle provided by a downstream SDK.
 67            Allows injecting hooks, custom headers, transport wrappers, and
 68            error mappers.
 69        **kwargs: Passed through to `AuthenticatedClient`.
 70
 71    Returns:
 72        An `AuthenticatedClient` configured with retry transport and
 73        authentication headers, ready for both sync and async API calls.
 74
 75    Raises:
 76        ValueError: If no API key is provided and ``IONQ_API_KEY`` is not set.
 77
 78    Examples:
 79        Basic usage with environment variable:
 80
 81        ```python
 82        from ionq_core import IonQClient
 83        from ionq_core.api.backends import get_backends
 84
 85        client = IonQClient()
 86        backends = get_backends.sync(client=client)
 87        ```
 88
 89        Explicit configuration:
 90
 91        ```python
 92        import httpx
 93        from ionq_core import IonQClient
 94
 95        client = IonQClient(
 96            api_key="your-api-key",
 97            max_retries=5,
 98            timeout=httpx.Timeout(30.0, connect=10.0),
 99        )
100        ```
101
102        Async usage with context manager:
103
104        ```python
105        async with IonQClient() as client:
106            backends = await get_backends.asyncio(client=client)
107        ```
108    """
109    key = api_key or os.environ.get("IONQ_API_KEY")
110    if not key:
111        raise ValueError("api_key or IONQ_API_KEY environment variable required")
112
113    if not base_url.startswith("https://"):
114        warnings.warn(
115            f"base_url {base_url!r} does not use HTTPS. API keys will be sent in cleartext.",
116            UserWarning,
117            stacklevel=2,
118        )
119    if kwargs.get("verify_ssl") is False:
120        warnings.warn(
121            "verify_ssl=False disables TLS certificate verification. "
122            "Your API key may be intercepted by a network attacker.",
123            UserWarning,
124            stacklevel=2,
125        )
126
127    ext = extension or ClientExtension()
128    ua_parts = [
129        f"ionq-core/{__version__}",
130        f"python/{platform.python_version()}",
131        f"httpx/{httpx.__version__}",
132        f"os/{platform.system().lower()}",
133        *filter(None, (additional_user_agent, ext.user_agent_token)),
134    ]
135    user_agent = " ".join(ua_parts)
136    effective_timeout = timeout or ext.timeout or DEFAULT_TIMEOUT
137    effective_retries = next(v for v in (max_retries, ext.max_retries, DEFAULT_MAX_RETRIES) if v is not None)
138
139    headers = {**ext.default_headers, "User-Agent": user_agent}
140
141    sync_transport = async_transport = build_transport(
142        effective_retries,
143        ext.retryable_status_codes or RETRYABLE_STATUS_CODES,
144    )
145
146    if ext.event_hooks or ext.error_mapper:
147        sync_transport = HookTransport(
148            sync_transport,
149            ext.event_hooks,
150            debug=ext.debug_hooks,
151            error_mapper=ext.error_mapper,
152        )
153    if ext.async_event_hooks or ext.error_mapper:
154        async_transport = HookTransport(
155            async_transport,
156            ext.async_event_hooks,
157            debug=ext.debug_hooks,
158            error_mapper=ext.error_mapper,
159        )
160    if ext.transport_wrapper:
161        sync_transport = ext.transport_wrapper(sync_transport)
162    if ext.async_transport_wrapper:
163        async_transport = ext.async_transport_wrapper(async_transport)
164
165    client = AuthenticatedClient(
166        base_url=base_url,
167        token=key,
168        prefix=_AUTH_PREFIX,
169        auth_header_name=_AUTH_HEADER,
170        timeout=effective_timeout,
171        headers=headers,
172        httpx_args={"transport": sync_transport},
173        **kwargs,
174    )
175    # `set_async_httpx_client` bypasses `AuthenticatedClient`'s lazy auth-header
176    # injection (see generated `client.py::get_async_httpx_client`), so we merge
177    # `Authorization` in manually here. The `_verify_ssl` / `_follow_redirects`
178    # fields are private on the generated `AuthenticatedClient` but are the only
179    # way to mirror the caller's choices onto the async transport; do not add a
180    # public accessor in the hand-written layer — they belong to generated code.
181    client.set_async_httpx_client(
182        httpx.AsyncClient(
183            base_url=base_url,
184            headers={**headers, _AUTH_HEADER: f"{_AUTH_PREFIX} {key}"},
185            timeout=effective_timeout,
186            transport=async_transport,
187            verify=client._verify_ssl,
188            follow_redirects=client._follow_redirects,
189        )
190    )
191    return client

Create an authenticated IonQ API client.

This is the recommended entry point for using the library. It handles authentication, retry configuration, User-Agent construction, and transport setup for both sync and async usage.

Arguments:
  • api_key: IonQ API key. If not provided, reads the IONQ_API_KEY environment variable.
  • base_url: API base URL. Defaults to the IonQ production API.
  • max_retries: Maximum retry attempts for transient errors (429, 5xx). Defaults to 2. Set to 0 to disable retries.
  • timeout: Request timeout as an httpx.Timeout instance. Defaults to 60 seconds with a 10-second connect timeout.
  • additional_user_agent: Extra token appended to the User-Agent header, useful for identifying calling applications.
  • extension: A ClientExtension bundle provided by a downstream SDK. Allows injecting hooks, custom headers, transport wrappers, and error mappers.
  • **kwargs: Passed through to AuthenticatedClient.
Returns:

An AuthenticatedClient configured with retry transport and authentication headers, ready for both sync and async API calls.

Raises:
  • ValueError: If no API key is provided and IONQ_API_KEY is not set.
Examples:

Basic usage with environment variable:

from ionq_core import IonQClient
from ionq_core.api.backends import get_backends

client = IonQClient()
backends = get_backends.sync(client=client)

Explicit configuration:

import httpx
from ionq_core import IonQClient

client = IonQClient(
    api_key="your-api-key",
    max_retries=5,
    timeout=httpx.Timeout(30.0, connect=10.0),
)

Async usage with context manager:

async with IonQClient() as client:
    backends = await get_backends.asyncio(client=client)
class IonQError(builtins.Exception):
50class IonQError(Exception):
51    """Base exception for all IonQ errors.
52
53    Catch this to handle any error raised by the library, including connection
54    failures, API errors, polling timeouts, and job failures.
55    """

Base exception for all IonQ errors.

Catch this to handle any error raised by the library, including connection failures, API errors, polling timeouts, and job failures.

class JobFailedError(ionq_core.IonQError):
68class JobFailedError(IonQError):
69    """Raised when a polled job reaches ``"failed"`` status.
70
71    Attributes:
72        job_id: The ID of the failed job.
73        failure: The failure detail object from the API response, or ``None``
74            if no failure details were provided.
75    """
76
77    def __init__(self, job_id: str, failure: object) -> None:
78        self.job_id = job_id
79        self.failure = failure
80        super().__init__(f"Job {job_id} failed: {failure}")

Raised when a polled job reaches "failed" status.

Attributes:
  • job_id: The ID of the failed job.
  • failure: The failure detail object from the API response, or None if no failure details were provided.
JobFailedError(job_id: str, failure: object)
77    def __init__(self, job_id: str, failure: object) -> None:
78        self.job_id = job_id
79        self.failure = failure
80        super().__init__(f"Job {job_id} failed: {failure}")
job_id
failure
class JobTimeoutError(ionq_core.IonQError):
51class JobTimeoutError(IonQError):
52    """Raised when a job does not reach a terminal state within the timeout.
53
54    Attributes:
55        job_id: The ID of the job that timed out.
56        timeout: The timeout value in seconds that was exceeded.
57        last_status: The last observed status before the timeout
58            (e.g. ``"running"``, ``"submitted"``).
59    """
60
61    def __init__(self, job_id: str, timeout: float, last_status: str) -> None:
62        self.job_id = job_id
63        self.timeout = timeout
64        self.last_status = last_status
65        super().__init__(f"Job {job_id} did not complete within {timeout}s (last status: {last_status})")

Raised when a job does not reach a terminal state within the timeout.

Attributes:
  • job_id: The ID of the job that timed out.
  • timeout: The timeout value in seconds that was exceeded.
  • last_status: The last observed status before the timeout (e.g. "running", "submitted").
JobTimeoutError(job_id: str, timeout: float, last_status: str)
61    def __init__(self, job_id: str, timeout: float, last_status: str) -> None:
62        self.job_id = job_id
63        self.timeout = timeout
64        self.last_status = last_status
65        super().__init__(f"Job {job_id} did not complete within {timeout}s (last status: {last_status})")
job_id
timeout
last_status
class NotFoundError(ionq_core.APIError):
117class NotFoundError(APIError):
118    """Raised on ``404 Not Found``.
119
120    The requested resource (job, session, backend, etc.) does not exist.
121    """

Raised on 404 Not Found.

The requested resource (job, session, backend, etc.) does not exist.

class PermissionDeniedError(ionq_core.APIError):
110class PermissionDeniedError(APIError):
111    """Raised on ``403 Forbidden``.
112
113    The API key is valid but lacks permission for the requested operation.
114    """

Raised on 403 Forbidden.

The API key is valid but lacks permission for the requested operation.

class RateLimitError(ionq_core.APIError):
132class RateLimitError(APIError):
133    """Raised on ``429 Too Many Requests``.
134
135    The client has exceeded the API rate limit. The ``retry_after`` attribute
136    indicates how many seconds to wait before retrying, if the server provided
137    a ``Retry-After`` header.
138
139    Attributes:
140        retry_after: Seconds to wait before retrying, or ``None`` if the
141            server did not include a ``Retry-After`` header.
142    """
143
144    def __init__(
145        self,
146        status_code: int = 429,
147        body: dict | str | None = None,
148        message: str | None = None,
149        retry_after: float | None = None,
150        *,
151        request_id: str | None = None,
152    ) -> None:
153        super().__init__(status_code, body, message, request_id=request_id)
154        self.retry_after = retry_after

Raised on 429 Too Many Requests.

The client has exceeded the API rate limit. The retry_after attribute indicates how many seconds to wait before retrying, if the server provided a Retry-After header.

Attributes:
  • retry_after: Seconds to wait before retrying, or None if the server did not include a Retry-After header.
RateLimitError( status_code: int = 429, body: dict | str | None = None, message: str | None = None, retry_after: float | None = None, *, request_id: str | None = None)
144    def __init__(
145        self,
146        status_code: int = 429,
147        body: dict | str | None = None,
148        message: str | None = None,
149        retry_after: float | None = None,
150        *,
151        request_id: str | None = None,
152    ) -> None:
153        super().__init__(status_code, body, message, request_id=request_id)
154        self.retry_after = retry_after
retry_after
class ServerError(ionq_core.APIError):
157class ServerError(APIError):
158    """Raised on ``5xx`` server errors.
159
160    These are typically transient and are automatically retried by the default
161    transport (see `IonQClient`).
162    """

Raised on 5xx server errors.

These are typically transient and are automatically retried by the default transport (see IonQClient).

class SessionManager:
 49class SessionManager:
 50    """Convenience wrapper around session create / end / status APIs.
 51
 52    Can be used as both a sync and async context manager. On exit the
 53    session is automatically ended. Exceptions during close are logged
 54    and suppressed so that cleanup does not mask the original error.
 55
 56    Args:
 57        client: An authenticated API client.
 58        backend: The backend to create a session on (e.g. ``"qpu.aria-1"``).
 59        max_jobs: Optional maximum number of jobs for this session.
 60        max_time: Optional maximum session duration in minutes.
 61        max_cost: Optional maximum cost in USD for the session.
 62
 63    Examples:
 64        Sync context manager:
 65
 66        ```python
 67        with SessionManager(client, "qpu.aria-1", max_jobs=10) as session:
 68            print(session.session_id)
 69        ```
 70
 71        Async context manager:
 72
 73        ```python
 74        async with SessionManager(client, "qpu.aria-1") as session:
 75            print(session.session_id)
 76        ```
 77    """
 78
 79    def __init__(
 80        self,
 81        client: AuthenticatedClient,
 82        backend: str,
 83        *,
 84        max_jobs: int | None = None,
 85        max_time: int | None = None,
 86        max_cost: float | None = None,
 87    ) -> None:
 88        self._client = client
 89        self._backend = backend
 90        self._max_jobs = max_jobs
 91        self._max_time = max_time
 92        self._max_cost = max_cost
 93        self._session_id: str | None = None
 94
 95    @classmethod
 96    def from_id(cls, client: AuthenticatedClient, session_id: str) -> SessionManager:
 97        """Reconnect to an existing session without creating a new one.
 98
 99        This is useful for resuming work with a session that was created
100        in a previous process or by another client.
101
102        Args:
103            client: An authenticated API client.
104            session_id: The ID of the existing session.
105
106        Returns:
107            A `SessionManager` bound to the given session ID. The ``backend``
108            field will be empty since it is not needed for status checks
109            or ending the session.
110        """
111        mgr = cls(client, backend="")
112        mgr._session_id = session_id
113        return mgr
114
115    @property
116    def session_id(self) -> str | None:
117        """The session ID, or ``None`` if `open` has not been called."""
118        return self._session_id
119
120    def _build_settings(self) -> SessionSettingsRequest | Unset:
121        kw: dict = {}
122        if self._max_jobs is not None:
123            kw["job_count_limit"] = self._max_jobs
124        if self._max_time is not None:
125            kw["duration_limit_min"] = self._max_time
126        if self._max_cost is not None:
127            kw["cost_limit"] = SessionCostLimit(unit="usd", value=self._max_cost)
128        return SessionSettingsRequest(**kw) if kw else UNSET
129
130    def open(self) -> None:
131        """Create a new session on the configured backend.
132
133        Raises:
134            IonQError: If a session is already open or creation fails.
135        """
136        if self._session_id is not None:
137            raise IonQError("Session already open")
138        body = CreateSessionRequest(backend=self._backend, settings=self._build_settings())
139        session = create_session.sync(client=self._client, body=body)
140        if session is None:
141            raise IonQError("Failed to create session")
142        self._session_id = session.id
143        logger.info("Opened session %s", self._session_id)
144
145    def close(self) -> None:
146        """End the session. Suppresses exceptions so cleanup is safe."""
147        if self._session_id is None:
148            return
149        try:
150            end_session.sync(session_id=self._session_id, client=self._client)
151            logger.info("Closed session %s", self._session_id)
152        except Exception:
153            logger.warning("Failed to end session %s", self._session_id, exc_info=True)
154
155    def status(self) -> str:
156        """Get the current session status (e.g. ``"created"``, ``"started"``, ``"ended"``).
157
158        Raises:
159            IonQError: If no session is open or the status fetch fails.
160        """
161        if self._session_id is None:
162            raise IonQError("No session ID; call open() first")
163        session = get_session.sync(session_id=self._session_id, client=self._client)
164        if session is None:
165            raise IonQError(f"Failed to fetch session {self._session_id}")
166        return session.status
167
168    async def async_open(self) -> None:
169        """Async version of `open`."""
170        if self._session_id is not None:
171            raise IonQError("Session already open")
172        body = CreateSessionRequest(backend=self._backend, settings=self._build_settings())
173        session = await create_session.asyncio(client=self._client, body=body)
174        if session is None:
175            raise IonQError("Failed to create session")
176        self._session_id = session.id
177        logger.info("Opened session %s", self._session_id)
178
179    async def async_close(self) -> None:
180        """End the session (async). Suppresses exceptions so cleanup is safe."""
181        if self._session_id is None:
182            return
183        try:
184            await end_session.asyncio(session_id=self._session_id, client=self._client)
185            logger.info("Closed session %s", self._session_id)
186        except Exception:
187            logger.warning("Failed to end session %s", self._session_id, exc_info=True)
188
189    async def async_status(self) -> str:
190        """Async version of `status`."""
191        if self._session_id is None:
192            raise IonQError("No session ID; call open() first")
193        session = await get_session.asyncio(session_id=self._session_id, client=self._client)
194        if session is None:
195            raise IonQError(f"Failed to fetch session {self._session_id}")
196        return session.status
197
198    def __enter__(self) -> SessionManager:
199        self.open()
200        return self
201
202    def __exit__(self, *exc: object) -> None:
203        self.close()
204
205    async def __aenter__(self) -> SessionManager:
206        await self.async_open()
207        return self
208
209    async def __aexit__(self, *exc: object) -> None:
210        await self.async_close()

Convenience wrapper around session create / end / status APIs.

Can be used as both a sync and async context manager. On exit the session is automatically ended. Exceptions during close are logged and suppressed so that cleanup does not mask the original error.

Arguments:
  • client: An authenticated API client.
  • backend: The backend to create a session on (e.g. "qpu.aria-1").
  • max_jobs: Optional maximum number of jobs for this session.
  • max_time: Optional maximum session duration in minutes.
  • max_cost: Optional maximum cost in USD for the session.
Examples:

Sync context manager:

with SessionManager(client, "qpu.aria-1", max_jobs=10) as session:
    print(session.session_id)

Async context manager:

async with SessionManager(client, "qpu.aria-1") as session:
    print(session.session_id)
SessionManager( client: AuthenticatedClient, backend: str, *, max_jobs: int | None = None, max_time: int | None = None, max_cost: float | None = None)
79    def __init__(
80        self,
81        client: AuthenticatedClient,
82        backend: str,
83        *,
84        max_jobs: int | None = None,
85        max_time: int | None = None,
86        max_cost: float | None = None,
87    ) -> None:
88        self._client = client
89        self._backend = backend
90        self._max_jobs = max_jobs
91        self._max_time = max_time
92        self._max_cost = max_cost
93        self._session_id: str | None = None
@classmethod
def from_id( cls, client: AuthenticatedClient, session_id: str) -> SessionManager:
 95    @classmethod
 96    def from_id(cls, client: AuthenticatedClient, session_id: str) -> SessionManager:
 97        """Reconnect to an existing session without creating a new one.
 98
 99        This is useful for resuming work with a session that was created
100        in a previous process or by another client.
101
102        Args:
103            client: An authenticated API client.
104            session_id: The ID of the existing session.
105
106        Returns:
107            A `SessionManager` bound to the given session ID. The ``backend``
108            field will be empty since it is not needed for status checks
109            or ending the session.
110        """
111        mgr = cls(client, backend="")
112        mgr._session_id = session_id
113        return mgr

Reconnect to an existing session without creating a new one.

This is useful for resuming work with a session that was created in a previous process or by another client.

Arguments:
  • client: An authenticated API client.
  • session_id: The ID of the existing session.
Returns:

A SessionManager bound to the given session ID. The backend field will be empty since it is not needed for status checks or ending the session.

session_id: str | None
115    @property
116    def session_id(self) -> str | None:
117        """The session ID, or ``None`` if `open` has not been called."""
118        return self._session_id

The session ID, or None if open has not been called.

def open(self) -> None:
130    def open(self) -> None:
131        """Create a new session on the configured backend.
132
133        Raises:
134            IonQError: If a session is already open or creation fails.
135        """
136        if self._session_id is not None:
137            raise IonQError("Session already open")
138        body = CreateSessionRequest(backend=self._backend, settings=self._build_settings())
139        session = create_session.sync(client=self._client, body=body)
140        if session is None:
141            raise IonQError("Failed to create session")
142        self._session_id = session.id
143        logger.info("Opened session %s", self._session_id)

Create a new session on the configured backend.

Raises:
  • IonQError: If a session is already open or creation fails.
def close(self) -> None:
145    def close(self) -> None:
146        """End the session. Suppresses exceptions so cleanup is safe."""
147        if self._session_id is None:
148            return
149        try:
150            end_session.sync(session_id=self._session_id, client=self._client)
151            logger.info("Closed session %s", self._session_id)
152        except Exception:
153            logger.warning("Failed to end session %s", self._session_id, exc_info=True)

End the session. Suppresses exceptions so cleanup is safe.

def status(self) -> str:
155    def status(self) -> str:
156        """Get the current session status (e.g. ``"created"``, ``"started"``, ``"ended"``).
157
158        Raises:
159            IonQError: If no session is open or the status fetch fails.
160        """
161        if self._session_id is None:
162            raise IonQError("No session ID; call open() first")
163        session = get_session.sync(session_id=self._session_id, client=self._client)
164        if session is None:
165            raise IonQError(f"Failed to fetch session {self._session_id}")
166        return session.status

Get the current session status (e.g. "created", "started", "ended").

Raises:
  • IonQError: If no session is open or the status fetch fails.
async def async_open(self) -> None:
168    async def async_open(self) -> None:
169        """Async version of `open`."""
170        if self._session_id is not None:
171            raise IonQError("Session already open")
172        body = CreateSessionRequest(backend=self._backend, settings=self._build_settings())
173        session = await create_session.asyncio(client=self._client, body=body)
174        if session is None:
175            raise IonQError("Failed to create session")
176        self._session_id = session.id
177        logger.info("Opened session %s", self._session_id)

Async version of open.

async def async_close(self) -> None:
179    async def async_close(self) -> None:
180        """End the session (async). Suppresses exceptions so cleanup is safe."""
181        if self._session_id is None:
182            return
183        try:
184            await end_session.asyncio(session_id=self._session_id, client=self._client)
185            logger.info("Closed session %s", self._session_id)
186        except Exception:
187            logger.warning("Failed to end session %s", self._session_id, exc_info=True)

End the session (async). Suppresses exceptions so cleanup is safe.

async def async_status(self) -> str:
189    async def async_status(self) -> str:
190        """Async version of `status`."""
191        if self._session_id is None:
192            raise IonQError("No session ID; call open() first")
193        session = await get_session.asyncio(session_id=self._session_id, client=self._client)
194        if session is None:
195            raise IonQError(f"Failed to fetch session {self._session_id}")
196        return session.status

Async version of status.

UNSET = <Unset object>
class Unset:
15class Unset:
16    def __bool__(self) -> Literal[False]:
17        return False
__version__ = '0.1.1'
def aiter_jobs( client: AuthenticatedClient, *, status: Union[Literal['canceled', 'completed', 'failed', 'ready', 'started', 'submitted'], Unset] = <Unset object>, target: str | Unset = <Unset object>, session_id: str | Unset = <Unset object>, submitter_id: str | Unset = <Unset object>, limit: int | Unset = <Unset object>) -> AsyncIterator[ionq_core.models.base_job.BaseJob]:
106def aiter_jobs(
107    client: AuthenticatedClient,
108    *,
109    status: JobStatus | Unset = UNSET,
110    target: str | Unset = UNSET,
111    session_id: str | Unset = UNSET,
112    submitter_id: str | Unset = UNSET,
113    limit: int | Unset = UNSET,
114) -> AsyncIterator[Job]:
115    """Async version of `iter_jobs`.
116
117    Args:
118        client: An authenticated API client.
119        status: Filter by job status.
120        target: Filter by backend target name.
121        session_id: Filter by session ID.
122        submitter_id: Filter by submitter user ID.
123        limit: Maximum number of jobs per page.
124
125    Yields:
126        Individual job objects across all pages.
127
128    Raises:
129        IonQError: If the API returns a ``None`` response.
130    """
131    return _apaginate(
132        get_jobs.asyncio,
133        "jobs",
134        client=client,
135        status=status,
136        target=target,
137        session_id=session_id,
138        submitter_id=submitter_id,
139        limit=limit,
140    )

Async version of iter_jobs.

Arguments:
  • client: An authenticated API client.
  • status: Filter by job status.
  • target: Filter by backend target name.
  • session_id: Filter by session ID.
  • submitter_id: Filter by submitter user ID.
  • limit: Maximum number of jobs per page.
Yields:

Individual job objects across all pages.

Raises:
  • IonQError: If the API returns a None response.
def aiter_session_jobs( client: AuthenticatedClient, session_id: str, *, status: Union[Literal['canceled', 'completed', 'failed', 'ready', 'started', 'submitted'], Unset] = <Unset object>, target: str | Unset = <Unset object>, submitter_id: str | Unset = <Unset object>, limit: int | Unset = <Unset object>) -> AsyncIterator[ionq_core.models.base_job.BaseJob]:
182def aiter_session_jobs(
183    client: AuthenticatedClient,
184    session_id: str,
185    *,
186    status: JobStatus | Unset = UNSET,
187    target: str | Unset = UNSET,
188    submitter_id: str | Unset = UNSET,
189    limit: int | Unset = UNSET,
190) -> AsyncIterator[Job]:
191    """Async version of `iter_session_jobs`.
192
193    Args:
194        client: An authenticated API client.
195        session_id: The session ID to list jobs for.
196        status: Filter by job status.
197        target: Filter by backend target name.
198        submitter_id: Filter by submitter user ID.
199        limit: Maximum number of jobs per page.
200
201    Yields:
202        Individual job objects across all pages.
203
204    Raises:
205        IonQError: If the API returns a ``None`` response.
206    """
207    return _apaginate(
208        get_session_jobs.asyncio,
209        "session jobs",
210        session_id,
211        client=client,
212        status=status,
213        target=target,
214        submitter_id=submitter_id,
215        limit=limit,
216    )

Async version of iter_session_jobs.

Arguments:
  • client: An authenticated API client.
  • session_id: The session ID to list jobs for.
  • status: Filter by job status.
  • target: Filter by backend target name.
  • submitter_id: Filter by submitter user ID.
  • limit: Maximum number of jobs per page.
Yields:

Individual job objects across all pages.

Raises:
  • IonQError: If the API returns a None response.
async def async_wait_for_job( client: AuthenticatedClient, job_id: str, *, poll_interval: float = 1.0, timeout: float = 300.0, raise_on_failure: bool = True) -> ionq_core.models.get_job_response.GetJobResponse:
140async def async_wait_for_job(
141    client: AuthenticatedClient,
142    job_id: str,
143    *,
144    poll_interval: float = _DEFAULT_INTERVAL,
145    timeout: float = _DEFAULT_TIMEOUT,
146    raise_on_failure: bool = True,
147) -> GetJobResponse:
148    """Async version of `wait_for_job`.
149
150    Args:
151        client: An authenticated API client.
152        job_id: The UUID of the job to poll.
153        poll_interval: Initial interval between polls in seconds.
154            Defaults to 1.0.
155        timeout: Maximum total wait time in seconds. Defaults to 300.
156        raise_on_failure: If ``True``, raise `JobFailedError` on failure.
157
158    Returns:
159        The final job response once a terminal state is reached.
160
161    Raises:
162        JobTimeoutError: If the job does not finish within ``timeout``.
163        JobFailedError: If ``raise_on_failure`` is ``True`` and the job fails.
164        IonQError: If the API returns a ``None`` response.
165    """
166    deadline = time.monotonic() + timeout
167    interval = poll_interval
168    while True:
169        job = await get_job.asyncio(uuid=job_id, client=client)
170        if job is None:
171            raise IonQError(f"Failed to fetch job {job_id}")
172        logger.debug("Job %s status: %s", job_id, job.status)
173        if _check_terminal(job, raise_on_failure):
174            return job
175        if time.monotonic() >= deadline:
176            raise JobTimeoutError(job_id, timeout, job.status)
177        await asyncio.sleep(max(0, min(interval, deadline - time.monotonic())))
178        interval = min(interval * _BACKOFF_FACTOR, _MAX_INTERVAL)

Async version of wait_for_job.

Arguments:
  • client: An authenticated API client.
  • job_id: The UUID of the job to poll.
  • poll_interval: Initial interval between polls in seconds. Defaults to 1.0.
  • timeout: Maximum total wait time in seconds. Defaults to 300.
  • raise_on_failure: If True, raise JobFailedError on failure.
Returns:

The final job response once a terminal state is reached.

Raises:
  • JobTimeoutError: If the job does not finish within timeout.
  • JobFailedError: If raise_on_failure is True and the job fails.
  • IonQError: If the API returns a None response.
def gpi2_matrix(phi: float) -> tuple[tuple[complex, complex], tuple[complex, complex]]:
74def gpi2_matrix(phi: float) -> Matrix2x2:
75    """Single-qubit GPI2 gate (pi/2 rotation about an axis in the XY plane).
76
77    Args:
78        phi: Phase angle in turns (fractions of 2*pi) defining the
79            rotation axis in the XY plane.
80
81    Returns:
82        A `Matrix2x2` unitary matrix.
83    """
84    e = cmath.exp(1j * _2PI * phi)
85    s = 1 / math.sqrt(2)
86    return ((s, -1j * s / e), (-1j * s * e, s))

Single-qubit GPI2 gate (pi/2 rotation about an axis in the XY plane).

Arguments:
  • phi: Phase angle in turns (fractions of 2*pi) defining the rotation axis in the XY plane.
Returns:

A Matrix2x2 unitary matrix.

def gpi_matrix(phi: float) -> tuple[tuple[complex, complex], tuple[complex, complex]]:
51def gpi_matrix(phi: float) -> Matrix2x2:
52    r"""Single-qubit GPI gate.
53
54    Matrix form: ``[[0, e^{-i*2*pi*phi}], [e^{i*2*pi*phi}, 0]]``
55
56    At ``phi=0`` this is the Pauli X gate.
57
58    Args:
59        phi: Phase angle in turns (fractions of 2*pi).
60
61    Returns:
62        A `Matrix2x2` unitary matrix.
63
64    Examples:
65        ```python
66        >>> gpi_matrix(0)       # Pauli X
67        ((0, (1+0j)), ((1+0j), 0))
68        ```
69    """
70    e = cmath.exp(1j * _2PI * phi)
71    return ((0, 1 / e), (e, 0))

Single-qubit GPI gate.

Matrix form: [[0, e^{-i*2*pi*phi}], [e^{i*2*pi*phi}, 0]]

At phi=0 this is the Pauli X gate.

Arguments:
  • phi: Phase angle in turns (fractions of 2*pi).
Returns:

A Matrix2x2 unitary matrix.

Examples:
>>> gpi_matrix(0)       # Pauli X
((0, (1+0j)), ((1+0j), 0))
def iter_jobs( client: AuthenticatedClient, *, status: Union[Literal['canceled', 'completed', 'failed', 'ready', 'started', 'submitted'], Unset] = <Unset object>, target: str | Unset = <Unset object>, session_id: str | Unset = <Unset object>, submitter_id: str | Unset = <Unset object>, limit: int | Unset = <Unset object>) -> Iterator[ionq_core.models.base_job.BaseJob]:
 68def iter_jobs(
 69    client: AuthenticatedClient,
 70    *,
 71    status: JobStatus | Unset = UNSET,
 72    target: str | Unset = UNSET,
 73    session_id: str | Unset = UNSET,
 74    submitter_id: str | Unset = UNSET,
 75    limit: int | Unset = UNSET,
 76) -> Iterator[Job]:
 77    """Iterate over all jobs, automatically following pagination cursors.
 78
 79    Args:
 80        client: An authenticated API client.
 81        status: Filter by job status (e.g. ``"completed"``, ``"failed"``).
 82        target: Filter by backend target name.
 83        session_id: Filter by session ID.
 84        submitter_id: Filter by submitter user ID.
 85        limit: Maximum number of jobs per page (server default applies
 86            if unset).
 87
 88    Yields:
 89        Individual job objects across all pages.
 90
 91    Raises:
 92        IonQError: If the API returns a ``None`` response.
 93    """
 94    return _paginate(
 95        get_jobs.sync,
 96        "jobs",
 97        client=client,
 98        status=status,
 99        target=target,
100        session_id=session_id,
101        submitter_id=submitter_id,
102        limit=limit,
103    )

Iterate over all jobs, automatically following pagination cursors.

Arguments:
  • client: An authenticated API client.
  • status: Filter by job status (e.g. "completed", "failed").
  • target: Filter by backend target name.
  • session_id: Filter by session ID.
  • submitter_id: Filter by submitter user ID.
  • limit: Maximum number of jobs per page (server default applies if unset).
Yields:

Individual job objects across all pages.

Raises:
  • IonQError: If the API returns a None response.
def iter_session_jobs( client: AuthenticatedClient, session_id: str, *, status: Union[Literal['canceled', 'completed', 'failed', 'ready', 'started', 'submitted'], Unset] = <Unset object>, target: str | Unset = <Unset object>, submitter_id: str | Unset = <Unset object>, limit: int | Unset = <Unset object>) -> Iterator[ionq_core.models.base_job.BaseJob]:
143def iter_session_jobs(
144    client: AuthenticatedClient,
145    session_id: str,
146    *,
147    status: JobStatus | Unset = UNSET,
148    target: str | Unset = UNSET,
149    submitter_id: str | Unset = UNSET,
150    limit: int | Unset = UNSET,
151) -> Iterator[Job]:
152    """Iterate over all jobs in a specific session.
153
154    Like `iter_jobs`, but scoped to a single session.
155
156    Args:
157        client: An authenticated API client.
158        session_id: The session ID to list jobs for.
159        status: Filter by job status.
160        target: Filter by backend target name.
161        submitter_id: Filter by submitter user ID.
162        limit: Maximum number of jobs per page.
163
164    Yields:
165        Individual job objects across all pages.
166
167    Raises:
168        IonQError: If the API returns a ``None`` response.
169    """
170    return _paginate(
171        get_session_jobs.sync,
172        "session jobs",
173        session_id,
174        client=client,
175        status=status,
176        target=target,
177        submitter_id=submitter_id,
178        limit=limit,
179    )

Iterate over all jobs in a specific session.

Like iter_jobs, but scoped to a single session.

Arguments:
  • client: An authenticated API client.
  • session_id: The session ID to list jobs for.
  • status: Filter by job status.
  • target: Filter by backend target name.
  • submitter_id: Filter by submitter user ID.
  • limit: Maximum number of jobs per page.
Yields:

Individual job objects across all pages.

Raises:
  • IonQError: If the API returns a None response.
def ms_matrix( phi0: float, phi1: float, angle: float = 0.25) -> tuple[tuple[complex, complex, complex, complex], tuple[complex, complex, complex, complex], tuple[complex, complex, complex, complex], tuple[complex, complex, complex, complex]]:
 89def ms_matrix(phi0: float, phi1: float, angle: float = 0.25) -> Matrix4x4:
 90    """Two-qubit Molmer-Sorensen (MS) gate.
 91
 92    The default ``angle=0.25`` produces a maximally-entangling gate.
 93
 94    Args:
 95        phi0: Frame rotation phase for qubit 0 in turns.
 96        phi1: Frame rotation phase for qubit 1 in turns.
 97        angle: Interaction angle in units of pi. Defaults to 0.25
 98            (i.e. pi/4 radians).
 99
100    Returns:
101        A `Matrix4x4` unitary matrix.
102
103    Examples:
104        ```python
105        >>> ms_matrix(0, 0)         # maximally-entangling MS gate
106        >>> ms_matrix(0, 0, 0.125)  # partial entanglement
107        ```
108    """
109    a = math.pi * angle
110    ca, sa = math.cos(a), math.sin(a)
111    ep = cmath.exp(1j * _2PI * (phi0 + phi1))
112    em = cmath.exp(1j * _2PI * (phi0 - phi1))
113    return (
114        (ca, 0, 0, -1j * sa / ep),
115        (0, ca, -1j * sa / em, 0),
116        (0, -1j * sa * em, ca, 0),
117        (-1j * sa * ep, 0, 0, ca),
118    )

Two-qubit Molmer-Sorensen (MS) gate.

The default angle=0.25 produces a maximally-entangling gate.

Arguments:
  • phi0: Frame rotation phase for qubit 0 in turns.
  • phi1: Frame rotation phase for qubit 1 in turns.
  • angle: Interaction angle in units of pi. Defaults to 0.25 (i.e. pi/4 radians).
Returns:

A Matrix4x4 unitary matrix.

Examples:
>>> ms_matrix(0, 0)         # maximally-entangling MS gate
>>> ms_matrix(0, 0, 0.125)  # partial entanglement
def wait_for_job( client: AuthenticatedClient, job_id: str, *, poll_interval: float = 1.0, timeout: float = 300.0, raise_on_failure: bool = True) -> ionq_core.models.get_job_response.GetJobResponse:
 92def wait_for_job(
 93    client: AuthenticatedClient,
 94    job_id: str,
 95    *,
 96    poll_interval: float = _DEFAULT_INTERVAL,
 97    timeout: float = _DEFAULT_TIMEOUT,
 98    raise_on_failure: bool = True,
 99) -> GetJobResponse:
100    """Poll a job until it reaches a terminal state.
101
102    Terminal states are ``"completed"``, ``"failed"``, and ``"canceled"``.
103    Polling starts at ``poll_interval`` and increases by 1.5x each
104    iteration, capped at 30 seconds.
105
106    Args:
107        client: An authenticated API client.
108        job_id: The UUID of the job to poll.
109        poll_interval: Initial interval between polls in seconds.
110            Defaults to 1.0.
111        timeout: Maximum total wait time in seconds. Defaults to 300
112            (5 minutes).
113        raise_on_failure: If ``True`` (the default), raise `JobFailedError`
114            when the job status is ``"failed"``. If ``False``, return the
115            failed job response instead.
116
117    Returns:
118        The final job response once a terminal state is reached.
119
120    Raises:
121        JobTimeoutError: If the job does not finish within ``timeout``.
122        JobFailedError: If ``raise_on_failure`` is ``True`` and the job fails.
123        IonQError: If the API returns a ``None`` response.
124    """
125    deadline = time.monotonic() + timeout
126    interval = poll_interval
127    while True:
128        job = get_job.sync(uuid=job_id, client=client)
129        if job is None:
130            raise IonQError(f"Failed to fetch job {job_id}")
131        logger.debug("Job %s status: %s", job_id, job.status)
132        if _check_terminal(job, raise_on_failure):
133            return job
134        if time.monotonic() >= deadline:
135            raise JobTimeoutError(job_id, timeout, job.status)
136        time.sleep(max(0, min(interval, deadline - time.monotonic())))
137        interval = min(interval * _BACKOFF_FACTOR, _MAX_INTERVAL)

Poll a job until it reaches a terminal state.

Terminal states are "completed", "failed", and "canceled". Polling starts at poll_interval and increases by 1.5x each iteration, capped at 30 seconds.

Arguments:
  • client: An authenticated API client.
  • job_id: The UUID of the job to poll.
  • poll_interval: Initial interval between polls in seconds. Defaults to 1.0.
  • timeout: Maximum total wait time in seconds. Defaults to 300 (5 minutes).
  • raise_on_failure: If True (the default), raise JobFailedError when the job status is "failed". If False, return the failed job response instead.
Returns:

The final job response once a terminal state is reached.

Raises:
  • JobTimeoutError: If the job does not finish within timeout.
  • JobFailedError: If raise_on_failure is True and the job fails.
  • IonQError: If the API returns a None response.
def zz_matrix( angle: float) -> tuple[tuple[complex, complex, complex, complex], tuple[complex, complex, complex, complex], tuple[complex, complex, complex, complex], tuple[complex, complex, complex, complex]]:
121def zz_matrix(angle: float) -> Matrix4x4:
122    """Two-qubit ZZ interaction gate.
123
124    Diagonal matrix: ``diag(e^{-i*pi*a}, e^{i*pi*a}, e^{i*pi*a}, e^{-i*pi*a})``
125
126    At ``angle=0`` this is the identity gate.
127
128    Args:
129        angle: Interaction angle in units of pi.
130
131    Returns:
132        A `Matrix4x4` unitary matrix.
133    """
134    em = cmath.exp(-1j * math.pi * angle)
135    ep = cmath.exp(1j * math.pi * angle)
136    return (
137        (em, 0, 0, 0),
138        (0, ep, 0, 0),
139        (0, 0, ep, 0),
140        (0, 0, 0, em),
141    )

Two-qubit ZZ interaction gate.

Diagonal matrix: diag(e^{-i*pi*a}, e^{i*pi*a}, e^{i*pi*a}, e^{-i*pi*a})

At angle=0 this is the identity gate.

Arguments:
  • angle: Interaction angle in units of pi.
Returns:

A Matrix4x4 unitary matrix.