Skip to content

Commit

Permalink
Merge pull request #143 from luk27official/api-change
Browse files Browse the repository at this point in the history
Allow choosing a prediction model for custom structures & API changes
  • Loading branch information
skodapetr authored Apr 26, 2024
2 parents 79aa072 + 6db64e4 commit eb7cc5d
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 101 deletions.
61 changes: 29 additions & 32 deletions documentation/prankweb.open-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ openapi: 3.0.2

info:
title: Prankweb API
version: 1.0.1
version: 1.1.0

servers:
- url: https://prankweb.cz/api/v2/

paths:
/predictions/{database}/{task}/:
/prediction/{database}/{prediction_task_id}:
get:
parameters:
- in: path
Expand All @@ -17,18 +17,18 @@ paths:
schema:
$ref: '#/components/schemas/DatabaseId'
- in: path
name: task
name: prediction_task_id
required: true
schema:
$ref: '#/components/schemas/TaskId'
$ref: '#/components/schemas/PredictionTaskId'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Task'
/predictions/{database}/{task}/log:
$ref: '#/components/schemas/PredictionTask'
/prediction/{database}/{prediction_task_id}/log:
get:
parameters:
- in: path
Expand All @@ -37,18 +37,18 @@ paths:
schema:
$ref: '#/components/schemas/DatabaseId'
- in: path
name: task
name: prediction_task_id
required: true
schema:
$ref: '#/components/schemas/TaskId'
$ref: '#/components/schemas/PredictionTaskId'
responses:
'200':
description: Success
content:
text/plain:
schema:
type: string
/predictions/{database}/{task}/public/prediction.json:
/prediction/{database}/{prediction_task_id}/public/prediction.json:
get:
parameters:
- in: path
Expand All @@ -57,18 +57,18 @@ paths:
schema:
$ref: '#/components/schemas/DatabaseId'
- in: path
name: task
name: prediction_task_id
required: true
schema:
$ref: '#/components/schemas/TaskId'
$ref: '#/components/schemas/PredictionTaskId'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Prediction'
/docking/{database}/{task}/tasks:
/docking/{database}/{prediction_task_id}/tasks:
get:
parameters:
- in: path
Expand All @@ -77,37 +77,35 @@ paths:
schema:
$ref: '#/components/schemas/DatabaseId'
- in: path
name: task
name: prediction_task_id
required: true
schema:
$ref: '#/components/schemas/TaskId'
$ref: '#/components/schemas/PredictionTaskId'
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/DockingTaskList'
/docking/{database}/{task}/public/result.json:
post:
/docking/{database}/{prediction_task_id}/{docking_task_hash}/public/result.json:
get:
parameters:
- in: path
name: database
required: true
schema:
$ref: '#/components/schemas/DatabaseId'
- in: path
name: task
name: prediction_task_id
required: true
schema:
$ref: '#/components/schemas/TaskId'
requestBody:
description: The request needs to contain the hash of the docking task.
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DockingRequest'
$ref: '#/components/schemas/PredictionTaskId'
- in: path
name: docking_task_hash
required: true
schema:
type: string
responses:
'200':
description: Success
Expand All @@ -120,13 +118,15 @@ components:
schemas:
DatabaseId:
type : string
TaskId:
PredictionTaskId:
type : string
Task:
PredictionTask:
type: object
properties:
id:
type: string
database:
type: string
created:
type: string
format: date-time
Expand All @@ -136,6 +136,8 @@ components:
status:
type: string
enum: ['queued', 'running', 'failed', 'successful']
metadata:
type: object
Prediction:
type: object
properties:
Expand Down Expand Up @@ -223,11 +225,6 @@ components:
type: string
pocket:
type: string
DockingRequest:
type: object
properties:
hash:
type: string
DockingResponse:
type: array
items:
Expand Down
4 changes: 2 additions & 2 deletions executor-docking/run_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def execute_directory_task(docking_directory: str, taskId: int):
return

