Skip to main content

Official Python SDK and CLI for the FastFold API

Project description

FastFold Python SDK and CLI

Python client and CLI for the FastFold Jobs API.

Installation

From the project root:

pip install .

Or for development:

pip install -e .

Requires Python 3.8+.

Authentication

Set your API key in the environment:

export FASTFOLD_API_KEY="sk-...your-api-key"

You can also pass an API key when creating the client or via the CLI flag --api-key.

SDK Usage

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)

# Wait for completion, then fetch CIF URL (boltz-2 complex)
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)
# Generate a shareable viewer link for this job
link = results.get_viewer_link()
print("Open in viewer:", link)

Advanced usage for Boltz-2 with Affinity prediction and pockets:

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},
                ],
            }
        ]
    },
)

# Wait for completion and fetch CIF URL (boltz-2 complex)
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)

# Create a non-complex job with two protein chains and fetch per-sequence artifacts by index
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",
    },
)

# Wait for completion then access per-sequence artifacts by index
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
# Access per-sequence artifacts by index
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)

# Generate a shareable viewer link for this job
link = results.get_viewer_link()
print("Open in viewer:", link)

Create with library source (from_id) and additional params

myJob = client.fold.create(
    model="boltz-2",
    sequence="LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES",
    from_id="770e8400-e29b-41d4-a716-446655440002",
    params={"relaxPrediction": True, "recyclingSteps": 2},
)

# Wait for completion
results = client.jobs.wait_for_completion(myJob.id, poll_interval=5.0, timeout=900.0)
print("Completed:", results.job.status)

Fetch results and status

# Prefer waiting for completion in scripts/notebooks
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 accessible

Get artifact URLs

# Ensure we have completed results
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

# Ensure the job has completed
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 existing job by ID

from fastfold import Client

client = Client()
job_id = "550e8400-e29b-41d4-a716-446655440000"

# Wait for the existing job to complete
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)

# Optional: viewer link
link = results.get_viewer_link()
print("Open in viewer:", link)
# Non-complex example (index into sequences)
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)

CLI Usage

Submit a folding job:

fastfold fold --sequence "LLGDFFRKSKEKIGKEFKRIVQRIKDFLRNLVPRTES" --model boltz-2

Optional flags:

fastfold fold \
  --sequence "..." \
  --model boltz-2 \
  --name "My Job" \
  --api-key "sk-..." \
  --base-url "https://api.fastfold.ai"

On success the CLI prints the created job ID to stdout.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastfold_ai-0.1.2.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastfold_ai-0.1.2-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file fastfold_ai-0.1.2.tar.gz.

File metadata

  • Download URL: fastfold_ai-0.1.2.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for fastfold_ai-0.1.2.tar.gz
Algorithm Hash digest
SHA256 a5c4169d89905a87b53e3df0de70f575d9fc4cf8ec9354df536772a7dfa9cbd4
MD5 c7acb59eaab5d426b61f48ebe42d2de3
BLAKE2b-256 b8b73f0755182a8b6a9acf29fbbdc523095bc2d39312f81d871b99e3159025b4

See more details on using hashes here.

File details

Details for the file fastfold_ai-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: fastfold_ai-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 12.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for fastfold_ai-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 65f52f84374c622d45eb73de7565ecd1fe00131866812413955312d83b8bee7f
MD5 dc01dca6efc8114b8c472937bb0e7696
BLAKE2b-256 39c089f2335088d9a48fe01d4b1d6fce8804d446fcf8323a76c77315195aad4d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page