openprotein-python 0.12.0__tar.gz → 0.12.1__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 (205) hide show
  1. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/PKG-INFO +1 -1
  2. openprotein_python-0.12.1/openprotein/api/__init__.py +9 -0
  3. openprotein_python-0.12.1/openprotein/api/align.py +400 -0
  4. openprotein_python-0.12.1/openprotein/api/assaydata.py +216 -0
  5. openprotein_python-0.12.1/openprotein/api/deprecated/__init__.py +5 -0
  6. openprotein_python-0.12.1/openprotein/api/deprecated/design.py +86 -0
  7. openprotein_python-0.12.1/openprotein/api/deprecated/poet.py +308 -0
  8. openprotein_python-0.12.1/openprotein/api/deprecated/predict.py +276 -0
  9. openprotein_python-0.12.1/openprotein/api/deprecated/train.py +224 -0
  10. openprotein_python-0.12.1/openprotein/api/design.py +86 -0
  11. openprotein_python-0.12.1/openprotein/api/designer.py +267 -0
  12. openprotein_python-0.12.1/openprotein/api/embedding.py +446 -0
  13. openprotein_python-0.12.1/openprotein/api/error.py +5 -0
  14. openprotein_python-0.12.1/openprotein/api/fold.py +157 -0
  15. openprotein_python-0.12.1/openprotein/api/job.py +94 -0
  16. openprotein_python-0.12.1/openprotein/api/predict.py +273 -0
  17. openprotein_python-0.12.1/openprotein/api/predictor.py +326 -0
  18. openprotein_python-0.12.1/openprotein/api/prompt.py +464 -0
  19. openprotein_python-0.12.1/openprotein/api/svd.py +203 -0
  20. openprotein_python-0.12.1/openprotein/api/train.py +222 -0
  21. openprotein_python-0.12.1/openprotein/api/umap.py +257 -0
  22. openprotein_python-0.12.1/openprotein/app/__init__.py +19 -0
  23. openprotein_python-0.12.1/openprotein/app/deprecated.py +8 -0
  24. openprotein_python-0.12.1/openprotein/app/models/__init__.py +33 -0
  25. openprotein_python-0.12.1/openprotein/app/models/align/__init__.py +4 -0
  26. openprotein_python-0.12.1/openprotein/app/models/align/base.py +20 -0
  27. openprotein_python-0.12.1/openprotein/app/models/align/msa.py +134 -0
  28. openprotein_python-0.12.1/openprotein/app/models/align/prompt.py +78 -0
  29. openprotein_python-0.12.1/openprotein/app/models/assaydata.py +176 -0
  30. openprotein_python-0.12.1/openprotein/app/models/deprecated/__init__.py +10 -0
  31. openprotein_python-0.12.1/openprotein/app/models/deprecated/design.py +109 -0
  32. openprotein_python-0.12.1/openprotein/app/models/deprecated/poet.py +204 -0
  33. openprotein_python-0.12.1/openprotein/app/models/deprecated/predict.py +232 -0
  34. openprotein_python-0.12.1/openprotein/app/models/deprecated/train.py +307 -0
  35. openprotein_python-0.12.1/openprotein/app/models/design.py +105 -0
  36. openprotein_python-0.12.1/openprotein/app/models/designer.py +143 -0
  37. openprotein_python-0.12.1/openprotein/app/models/embeddings/__init__.py +12 -0
  38. openprotein_python-0.12.1/openprotein/app/models/embeddings/base.py +337 -0
  39. openprotein_python-0.12.1/openprotein/app/models/embeddings/esm.py +32 -0
  40. openprotein_python-0.12.1/openprotein/app/models/embeddings/future.py +135 -0
  41. openprotein_python-0.12.1/openprotein/app/models/embeddings/openprotein.py +21 -0
  42. openprotein_python-0.12.1/openprotein/app/models/embeddings/poet.py +366 -0
  43. openprotein_python-0.12.1/openprotein/app/models/embeddings/poet2.py +385 -0
  44. openprotein_python-0.12.1/openprotein/app/models/embeddings/test.py +38 -0
  45. openprotein_python-0.12.1/openprotein/app/models/fold/__init__.py +6 -0
  46. openprotein_python-0.12.1/openprotein/app/models/fold/alphafold2.py +54 -0
  47. openprotein_python-0.12.1/openprotein/app/models/fold/base.py +81 -0
  48. openprotein_python-0.12.1/openprotein/app/models/fold/boltz.py +57 -0
  49. openprotein_python-0.12.1/openprotein/app/models/fold/esmfold.py +38 -0
  50. openprotein_python-0.12.1/openprotein/app/models/fold/future.py +56 -0
  51. openprotein_python-0.12.1/openprotein/app/models/futures.py +473 -0
  52. openprotein_python-0.12.1/openprotein/app/models/predict.py +246 -0
  53. openprotein_python-0.12.1/openprotein/app/models/predictor/__init__.py +4 -0
  54. openprotein_python-0.12.1/openprotein/app/models/predictor/predict.py +78 -0
  55. openprotein_python-0.12.1/openprotein/app/models/predictor/predictor.py +362 -0
  56. openprotein_python-0.12.1/openprotein/app/models/predictor/validate.py +37 -0
  57. openprotein_python-0.12.1/openprotein/app/models/prompt.py +141 -0
  58. openprotein_python-0.12.1/openprotein/app/models/svd.py +260 -0
  59. openprotein_python-0.12.1/openprotein/app/models/train.py +303 -0
  60. openprotein_python-0.12.1/openprotein/app/models/umap.py +156 -0
  61. openprotein_python-0.12.1/openprotein/app/services/__init__.py +16 -0
  62. openprotein_python-0.12.1/openprotein/app/services/align.py +356 -0
  63. openprotein_python-0.12.1/openprotein/app/services/assaydata.py +119 -0
  64. openprotein_python-0.12.1/openprotein/app/services/deprecated/__init__.py +9 -0
  65. openprotein_python-0.12.1/openprotein/app/services/deprecated/design.py +79 -0
  66. openprotein_python-0.12.1/openprotein/app/services/deprecated/predict.py +152 -0
  67. openprotein_python-0.12.1/openprotein/app/services/deprecated/train.py +140 -0
  68. openprotein_python-0.12.1/openprotein/app/services/design.py +79 -0
  69. openprotein_python-0.12.1/openprotein/app/services/designer.py +107 -0
  70. openprotein_python-0.12.1/openprotein/app/services/embeddings.py +137 -0
  71. openprotein_python-0.12.1/openprotein/app/services/fold.py +89 -0
  72. openprotein_python-0.12.1/openprotein/app/services/job.py +61 -0
  73. openprotein_python-0.12.1/openprotein/app/services/predict.py +145 -0
  74. openprotein_python-0.12.1/openprotein/app/services/predictor.py +192 -0
  75. openprotein_python-0.12.1/openprotein/app/services/prompt.py +133 -0
  76. openprotein_python-0.12.1/openprotein/app/services/svd.py +102 -0
  77. openprotein_python-0.12.1/openprotein/app/services/train.py +135 -0
  78. openprotein_python-0.12.1/openprotein/app/services/umap.py +97 -0
  79. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/future.py +36 -23
  80. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/errors.py +5 -1
  81. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/__init__.py +2 -1
  82. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/future.py +14 -6
  83. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/protenix.py +60 -0
  84. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/jobs/futures.py +21 -11
  85. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/prompt/models.py +10 -3
  86. openprotein_python-0.12.1/openprotein/schemas/__init__.py +74 -0
  87. openprotein_python-0.12.1/openprotein/schemas/align.py +61 -0
  88. openprotein_python-0.12.1/openprotein/schemas/assaydata.py +27 -0
  89. openprotein_python-0.12.1/openprotein/schemas/deprecated/__init__.py +21 -0
  90. openprotein_python-0.12.1/openprotein/schemas/deprecated/design.py +173 -0
  91. openprotein_python-0.12.1/openprotein/schemas/deprecated/poet.py +70 -0
  92. openprotein_python-0.12.1/openprotein/schemas/deprecated/predict.py +82 -0
  93. openprotein_python-0.12.1/openprotein/schemas/deprecated/train.py +34 -0
  94. openprotein_python-0.12.1/openprotein/schemas/design.py +202 -0
  95. openprotein_python-0.12.1/openprotein/schemas/designer.py +38 -0
  96. openprotein_python-0.12.1/openprotein/schemas/embeddings.py +102 -0
  97. openprotein_python-0.12.1/openprotein/schemas/features.py +7 -0
  98. openprotein_python-0.12.1/openprotein/schemas/fold.py +10 -0
  99. openprotein_python-0.12.1/openprotein/schemas/job.py +134 -0
  100. openprotein_python-0.12.1/openprotein/schemas/predict.py +82 -0
  101. openprotein_python-0.12.1/openprotein/schemas/predictor.py +96 -0
  102. openprotein_python-0.12.1/openprotein/schemas/prompt.py +28 -0
  103. openprotein_python-0.12.1/openprotein/schemas/svd.py +31 -0
  104. openprotein_python-0.12.1/openprotein/schemas/train.py +34 -0
  105. openprotein_python-0.12.1/openprotein/schemas/umap.py +35 -0
  106. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/utils/chain_id.py +3 -5
  107. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/pyproject.toml +1 -1
  108. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/.gitignore +0 -0
  109. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/LICENSE.txt +0 -0
  110. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/README.md +0 -0
  111. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/__init__.py +0 -0
  112. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/_version.py +0 -0
  113. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/align/__init__.py +0 -0
  114. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/align/align.py +0 -0
  115. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/align/api.py +0 -0
  116. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/align/future.py +0 -0
  117. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/align/msa.py +0 -0
  118. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/align/schemas.py +0 -0
  119. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/base.py +0 -0
  120. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/chains.py +0 -0
  121. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/common/__init__.py +0 -0
  122. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/common/features.py +0 -0
  123. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/common/model_metadata.py +0 -0
  124. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/common/reduction.py +0 -0
  125. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/common/residue_contants.py +0 -0
  126. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/config.py +0 -0
  127. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/csv.py +0 -0
  128. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/data/__init__.py +0 -0
  129. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/data/api.py +0 -0
  130. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/data/assaydataset.py +0 -0
  131. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/data/data.py +0 -0
  132. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/data/schemas.py +0 -0
  133. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/design/__init__.py +0 -0
  134. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/design/api.py +0 -0
  135. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/design/design.py +0 -0
  136. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/design/future.py +0 -0
  137. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/design/schemas.py +0 -0
  138. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/__init__.py +0 -0
  139. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/ablang.py +0 -0
  140. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/api.py +0 -0
  141. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/embeddings.py +0 -0
  142. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/esm.py +0 -0
  143. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/models.py +0 -0
  144. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/openprotein.py +0 -0
  145. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/poet.py +0 -0
  146. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/poet2.py +0 -0
  147. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/embeddings/schemas.py +0 -0
  148. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fasta.py +0 -0
  149. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/alphafold2.py +0 -0
  150. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/api.py +0 -0
  151. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/boltz.py +0 -0
  152. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/common.py +0 -0
  153. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/complex.py +0 -0
  154. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/esmfold.py +0 -0
  155. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/fold.py +0 -0
  156. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/minifold.py +0 -0
  157. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/models.py +0 -0
  158. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/rosettafold3.py +0 -0
  159. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/fold/schemas.py +0 -0
  160. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/jobs/__init__.py +0 -0
  161. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/jobs/api.py +0 -0
  162. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/jobs/jobs.py +0 -0
  163. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/jobs/schemas.py +0 -0
  164. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/__init__.py +0 -0
  165. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/base.py +0 -0
  166. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/foundation/boltzgen.py +0 -0
  167. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/foundation/boltzgen_schema.py +0 -0
  168. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/foundation/proteinmpnn.py +0 -0
  169. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/foundation/rfdiffusion.py +0 -0
  170. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/models.py +0 -0
  171. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/models/structure_generation.py +0 -0
  172. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/molecules/__init__.py +0 -0
  173. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/molecules/chains.py +0 -0
  174. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/molecules/complex.py +0 -0
  175. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/molecules/protein.py +0 -0
  176. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/molecules/structure.py +0 -0
  177. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/molecules/template.py +0 -0
  178. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/predictor/__init__.py +0 -0
  179. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/predictor/api.py +0 -0
  180. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/predictor/models.py +0 -0
  181. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/predictor/prediction.py +0 -0
  182. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/predictor/predictor.py +0 -0
  183. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/predictor/schemas.py +0 -0
  184. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/predictor/validate.py +0 -0
  185. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/prompt/__init__.py +0 -0
  186. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/prompt/api.py +0 -0
  187. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/prompt/prompt.py +0 -0
  188. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/prompt/schemas.py +0 -0
  189. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/protein.py +0 -0
  190. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/scaffolds.py +0 -0
  191. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/svd/__init__.py +0 -0
  192. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/svd/api.py +0 -0
  193. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/svd/models.py +0 -0
  194. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/svd/schemas.py +0 -0
  195. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/svd/svd.py +0 -0
  196. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/umap/__init__.py +0 -0
  197. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/umap/api.py +0 -0
  198. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/umap/models.py +0 -0
  199. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/umap/schemas.py +0 -0
  200. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/umap/umap.py +0 -0
  201. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/utils/__init__.py +0 -0
  202. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/utils/cif.py +0 -0
  203. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/utils/numpy.py +0 -0
  204. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/utils/sequence.py +0 -0
  205. {openprotein_python-0.12.0 → openprotein_python-0.12.1}/openprotein/utils/uuid.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openprotein-python