#parse the prediction file and do some calculations - in this case just counting the number of residues per pocket
#API is /docking/<database_name>/<prediction_name>/public/<file_name>
#API is /docking/<database_name>/<prediction_name>/<hash>/public/<file_name>
#split docking_directory to get database_name and prediction_name
result = []
database_name = docking_directory.split("/")[4]
Expand All @@ -151,7 +151,7 @@ def execute_directory_task(docking_directory: str, taskId: int):
else:
prediction_name = docking_directory.split("/")[6]

result_url = "./api/v2/docking/" + database_name + "/" + prediction_name + "/public/results.zip"
result_url = "./api/v2/docking/" + database_name + "/" + prediction_name + "/" + status["tasks"][taskId]["initialData"]["hash"] + "/public/results.zip"
result.append({
"url": result_url
})
Expand Down
55 changes: 37 additions & 18 deletions frontend/client/index/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h1 class="text-center">
<input class="form-check-input" type="radio" id="input-uniprot" value="input-uniprot"
name="input-type">
<label class="form-check-label" for="input-uniprot">
Predicted structure
AlphaFold structure
</label>
</div>
</div>
Expand All @@ -58,6 +58,15 @@ <h1 class="text-center">
Use original structure
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="conservation-pdb"
title="If checked, a model that exploits conservation will be used to classify protein binding sites."
checked="checked">
<label class="form-check-label" for="conservation-pdb">
Use
<a href="./help#conservation" target="_blank">conservation</a>
</label>
</div>
<div id="pdb-chains" style="display: none">
<input id="pdb-chains-store" style="display: none">
<div id="pdb-chains-label">
Expand All @@ -80,39 +89,49 @@ <h1 class="text-center">
<input type="text" class="form-control" id="user-file-chains" name="userFileChains"
placeholder="A,B" title="Optional. Comma separated list of chains to analyze.">
</div>
<div>
<input type="radio" name="user-input-model" id="user-input-model-1" value="default"
title="If selected, a default prediction model will be used.">
<label for="user-input-model-1" class="form-label">Default prediction model</label><br>

<input type="radio" name="user-input-model" id="user-input-model-2" value="conservation_hmm"
checked="checked"
title="If selected, a default prediction model with conservation will be used.">
<label for="user-input-model-2" class="form-label">Default model with
<a href="./help#conservation" target="_blank">conservation</a></label><br>

<input type="radio" name="user-input-model" id="user-input-model-3" value="alphafold"
title="If selected, an AlphaFold prediction model will be used.">
<label for="user-input-model-3" class="form-label">AlphaFold model</label><br>

<input type="radio" name="user-input-model" id="user-input-model-4"
value="alphafold_conservation_hmm"
title="If selected, an AlphaFold prediction model with conservation will be used.">
<label for="user-input-model-4" class="form-label">AlphaFold model with
<a href="./help#conservation" target="_blank">conservation</a></label><br>
</div>
</div>
<div id="input-uniprot-block" style="display: none">
<div class="mb-3">
<label for="uniprot-code" class="form-label">UniProt ID</label>
<input type="text" class="form-control" id="uniprot-code" name="uniprotCode"
placeholder="Q5VSL9" title="PrankWeb will use AlphaFold predicted structure.">
</div>
</div>
</div>
<div class="card-footer" id="message" style="display: none">
<!-- Messages are here. -->
</div>
</div>

<div class="card" id="conservation-block">
<div class="card-header">
Conservation
</div>
<div class="card-body">
<div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" id="conservation"
<div class="form-check">
<input class="form-check-input" type="checkbox" id="conservation-uniprot"
title="If checked, a model that exploits conservation will be used to classify protein binding sites."
checked="checked">
<label class="form-check-label" for="conservation">
<label class="form-check-label" for="conservation-uniprot">
Use
<a href="./help#conservation" target="_blank">conservation</a>
</label>
</div>
</div>
</div>
<div class="card-footer" id="message" style="display: none">
<!-- Messages are here. -->
</div>
</div>

