Recipes & Examples
Reference workflows by job type (single-sequence, complex/ligand, non-complex indexing, artifacts, metrics, fetch-by-id).
This page collects reference workflows for the FastFold Python SDK, grouped by common job types and model usage.
Quick map (job types → typical models)
- Single-sequence fold: common starting point (example uses
boltz-2) - Complex with ligand + optional constraints (pockets): advanced structure + property prediction (example uses
boltz-2) - Non-complex multi-sequence (indexing): multiple independent sequences; access artifacts via
results[i](example usessimplefold_100M) - Create from library (
from_id): start from a known library entry and override parameters (example usesboltz-2) - Fetch by job id: resume work in another script/notebook (works for complex and non-complex jobs)
Minimal SDK usage (single sequence)
from fastfold import Client
client = Client() # Reads FASTFOLD_API_KEY from env by default
myJob = client.fold.create(
sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES",
model="boltz-2",
is_public=True,
)
print("Job ID:", myJob.id)
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
print("Status:", results.job.status)
print("CIF URL:", results.cif_url())
print("Mean PLDDT:", results.metrics().mean_PLDDT)
link = results.get_viewer_link()
print("Open in viewer:", link)Advanced Boltz-2: affinity prediction + pockets
from fastfold import Client
client = Client()
myJob = client.fold.create(
name="Streptococcal protein G with Pocket",
model="boltz-2",
sequences=[
{
"proteinChain": {
"sequence": "MTYKLILNGKTLKGETTTEAVDAATAEKVFKQYANDNGVDGEWTYDDATKTFTVTE",
"count": 1,
"chain_id": "A",
"label": "mobile-purple",
}
},
{
"ligandSequence": {
"sequence": "ATP",
"count": 1,
"chain_id": "B",
"label": "constitutional-brown",
"is_ccd": True,
"property_type": "affinity",
}
},
],
params={
"modelName": "boltz-2",
"weightSet": "Boltz-2",
"relaxPrediction": True,
"method": "Boltz-2",
"recyclingSteps": 3,
"samplingSteps": 200,
"diffusionSample": 1,
"stepScale": 1.638,
"affinityMwCorrection": False,
"samplingStepsAffinity": 200,
"diffusionSamplesAffinity": 5,
},
constraints={
"pocket": [
{
"binder": {"chain_id": "B"},
"contacts": [
{"chain_id": "A", "res_idx": 12},
{"chain_id": "A", "res_idx": 15},
{"chain_id": "A", "res_idx": 18},
],
}
]
},
)
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
print("Completed CIF URL:", results.cif_url())
metrics = results.metrics()
print("Mean PLDDT:", metrics.mean_PLDDT)
print("ptm_score:", metrics.ptm_score)
print("iptm_score:", metrics.iptm_score)
# Boltz-2 affinity metrics (present only if provided by API)
print("affinity_pred_value:", metrics.affinity_pred_value)
print("affinity_probability_binary:", metrics.affinity_probability_binary)
print("affinity_pred_value1:", metrics.affinity_pred_value1)
print("affinity_probability_binary1:", metrics.affinity_probability_binary1)
print("affinity_pred_value2:", metrics.affinity_pred_value2)
print("affinity_probability_binary2:", metrics.affinity_probability_binary2)
link = results.get_viewer_link()
print("Open in viewer:", link)Non-complex multi-sequence artifacts (indexing)
Use indexing (results[0], results[1], …) to access per-sequence artifacts when the job is not a complex.
from fastfold import Client
client = Client()
myJob = client.fold.create(
name="My Protein List",
model="simplefold_100M",
sequences=[
{
"proteinChain": {
"sequence": "MCNTNMSVSTEGAASTSQIPASEQETLVRPKPLLLKLLKSVGAQNDTYTMKEIIFYIGQYIMTKRLYDEKQQHIVYCSNDLLGDVFGVPSFSVKEHRKIYAMIYRNLVAV",
"count": 1,
"chain_id": "A",
"label": "specific-white",
}
},
{
"proteinChain": {
"sequence": "SQETFSGLWKLLPPE",
"count": 1,
"chain_id": "B",
"label": "wily-amethyst",
}
},
],
params={
"modelName": "simplefold_100M",
"weightSet": "SimpleFold",
"method": "SimpleFold",
},
)
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
cif_url_chain_a = results[0].cif_url()
cif_url_chain_b = results[1].cif_url()
print("Chain A CIF:", cif_url_chain_a)
print("Chain B CIF:", cif_url_chain_b)
m0 = results[0].metrics()
m1 = results[1].metrics()
print("Chain A mean PLDDT:", m0.mean_PLDDT)
print("Chain B mean PLDDT:", m1.mean_PLDDT)
link = results.get_viewer_link()
print("Open in viewer:", link)Create with library source (from_id) and additional params
from fastfold import Client
client = Client()
myJob = client.fold.create(
model="boltz-2",
sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES",
from_id="770e8400-e29b-41d4-a716-446655440002",
params={"relaxPrediction": True, "recyclingSteps": 2},
)
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
print("Completed:", results.job.status)Fetch results and status
from fastfold import Client
client = Client()
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
status = results.job.status
print("Status:", status)Status could be:
- PENDING: Job queued but not yet initialized
- INITIALIZED: Job created and ready to run
- RUNNING: Job is processing
- COMPLETED: Job finished successfully
- FAILED: Job encountered an error
- STOPPED: Job was stopped before completion
Update visibility
client.jobs.set_public(myJob.id, True) # make job publicly accessibleGet artifact URLs
from fastfold import Client
client = Client()
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
# Complex jobs (shared artifacts at top level)
if results.job.is_complex:
cif_url = results.cif_url()
pdb_url = results.pdb_url()
pae_url = results.pae_plot_url()
plddt_url = results.plddt_plot_url()
else:
# Non-complex: per-sequence artifacts via indexing
cif_url = results[0].cif_url()
pdb_url = results[0].pdb_url()Get metrics
from fastfold import Client
client = Client()
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
# Complex (boltz-2) jobs: top-level metrics
if results.job.is_complex:
metrics = results.metrics()
print("mean_PLDDT:", metrics.mean_PLDDT)
print("ptm_score:", metrics.ptm_score)
print("iptm_score:", metrics.iptm_score)
print("max_pae_score:", metrics.max_pae_score)
# Boltz-2 affinity metrics (present only if provided by API)
print("affinity_pred_value:", metrics.affinity_pred_value)
print("affinity_probability_binary:", metrics.affinity_probability_binary)
print("affinity_pred_value1:", metrics.affinity_pred_value1)
print("affinity_probability_binary1:", metrics.affinity_probability_binary1)
print("affinity_pred_value2:", metrics.affinity_pred_value2)
print("affinity_probability_binary2:", metrics.affinity_probability_binary2)
else:
# Non-complex: per-sequence metrics via indexing
m0 = results[0].metrics()
print("Chain A mean PLDDT:", m0.mean_PLDDT)
m1 = results[1].metrics()
print("Chain B mean PLDDT:", m1.mean_PLDDT)Fetch an existing job by ID
from fastfold import Client
client = Client()
job_id = "550e8400-e29b-41d4-a716-446655440000"
results = client.jobs.wait_for_completion(job_id, poll_interval=5.0, timeout=900.0)
print("Status:", results.job.status)
# Complex job example (top-level artifacts)
cif_url = results.cif_url()
pdb_url = results.pdb_url()
pae_url = results.pae_plot_url()
plddt_url = results.plddt_plot_url()
print("CIF URL:", cif_url)
print("PDB URL:", pdb_url)
print("PAE URL:", pae_url)
print("pLDDT URL:", plddt_url)
metrics = results.metrics()
print("mean_PLDDT:", metrics.mean_PLDDT)
print("ptm_score:", metrics.ptm_score)
print("iptm_score:", metrics.iptm_score)
print("max_pae_score:", metrics.max_pae_score)
link = results.get_viewer_link()
print("Open in viewer:", link)# Non-complex example (index into sequences)
from fastfold import Client
client = Client()
job_id = "550e8400-e29b-41d4-a716-446655440000"
results = client.jobs.wait_for_completion(job_id, poll_interval=5.0, timeout=900.0)
cif_seq0 = results[0].cif_url()
pdb_seq0 = results[0].pdb_url()
m0 = results[0].metrics()
print("Seq0 CIF:", cif_seq0)
print("Seq0 PDB:", pdb_seq0)
print("Seq0 mean_PLDDT:", m0.mean_PLDDT)A practical “safe” wrapper (error handling)
If you’re running this in a pipeline, you’ll usually want a small wrapper so failures are obvious and easy to debug.
from fastfold import Client
def fold_and_print(sequence: str, model: str = "boltz-2") -> None:
client = Client()
job = client.fold.create(sequence=sequence, model=model, is_public=True)
results = client.jobs.wait_for_completion(job.id, poll_interval=5.0, timeout=900.0)
if results.job.status != "COMPLETED":
raise RuntimeError(f"FastFold job did not complete: status={results.job.status} job_id={job.id}")
print("Job ID:", job.id)
print("CIF URL:", results.cif_url())
print("Mean PLDDT:", results.metrics().mean_PLDDT)
print("Viewer:", results.get_viewer_link())Last updated on