Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

534 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Open Kinetics Predictor

Predict enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES.

Live ServiceLicenseStarsForksPythonDjangoReactPyTorch

Live Demo · API Docs · Contributing

Open Kinetics Predictor is a production web interface for predicting enzyme kinetic parameters (kcat and KM) from protein sequence and substrate SMILES. It consolidates several state‑of‑the‑art machine learning / deep learning models behind a unified, asynchronous job API so you can submit sequences and retrieve structured predictions.

Live service:https://predictor.openkinetics.org/

Prediction Engines

EngineInput neededOutputCitation
KinForm-HProtein sequence + substrate SMILESkcat or KmAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
KinForm-LProtein sequence + substrate SMILESkcatAlwer & Fleming, npj Syst Biol Appl 2026 (GitHub)
UniKPProtein sequence + substrate SMILESkcat or KmYu et al., Nat Commun 2023 (GitHub)
DLKcatProtein sequence + substrate SMILESkcatLi et al., Nat Catal 2022 (GitHub)
TurNupProtein sequence + substrates list + products listkcatKroll et al., Nat Commun 2023 (GitHub)
EITLEMProtein sequence + substrate SMILESkcat or KmShen et al., Biotechnol Adv 2024 (GitHub)
CataProProtein sequence + substrate SMILESkcat, Km, or kcat/KmWang et al., Nat Commun 2025 (GitHub)
CatPredProtein sequence + substrate SMILESkcat or KmBoorla et al., Nat Commun 2025 (GitHub)
OmniESIProtein sequence + substrate SMILESkcat or KmNie et al., arXiv 2025 (GitHub)
CatRangeProtein sequence + substrate SMILESkcat or KmSajeevan et al., bioRxiv 2025 (GitHub)
IECataProtein sequence + substrate SMILESkcat/KmWang et al., Brief Bioinform 2025 (GitHub)
MMISA-KMProtein sequence + substrate SMILESKmSong & Wang, DDCLS 2025 (GitHub)

Each model is loaded with its published weights/code from models/ and invoked through integration wrappers in api/prediction_engines/, so new engines can be added with minimal wiring.

Adding a New Prediction Method

See docs/project/contributing.rst for a step-by-step guide.

Features

  • Batch submission of sequences and substrates.
  • Long‑running inference handled asynchronously (Celery + Redis) with progress tracking.
  • Sequence similarity distribution of input data vs mehtods' training data (Using mmseq2).
  • Caching sequence embeddings.

Stack

Frontend

  • React 18 + Vite (fast dev + ESM build)
  • Bootstrap / React‑Bootstrap for layout & components
  • Axios for API calls; Chart.js for result visualisation

Backend

  • Django 5.1 (REST-style endpoints under api/)
  • Celery workers for queued prediction tasks (api/tasks.py)
  • Redis as Celery broker
  • SQLite
  • PyTorch, scikit-learn, RDKit, pandas for model computation & cheminformatics

Required Environment Variable

DJANGO_SECRET_KEY is required at runtime (no fallback hardcoded key).

Generate a strong key:

openssl rand -hex 50

Local/dev setup:

cp .env.example .env
# edit .env and set DJANGO_SECRET_KEY=...
docker compose up -d --build

Production setup:

# on the production host
cp .env.example .env.production
# edit .env.production and set DJANGO_SECRET_KEY=...
./deploy.sh prod

deploy.sh prod now reads .env.production automatically (falls back to .env if present). For non-interactive deploys (for example CI/systemd), provide an env file or inject DJANGO_SECRET_KEY in the service environment before running docker compose.

High-Level Flow

  1. User submits a job (sequence + substrate(s) [+ products/mutant context if required]) via the frontend.
  2. Backend validates input (api/services/validation_service.py).
  3. A Celery task is enqueued; Redis broker stores the task message.
  4. Worker loads the selected model wrapper (e.g. prediction_engines/kinform.py) and executes inference.
  5. Results & intermediate status are persisted; cached for repeated identical queries.
  6. Frontend polls job status endpoint to update progress and results.

