Topallaj Denis commited on
Commit
b83473a
1 Parent(s): 6aadb65

refactored UniKP page

Browse files
Files changed (4) hide show
  1. main.py +28 -9
  2. static/index.html +73 -0
  3. static/index.js +30 -0
  4. static/styles.css +94 -0
main.py CHANGED
@@ -1,4 +1,7 @@
1
  from fastapi import FastAPI
 
 
 
2
  from typing import Dict, List, Any, Tuple
3
  import pickle
4
  import math
@@ -14,29 +17,45 @@ import pydantic
14
 
15
  app = FastAPI()
16
 
17
- tokenizer = T5Tokenizer.from_pretrained(
18
- "Rostlab/prot_t5_xl_half_uniref50-enc", do_lower_case=False, torch_dtype=torch.float16)
19
 
20
- model = T5EncoderModel.from_pretrained(
21
- "Rostlab/prot_t5_xl_half_uniref50-enc")
 
 
 
 
 
22
 
23
- class Item(pydantic.BaseModel):
 
 
 
 
 
24
  sequence: str
25
  smiles: str
26
 
27
- @app.post("/predict")
28
- def predict(item: Item):
29
 
30
  endpointHandler = EndpointHandler()
31
  result = endpointHandler.predict({
32
  "inputs": {
33
- "sequence": item.sequence,
34
- "smiles": item.smiles
35
  }
36
  })
37
 
38
  return result
39
 
 
 
 
 
 
 
 
40
  class EndpointHandler():
41
  def __init__(self, path=""):
42
 
 
1
  from fastapi import FastAPI
2
+ from fastapi.responses import HTMLResponse, FileResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from fastapi.staticfiles import StaticFiles
5
  from typing import Dict, List, Any, Tuple
6
  import pickle
7
  import math
 
17
 
18
  app = FastAPI()
19
 
20
+ app.mount("/static", StaticFiles(directory="static"), name="static")
 
21
 
22
+ app.add_middleware(
23
+ CORSMiddleware,
24
+ allow_origins=["*"],
25
+ allow_credentials=True,
26
+ allow_methods=["*"],
27
+ allow_headers=["*"],
28
+ )
29
 
30
+ @app.get("/", response_class=HTMLResponse)
31
+ async def read_root():
32
+ return FileResponse("static/index.html")
33
+
34
+
35
+ class PredictData(pydantic.BaseModel):
36
  sequence: str
37
  smiles: str
38
 
39
+ @app.post("/api/predict")
40
+ async def predict(data: PredictData):
41
 
42
  endpointHandler = EndpointHandler()
43
  result = endpointHandler.predict({
44
  "inputs": {
45
+ "sequence": data.sequence,
46
+ "smiles": data.smiles
47
  }
48
  })
49
 
50
  return result
51
 
52
+
53
+ tokenizer = T5Tokenizer.from_pretrained(
54
+ "Rostlab/prot_t5_xl_half_uniref50-enc", do_lower_case=False, torch_dtype=torch.float16)
55
+
56
+ model = T5EncoderModel.from_pretrained(
57
+ "Rostlab/prot_t5_xl_half_uniref50-enc")
58
+
59
  class EndpointHandler():
60
  def __init__(self, path=""):
61
 
