SDK Tutorial
Customer walkthrough for using `OmClient` with Generated Data, diligence workflows, Hub jobs, Molecule Fulfillment, jobs, and data loading.
Install and authenticate
Install packagesBash
pip install omtxSet API key and run a smoke testBash
export OMTX_API_KEY="omtx_..."
python - <<'PY'
from omtx import OmClient
with OmClient() as client:
print(client.status())
print(client.users.profile())
PYGenerated Data catalog visibility
Read Generated Data contextPython
from omtx import OmClient
with OmClient() as client:
models = client.models.catalog(limit=5)
catalog = client.datasets.catalog()
print("Model count:", models["count"])
print("Generated Data rows:", catalog["data_generated"]["count"])
print("Generated Data protein UUIDs:", catalog["accessible_generated_protein_uuids"][:5])Customer use cases
- Generated Data visibility: render
data_generated.items[]plusaccessible_generated_protein_uuids[]for Generated Data proteins available now. - Generated Data access checks: use
accessible_generated_protein_uuids[]to confirm which proteins are available to your account. - Access control: request shard exports only for Generated Data tied to qualifying Data Generation output.
Load dataframes from protein UUID
Combined loading for model training (single call)Python
from omtx import OmClient
with OmClient() as client:
loaded = client.load_data(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
binders=50000,
nonbinder_multiplier=5,
sample_seed=42,
)
binders = loaded["binders"]
nonbinders = loaded["nonbinders"]
print("Binder rows:", len(binders))
print("Non-binder rows:", len(nonbinders))
binders.show(top_n=24) # defaults: smiles + binding_scoreSeparate pool loading for explicit controlPython
from omtx import OmClient
with OmClient() as client:
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("Binder rows:", len(binders))
print("Non-binder rows:", len(nonbinders))
print("Binder columns:", binders.columns)
# show() renders inline in notebooks; no extra display() wrapper needed.
binders.show(top_n=24) # defaults: smiles + binding_score
binders.show(top_n=24, sort_by="selectivity_score")Manual shard export (advanced)Python
from omtx import OmClient
with OmClient() as client:
urls = client.binders.urls(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
)
print("URLs expire at:", urls["expires_at"])
print("Binder shard count:", len(urls["binder_urls"]))
print("Non-binder shard count:", len(urls["non_binder_urls"]))
print("First binder URL:", urls["binder_urls"][0])Run diligence workflows
Search, gather, and crawl (asynchronous)Python
from omtx import OmClient
with OmClient() as client:
search_job = client.diligence.search(query="PARP inhibitor resistance mechanisms")
gather_job = client.diligence.gather(
query="EGFR inhibitor clinical evidence",
preset="quick",
)
crawl_job = client.diligence.crawl(
url="https://example.org/egfr-review",
preset="quick",
)
search_result = client.jobs.wait(search_job["job_id"], poll_interval=5, timeout=1800)
gather_result = client.jobs.wait(gather_job["job_id"], poll_interval=5, timeout=1800)
crawl_result = client.jobs.wait(crawl_job["job_id"], poll_interval=5, timeout=1800)
print("Search status:", search_result["status"])
print("Gather status:", gather_result["status"])
print("Crawl status:", crawl_result["status"])Deep diligence and report synthesisPython
from omtx import OmClient
with OmClient() as client:
dd_job = client.diligence.deep_diligence(
query="BRAF inhibitor resistance landscape",
preset="quick",
)
dd_result = client.jobs.wait(
dd_job["job_id"],
result_endpoint="/v2/jobs/deep-diligence/{job_id}",
poll_interval=5,
timeout=1800,
)
synth_job = client.diligence.synthesize_report(gene_key="brd4")
synth_result = client.jobs.wait(
synth_job["job_id"],
result_endpoint="/v2/jobs/synthesizeReport/{job_id}",
poll_interval=5,
timeout=1800,
)
print("Deep diligence claims:", dd_result["result"]["total_claims"])
print("Synthesis keys:", list(synth_result.keys()))Fulfill molecules
Search, quote, and invoice OnePot-backed moleculesPython
from omtx import OmClient
with OmClient() 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}],
)
invoice = client.molecules.checkout(
items=[{"smiles": "CC(=O)Oc1ccccc1C(=O)O", "quantity": 1}],
shipping_address_id="addr_123",
)
print("Provider:", pricing["provider"])
print("Search response keys:", list(hits.keys()))
print("Quote total cents:", quote["total_amount_cents"])
print("Order number:", invoice["order_number"])Function map for API-key users
Available SDK functionsPython
from omtx import OmClient
with OmClient() as client:
# Health and account
client.status()
client.users.profile()
# Wallet funding is explicit only:
# confirmation = client.wallet.expected_topup_confirmation(amount_cents=12500, payment_mode="saved_card")
# client.wallet.topup(amount_cents=12500, payment_mode="saved_card", user_approval_confirmation=confirmation, idempotency_key="wallet-topup-demo-001")
# Generated Data and shard exports
client.models.catalog(limit=5)
client.datasets.catalog()
client.load_data(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
binders=1000,
nonbinder_multiplier=5,
sample_seed=42,
)
client.load_binders(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
n=1000,
sample_seed=42,
).show(top_n=24) # default columns: smiles + binding_score
client.load_nonbinders(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
n=10000,
sample_seed=42,
)
client.binders.urls(
protein_uuid="YOUR_GENERATED_PROTEIN_UUID",
)
# Data Generation order creation
sequences = [{"name": "target", "sequence": "M" * 120}]
client.data_generation.quota_order(
sequences=sequences,
idempotency_key="dg-quota-target-001",
)
client.data_generation.invoice_order(
sequences=sequences,
idempotency_key="dg-invoice-target-001",
)
# Diligence workflows
client.diligence.search(query="example")
client.diligence.gather(query="example", preset="quick")
client.diligence.crawl(url="https://example.org", preset="quick")
client.diligence.deep_diligence(query="example", preset="quick")
client.diligence.synthesize_report(gene_key="brd4")
client.diligence.list_gene_keys()
# Artifacts and Hub workflows
client.artifacts.upload("target.pdb")
client.artifacts.get("artifact-id")
client.hub.submit(
job_type="hub.diffdock",
payload={
"protein_artifact_id": "artifact-id",
"ligand_smiles": "CCO",
},
)
client.hub.diffdock(
protein_artifact_id="artifact-id",
ligand_smiles="CCO",
)
# Molecule Fulfillment
client.molecules.pricing()
client.molecules.search(
smiles_list=["CC(=O)Oc1ccccc1C(=O)O"],
max_results=5,
)
client.molecules.quote(
items=[{"smiles": "CC(=O)Oc1ccccc1C(=O)O", "quantity": 1}]
)
client.molecules.checkout(
items=[{"smiles": "CC(=O)Oc1ccccc1C(=O)O", "quantity": 1}],
shipping_address_id="addr_123",
)
client.molecules.orders(limit=20)
client.molecules.status(order_number="MF-20260527-ABC123EF")
# Jobs
client.jobs.history(limit=20)
client.jobs.status("job_123")
client.jobs.wait("job_123", poll_interval=5, timeout=1800)Reliability patterns
Explicit idempotency and timeout handlingPython
from omtx import JobTimeoutError, OMTXError, OmClient
with OmClient() as client:
try:
job = client.diligence.deep_diligence(
query="KRAS mutation treatment pathways",
preset="quick",
idempotency_key="dd-kras-2026-02-25",
)
result = client.jobs.wait(job["job_id"], timeout=900)
print(result["status"])
except JobTimeoutError:
print("Job did not finish before timeout; resume later with jobs.status(job_id).")
except OMTXError as exc:
print("SDK/API error:", exc)