API Access

OpenKineticsPredictor provides a REST API for programmatic access. Submit prediction jobs, poll their status, and download results — no web browser required.

Base URL:https://predictor.openkinetics.org/api/v1

Full interactive documentation is also available on the live site at /api-docs.


Endpoint Overview

MethodEndpointAuthDescription
GET/health/NoService health check
GET/methods/NoList available methods and required columns
GET/quota/YesCheck remaining daily quota
POST/validate/YesValidate input data without submitting a job
POST/submit/YesSubmit a prediction job
GET/status/<jobId>/YesPoll job status and progress
GET/result/<jobId>/YesDownload results (CSV or ?format=json)

Quick Start — Python

importrequestsimporttimeAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit a jobwithopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/submit/",
headers=HEADERS,
files={"file": f},
data={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": "true",
},
)
resp.raise_for_status()
job=resp.json()
print(f"Job ID: {job['jobId']} | Quota remaining: {job['quota']['remaining']:,}")
# 2. Poll until completewhileTrue:
status=requests.get(f"{BASE}/status/{job['jobId']}/", headers=HEADERS).json()
print(f" {status['status']} ({status['elapsedSeconds']}s)")
ifstatus["status"] =="Completed":
breakifstatus["status"] =="Failed":
raiseRuntimeError(f"Job failed: {status.get('error')}")
time.sleep(5)
# 3. Download resultsresult=requests.get(f"{BASE}/result/{job['jobId']}/", headers=HEADERS)
withopen("output.csv", "wb") asf:
f.write(result.content)
print("Saved to output.csv")

Quick Start — curl

API_KEY="ak_your_key_here"
BASE="https://predictor.openkinetics.org/api/v1"# 1. Submit
JOB=$(curl -s -X POST "$BASE/submit/" \ -H "Authorization: Bearer $API_KEY" \ -F "file=@input.csv" \ -F "predictionType=kcat" \ -F "kcatMethod=DLKcat" \ -F "handleLongSequences=truncate")
JOB_ID=$(echo "$JOB"| python3 -c "import sys,json; print(json.load(sys.stdin)['jobId'])")echo"Submitted: $JOB_ID"# 2. Pollwhiletrue;do
STATE=$(curl -s "$BASE/status/$JOB_ID/" \ -H "Authorization: Bearer $API_KEY" \| python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")echo"$STATE"
[ "$STATE"="Completed" ] &&break
[ "$STATE"="Failed" ] && { echo"Job failed";exit 1; }
sleep 5
done# 3. Download
curl -s "$BASE/result/$JOB_ID/" \
-H "Authorization: Bearer $API_KEY" \
-o output.csv

JSON Body Submission (no CSV file needed)

For small datasets (≤ 10,000 rows) you can send data directly as JSON:

requests.post(
f"{BASE}/submit/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"predictionType": "kcat",
"kcatMethod": "DLKcat",
"handleLongSequences": "truncate",
"useExperimental": True,
"data": [
{"Protein Sequence": "MKTLLIFAG...", "Substrate": "CC(=O)O"},
{"Protein Sequence": "MGSSHHHHH...", "Substrate": "C1CCCCC1"},
],
},
)

Validating Input Before Submission

Use /validate/ to check substrate SMILES/InChI strings, protein sequences, and per-model length limits without consuming any quota or running predictions. This is equivalent to the validation step available in the web interface.

importrequestsAPI_KEY="ak_your_key_here"BASE="https://predictor.openkinetics.org/api/v1"HEADERS= {"Authorization": f"Bearer {API_KEY}"}
# Basic validation (fast)withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "false"},
)
result=resp.json()
print(f"Rows: {result['rowCount']}")
print(f"Invalid substrates: {len(result['invalidSubstrates'])}")
print(f"Invalid proteins: {len(result['invalidProteins'])}")
print(f"Length violations: {result['lengthViolations']}")

