"""A job's answer as a plain dict, with helpers for what is read most.""" from __future__ import annotations import json from typing import Any, Dict, List, Optional __all__ = ["Job", "Verification"] class Verification(dict): """Whether a receipt seals its request and its result and every rule holds: ``valid``, the ``reasons`` when it is not, the ``key`` it names (64 hex digits) and the ``signer`` (that key as a ``did:key``). True exactly when the receipt is valid.""" @property def valid(self) -> bool: return self.get("valid") is True @property def reasons(self) -> List[str]: return list(self.get("reasons") or []) @property def signer(self) -> Optional[str]: return self.get("signer") @property def key(self) -> Optional[str]: return self.get("key") def __bool__(self) -> bool: return self.valid def _repr_html_(self) -> str: from . import _render return _render.verification_html(self) class Job(dict): """A job as every surface returns it, the service's form: ``status``, ``method``, ``why``, ``estimate``, ``request``, and ``result`` with its ``receipt``. It is a plain dict (``json.dumps`` writes it as the service sends it); the properties read the parts most often wanted. """ @property def status(self) -> Optional[str]: return self.get("status") @property def method(self) -> Optional[str]: return self.get("method") or self.result.get("method") @property def request(self) -> Dict[str, Any]: return self.get("request") or {} @property def result(self) -> Dict[str, Any]: return self.get("result") or {} @property def accuracy(self) -> Optional[str]: """The result's accuracy class: ``bit-exact``, ``exact``, ``bounded``, ``estimate``, ``heuristic`` or ``single``.""" a = self.result.get("accuracy") return a.get("class") if isinstance(a, dict) else a @property def receipt(self) -> Optional[Dict[str, Any]]: return self.result.get("receipt") @property def verdict(self) -> Optional[Dict[str, Any]]: """How far the engine checked the job, sealed by its receipt, when the job asked for it (``intent=``, or ``verdict=True``): its ``level``, whether its intents ``hold``, and its ``statement``.""" return self.result.get("verdict") @property def counts(self) -> Dict[str, int]: """Each outcome's count, the most frequent first (bit strings with the highest classical bit first).""" return dict(self.result.get("counts") or {}) @property def shots(self) -> int: """The shots sampled: the counts listed and those omitted.""" return sum(self.counts.values()) + int(self.result.get("omitted_shots") or 0) def probabilities(self) -> Dict[str, float]: """Each listed outcome's sampled frequency: its count over the shots. These are samples of the distribution, as exact as the shots allow; for an exact probability ask for the amplitude.""" n = self.shots return {k: v / n for k, v in self.counts.items()} if n else {} @property def expectations(self) -> Dict[str, float]: """Each observable's expectation value, by the observable as asked.""" return {e["observable"]: e["value"] for e in self.result.get("expectations") or []} @property def amplitudes(self) -> Dict[str, complex]: """Each asked-for basis state's amplitude, by its bit string (one bit per qubit, qubit n − 1 first).""" return {a["bits"]: complex(a["re"], a["im"]) for a in self.result.get("amplitudes") or []} def verify(self) -> Verification: """Whether the result's receipt seals it and the request, checked here, offline.""" from ._api import verify return verify(self) def to_json(self, **kw: Any) -> str: return json.dumps(self, **kw) def summary(self) -> str: """One line: the method, the accuracy class and what the result holds.""" bits: List[str] = [f"{self.method or '?'}", f"accuracy {self.accuracy or '?'}"] if self.counts: bits.append(f"{self.shots} shots, {len(self.counts)} outcomes listed") if self.result.get("expectations"): bits.append(f"{len(self.result['expectations'])} expectation values") if self.result.get("amplitudes"): bits.append(f"{len(self.result['amplitudes'])} amplitudes") if self.verdict: bits.append(f"verdict {self.verdict.get('level')}") if self.receipt: bits.append("sealed") return ", ".join(bits) def _repr_html_(self) -> str: from . import _render return _render.job_html(self)