Python SDK
Use the official `omtx` package to score Om Accessible Space with LULA, order selected molecules with Wallet Credits, submit diligence and Hub jobs, upload artifacts, request signed artifact URLs, and load account-accessible Generated Data from Python.
Install
pipBash
pip install omtxQuick startPython
from omtx import OmClient
client = OmClient(api_key="YOUR_API_KEY")
profile = client.users.profile()
print("Available Wallet Credits:", profile["available_credits"])
health = client.status()
print("API version:", health["version"])
models = client.models.catalog(limit=5)
print("Model count:", models["count"])
catalog = client.datasets.catalog()
print("Generated Data rows:", catalog["data_generated"]["count"])
gene_keys = client.diligence.list_gene_keys()
print("Sample gene keys:", [item["gene_key"] for item in gene_keys["items"][:5]])Data access helpers
Combined loading (recommended for training sets)Python
loaded = client.load_data(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
binders=50000,
nonbinder_multiplier=5, # default
# nonbinders=200000, # optional explicit override
sample_seed=42,
)
binders = loaded["binders"]
nonbinders = loaded["nonbinders"]
print("Rows loaded:", len(binders), len(nonbinders))
binders.show(top_n=24) # defaults: smiles + binding_scoreSeparate pool loading (explicit control)Python
binders = client.load_binders(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
n=1000,
sample_seed=42,
)
nonbinders = client.load_nonbinders(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
n=10000,
sample_seed=42,
)
# Omit n (or set n=None) to load the full pool.
print("Rows loaded:", len(binders), len(nonbinders))
binders.show(top_n=24) # defaults: smiles + binding_scoreManual shard export (advanced)Python
urls = client.binders.urls(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
)
print("Binder shard URLs:", len(urls["binder_urls"]))
print("Non-binder shard URLs:", len(urls["non_binder_urls"]))Data Generation orders
Create a Wallet Credits-funded orderPython
import requests
sequences = [{"name": "target", "sequence": "M" * 120}]
response = requests.post(
"https://api.omtx.ai/v2/data-generation/orders",
headers={
"x-api-key": "YOUR_API_KEY",
"Idempotency-Key": "dg-wallet-target-001",
"Content-Type": "application/json",
},
json={"sequences": sequences},
timeout=60,
)
response.raise_for_status()
order = response.json()
print(order["order_number"])
print(order["total_amount_cents"])Molecule Fulfillment
Score Om Accessible Space, then order selected hitsPython
from pathlib import Path
from uuid import uuid4
import polars as pl
from omtx import OmClient
with OmClient(api_key="YOUR_API_KEY") as client:
job = client.lula2.score(
protein_sequence="YOUR_JAK2_V617F_PROTEIN_SEQUENCE",
source="om",
tier=50,
n=50_000,
top_k=10_000,
idempotency_key="jak2-v617f-lula2-r1",
)
artifact_paths = []
result_dir = Path("outputs/jak2-v617f-lula2-r1")
for job_id in job["job_ids"]:
client.jobs.wait(job_id, poll_interval=5, timeout=3600)
artifact_paths.extend(
client.jobs.download_all_artifacts(
job_id,
output_dir=result_dir / job_id,
overwrite=True,
)
)
score_tables = [
pl.read_parquet(path)
for path in artifact_paths
if path.name == "top_hits.parquet"
]
score_rows = pl.concat(score_tables).sort("score", descending=True)
selected_hits = score_rows.head(100).to_dicts()
addresses = client.molecules.shipping_addresses()
order = client.molecules.order(
items=selected_hits,
shipping_address_id=addresses["default_shipping_address_id"],
idempotency_key=f"jak2-v617f-round-1-{uuid4()}",
)
print(len(selected_hits), order["order_number"])Score Om Accessible Space locally with open-weight LULAPython
from uuid import uuid4
from omtx import OmClient
from omtx.lula import load_model
with OmClient(api_key="YOUR_API_KEY") as client:
model = load_model("lula1.1")
scores = model.score(
protein_sequence="YOUR_PROTEIN_SEQUENCE",
source="om",
tier=50,
n=50_000,
client=client,
)
selected_hits = scores[:96]
addresses = client.molecules.shipping_addresses()
order = client.molecules.order(
items=selected_hits,
shipping_address_id=addresses["default_shipping_address_id"],
idempotency_key=f"local-lula-order-{uuid4()}",
)
print(len(selected_hits), order["order_number"])Search, quote, and order arbitrary submitted SMILESPython
from omtx import OmClient
with OmClient(api_key="YOUR_API_KEY") as client:
pricing = client.molecules.pricing()
hits = client.molecules.search(
smiles_list=["CC(=O)Oc1ccccc1C(=O)O"],
max_results=5,
)
quote = client.molecules.quote(
items=[{"smiles": "CC(=O)Oc1ccccc1C(=O)O", "quantity": 1}],
)
order = client.molecules.order(
items=[{"smiles": "CC(=O)Oc1ccccc1C(=O)O", "quantity": 1}],
shipping_address_id="addr_123",
idempotency_key="molecule-wallet-order-001",
)
print(pricing["provider"], quote["total_amount_cents"], order["order_number"])Diligence jobs
Submit and waitPython
job = client.diligence.deep_diligence(
query="BRAF clinical inhibitor landscape",
preset="quick",
)
result = client.jobs.wait(
job_id=job["job_id"],
result_endpoint="/v2/jobs/deep-diligence/{job_id}",
poll_interval=5,
timeout=1800,
)
print("Claims:", result["result"]["total_claims"])SDK Notes
- Idempotency keys are generated automatically for POST and PUT calls. Diligence helpers also accept
idempotency_key=when you want to reuse a specific key. - Use
client.jobs.wait()for asynchronous calls that returnjob_idorjob_ids. - Diligence wrappers include
search,gather, andcrawlin addition todeep_diligence/synthesize_report. client.hub.submit(...)lets you start broad public Hub models from the SDK; use LULA and Om foundation-model workflows for model execution, andclient.datasets.catalog()for account-accessible Generated Data.client.wallet.topup(...)explicitly funds Wallet Credits by saved card or invoice; saved-card top-ups use the account's funding limit and require exact approval text plus a retry-stableidempotency_key.- Upload files with
client.artifacts.upload(...)before starting Hub workflows that use uploaded structures. - For larger uploaded files, use
client.artifacts.upload_via_signed_url(...). - For large result files, use
client.jobs.get_artifact_url(...)instead of inlining artifact bytes. - Wallet Credits fund explicit Generated Data orders through
/v2/data-generation/orders. client.lula1.score(...)andclient.lula2.score(...)submit async hosted scoring jobs for explicit SMILES or Om Accessible Space tiers; passsource="om",tier, andnfor the current public Om-space path, then wait onjob["job_ids"]and download completed artifacts for ranked rows.- Open-weight local LULA can score explicit SMILES without Om, but local scoring against
source="om"requires an authenticatedOmClientso the SDK can fetch orderable Om rows without sending your protein sequence to Om. client.molecules.shipping_addresses()returnsaddresses,count, anddefault_shipping_address_id; order creation requires a saved shipping address id.client.molecules.*wraps Molecule Fulfillment pricing, search, quote, shipping addresses, order history, and order status. Wallet-funded order creation uses/v2/molecules/fulfillment/orders; selected Om Accessible Space score rows carry their resultsource_metadatainto order items.- Use
client.jobs.history(limit=...)andcursorto page through recent jobs chronologically. client.status()is the primary health helper.load_data(...)loads binders and non-binders in one call (bindersrequired, non-binders default to 5x multiplier).load_binders(...)andload_nonbinders(...)are the primary dataframe loaders for separate training pools.- If
nis omitted (orn=None), loaders pull the full pool; sampling occurs only whennis set. OmData.show(...)usessmilesandbinding_scoreby default.- For selectivity ranking, pass
sort_by="selectivity_score". OmData.show(...)displays inline in notebooks and returnsNoneafter successful display to avoid duplicate rendering.binders.urls(...)returns flatbinder_urls/non_binder_urlslists for quick iteration.- Use the client as a context manager to close sessions automatically.
Hub jobs and artifacts
Hub launch from uploaded structurePython
artifact = client.artifacts.upload("target.pdb")
job = client.hub.diffdock(
protein_artifact_id=artifact["artifact_id"],
ligand_smiles="CCO",
idempotency_key="diffdock-demo-20260316",
)
status = client.jobs.wait(job["job_id"], poll_interval=5, timeout=1800)
print(status["job_type"], status["status"])Large artifact flow via signed URLsPython
artifact = client.artifacts.upload_via_signed_url("target.cif")
job = client.hub.rfd3(
pdb_artifact_id=artifact["artifact_id"],
design_mode="monomer",
contig="120",
idempotency_key="rfd3-demo-20260331",
)
url_info = client.jobs.get_artifact_url(
job["job_id"],
"outputs/results.json",
)
print(url_info["download_url"])