Set runSimilarity=true to also run MMseqs2 sequence similarity analysis against each method's training database. The request blocks synchronously until the analysis is complete (can take several minutes for large inputs):

withopen("input.csv", "rb") asf:
resp=requests.post(
f"{BASE}/validate/",
headers=HEADERS,
files={"file": f},
data={"runSimilarity": "true"},
timeout=600,
)
similarity=resp.json()["similarity"]
formethod, datainsimilarity.items():
print(f"{method}: avg max identity = {data['average_max_similarity']:.1f}%")

The similarity field in the response is a dict keyed by method name. Each entry contains histogram_max, histogram_mean (10-bin arrays, 0–100% identity), average_max_similarity, average_mean_similarity, count_max, and count_mean.


CSV Format

Supported input schemas are:

  • Protein Sequence, Substrate for one molecular input.
  • Protein Sequence, Substrates for a Multi-Substrate input: an ordered, semicolon-separated list.
  • Protein Sequence, Substrates, Products for a full reaction. Products is required by TurNup and is preserved but ignored by substrate-pair methods.

For a Substrates list, single-substrate methods predict every protein/substrate pair. The reaction kcat is the maximum successful value; Km and direct kcat/Km outputs are JSON arrays in substrate order, with null for failed entries. The matching Extra Info <target> cell contains a JSON array with each substrate's one-based position, input value, prediction, source, error, and the selected kcat maximum.

CatPred kcat is the exception: it consumes the complete ordered substrate set as one native multi-substrate input and returns one scalar. CatPred Km still uses the per-substrate array behavior, including when kcat and Km are requested together. TurNup consumes both sides of a full reaction; every other method preserves but ignores Products.

MethodPredictsRequired columnsMax sequence length
DLKcatkcatProtein Sequence, Substrate or SubstratesNo limit
TurNupkcatProtein Sequence, Substrates, Products1,024 residues
EITLEMkcat or KmProtein Sequence, Substrate or Substrates1,024 residues
UniKPkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
CataProkcat, Km, or kcat/KmProtein Sequence, Substrate or Substrates1,000 residues
KinForm-Hkcat or KmProtein Sequence, Substrate or Substrates1,500 residues
KinForm-Lkcat onlyProtein Sequence, Substrate or Substrates1,500 residues
CatPredkcat or Kmkcat: Substrates; Km: Substrate or Substrates2,048 residues
OmniESIkcat or KmProtein Sequence, Substrate or Substrates1,000 residues
RealKcatkcat or KmProtein Sequence, Substrate or Substrates1,022 residues
IECatakcat/KmProtein Sequence, Substrate or Substrates1,000 residues
MMISA-KMKmProtein Sequence, Substrate or Substrates500 residues

Substrates and products must be SMILES or InChI strings. Separate ordered values in Substrates and Products with semicolons, for example CC(=O)O;C1CCCCC1. Supplied products are validated even when the selected method preserves but does not use them.


Rate Limits

  • 20,000 input reaction rows/day per API key (default; custom limits available). Internal per-substrate predictions do not consume additional quota.
  • Counter resets at midnight UTC.
  • Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • HTTP 429 is returned when the quota is exceeded.

Error Format

All errors return JSON with a single error key:

{ "error": "A human-readable description of what went wrong." }
StatusMeaning
400Invalid parameters, missing CSV columns, or bad data
401Missing or invalid API key
403Account suspended
404Job not found
409Results not ready yet
429Quota exceeded
500Internal server error

Attribution

Please cite the original publications when using predictions from a specific engine. Cite all underlying sources plus this platform.

Contact

For questions or collaboration: open an issue or reach out to the authors of the respective model.

Funding

This work was supported by EU Horizon Europe #101080997, Swiss SERI #23.00232, UKRI #10083717 & #10080153, FNR PRIDE21/16763386/CANBIO2, Novo Nordisk Foundation #NNF10CC1016517, Knut & Alice Wallenberg Foundation, EU Horizon 2020 #686070 & #814650, National Key R&D China 2025YFA0922700

About

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages