openprotein-python 0.8.8__tar.gz → 0.8.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/PKG-INFO +1 -1
  2. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/api.py +16 -32
  3. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/future.py +53 -0
  4. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/.gitignore +0 -0
  5. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/LICENSE.txt +0 -0
  6. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/README.md +0 -0
  7. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/__init__.py +0 -0
  8. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/_version.py +0 -0
  9. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/align/__init__.py +0 -0
  10. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/align/align.py +0 -0
  11. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/align/api.py +0 -0
  12. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/align/future.py +0 -0
  13. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/align/msa.py +0 -0
  14. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/align/schemas.py +0 -0
  15. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/base.py +0 -0
  16. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/chains.py +0 -0
  17. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/common/__init__.py +0 -0
  18. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/common/features.py +0 -0
  19. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/common/model_metadata.py +0 -0
  20. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/common/reduction.py +0 -0
  21. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/config.py +0 -0
  22. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/csv.py +0 -0
  23. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/data/__init__.py +0 -0
  24. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/data/api.py +0 -0
  25. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/data/assaydataset.py +0 -0
  26. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/data/data.py +0 -0
  27. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/data/schemas.py +0 -0
  28. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/design/__init__.py +0 -0
  29. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/design/api.py +0 -0
  30. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/design/design.py +0 -0
  31. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/design/future.py +0 -0
  32. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/design/schemas.py +0 -0
  33. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/__init__.py +0 -0
  34. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/api.py +0 -0
  35. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/embeddings.py +0 -0
  36. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/esm.py +0 -0
  37. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/future.py +0 -0
  38. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/models.py +0 -0
  39. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/openprotein.py +0 -0
  40. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/poet.py +0 -0
  41. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/poet2.py +0 -0
  42. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/embeddings/schemas.py +0 -0
  43. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/errors.py +0 -0
  44. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fasta.py +0 -0
  45. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/__init__.py +0 -0
  46. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/alphafold2.py +0 -0
  47. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/boltz.py +0 -0
  48. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/complex.py +0 -0
  49. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/esmfold.py +0 -0
  50. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/fold.py +0 -0
  51. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/minifold.py +0 -0
  52. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/models.py +0 -0
  53. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/rosettafold3.py +0 -0
  54. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/fold/schemas.py +0 -0
  55. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/jobs/__init__.py +0 -0
  56. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/jobs/api.py +0 -0
  57. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/jobs/futures.py +0 -0
  58. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/jobs/jobs.py +0 -0
  59. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/jobs/schemas.py +0 -0
  60. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/models/__init__.py +0 -0
  61. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/models/base.py +0 -0
  62. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/models/foundation/rfdiffusion.py +0 -0
  63. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/models/models.py +0 -0
  64. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/predictor/__init__.py +0 -0
  65. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/predictor/api.py +0 -0
  66. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/predictor/models.py +0 -0
  67. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/predictor/prediction.py +0 -0
  68. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/predictor/predictor.py +0 -0
  69. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/predictor/schemas.py +0 -0
  70. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/predictor/validate.py +0 -0
  71. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/prompt/__init__.py +0 -0
  72. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/prompt/api.py +0 -0
  73. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/prompt/models.py +0 -0
  74. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/prompt/prompt.py +0 -0
  75. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/prompt/schemas.py +0 -0
  76. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/protein.py +0 -0
  77. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/svd/__init__.py +0 -0
  78. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/svd/api.py +0 -0
  79. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/svd/models.py +0 -0
  80. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/svd/schemas.py +0 -0
  81. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/svd/svd.py +0 -0
  82. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/umap/__init__.py +0 -0
  83. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/umap/api.py +0 -0
  84. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/umap/models.py +0 -0
  85. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/umap/schemas.py +0 -0
  86. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/umap/umap.py +0 -0
  87. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/openprotein/utils/uuid.py +0 -0
  88. {openprotein_python-0.8.8 → openprotein_python-0.8.9}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openprotein-python
3
- Version: 0.8.8
3
+ Version: 0.8.9
4
4
  Summary: OpenProtein Python interface.
5
5
  Author-email: Mark Gee <markgee@ne47.bio>, "Timothy Truong Jr." <ttruong@ne47.bio>, Tristan Bepler <tbepler@ne47.bio>
6
6
  License-Expression: MIT
@@ -1,7 +1,7 @@
1
1
  """Fold REST API interface for making HTTP calls to our fold backend."""
2
2
 
3
3
  import io
4
- from typing import Literal
4
+ from typing import TYPE_CHECKING, Literal
5
5
 
6
6
  import numpy as np
7
7
  from pydantic import TypeAdapter
@@ -12,6 +12,9 @@ from openprotein.errors import HTTPError
12
12
 
13
13
  from .schemas import FoldJob, FoldMetadata
14
14
 
15
+ if TYPE_CHECKING:
16
+ import pandas as pd
17
+
15
18
  PATH_PREFIX = "v1/fold"
16
19
 
17
20
 
