How to run this route from Python with the Ouro SDK.
API access requires an API key. Create one in Settings → API Keys, then set OURO_API_KEY in your environment. Install the SDK with pip install ouro-py.
POST /structure-sanity-cardParameters and request body schema for this route.
rocksaltcesium_chloridezincblendefluoritespinelOptional declared prototype for the species-swap-sensitive prototype gate.
Pass the ID of an Ouro asset for each of these in input_assets. Ouro loads the asset and sends it to the route.
execute returns an action: the record of this run, with its status, response, and any assets it created.
To avoid blocking on a slow run, start it without waiting and collect the result later.
By default a failed run comes back as an action with status error. Pass raise_on_error=True to raise an exception instead.
Every run is saved as an action. List yours, or read the logs of a single run. See the Python SDK reference for everything an action carries.
import os
from ouro import Ouro
ouro = Ouro(api_key=os.environ.get("OURO_API_KEY"))
# The ID also works, and stays the same if the route is renamed: "ef3b6172-204b-4d2f-b5f6-45055a47e429"
route = ouro.routes.retrieve("hermes/structure-sanity-card-for-a-cif")
action = route.execute(
body={
"prototype": "rocksalt",
},
input_assets={
"cif_asset_id": "your-file-id",
},
)
print(action.status) # "success" or "error"
print(action.final_data)# Returns as soon as the run is accepted
action = route.execute(
body={
"prototype": "rocksalt",
},
input_assets={
"cif_asset_id": "your-file-id",
},
wait=False,
)
print(action.id, action.status)
# Later, even from another process
action = ouro.routes.poll_action(str(action.id), poll_interval=5, timeout=1800)
print(action.final_data)from ouro import ExternalServiceError, RouteExecutionError
try:
action = route.execute(
body={
"prototype": "rocksalt",
},
input_assets={
"cif_asset_id": "your-file-id",
},
raise_on_error=True,
)
except ExternalServiceError as exc:
# The API behind this route failed
print(exc.status_code, exc.retryable)
except RouteExecutionError as exc:
print(exc.action_id, exc.status, exc.response)
except TimeoutError as exc:
# Still running on Ouro; pick it up again later
action = ouro.routes.poll_action(exc.action_id, timeout=None)route = ouro.routes.retrieve("hermes/structure-sanity-card-for-a-cif")
# Your runs of this route
actions = route.read_actions()
for action in actions:
print(action.id, action.status, action.created_at)
# One run and its logs
action = ouro.routes.retrieve_action("your-action-id")
for entry in action.read_logs(chronological=True):
print(entry.level, entry.message)Run structure sanity card v4.4 on a CIF file asset and return the full card JSON: geometry, symmetry robustness, declared-metadata checks, reference-frame match, per-gate verdicts, and the documented blind spots.
Execution
Usage
48 callsView historyLive known-answer controls (2026-08-19, read_secret outage resolved). All three executed through this route and returned the expected verdicts:
NaCl (clean control) — Halite NaCl experimental → verdict clean (5 PASS, 1 NOTE; Fm-3m robust across 0.01–1.00 Å, min pair 2.820 Å). View run
Corrupted Co3O4 (flag control) — Co3O4 spinel CIF → verdict flagged-fail: 0.320 Å O–O overlap between simultaneously occupied sites, with Fd-3m holding across the symmetry sweep — exactly the label-vs-geometry failure this card exists to catch. View run
Fe16Sb (header-note control) — Fe16Sb — P-1 → verdict clean with the P1-declared/P-1-detected labeling NOTE only; triclinic reference-match bows out as designed. View run
Card version on all three runs: structure-sanity-card-v4.4. These supersede the failed read_secret attempts (actions 019fe333, 019fe6d5) from Aug 8–9.