<div>
<button type="submit" class="btn btn-primary float-md-end" id="submit-button">
Submit
Expand Down
41 changes: 27 additions & 14 deletions frontend/client/index/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class View {
this.uniprotSection = document.getElementById("input-uniprot-block");
this.uniprotCode = document.getElementById("uniprot-code");
this.message = document.getElementById("message");
this.conservation = document.getElementById("conservation");
this.conservationPdb = document.getElementById("conservation-pdb");
this.conservationUniprot = document.getElementById("conservation-uniprot");
this.submit = document.getElementById("submit-button");
//
this.controller = null;
Expand All @@ -40,13 +41,13 @@ class View {
//
this.pdbInput.addEventListener(
"change",
() => controller.onInputChange(View.PDB_VIEW))
() => controller.onInputChange(View.PDB_VIEW));
this.userInput.addEventListener(
"change",
() => controller.onInputChange(View.USER_VIEW))
() => controller.onInputChange(View.USER_VIEW));
this.uniprotInput.addEventListener(
"change",
() => controller.onInputChange(View.UNIPROT_VIEW))
() => controller.onInputChange(View.UNIPROT_VIEW));
this.pdbSealStructure.addEventListener(
"change",
(event) => controller.onPdbSealedChange(event.target.checked));
Expand Down Expand Up @@ -209,7 +210,7 @@ class View {
const label = document.createElement("label");
label.appendChild(input);
label.appendChild(document.createTextNode(
`\u00A0${chain}\u00A0\u00A0`))
`\u00A0${chain}\u00A0\u00A0`));
label.className = "form-check-label";
return label;
}
Expand Down Expand Up @@ -262,9 +263,22 @@ class View {
}

getConservation() {
return this.conservation.checked;
// this does not apply to user uploaded files, those are treated differently as the user
// selects the model directly
switch (this.getInputSection()) {
case View.PDB_VIEW:
return this.conservationPdb.checked;
case View.UNIPROT_VIEW:
return this.conservationUniprot.checked;
default:
return false;
}
}

getModelUserUpload() {
const selectedModel = document.querySelector('input[name="user-input-model"]:checked');
return selectedModel.value;
}
}

class Controller {
Expand Down Expand Up @@ -338,7 +352,7 @@ class Controller {
return true;
} else {
if (chains.count > 0) {
this.view.setMessage("At least one chain must be selected.")
this.view.setMessage("At least one chain must be selected.");
}
return false;
}
Expand Down Expand Up @@ -400,7 +414,7 @@ class Controller {
if (!this.validatePdbCode(code)) {
return;
}
await this.fetchChainsForPdbCode(code, false)
await this.fetchChainsForPdbCode(code, false);
if (code !== this.view.getPdbCode()) {
// User changed the code in a meanwhile.
return;
Expand Down Expand Up @@ -454,8 +468,7 @@ class Submit {
submitUserFile(view) {
const structure = view.getUserFileObject();
const chains = view.getUserChains();
const conservation = view.getConservation();
//
const model = view.getModelUserUpload();
const formData = new FormData();
formData.append(
"structure", structure, structure.name);
Expand All @@ -464,14 +477,14 @@ class Submit {
this.asJsonBlob({
"chains": chains,
"structure-sealed": chains.length === 0,
"compute-conservation": conservation,
"prediction-model": model,
}),
"configuration.json");
this.sendPostRequest("./api/v2/prediction/v3-user-upload", formData);
}

asJsonBlob(content) {
return new Blob([JSON.stringify(content)], {"type": "text/json"});
return new Blob([JSON.stringify(content)], { "type": "text/json" });
}

sendPostRequest(url, data) {
Expand All @@ -493,9 +506,9 @@ class Submit {
const conservation = view.getConservation();
let url;
if (conservation) {
url = this.createUrl("v3-alphafold-conservation-hmm", code, [])
url = this.createUrl("v3-alphafold-conservation-hmm", code, []);
} else {
url = this.createUrl("v3-alphafold", code, [])
url = this.createUrl("v3-alphafold", code, []);
}
window.location.href = url;
}
Expand Down
Loading

0 comments on commit eb7cc5d

Please sign in to comment.