@@ -160,8 +163,8 @@ def fold_get_complex_result(
160
163
  def fold_get_complex_extra_result(
161
164
  session: APISession,
162
165
  job_id: str,
163
- key: Literal["pae", "pde", "plddt", "confidence", "affinity"],
164
- ) -> np.ndarray | list[dict]:
166
+ key: Literal["pae", "pde", "plddt", "confidence", "affinity", "score", "metrics"],
167
+ ) -> "np.ndarray | list[dict] | pd.DataFrame":
165
168
  """
166
169
  Get extra result for a complex from the request ID.
167
170
 
@@ -183,6 +186,10 @@ def fold_get_complex_extra_result(
183
186
  formatter = lambda response: np.load(io.BytesIO(response.content))
184
187
  elif key in {"confidence", "affinity"}:
185
188
  formatter = lambda response: response.json()
189
+ elif key in {"score", "metrics"}:
190
+ import pandas as pd
191
+
192
+ formatter = lambda response: pd.read_csv(io.StringIO(response.content.decode()))
186
193
  else:
187
194
  raise ValueError(f"Unexpected key: {key}")
188
195
  endpoint = PATH_PREFIX + f"/{job_id}/complex/{key}"
@@ -194,7 +201,7 @@ def fold_get_complex_extra_result(
194
201
  if e.status_code == 400 and key == "affinity":
195
202
  raise ValueError("affinity not found for request") from None
196
203
  raise e
197
- output: np.ndarray | list[dict] = formatter(response)
204
+ output = formatter(response)
198
205
  return output
199
206
 
200
207
 
@@ -254,34 +261,11 @@ def fold_models_post(
254
261
  sequences = kwargs["sequences"]
255
262
  # NOTE we are handling the boltz form here too
256
263
  sequences = [s.decode() if isinstance(s, bytes) else s for s in sequences]
257
- body["sequences"] = sequences
258
- if kwargs.get("msa_id"):
259
- body["msa_id"] = kwargs["msa_id"]
260
- if kwargs.get("num_recycles"):
261
- body["num_recycles"] = kwargs["num_recycles"]
262
- if kwargs.get("num_models"):
263
- body["num_models"] = kwargs["num_models"]
264
- if kwargs.get("num_relax"):
265
- body["num_relax"] = kwargs["num_relax"]
266
- if kwargs.get("use_potentials"):
267
- body["use_potentials"] = kwargs["use_potentials"]
268
- # boltz
269
- if kwargs.get("diffusion_samples"):
270
- body["diffusion_samples"] = kwargs["diffusion_samples"]
271
- if kwargs.get("recycling_steps"):
272
- body["recycling_steps"] = kwargs["recycling_steps"]
273
- if kwargs.get("sampling_steps"):
274
- body["sampling_steps"] = kwargs["sampling_steps"]
275
- if kwargs.get("step_scale"):
276
- body["step_scale"] = kwargs["step_scale"]
277
- if kwargs.get("constraints"):
278
- body["constraints"] = kwargs["constraints"]
279
- if kwargs.get("templates"):
280
- body["templates"] = kwargs["templates"]
281
- if kwargs.get("properties"):
282
- body["properties"] = kwargs["properties"]
283
- if kwargs.get("method"):
284
- body["method"] = kwargs["method"]
264
+ kwargs["sequences"] = sequences
265
+ # add non-None args - note this doesnt affect msa_id which is nested
266
+ for k, v in kwargs.items():
267
+ if v is not None:
268
+ body[k] = v
285
269
 
286
270
  response = session.post(endpoint, json=body)
287
271
  return FoldJob.model_validate(response.json())
@@ -3,6 +3,7 @@
3
3
  from typing import TYPE_CHECKING, Literal
4
4
 
5
5
  import numpy as np
6
+ import pandas as pd
6
7
  from pydantic.type_adapter import TypeAdapter
7
8
  from typing_extensions import Self
8
9
 
@@ -246,6 +247,8 @@ class FoldComplexResultFuture(Future):
246
247
  self._pae: np.ndarray | None = None
247
248
  self._pde: np.ndarray | None = None
248
249
  self._plddt: np.ndarray | None = None
250
+ self._score: pd.DataFrame | None = None
251
+ self._metrics: pd.DataFrame | None = None
249
252
  self._confidence: list["BoltzConfidence"] | None = None
250
253
  self._affinity: "BoltzAffinity | None" = None
251
254
 
@@ -439,6 +442,56 @@ class FoldComplexResultFuture(Future):
439
442
  self._plddt = plddt
440
443
  return self._plddt
441
444
 
445
+ @property
446
+ def score(self) -> pd.DataFrame:
447
+ """
448
+ Get the predicted scores.
449
+
450
+ Returns
451
+ -------
452
+ pd.DataFrame
453
+ Structure prediction scores.
454
+
455
+ Raises
456
+ ------
457
+ AttributeError
458
+ If score is not supported for the model.
459
+ """
460
+ if self.model_id not in {"rosettafold-3"}:
461
+ raise AttributeError("score not supported for non-RosettaFold model")
462
+ if self._score is None:
463
+ score = api.fold_get_complex_extra_result(
464
+ session=self.session, job_id=self.job.job_id, key="score"
465
+ )
466
+ assert isinstance(score, pd.DataFrame)
467
+ self._score = score
468
+ return self._score
469
+
470
+ @property
471
+ def metrics(self) -> pd.DataFrame:
472
+ """
473
+ Get the predicted metrics.
474
+
475
+ Returns
476
+ -------
477
+ pd.DataFrame
478
+ Structure prediction metrics.
479
+
480
+ Raises
481
+ ------
482
+ AttributeError
483
+ If metrics is not supported for the model.
484
+ """
485
+ if self.model_id not in {"rosettafold-3"}:
486
+ raise AttributeError("metrics not supported for non-RosettaFold model")
487
+ if self._metrics is None:
488
+ metrics = api.fold_get_complex_extra_result(
489
+ session=self.session, job_id=self.job.job_id, key="metrics"
490
+ )
491
+ assert isinstance(metrics, pd.DataFrame)
492
+ self._metrics = metrics
493
+ return self._metrics
494
+
442
495
  @property
443
496
  def confidence(self) -> list["BoltzConfidence"]:
444
497
  """