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.

Open In Colab

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.3.tar.gz (11.0 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.3-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: fastfold_ai-0.1.3.tar.gz
  • Upload date:
  • Size: 11.0 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.3.tar.gz
Algorithm Hash digest
SHA256 2fc6743508fff5cc092c2a85920be318ea15a82457fb08bfe5bdce0ae5192c25
MD5 332e64401d2db24688ed50ee1b7c022f
BLAKE2b-256 0635b26ae77a4983632ecf6d8c176f8076404559cd44b09566bf5a275cf3c507

See more details on using hashes here.

File details

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

File metadata

  • Download URL: fastfold_ai-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 12.2 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 fa3c02484df9132f91dbf668fe4755ed235093393239ed194d2c4acf8b58dc2d
MD5 25aa2a9e07d1f882d09d3e07b6d49a8c
BLAKE2b-256 0cd5c68071b6558f84bf3ef4743c08d77f52a67c5735f1702c45f21b5b4dc366

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