static/index.html ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>UniKP Kinetic Values Prediction</title>
7
+ <script src="/static/index.js" defer></script>
8
+ <link rel="stylesheet" type="text/css" href="/static/styles.css" />
9
+ </head>
10
+ <body>
11
+ <h1>UniKP Kinetic Values Prediction</h1>
12
+ <p> <a href="/docs" target="_blank">API Usage</a></p>
13
+ <div class="box">
14
+ <form id="predictionForm">
15
+ <label for="sequence">Sequence:</label>
16
+ <textarea id="sequence" name="sequence"></textarea>
17
+ <label for="smiles">SMILES:</label><br />
18
+ <textarea id="smiles" name="smiles"></textarea>
19
+ <input type="submit" value="Submit" />
20
+ </form>
21
+ </div>
22
+ <div id="predictionResults" class="box"></div>
23
+
24
+ <div class="box">
25
+ <h2>UniKP</h2>
26
+ <h3>What is UniKP?</h3>
27
+ <p>
28
+ UniKP is a unified framework for the prediction of enzyme
29
+ kinetic parameters. It is a machine learning model that predicts
30
+ the kinetic parameters of enzymes based on their amino acid
31
+ sequences and SMILES representations of a substrate.
32
+ </p>
33
+ <h3>Why is this interesting?</h3>
34
+ <p>
35
+ UniKP can be used to predict the kinetic parameters of enzymes,
36
+ which can be used for feature extraction in enzyme engineering.
37
+ Knowing the kinetic parameters of an enzyme can help to
38
+ understand its function and can be used to optimize its
39
+ performance.
40
+ </p>
41
+ </div>
42
+ <div class="box">
43
+ <h2>References</h2>
44
+ <ul>
45
+ <li>
46
+ <a
47
+ href="https://github.com/Luo-SynBioLab/UniKP"
48
+ target="_blank"
49
+ ><img
50
+ class="devicon"
51
+ src="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/github/github-original-wordmark.svg"
52
+ alt="UniKP"
53
+ /></a>
54
+ </li>
55
+ <li>
56
+ <a
57
+ href="https://www.nature.com/articles/s41467-023-44113-1"
58
+ target="_blank"
59
+ >Yu, H., Deng, H., He, J. et al. UniKP: a unified
60
+ framework for the prediction of enzyme kinetic
61
+ parameters. Nat Commun 14, 8211 (2023)</a
62
+ >
63
+ </li>
64
+ <li><a href="https://www.ml6.eu/" target="_blank">ML6</a></li>
65
+ <li>
66
+ <a href="https://www.decypher.bio/" target="_blank"
67
+ >deCYPher</a
68
+ >
69
+ </li>
70
+ </ul>
71
+ </div>
72
+ </body>
73
+ </html>
static/index.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use strict";
2
+
3
+ const form = document.getElementById("predictionForm");
4
+ form.addEventListener("submit", async (e) => {
5
+ e.preventDefault();
6
+
7
+ const sequence = document.getElementById("sequence").value;
8
+ const smiles = document.getElementById("smiles").value;
9
+
10
+ const response = await fetch("/api/predict", {
11
+ method: "POST",
12
+ headers: {
13
+ "Content-Type": "application/json",
14
+ "Accept": "application/json",
15
+ },
16
+ body: JSON.stringify({ sequence, smiles }),
17
+ });
18
+
19
+ const data = await response.json();
20
+ const predictionResults = document.getElementById("predictionResults");
21
+
22
+ // unhide the results
23
+ predictionResults.style.display = "block";
24
+
25
+ predictionResults.innerHTML = `
26
+ <h2>Prediction Results</h2>
27
+ <p><strong>Km:</strong> ${data.km}</p>
28
+ <p><strong>Kcat:</strong> ${data.kcat}</p>
29
+ <p><strong>Vmax:</strong> ${data.vmax}</p>`;
30
+ });
static/styles.css ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: Arial, sans-serif;
3
+ background-color: #f8f8f8;
4
+ margin: 0;
5
+ padding: 0;
6
+ display: flex;
7
+ justify-content: center;
8
+ align-items: center;
9
+ flex-direction: column;
10
+ }
11
+
12
+ h1 {
13
+ color: #333;
14
+ text-align: center;
15
+ }
16
+
17
+ form {
18
+ margin: 20px auto;
19
+ width: 50%;
20
+ text-align: center;
21
+ }
22
+
23
+ label {
24
+ display: block;
25
+ margin-bottom: 5px;
26
+ }
27
+
28
+ textarea {
29
+ width: 80%;
30
+ padding: 8px;
31
+ margin-bottom: 10px;
32
+ border: 1px solid #ccc;
33
+ border-radius: 5px;
34
+ }
35
+
36
+ input[type="submit"] {
37
+ background-color: #4caf50;
38
+ color: white;
39
+ padding: 10px 20px;
40
+ border: none;
41
+ border-radius: 5px;
42
+ cursor: pointer;
43
+ }
44
+
45
+ input[type="submit"]:hover {
46
+ background-color: #45a049;
47
+ }
48
+
49
+ #predictionResults {
50
+ margin: 20px auto;
51
+ width: 50%;
52
+ padding: 10px;
53
+ border: 1px solid #ccc;
54
+ border-radius: 5px;
55
+ display: none;
56
+ }
57
+
58
+ .box {
59
+ margin: 20px auto;
60
+ width: 50%;
61
+ background-color: #f9f9f9;
62
+ padding: 10px;
63
+ border: 1px solid #ccc;
64
+ border-radius: 5px;
65
+ }
66
+
67
+ .box h2 {
68
+ color: #333;
69
+ margin-bottom: 10px;
70
+ }
71
+
72
+ .box ul {
73
+ list-style-type: none;
74
+ padding: 0;
75
+ }
76
+
77
+ .box li {
78
+ margin-bottom: 5px;
79
+ }
80
+
81
+ a {
82
+ color: #ff6600;
83
+ text-decoration: none;
84
+ }
85
+
86
+ a:hover {
87
+ text-decoration: underline;
88
+ }
89
+
90
+ .devicon {
91
+ width: 50px;
92
+ height: 50px;
93
+ margin-right: 5px;
94
+ }