3
- Version: 0.12.0
3
+ Version: 0.12.1
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
@@ -0,0 +1,9 @@
1
+ from . import align, assaydata, embedding, fold, predictor
2
+
3
+ __all__ = [
4
+ "align",
5
+ "assaydata",
6
+ "embedding",
7
+ "fold",
8
+ "predictor",
9
+ ]
@@ -0,0 +1,400 @@
1
+ import io
2
+ import random
3
+ from typing import BinaryIO, Iterator
4
+
5
+ import requests
6
+
7
+ import openprotein.config as config
8
+ from openprotein.base import APISession
9
+ from openprotein.csv import csv_stream
10
+ from openprotein.errors import APIError, InvalidParameterError, MissingParameterError
11
+ from openprotein.schemas import AlignType, Job, MSASamplingMethod
12
+
13
+
14
+ def get_align_job_inputs(
15
+ session: APISession,
16
+ job_id: str,
17
+ input_type: AlignType,
18
+ prompt_index: int | None = None,
19
+ ) -> requests.Response:
20
+ """
21
+ Get MSA and related data for an align job.
22
+
23
+ Returns either the original user seed (RAW), the generated MSA or the prompt.
24
+
25
+ Specify prompt_index to retreive the specific prompt for each replicate when input_type is PROMPT.
26
+
27
+ Parameters
28
+ ----------
29
+ session : APISession
30
+ The API session.
31
+ job_id : int or str
32
+ The job identifier.
33
+ input_type : PoetInputType
34
+ The type of MSA data.
35
+ prompt_index : Optional[int]
36
+ The replicate number for the prompt (input_type=-PROMPT only)
37
+
38
+ Returns
39
+ -------
40
+ requests.Response
41
+ The response from the server.
42
+ """
43
+ endpoint = "v1/align/inputs"
44
+
45
+ params = {"job_id": job_id, "msa_type": input_type}
46
+ if prompt_index is not None:
47
+ params["replicate"] = prompt_index
48
+
49
+ response = session.get(endpoint, params=params, stream=True)
50
+ return response
51
+
52
+
53
+ def get_input(
54
+ session: APISession,
55
+ job: Job,
56
+ input_type: AlignType,
57
+ prompt_index: int | None = None,
58
+ ) -> Iterator[list[str]]:
59
+ """
60
+ Get input data for a given job.
61
+
62
+ Parameters
63
+ ----------
64
+ session : APISession
65
+ The API session.
66
+ job : Job
67
+ The job for which to retrieve data.
68
+ input_type : PoetInputType
69
+ The type of MSA data.
70
+ prompt_index : Optional[int]
71
+ The replicate number for the prompt (input_type=-PROMPT only)
72
+
73
+ Returns
74
+ -------
75
+ csv.reader
76
+ A CSV reader for the response data.
77
+ """
78
+ job_id = job.job_id
79
+ response = get_align_job_inputs(
80
+ session=session, job_id=job_id, input_type=input_type, prompt_index=prompt_index
81
+ )
82
+ return csv_stream(response)
83
+
84
+
85
+ def get_seed(session: APISession, job: Job) -> Iterator[list[str]]:
86
+ """
87
+ Get the seed for a given MSA job.
88
+
89
+ Parameters
90
+ ----------
91
+ session : APISession
92
+ The API session.
93
+ job : Job
94
+ The job for which to retrieve the seed.
95
+
96
+ Returns
97
+ -------
98
+ Iterator[list[str]]
99
+ A CSV reader for the seed sequence.
100
+ """
101
+ return get_input(session=session, job=job, input_type=AlignType.INPUT)
102
+
103
+
104
+ def get_msa(session: APISession, job: Job) -> Iterator[list[str]]:
105
+ """
106
+ Get the generated MSA (Multiple Sequence Alignment) for a given job.
107
+
108
+ Parameters
109
+ ----------
110
+ session : APISession
111
+ The API session.
112
+ job : Job
113
+ The job for which to retrieve the MSA.
114
+
115
+ Returns
116
+ -------
117
+ Iterator[list[str]]
118
+ A CSV reader for the MSA data.
119
+ """
120
+ return get_input(session=session, job=job, input_type=AlignType.MSA)
121
+
122
+
123
+ def msa_post(
124
+ session: APISession,
125
+ msa_file: BinaryIO | None = None,
126
+ seed: str | bytes | None = None,
127
+ ) -> Job:
128
+ """
129
+ Create an MSA.
130
+
131
+ Either via a seed sequence (which will trigger MSA creation) or a ready-to-use MSA (via msa_file).
132
+
133
+ Note that seed and msa_file are mutually exclusive, and one or the other must be set.
134
+
135
+ Parameters
136
+ ----------
137
+ session : APISession
138
+
139
+ msa_file : BinaryIO, Optional
140
+ Ready-made MSA file. Defaults to None.
141
+ seed : str | bytes, optional
142
+ Seed sequence to trigger MSA job. Defaults to None.
143
+
144
+ Raises
145
+ ------
146
+ Exception
147
+ If msa_file and seed are both None.
148
+
149
+ Returns
150
+ -------
151
+ Job
152
+ Job details.
153
+ """
154
+ if (msa_file is None and seed is None) or (
155
+ msa_file is not None and seed is not None
156
+ ):
157
+ raise MissingParameterError("seed OR msa_file must be provided.")
158
+ endpoint = "v1/align/msa"
159
+
160
+ is_seed = False
161
+ if seed is not None:
162
+ seed = seed.encode() if isinstance(seed, str) else seed
163
+ msa_file = io.BytesIO(b"\n".join([b">seed", seed]))
164
+ is_seed = True
165
+
166
+ params = {"is_seed": is_seed}
167
+ files = {"msa_file": msa_file}
168
+
169
+ response = session.post(endpoint, files=files, params=params)
170
+ return Job.model_validate(response.json())
171
+
172
+
173
+ # TODO - document the `ep` and `op` parameters
174
+ def mafft_post(
175
+ session: APISession,
176
+ sequence_file: BinaryIO,
177
+ auto: bool = True,
178
+ ep: float | None = None,
179
+ op: float | None = None,
180
+ ) -> Job:
181
+ """
182
+ Align sequences using the `mafft` algorithm. Sequences can be provided as `fasta` or `csv` formats. If `csv`, the file must be headerless with either a single sequence column or name, sequence columns.
183
+
184
+ Set auto to True to automatically attempt the best params. Leave a parameter as None to use system defaults.
185
+
186
+ Parameters
187
+ ----------
188
+ session : APISession
189
+ sequence_file : BinaryIO
190
+ Sequences to align in fasta or csv format.
191
+ auto : bool = True, optional
192
+ Set to true to automatically set algorithm parameters.
193
+ ep : float, optional
194
+ mafft parameter
195
+ op : float, optional
196
+ mafft parameter
197
+
198
+ Returns
199
+ -------
200
+ Job
201
+ Job details.
202
+ """
203
+ endpoint = "v1/align/mafft"
204
+
205
+ files = {"file": sequence_file}
206
+ params: dict = {"auto": auto}
207
+ if ep is not None:
208
+ params["ep"] = ep
209
+ if op is not None:
210
+ params["op"] = op
211
+
212
+ response = session.post(endpoint, files=files, params=params)
213
+ return Job.model_validate(response.json())
214
+
215
+
216
+ # TODO - document the `clustersize` and `iterations` parameters
217
+ def clustalo_post(
218
+ session: APISession,
219
+ sequence_file: BinaryIO,
220
+ clustersize: int | None = None,
221
+ iterations: int | None = None,
222
+ ) -> Job:
223
+ """
224
+ Align sequences using the `clustal omega` algorithm. Sequences can be provided as `fasta` or `csv` formats. If `csv`, the file must be headerless with either a single sequence column or name, sequence columns.
225
+
226
+ Leave a parameter as None to use system defaults.
227
+
228
+ Parameters
229
+ ----------
230
+ session : APISession
231
+ sequence_file : BinaryIO
232
+ Sequences to align in fasta or csv format.
233
+ clustersize : int, optional
234
+ clustal omega parameter
235
+ iterations : int, optional
236
+ clustal omega parameter
237
+
238
+ Returns
239
+ -------
240
+ Job
241
+ Job details.
242
+ """
243
+ endpoint = "v1/align/clustalo"
244
+
245
+ files = {"file": sequence_file}
246
+ params = {}
247
+ if clustersize is not None:
248
+ params["clustersize"] = clustersize
249
+ if iterations is not None:
250
+ params["iterations"] = iterations
251
+
252
+ response = session.post(endpoint, files=files, params=params)
253
+ return Job.model_validate(response.json())
254
+
255
+
256
+ def abnumber_post(
257
+ session: APISession,
258
+ sequence_file: BinaryIO,
259
+ scheme: str = "imgt",
260
+ ) -> Job:
261
+ """
262
+ Align antibody using `AbNumber`. Sequences can be provided as `fasta` or `csv` formats. If `csv`, the file must be headerless with either a single sequence column or name, sequence columns.
263
+
264
+ The antibody numbering scheme can be specified from `imgt` (default), `chothia`, `kabat`, or `aho`.
265
+
266
+ Parameters
267
+ ----------
268
+ session : APISession
269
+ sequence_file : BinaryIO
270
+ Sequences to align in fasta or csv format.
271
+ scheme : str = 'imgt'
272
+ Antibody numbering scheme. Can be one of 'imgt', 'chothia', 'kabat', or 'aho'
273
+
274
+ Returns
275
+ -------
276
+ Job
277
+ Job details.
278
+ """
279
+ endpoint = "v1/align/abnumber"
280
+
281
+ valid_schemes = ["imgt", "chothia", "kabat", "aho"]
282
+ if scheme not in valid_schemes:
283
+ raise Exception(
284
+ f"Antibody numbering {scheme} not recognized. Must be one of {valid_schemes}."
285
+ )
286
+
287
+ files = {"file": sequence_file}
288
+ params = {"scheme": scheme}
289
+
290
+ response = session.post(endpoint, files=files, params=params)
291
+ return Job.model_validate(response.json())
292
+
293
+
294
+ # TODO - implement support for getting the antibody numbering from an `AbNumber` job
295
+ def antibody_schema_get(session: APISession, job_id: str):
296
+ """
297
+ Return the antibody numbering for an `AbNumber` job.
298
+ """
299
+ raise NotImplementedError()
300
+
301
+
302
+ def prompt_post(
303
+ session: APISession,
304
+ msa_id: str,
305
+ num_sequences: int | None = None,
306
+ num_residues: int | None = None,
307
+ method: MSASamplingMethod = MSASamplingMethod.NEIGHBORS_NONGAP_NORM_NO_LIMIT,
308
+ homology_level: float = 0.8,
309
+ max_similarity: float = 1.0,
310
+ min_similarity: float = 0.0,
311
+ always_include_seed_sequence: bool = False,
312
+ num_ensemble_prompts: int = 1,
313
+ random_seed: int | None = None,
314
+ ) -> Job:
315
+ """
316
+ Create a protein sequence prompt from a linked MSA (Multiple Sequence Alignment) for PoET Jobs.
317
+
318
+ The MSA is specified by msa_id and created in msa_post.
319
+
320
+ Parameters
321
+ ----------
322
+ session : APISession
323
+ An instance of APISession to manage interactions with the API.
324
+ msa_id : str
325
+ The ID of the Multiple Sequence Alignment to use for the prompt.
326
+ num_sequences : int, optional
327
+ Maximum number of sequences in the prompt. Must be <100.
328
+ num_residues : int, optional
329
+ Maximum number of residues (tokens) in the prompt. Must be less than 24577.
330
+ method : MSASamplingMethod, optional
331
+ Method to use for MSA sampling. Defaults to NEIGHBORS_NONGAP_NORM_NO_LIMIT.
332
+ homology_level : float, optional
333
+ Level of homology for sequences in the MSA (neighbors methods only). Must be between 0 and 1. Defaults to 0.8.
334
+ max_similarity : float, optional
335
+ Maximum similarity between sequences in the MSA and the seed. Must be between 0 and 1. Defaults to 1.0.
336
+ min_similarity : float, optional
337
+ Minimum similarity between sequences in the MSA and the seed. Must be between 0 and 1. Defaults to 0.0.
338
+ always_include_seed_sequence : bool, optional
339
+ Whether to always include the seed sequence in the MSA. Defaults to False.
340
+ num_ensemble_prompts : int, optional
341
+ Number of ensemble jobs to run. Defaults to 1.
342
+ random_seed : int, optional
343
+ Seed for random number generation. Defaults to a random number between 0 and 2**32-1.
344
+
345
+ Raises
346
+ ------
347
+ InvalidParameterError
348
+ If provided parameter values are not in the allowed range.
349
+ MissingParameterError
350
+ If both or none of 'num_sequences', 'num_residues' is specified.
351
+
352
+ Returns
353
+ -------
354
+ Job
355
+ """
356
+ endpoint = "v1/align/prompt"
357
+
358
+ if not (0 <= homology_level <= 1):
359
+ raise InvalidParameterError("The 'homology_level' must be between 0 and 1.")
360
+ if not (0 <= max_similarity <= 1):
361
+ raise InvalidParameterError("The 'max_similarity' must be between 0 and 1.")
362
+ if not (0 <= min_similarity <= 1):
363
+ raise InvalidParameterError("The 'min_similarity' must be between 0 and 1.")
364
+
365
+ if num_residues is None and num_sequences is None:
366
+ num_residues = 12288
367
+
368
+ if (num_sequences is None and num_residues is None) or (
369
+ num_sequences is not None and num_residues is not None
370
+ ):
371
+ raise MissingParameterError(
372
+ "Either 'num_sequences' or 'num_residues' must be set, but not both."
373
+ )
374
+
375
+ if num_sequences is not None and not (0 <= num_sequences < 100):
376
+ raise InvalidParameterError("The 'num_sequences' must be between 0 and 100.")
377
+
378
+ if num_residues is not None and not (0 <= num_residues < 24577):
379
+ raise InvalidParameterError("The 'num_residues' must be between 0 and 24577.")
380
+
381
+ if random_seed is None:
382
+ random_seed = random.randrange(2**32)
383
+
384
+ params = {
385
+ "msa_id": msa_id,
386
+ "msa_method": method,
387
+ "homology_level": homology_level,
388
+ "max_similarity": max_similarity,
389
+ "min_similarity": min_similarity,
390
+ "force_include_first": always_include_seed_sequence,
391
+ "replicates": num_ensemble_prompts,
392
+ "seed": random_seed,
393
+ }
394
+ if num_sequences is not None:
395
+ params["max_msa_sequences"] = num_sequences
396
+ if num_residues is not None:
397
+ params["max_msa_tokens"] = num_residues
398
+
399
+ response = session.post(endpoint, params=params)
400
+ return Job.model_validate(response.json())
@@ -0,0 +1,216 @@
1
+ from openprotein.base import APISession
2
+ from openprotein.errors import APIError
3
+ from openprotein.schemas import AssayDataPage, AssayMetadata
4
+ from pydantic import TypeAdapter
5
+
6
+
7
+ def list_models(session: APISession, assay_id: str) -> list:
8
+ """
9
+ List models assoicated with assay.
10
+
11
+ Parameters
12
+ ----------
13
+ session : APISession
14
+ Session object for API communication.
15
+ assay_id : str
16
+ assay ID
17
+
18
+ Returns
19
+ -------
20
+ List
21
+ List of models
22
+ """
23
+ endpoint = "v1/models"
24
+ response = session.get(endpoint, params={"assay_id": assay_id})
25
+ return response.json()
26
+
27
+
28
+ def assaydata_post(
29
+ session: APISession,
30
+ assay_file,
31
+ assay_name: str,
32
+ assay_description: str | None = "",
33
+ ) -> AssayMetadata:
34
+ """
35
+ Post assay data.
36
+
37
+ Parameters
38
+ ----------
39
+ session : APISession
40
+ Session object for API communication.
41
+ assay_file : str
42
+ Path to the assay data file.
43
+ assay_name : str
44
+ Name of the assay.
45
+ assay_description : str, optional
46
+ Description of the assay, by default ''.
47
+
48
+ Returns
49
+ -------
50
+ AssayMetadata
51
+ Metadata of the posted assay data.
52
+ """
53
+ endpoint = "v1/assaydata"
54
+
55
+ files = {"assay_data": assay_file}
56
+ data = {"assay_name": assay_name, "assay_description": assay_description}
57
+
58
+ response = session.post(endpoint, files=files, data=data)
59
+ if response.status_code == 200:
60
+ return TypeAdapter(AssayMetadata).validate_python(response.json())
61
+ else:
62
+ raise APIError(f"Unable to post assay data: {response.text}")
63
+
64
+
65
+ def assaydata_list(session: APISession) -> list[AssayMetadata]:
66
+ """
67
+ Get a list of all assay metadata.
68
+
69
+ Parameters
70
+ ----------
71
+ session : APISession
72
+ Session object for API communication.
73
+
74
+ Returns
75
+ -------
76
+ List[AssayMetadata]
77
+ List of all assay metadata.
78
+
79
+ Raises
80
+ ------
81
+ APIError
82
+ If an error occurs during the API request.
83
+ """
84
+ endpoint = "v1/assaydata"
85
+ response = session.get(endpoint)
86
+ if response.status_code == 200:
87
+ return TypeAdapter(list[AssayMetadata]).validate_python(response.json())
88
+ else:
89
+ raise APIError(f"Unable to list assay data: {response.text}")
90
+
91
+
92
+ def get_assay_metadata(session: APISession, assay_id: str) -> AssayMetadata:
93
+ """
94
+ Retrieve metadata for a specified assay.
95
+
96
+
97
+ Parameters
98
+ ----------
99
+ session : APISession
100
+ The current API session for communication with the server.
101
+ assay_id : str
102
+ The identifier of the assay for which metadata is to be retrieved.
103
+
104
+ Returns
105
+ -------
106
+ AssayMetadata
107
+ An AssayMetadata that contains the metadata for the specified assay.
108
+
109
+ Raises
110
+ ------
111
+ InvalidJob
112
+ If no assay metadata with the specified assay_id is found.
113
+ """
114
+
115
+ endpoint = "v1/assaydata/metadata"
116
+ response = session.get(endpoint, params={"assay_id": assay_id})
117
+ if response.status_code == 200:
118
+ data = TypeAdapter(AssayMetadata).validate_python(response.json())
119
+ else:
120
+ raise APIError(f"Unable to list assay data: {response.text}")
121
+ if data == []:
122
+ raise APIError(f"No assay with id={assay_id} found")
123
+ return data
124
+
125
+
126
+ def assaydata_put(
127
+ session: APISession,
128
+ assay_id: str,
129
+ assay_name: str | None = None,
130
+ assay_description: str | None = None,
131
+ ) -> AssayMetadata:
132
+ """
133
+ Update assay metadata.
134
+
135
+ Parameters
136
+ ----------
137
+ session : APISession
138
+ Session object for API communication.
139
+ assay_id : str
140
+ Id of the assay.
141
+ assay_name : str, optional
142
+ New name of the assay, by default None.
143
+ assay_description : str, optional
144
+ New description of the assay, by default None.
145
+
146
+ Returns
147
+ -------
148
+ AssayMetadata
149
+ Updated metadata of the assay.
150
+
151
+ Raises
152
+ ------
153
+ APIError
154
+ If an error occurs during the API request.
155
+ """
156
+ endpoint = f"v1/assaydata/{assay_id}"
157
+ data = {}
158
+ if assay_name is not None:
159
+ data["assay_name"] = assay_name
160
+ if assay_description is not None:
161
+ data["assay_description"] = assay_description
162
+
163
+ response = session.put(endpoint, data=data)
164
+ if response.status_code == 200:
165
+ return TypeAdapter(AssayMetadata).validate_python(response.json())
166
+ else:
167
+ raise APIError(f"Unable to update assay data: {response.text}")
168
+
169
+
170
+ def assaydata_page_get(
171
+ session: APISession,
172
+ assay_id: str,
173
+ measurement_name: str | None = None,
174
+ page_offset: int = 0,
175
+ page_size: int = 1000,
176
+ data_format: str = "wide",
177
+ ) -> AssayDataPage:
178
+ """
179
+ Get a page of assay data.
180
+
181
+ Parameters
182
+ ----------
183
+ session : APISession
184
+ Session object for API communication.
185
+ assay_id : str
186
+ Id of the assay.
187
+ measurement_name : str, optional
188
+ Name of the measurement, by default None.
189
+ page_offset : int, optional
190
+ Offset of the page, by default 0.
191
+ page_size : int, optional
192
+ Size of the page, by default 1000.
193
+ data_format : str, optional
194
+ data_format of the data, by default 'wide'.
195
+
196
+ Returns
197
+ -------
198
+ AssayDataPage
199
+ Page of assay data.
200
+
201
+ Raises
202
+ ------
203
+ APIError
204
+ If an error occurs during the API request.
205
+ """
206
+ endpoint = f"v1/assaydata/{assay_id}"
207
+
208
+ params = {"page_offset": page_offset, "page_size": page_size, "format": data_format}
209
+ if measurement_name is not None:
210
+ params["measurement_name"] = measurement_name
211
+
212
+ response = session.get(endpoint, params=params)
213
+ if response.status_code == 200:
214
+ return TypeAdapter(AssayDataPage).validate_python(response.json())
215
+ else:
216
+ raise APIError(f"Unable to get assay data page: {response.text}")
@@ -0,0 +1,5 @@
1
+ """Deprecated OpenProtein APIs."""
2
+
3
+ from . import design, predict, train
4
+
5
+ __all__ = ["design", "predict", "train"]