atalaydenknalbant commited on
Commit
1f4b51c
·
1 Parent(s): 6777e11

Fix: Resolve runtime errors and add MCP support

Browse files
Files changed (1) hide show
  1. app.py +99 -14
app.py CHANGED
@@ -24,9 +24,17 @@ theme = gr.themes.Monochrome(
24
  primary_hue="gray",
25
  )
26
 
27
- ## Function to get model from Hugging Face using token
28
  def get_model(model_name, token):
 
 
29
 
 
 
 
 
 
 
 
30
  if token:
31
  login(token=token)
32
 
@@ -38,14 +46,36 @@ def get_model(model_name, token):
38
  # model = ESM3.from_pretrained(model_name, device=torch.device("cpu"))
39
  return model
40
 
41
- ## Function to get PDB data
42
  def get_pdb(pdb_id, chain_id):
 
 
 
 
 
 
 
 
 
 
43
  pdb = ProteinChain.from_rcsb(pdb_id, chain_id)
44
  # return [pdb.sequence, render_pdb(pdb.to_pdb_string())]
45
  return pdb
46
 
47
- ## Function to generate rep for 3D structure
48
  def make_reps(res_start=None, res_end=None, main_color="whiteCarbon", highlight_color="redCarbon", main_style="cartoon", highlight_style="cartoon"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  residue_range = f"{res_start}-{res_end}" if res_start != res_end else ""
50
 
51
  return [
@@ -72,8 +102,21 @@ def make_reps(res_start=None, res_end=None, main_color="whiteCarbon", highlight_
72
  "visible": True
73
  }]
74
 
75
- ## Function to render 3D structure
76
  def render_pdb(pdb_id, chain_id, res_start, res_end, pdb_string=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  if pdb_string is None:
78
  pdb_string = get_pdb(pdb_id, chain_id).to_pdb_string()
79
  ## Write to temporary file and read back in to get the 3D structure
@@ -82,11 +125,25 @@ def render_pdb(pdb_id, chain_id, res_start, res_end, pdb_string=None):
82
 
83
  return Molecule3D(tmp_pdb.name, reps=make_reps(res_start=res_start, res_end=res_end))
84
 
85
-
86
-
87
- ## Function for Scaffolding
88
  @spaces.GPU()
89
  def scaffold(model_name, pdb_id, chain_id, motif_start, motif_end, prompt_length, insert_size):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  pdb = get_pdb(pdb_id, chain_id)
91
 
92
  ## Get motif sequence and atom37 positions
@@ -145,9 +202,23 @@ def scaffold(model_name, pdb_id, chain_id, motif_start, motif_end, prompt_length
145
  structure_new_highlight
146
  ]
147
 
148
- ## Function for Secondary Structure Editing
149
  @spaces.GPU()
150
  def ss_edit(model_name, pdb_id, chain_id, region_start, region_end, shortened_region_length, shortening_ss8):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  pdb = get_pdb(pdb_id, chain_id)
152
  edit_region = np.arange(region_start, region_end)
153
 
@@ -192,9 +263,23 @@ def ss_edit(model_name, pdb_id, chain_id, region_start, region_end, shortened_re
192
  structure_new_highlight
193
  ]
194
 
195
- ## Function for SASA Editing
196
  @spaces.GPU()
197
  def sasa_edit(model_name, pdb_id, chain_id, span_start, span_end, n_samples):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  pdb = get_pdb(pdb_id, chain_id)
199
 
200
  structure_prompt = torch.full((len(pdb), 37, 3), torch.nan)
@@ -236,7 +321,7 @@ scaffold_app = gr.Interface(
236
  fn=scaffold,
237
  inputs=[
238
  gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
239
- # gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
240
  gr.Textbox(value="1ITU", label = "PDB Code"),
241
  gr.Textbox(value="A", label = "Chain"),
242
  gr.Number(value=123, label="Motif Start"),
@@ -262,7 +347,7 @@ ss_app = gr.Interface(
262
  fn=ss_edit,
263
  inputs=[
264
  gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
265
- # gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
266
  gr.Textbox(value = "7XBQ", label="PDB ID"),
267
  gr.Textbox(value = "A", label="Chain ID"),
268
  gr.Number(value=38, label="Edit Region Start"),
@@ -289,7 +374,7 @@ sasa_app = gr.Interface(
289
  fn=sasa_edit,
290
  inputs=[
291
  gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
292
- # gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
293
  gr.Textbox(value = "1LBS", label="PDB ID"),
294
  gr.Textbox(value = "A", label="Chain ID"),
295
  gr.Number(value=105, label="Span Start"),
@@ -332,7 +417,7 @@ with gr.Blocks(theme=theme) as esm_app:
332
  - GitHub: https://github.com/evolutionaryscale/esm
333
  - HuggingFace Model: https://huggingface.co/EvolutionaryScale/esm3-sm-open-v1
334
 
335
- Spaces App By: [[Colby T. Ford](https://colbyford.com)] from [Tuple, The Cloud Genomics Company](https://tuple.xyz)
336
 
337
  NOTE: You will need to agree to EvolutionaryScale's [license agreement](https://huggingface.co/EvolutionaryScale/esm3-sm-open-v1) to use the model. This space uses a stored token for API access.
338
  """
@@ -352,4 +437,4 @@ with gr.Blocks(theme=theme) as esm_app:
352
  ])
353
 
354
  if __name__ == "__main__":
355
- esm_app.launch()
 
24
  primary_hue="gray",
25
  )
26
 
 
27
  def get_model(model_name, token):
28
+ """
29
+ Logs into Hugging Face and loads a specified ESM3 model.
30
 
31
+ Args:
32
+ model_name (str): The name of the model to load from Hugging Face.
33
+ token (str): The Hugging Face authentication token.
34
+
35
+ Returns:
36
+ ESM3: The loaded ESM3 model moved to the CUDA device.
37
+ """
38
  if token:
39
  login(token=token)
40
 
 
46
  # model = ESM3.from_pretrained(model_name, device=torch.device("cpu"))
47
  return model
48
 
 
49
  def get_pdb(pdb_id, chain_id):
50
+ """
51
+ Fetches a protein structure from the RCSB PDB database.
52
+
53
+ Args:
54
+ pdb_id (str): The 4-character PDB identifier.
55
+ chain_id (str): The specific chain identifier within the PDB file.
56
+
57
+ Returns:
58
+ ProteinChain: An object representing the specified protein chain.
59
+ """
60
  pdb = ProteinChain.from_rcsb(pdb_id, chain_id)
61
  # return [pdb.sequence, render_pdb(pdb.to_pdb_string())]
62
  return pdb
63
 
 
64
  def make_reps(res_start=None, res_end=None, main_color="whiteCarbon", highlight_color="redCarbon", main_style="cartoon", highlight_style="cartoon"):
65
+ """
66
+ Creates representation styles for 3D protein visualization with py3Dmol.
67
+
68
+ Args:
69
+ res_start (int, optional): The starting residue for highlighting. Defaults to None.
70
+ res_end (int, optional): The ending residue for highlighting. Defaults to None.
71
+ main_color (str, optional): The color for the main protein structure. Defaults to "whiteCarbon".
72
+ highlight_color (str, optional): The color for the highlighted region. Defaults to "redCarbon".
73
+ main_style (str, optional): The style for the main structure (e.g., 'cartoon'). Defaults to "cartoon".
74
+ highlight_style (str, optional): The style for the highlighted region. Defaults to "cartoon".
75
+
76
+ Returns:
77
+ list: A list of dictionary objects defining the py3Dmol styles.
78
+ """
79
  residue_range = f"{res_start}-{res_end}" if res_start != res_end else ""
80
 
81
  return [
 
102
  "visible": True
103
  }]
104
 
 
105
  def render_pdb(pdb_id, chain_id, res_start, res_end, pdb_string=None):
106
+ """
107
+ Renders a PDB structure for display in a Gradio Molecule3D component.
108
+
109
+ Args:
110
+ pdb_id (str): The PDB ID, used for file naming.
111
+ chain_id (str): The chain ID, used for file naming.
112
+ res_start (int): The starting residue for highlighting.
113
+ res_end (int): The ending residue for highlighting.
114
+ pdb_string (str, optional): A string containing PDB data. If None,
115
+ it will be fetched from RCSB. Defaults to None.
116
+
117
+ Returns:
118
+ Molecule3D: A Gradio component object for 3D visualization.
119
+ """
120
  if pdb_string is None:
121
  pdb_string = get_pdb(pdb_id, chain_id).to_pdb_string()
122
  ## Write to temporary file and read back in to get the 3D structure
 
125
 
126
  return Molecule3D(tmp_pdb.name, reps=make_reps(res_start=res_start, res_end=res_end))
127
 
 
 
 
128
  @spaces.GPU()
129
  def scaffold(model_name, pdb_id, chain_id, motif_start, motif_end, prompt_length, insert_size):
130
+ """
131
+ Performs protein scaffolding by generating a new protein structure around a
132
+ functional motif from an existing protein.
133
+
134
+ Args:
135
+ model_name (str): The ESM3 model to use.
136
+ pdb_id (str): PDB ID of the source protein.
137
+ chain_id (str): Chain of the source protein.
138
+ motif_start (int): Starting residue of the motif.
139
+ motif_end (int): Ending residue of the motif.
140
+ prompt_length (int): Total length of the new protein sequence.
141
+ insert_size (int): Position where the motif will be inserted.
142
+
143
+ Returns:
144
+ list: A list of outputs for the Gradio interface, including sequences
145
+ and 3D structures.
146
+ """
147
  pdb = get_pdb(pdb_id, chain_id)
148
 
149
  ## Get motif sequence and atom37 positions
 
202
  structure_new_highlight
203
  ]
204
 
 
205
  @spaces.GPU()
206
  def ss_edit(model_name, pdb_id, chain_id, region_start, region_end, shortened_region_length, shortening_ss8):
207
+ """
208
+ Edits the secondary structure of a protein, for example, by shortening a helix.
209
+
210
+ Args:
211
+ model_name (str): The ESM3 model to use.
212
+ pdb_id (str): PDB ID of the source protein.
213
+ chain_id (str): Chain of the source protein.
214
+ region_start (int): Starting residue of the region to edit.
215
+ region_end (int): Ending residue of the region to edit.
216
+ shortened_region_length (int): The new length of the edited region.
217
+ shortening_ss8 (str): The 8-state secondary structure string for the original protein.
218
+
219
+ Returns:
220
+ list: A list of outputs for the Gradio interface.
221
+ """
222
  pdb = get_pdb(pdb_id, chain_id)
223
  edit_region = np.arange(region_start, region_end)
224
 
 
263
  structure_new_highlight
264
  ]
265
 
 
266
  @spaces.GPU()
267
  def sasa_edit(model_name, pdb_id, chain_id, span_start, span_end, n_samples):
268
+ """
269
+ Edits a protein region to increase its solvent-accessible surface area (SASA).
270
+
271
+ Args:
272
+ model_name (str): The ESM3 model to use.
273
+ pdb_id (str): PDB ID of the source protein.
274
+ chain_id (str): Chain of the source protein.
275
+ span_start (int): Starting residue of the region to edit.
276
+ span_end (int): Ending residue of the region to edit.
277
+ n_samples (int): The number of new designs to generate.
278
+
279
+ Returns:
280
+ list: A list of outputs for the Gradio interface, including the best
281
+ generated structure.
282
+ """
283
  pdb = get_pdb(pdb_id, chain_id)
284
 
285
  structure_prompt = torch.full((len(pdb), 37, 3), torch.nan)
 
321
  fn=scaffold,
322
  inputs=[
323
  gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
324
+ # gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
325
  gr.Textbox(value="1ITU", label = "PDB Code"),
326
  gr.Textbox(value="A", label = "Chain"),
327
  gr.Number(value=123, label="Motif Start"),
 
347
  fn=ss_edit,
348
  inputs=[
349
  gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
350
+ # gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
351
  gr.Textbox(value = "7XBQ", label="PDB ID"),
352
  gr.Textbox(value = "A", label="Chain ID"),
353
  gr.Number(value=38, label="Edit Region Start"),
 
374
  fn=sasa_edit,
375
  inputs=[
376
  gr.Dropdown(label="Model Name", choices=["esm3_sm_open_v1"], value="esm3_sm_open_v1", allow_custom_value=True),
377
+ # gr.Textbox(value = "hf_...", label="Hugging Face Token", type="password"),
378
  gr.Textbox(value = "1LBS", label="PDB ID"),
379
  gr.Textbox(value = "A", label="Chain ID"),
380
  gr.Number(value=105, label="Span Start"),
 
417
  - GitHub: https://github.com/evolutionaryscale/esm
418
  - HuggingFace Model: https://huggingface.co/EvolutionaryScale/esm3-sm-open-v1
419
 
420
+ Spaces App By: [[Colby T. Ford](https://colbyford.com)] from [Tuple, The Cloud Genomics Company](https://tuple.xyz)
421
 
422
  NOTE: You will need to agree to EvolutionaryScale's [license agreement](https://huggingface.co/EvolutionaryScale/esm3-sm-open-v1) to use the model. This space uses a stored token for API access.
423
  """
 
437
  ])
438
 
439
  if __name__ == "__main__":
440
+ esm_app.launch(mcp_server=True)