openprotein-python 0.8.12__tar.gz → 0.10.0__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 (211) hide show
  1. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/.gitignore +4 -0
  2. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/PKG-INFO +3 -2
  3. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/__init__.py +47 -3
  4. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/align/align.py +2 -2
  5. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/base.py +23 -32
  6. openprotein_python-0.10.0/openprotein/chains.py +12 -0
  7. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/common/model_metadata.py +4 -4
  8. openprotein_python-0.10.0/openprotein/common/reduction.py +22 -0
  9. openprotein_python-0.10.0/openprotein/common/residue_contants.py +75 -0
  10. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/future.py +65 -37
  11. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/poet2.py +46 -48
  12. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/__init__.py +1 -1
  13. openprotein_python-0.10.0/openprotein/fold/alphafold2.py +123 -0
  14. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/api.py +115 -23
  15. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/boltz.py +88 -215
  16. openprotein_python-0.10.0/openprotein/fold/common.py +117 -0
  17. openprotein_python-0.10.0/openprotein/fold/esmfold.py +79 -0
  18. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/fold.py +2 -2
  19. openprotein_python-0.10.0/openprotein/fold/future.py +680 -0
  20. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/minifold.py +14 -5
  21. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/models.py +2 -2
  22. openprotein_python-0.10.0/openprotein/fold/rosettafold3.py +108 -0
  23. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/schemas.py +2 -1
  24. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/jobs/futures.py +86 -36
  25. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/jobs/jobs.py +4 -0
  26. openprotein_python-0.10.0/openprotein/models/__init__.py +17 -0
  27. openprotein_python-0.10.0/openprotein/models/foundation/boltzgen.py +319 -0
  28. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/models/foundation/proteinmpnn.py +10 -26
  29. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/models/foundation/rfdiffusion.py +51 -23
  30. openprotein_python-0.10.0/openprotein/models/structure_generation.py +30 -0
  31. openprotein_python-0.10.0/openprotein/molecules/__init__.py +4 -0
  32. openprotein_python-0.10.0/openprotein/molecules/chains.py +222 -0
  33. openprotein_python-0.10.0/openprotein/molecules/complex.py +374 -0
  34. openprotein_python-0.10.0/openprotein/molecules/protein.py +1130 -0
  35. openprotein_python-0.10.0/openprotein/molecules/structure.py +223 -0
  36. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/prompt/api.py +34 -20
  37. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/prompt/models.py +30 -3
  38. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/prompt/prompt.py +30 -4
  39. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/prompt/schemas.py +1 -1
  40. openprotein_python-0.10.0/openprotein/protein.py +12 -0
  41. openprotein_python-0.10.0/openprotein/scaffolds.py +8 -0
  42. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/svd/models.py +9 -8
  43. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/umap/models.py +7 -5
  44. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/umap/umap.py +8 -1
  45. openprotein_python-0.10.0/openprotein/utils/__init__.py +0 -0
  46. openprotein_python-0.10.0/openprotein/utils/chain_id.py +62 -0
  47. openprotein_python-0.10.0/openprotein/utils/cif.py +125 -0
  48. openprotein_python-0.10.0/openprotein/utils/numpy.py +12 -0
  49. openprotein_python-0.10.0/openprotein/utils/sequence.py +193 -0
  50. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/pyproject.toml +7 -1
  51. openprotein_python-0.8.12/openprotein/api/__init__.py +0 -9
  52. openprotein_python-0.8.12/openprotein/api/align.py +0 -400
  53. openprotein_python-0.8.12/openprotein/api/assaydata.py +0 -216
  54. openprotein_python-0.8.12/openprotein/api/deprecated/__init__.py +0 -5
  55. openprotein_python-0.8.12/openprotein/api/deprecated/design.py +0 -86
  56. openprotein_python-0.8.12/openprotein/api/deprecated/poet.py +0 -308
  57. openprotein_python-0.8.12/openprotein/api/deprecated/predict.py +0 -276
  58. openprotein_python-0.8.12/openprotein/api/deprecated/train.py +0 -224
  59. openprotein_python-0.8.12/openprotein/api/design.py +0 -86
  60. openprotein_python-0.8.12/openprotein/api/designer.py +0 -267
  61. openprotein_python-0.8.12/openprotein/api/embedding.py +0 -446
  62. openprotein_python-0.8.12/openprotein/api/error.py +0 -5
  63. openprotein_python-0.8.12/openprotein/api/fold.py +0 -157
  64. openprotein_python-0.8.12/openprotein/api/job.py +0 -94
  65. openprotein_python-0.8.12/openprotein/api/predict.py +0 -273
  66. openprotein_python-0.8.12/openprotein/api/predictor.py +0 -326
  67. openprotein_python-0.8.12/openprotein/api/prompt.py +0 -464
  68. openprotein_python-0.8.12/openprotein/api/svd.py +0 -203
  69. openprotein_python-0.8.12/openprotein/api/train.py +0 -222
  70. openprotein_python-0.8.12/openprotein/api/umap.py +0 -257
  71. openprotein_python-0.8.12/openprotein/app/__init__.py +0 -19
  72. openprotein_python-0.8.12/openprotein/app/deprecated.py +0 -8
  73. openprotein_python-0.8.12/openprotein/app/models/__init__.py +0 -33
  74. openprotein_python-0.8.12/openprotein/app/models/align/__init__.py +0 -4
  75. openprotein_python-0.8.12/openprotein/app/models/align/base.py +0 -20
  76. openprotein_python-0.8.12/openprotein/app/models/align/msa.py +0 -134
  77. openprotein_python-0.8.12/openprotein/app/models/align/prompt.py +0 -78
  78. openprotein_python-0.8.12/openprotein/app/models/assaydata.py +0 -176
  79. openprotein_python-0.8.12/openprotein/app/models/deprecated/__init__.py +0 -10
  80. openprotein_python-0.8.12/openprotein/app/models/deprecated/design.py +0 -109
  81. openprotein_python-0.8.12/openprotein/app/models/deprecated/poet.py +0 -204
  82. openprotein_python-0.8.12/openprotein/app/models/deprecated/predict.py +0 -232
  83. openprotein_python-0.8.12/openprotein/app/models/deprecated/train.py +0 -307
  84. openprotein_python-0.8.12/openprotein/app/models/design.py +0 -105
  85. openprotein_python-0.8.12/openprotein/app/models/designer.py +0 -143
  86. openprotein_python-0.8.12/openprotein/app/models/embeddings/__init__.py +0 -12
  87. openprotein_python-0.8.12/openprotein/app/models/embeddings/base.py +0 -337
  88. openprotein_python-0.8.12/openprotein/app/models/embeddings/esm.py +0 -32
  89. openprotein_python-0.8.12/openprotein/app/models/embeddings/future.py +0 -135
  90. openprotein_python-0.8.12/openprotein/app/models/embeddings/openprotein.py +0 -21
  91. openprotein_python-0.8.12/openprotein/app/models/embeddings/poet.py +0 -366
  92. openprotein_python-0.8.12/openprotein/app/models/embeddings/poet2.py +0 -385
  93. openprotein_python-0.8.12/openprotein/app/models/embeddings/test.py +0 -38
  94. openprotein_python-0.8.12/openprotein/app/models/fold/__init__.py +0 -6
  95. openprotein_python-0.8.12/openprotein/app/models/fold/alphafold2.py +0 -54
  96. openprotein_python-0.8.12/openprotein/app/models/fold/base.py +0 -81
  97. openprotein_python-0.8.12/openprotein/app/models/fold/boltz.py +0 -57
  98. openprotein_python-0.8.12/openprotein/app/models/fold/esmfold.py +0 -38
  99. openprotein_python-0.8.12/openprotein/app/models/fold/future.py +0 -56
  100. openprotein_python-0.8.12/openprotein/app/models/futures.py +0 -473
  101. openprotein_python-0.8.12/openprotein/app/models/predict.py +0 -246
  102. openprotein_python-0.8.12/openprotein/app/models/predictor/__init__.py +0 -4
  103. openprotein_python-0.8.12/openprotein/app/models/predictor/predict.py +0 -78
  104. openprotein_python-0.8.12/openprotein/app/models/predictor/predictor.py +0 -362
  105. openprotein_python-0.8.12/openprotein/app/models/predictor/validate.py +0 -37
  106. openprotein_python-0.8.12/openprotein/app/models/prompt.py +0 -141
  107. openprotein_python-0.8.12/openprotein/app/models/svd.py +0 -260
  108. openprotein_python-0.8.12/openprotein/app/models/train.py +0 -303
  109. openprotein_python-0.8.12/openprotein/app/models/umap.py +0 -156
  110. openprotein_python-0.8.12/openprotein/app/services/__init__.py +0 -16
  111. openprotein_python-0.8.12/openprotein/app/services/align.py +0 -356
  112. openprotein_python-0.8.12/openprotein/app/services/assaydata.py +0 -119
  113. openprotein_python-0.8.12/openprotein/app/services/deprecated/__init__.py +0 -9
  114. openprotein_python-0.8.12/openprotein/app/services/deprecated/design.py +0 -79
  115. openprotein_python-0.8.12/openprotein/app/services/deprecated/predict.py +0 -152
  116. openprotein_python-0.8.12/openprotein/app/services/deprecated/train.py +0 -140
  117. openprotein_python-0.8.12/openprotein/app/services/design.py +0 -79
  118. openprotein_python-0.8.12/openprotein/app/services/designer.py +0 -107
  119. openprotein_python-0.8.12/openprotein/app/services/embeddings.py +0 -137
  120. openprotein_python-0.8.12/openprotein/app/services/fold.py +0 -89
  121. openprotein_python-0.8.12/openprotein/app/services/job.py +0 -61
  122. openprotein_python-0.8.12/openprotein/app/services/predict.py +0 -145
  123. openprotein_python-0.8.12/openprotein/app/services/predictor.py +0 -192
  124. openprotein_python-0.8.12/openprotein/app/services/prompt.py +0 -133
  125. openprotein_python-0.8.12/openprotein/app/services/svd.py +0 -102
  126. openprotein_python-0.8.12/openprotein/app/services/train.py +0 -135
  127. openprotein_python-0.8.12/openprotein/app/services/umap.py +0 -97
  128. openprotein_python-0.8.12/openprotein/chains.py +0 -88
  129. openprotein_python-0.8.12/openprotein/common/reduction.py +0 -14
  130. openprotein_python-0.8.12/openprotein/fold/alphafold2.py +0 -134
  131. openprotein_python-0.8.12/openprotein/fold/esmfold.py +0 -54
  132. openprotein_python-0.8.12/openprotein/fold/future.py +0 -591
  133. openprotein_python-0.8.12/openprotein/fold/rosettafold3.py +0 -148
  134. openprotein_python-0.8.12/openprotein/models/__init__.py +0 -6
  135. openprotein_python-0.8.12/openprotein/models/foundation/boltzgen.py +0 -208
  136. openprotein_python-0.8.12/openprotein/protein.py +0 -632
  137. openprotein_python-0.8.12/openprotein/schemas/__init__.py +0 -74
  138. openprotein_python-0.8.12/openprotein/schemas/align.py +0 -61
  139. openprotein_python-0.8.12/openprotein/schemas/assaydata.py +0 -27
  140. openprotein_python-0.8.12/openprotein/schemas/deprecated/__init__.py +0 -21
  141. openprotein_python-0.8.12/openprotein/schemas/deprecated/design.py +0 -173
  142. openprotein_python-0.8.12/openprotein/schemas/deprecated/poet.py +0 -70
  143. openprotein_python-0.8.12/openprotein/schemas/deprecated/predict.py +0 -82
  144. openprotein_python-0.8.12/openprotein/schemas/deprecated/train.py +0 -34
  145. openprotein_python-0.8.12/openprotein/schemas/design.py +0 -202
  146. openprotein_python-0.8.12/openprotein/schemas/designer.py +0 -38
  147. openprotein_python-0.8.12/openprotein/schemas/embeddings.py +0 -102
  148. openprotein_python-0.8.12/openprotein/schemas/features.py +0 -7
  149. openprotein_python-0.8.12/openprotein/schemas/fold.py +0 -10
  150. openprotein_python-0.8.12/openprotein/schemas/job.py +0 -134
  151. openprotein_python-0.8.12/openprotein/schemas/predict.py +0 -82
  152. openprotein_python-0.8.12/openprotein/schemas/predictor.py +0 -96
  153. openprotein_python-0.8.12/openprotein/schemas/prompt.py +0 -28
  154. openprotein_python-0.8.12/openprotein/schemas/svd.py +0 -31
  155. openprotein_python-0.8.12/openprotein/schemas/train.py +0 -34
  156. openprotein_python-0.8.12/openprotein/schemas/umap.py +0 -35
  157. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/LICENSE.txt +0 -0
  158. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/README.md +0 -0
  159. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/_version.py +0 -0
  160. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/align/__init__.py +0 -0
  161. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/align/api.py +0 -0
  162. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/align/future.py +0 -0
  163. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/align/msa.py +0 -0
  164. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/align/schemas.py +0 -0
  165. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/common/__init__.py +0 -0
  166. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/common/features.py +0 -0
  167. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/config.py +0 -0
  168. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/csv.py +0 -0
  169. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/data/__init__.py +0 -0
  170. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/data/api.py +0 -0
  171. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/data/assaydataset.py +0 -0
  172. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/data/data.py +0 -0
  173. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/data/schemas.py +0 -0
  174. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/design/__init__.py +0 -0
  175. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/design/api.py +0 -0
  176. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/design/design.py +0 -0
  177. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/design/future.py +0 -0
  178. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/design/schemas.py +0 -0
  179. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/__init__.py +0 -0
  180. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/api.py +0 -0
  181. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/embeddings.py +0 -0
  182. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/esm.py +0 -0
  183. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/models.py +0 -0
  184. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/openprotein.py +0 -0
  185. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/poet.py +0 -0
  186. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/embeddings/schemas.py +0 -0
  187. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/errors.py +0 -0
  188. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fasta.py +0 -0
  189. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/fold/complex.py +0 -0
  190. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/jobs/__init__.py +0 -0
  191. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/jobs/api.py +0 -0
  192. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/jobs/schemas.py +0 -0
  193. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/models/base.py +0 -0
  194. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/models/foundation/boltzgen_schema.py +0 -0
  195. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/models/models.py +0 -0
  196. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/predictor/__init__.py +0 -0
  197. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/predictor/api.py +0 -0
  198. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/predictor/models.py +0 -0
  199. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/predictor/prediction.py +0 -0
  200. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/predictor/predictor.py +0 -0
  201. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/predictor/schemas.py +0 -0
  202. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/predictor/validate.py +0 -0
  203. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/prompt/__init__.py +0 -0
  204. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/svd/__init__.py +0 -0
  205. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/svd/api.py +0 -0
  206. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/svd/schemas.py +0 -0
  207. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/svd/svd.py +0 -0
  208. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/umap/__init__.py +0 -0
  209. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/umap/api.py +0 -0
  210. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/umap/schemas.py +0 -0
  211. {openprotein_python-0.8.12 → openprotein_python-0.10.0}/openprotein/utils/uuid.py +0 -0
@@ -1,3 +1,4 @@
1
+ .vscode
1
2
 
2
3
  # SECRETS FILE
3
4
  secrets.config
@@ -363,3 +364,6 @@ __marimo__/
363
364
  # Streamlit
364
365
  .streamlit/secrets.toml
365
366
  /data/
367
+
368
+ .envrc
369
+ /.direnv/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openprotein-python
3
- Version: 0.8.12
3
+ Version: 0.10.0
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
@@ -8,11 +8,12 @@ License-File: LICENSE.txt
8
8
  Classifier: Development Status :: 4 - Beta
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Requires-Python: <3.13,>=3.10
11
- Requires-Dist: gemmi<0.8,>=0.7.0
11
+ Requires-Dist: gemmi<0.8,>=0.6.0
12
12
  Requires-Dist: numpy<3,>=1.9
13
13
  Requires-Dist: pandas<3,>=2.2.2
14
14
  Requires-Dist: pydantic<3,>=2.5
15
15
  Requires-Dist: requests<3,>=2.32.3
16
+ Requires-Dist: tomli<3,>=2.3.0
16
17
  Requires-Dist: tqdm<5,>=4.66.5
17
18
  Description-Content-Type: text/markdown
18
19
 
@@ -6,8 +6,8 @@ A pythonic interface for interacting with our cutting-edge protein engineering p
6
6
  isort:skip_file
7
7
  """
8
8
 
9
- from typing import TYPE_CHECKING
10
- import warnings
9
+ import os
10
+ from pathlib import Path
11
11
 
12
12
  from openprotein._version import __version__
13
13
  from openprotein.data import DataAPI
@@ -161,4 +161,48 @@ class OpenProtein(APISession):
161
161
  return self._models
162
162
 
163
163
 
164
- connect = OpenProtein
164
+ def connect(
165
+ username: str | None = None,
166
+ password: str | None = None,
167
+ backend: str | None = None,
168
+ timeout: int = 180,
169
+ ) -> OpenProtein:
170
+ """
171
+ Connect and create a :py:class:`OpenProtein` session.
172
+
173
+ Parameters
174
+ ----------
175
+ username : str, optional
176
+ The username of the user. If not provided, taken from the
177
+ environment variable ``OPENPROTEIN_USERNAME`` or a
178
+ configuration file at ``~/.openprotein/config.toml``.
179
+ password : str, optional
180
+ The password of the user. If not provided, taken from the
181
+ environment variable ``OPENPROTEIN_PASSWORD`` or a
182
+ configuration file at ``~/.openprotein/config.toml``.
183
+
184
+ Examples
185
+ --------
186
+ >>> session = openprotein.connect("username", "password")
187
+ """
188
+
189
+ CREDENTIALS_FILE_PATH = Path.home() / ".openprotein/config.toml"
190
+ if CREDENTIALS_FILE_PATH.exists():
191
+ import tomli
192
+
193
+ with open(CREDENTIALS_FILE_PATH, "rb") as f:
194
+ file_config = tomli.load(f)
195
+ else:
196
+ file_config = {}
197
+ USERNAME = os.getenv("OPENPROTEIN_USERNAME", str(file_config.get("username")))
198
+ PASSWORD = os.getenv("OPENPROTEIN_PASSWORD", str(file_config.get("password")))
199
+ BACKEND = os.getenv(
200
+ "OPENPROTEIN_API_BACKEND",
201
+ file_config.get("backend", "https://api.openprotein.ai/api/"),
202
+ )
203
+ return OpenProtein(
204
+ username=username or USERNAME,
205
+ password=password or PASSWORD,
206
+ backend=backend or BACKEND,
207
+ timeout=timeout,
208
+ )
@@ -7,7 +7,7 @@ from typing import BinaryIO, Iterator
7
7
  from openprotein.base import APISession
8
8
  from openprotein.errors import DeprecationError
9
9
  from openprotein.jobs import Job
10
- from openprotein.protein import Protein
10
+ from openprotein.molecules import Protein
11
11
 
12
12
  from . import api
13
13
  from .msa import MSAFuture
@@ -285,7 +285,7 @@ class AlignAPI:
285
285
  session=self.session, job=api.msa_post(self.session, msa_file=msa_file)
286
286
  )
287
287
 
288
- def create_msa(self, seed: bytes) -> MSAFuture:
288
+ def create_msa(self, seed: bytes | str) -> MSAFuture:
289
289
  """
290
290
  Construct an MSA via homology search with the seed sequence.
291
291
 
@@ -1,8 +1,6 @@
1
- import os
2
1
  import sys
3
2
  import warnings
4
- from collections.abc import Container, Mapping
5
- from typing import Union
3
+ from typing import Mapping, Sequence
6
4
  from urllib.parse import urljoin
7
5
 
8
6
  import requests
@@ -13,10 +11,6 @@ from requests.packages.urllib3.util.retry import Retry # type: ignore
13
11
  import openprotein.config as config
14
12
  from openprotein.errors import APIError, AuthError, HTTPError
15
13
 
16
- USERNAME = os.getenv("OPENPROTEIN_USERNAME")
17
- PASSWORD = os.getenv("OPENPROTEIN_PASSWORD")
18
- BACKEND = os.getenv("OPENPROTEIN_API_BACKEND", "https://api.openprotein.ai/api/")
19
-
20
14
 
21
15
  class BearerAuth(requests.auth.AuthBase):
22
16
  """
@@ -34,29 +28,18 @@ class BearerAuth(requests.auth.AuthBase):
34
28
  class APISession(requests.Session):
35
29
  """
36
30
  A class to handle API sessions. This class provides a connection session to the OpenProtein API.
37
-
38
- Parameters
39
- ----------
40
- username : str
41
- The username of the user.
42
- password : str
43
- The password of the user.
44
-
45
- Examples
46
- --------
47
- >>> session = APISession("username", "password")
48
31
  """
49
32
 
50
33
  def __init__(
51
34
  self,
52
- username: str | None = USERNAME,
53
- password: str | None = PASSWORD,
54
- backend: str = BACKEND,
35
+ username: str,
36
+ password: str,
37
+ backend: str,
55
38
  timeout: int = 180,
56
39
  ):
57
40
  if not username or not password:
58
41
  raise AuthError(
59
- "Expected username and password. Or use environment variables `OPENPROTEIN_USERNAME` and `OPENPROTEIN_PASSWORD`"
42
+ "Expected username and password. Or use environment variables `OPENPROTEIN_USERNAME` and `OPENPROTEIN_PASSWORD`. Or provide these variables (`username` and `password`) in ~/.openprotein/config.toml."
60
43
  )
61
44
  super().__init__()
62
45
  self.backend = backend
@@ -132,7 +115,7 @@ class APISession(requests.Session):
132
115
  response = super().request(method, full_url, *args, **kwargs)
133
116
 
134
117
  if (js := kwargs.get("json")) and js is not None:
135
- if total_size(js) > 1e6:
118
+ if _total_size(js) > 1e6:
136
119
  warnings.warn(
137
120
  "The requested payload is >1MB. There might be some delays or issues in processing. If the request fails, please try again with smaller sizes."
138
121
  )
@@ -153,7 +136,7 @@ class APISession(requests.Session):
153
136
  return response
154
137
 
155
138
 
156
- def total_size(o, seen=None):
139
+ def _total_size(o: Sequence | Mapping, seen=None):
157
140
  """Recursively finds size of objects including contents."""
158
141
  if seen is None:
159
142
  seen = set()
@@ -163,19 +146,27 @@ def total_size(o, seen=None):
163
146
  seen.add(obj_id)
164
147
  size = sys.getsizeof(o)
165
148
  if isinstance(o, dict):
166
- size += sum((total_size(k, seen) + total_size(v, seen)) for k, v in o.items())
149
+ size += sum((_total_size(k, seen) + _total_size(v, seen)) for k, v in o.items())
167
150
  elif isinstance(o, (list, tuple, set, frozenset)):
168
- size += sum(total_size(i, seen) for i in o)
151
+ size += sum(_total_size(i, seen) for i in o)
169
152
  return size
170
153
 
171
154
 
172
- class RestEndpoint:
173
- pass
174
-
175
-
176
155
  class TimeoutError(requests.exceptions.HTTPError):
177
- pass
156
+ """
157
+ An Exception raised due to timeout, possibly from overly large
158
+ requests.
159
+ """
178
160
 
179
161
 
180
162
  class CloudFrontError(requests.exceptions.HTTPError):
181
- pass
163
+ """
164
+ An Exception raised due to CloudFront.
165
+
166
+ This is usually due to the strict timeout from CloudFront.
167
+ AWS CloudFront limits responses to return within 2 minutes.
168
+ This can be a bit prohibitive for our system that tends to
169
+ deal with large data. It is usually safe to just ignore/retry upon
170
+ hitting this error. Our system will scale up and still handle
171
+ the job.
172
+ """
@@ -0,0 +1,12 @@
1
+ import warnings
2
+
3
+ warnings.warn(
4
+ "openprotein.chains is deprecated and will be removed in v0.11. "
5
+ "Use `from openprotein.molecules import DNA, RNA, Ligand` instead.",
6
+ FutureWarning,
7
+ stacklevel=2,
8
+ )
9
+
10
+ from openprotein.molecules import DNA, RNA, Ligand
11
+
12
+ __all__ = ["DNA", "RNA", "Ligand"]
@@ -26,8 +26,8 @@ class ModelMetadata(BaseModel):
26
26
  id: str = Field(..., alias="model_id")
27
27
  description: ModelDescription
28
28
  max_sequence_length: int | None = None
29
- dimension: int
30
- output_types: list[str]
31
- input_tokens: list[str] | None
29
+ dimension: int | None = None
30
+ output_types: list[str] | None = None
31
+ input_tokens: list[str] | None = None
32
32
  output_tokens: list[str] | None = None
33
- token_descriptions: list[list[TokenInfo]]
33
+ token_descriptions: list[list[TokenInfo]] | None = None
@@ -0,0 +1,22 @@
1
+ """Reduction types used in OpenProtein."""
2
+
3
+ from enum import Enum
4
+ from typing import Literal
5
+
6
+
7
+ class ReductionType(str, Enum):
8
+ """
9
+ ReductionType is an enumeration of the possible reduction types available.
10
+
11
+ Attributes:
12
+ MEAN : Mean reduction takes the mean of the embeddings across the sequence length dimension.
13
+ SUM : Sum reduction takes the sum of the embeddings across the sequence length dimension.
14
+ """
15
+
16
+ MEAN = "MEAN"
17
+ SUM = "SUM"
18
+
19
+
20
+ # NOTE: only works with python 3.12+
21
+ # Reduction = Literal[*tuple([r.value for r in ReductionType])]
22
+ Reduction = Literal["MEAN", "SUM"]
@@ -0,0 +1,75 @@
1
+ # fmt: off
2
+ residue_atoms = {
3
+ "ALA": ["C", "CA", "CB", "N", "O"],
4
+ "ARG": ["C", "CA", "CB", "CG", "CD", "CZ", "N", "NE", "O", "NH1", "NH2"],
5
+ "ASP": ["C", "CA", "CB", "CG", "N", "O", "OD1", "OD2"],
6
+ "ASN": ["C", "CA", "CB", "CG", "N", "ND2", "O", "OD1"],
7
+ "CYS": ["C", "CA", "CB", "N", "O", "SG"],
8
+ "GLU": ["C", "CA", "CB", "CG", "CD", "N", "O", "OE1", "OE2"],
9
+ "GLN": ["C", "CA", "CB", "CG", "CD", "N", "NE2", "O", "OE1"],
10
+ "GLY": ["C", "CA", "N", "O"],
11
+ "HIS": ["C", "CA", "CB", "CG", "CD2", "CE1", "N", "ND1", "NE2", "O"],
12
+ "ILE": ["C", "CA", "CB", "CG1", "CG2", "CD1", "N", "O"],
13
+ "LEU": ["C", "CA", "CB", "CG", "CD1", "CD2", "N", "O"],
14
+ "LYS": ["C", "CA", "CB", "CG", "CD", "CE", "N", "NZ", "O"],
15
+ "MET": ["C", "CA", "CB", "CG", "CE", "N", "O", "SD"],
16
+ "PHE": ["C", "CA", "CB", "CG", "CD1", "CD2", "CE1", "CE2", "CZ", "N", "O"],
17
+ "PRO": ["C", "CA", "CB", "CG", "CD", "N", "O"],
18
+ "SER": ["C", "CA", "CB", "N", "O", "OG"],
19
+ "THR": ["C", "CA", "CB", "CG2", "N", "O", "OG1"],
20
+ "TRP": [
21
+ "C",
22
+ "CA",
23
+ "CB",
24
+ "CG",
25
+ "CD1",
26
+ "CD2",
27
+ "CE2",
28
+ "CE3",
29
+ "CZ2",
30
+ "CZ3",
31
+ "CH2",
32
+ "N",
33
+ "NE1",
34
+ "O",
35
+ ],
36
+ "TYR": [
37
+ "C",
38
+ "CA",
39
+ "CB",
40
+ "CG",
41
+ "CD1",
42
+ "CD2",
43
+ "CE1",
44
+ "CE2",
45
+ "CZ",
46
+ "N",
47
+ "O",
48
+ "OH",
49
+ ],
50
+ "VAL": ["C", "CA", "CB", "CG1", "CG2", "N", "O"],
51
+ }
52
+
53
+ restype_1to3 = {
54
+ "A": "ALA",
55
+ "R": "ARG",
56
+ "N": "ASN",
57
+ "D": "ASP",
58
+ "C": "CYS",
59
+ "Q": "GLN",
60
+ "E": "GLU",
61
+ "G": "GLY",
62
+ "H": "HIS",
63
+ "I": "ILE",
64
+ "L": "LEU",
65
+ "K": "LYS",
66
+ "M": "MET",
67
+ "F": "PHE",
68
+ "P": "PRO",
69
+ "S": "SER",
70
+ "T": "THR",
71
+ "W": "TRP",
72
+ "Y": "TYR",
73
+ "V": "VAL",
74
+ }
75
+ # fmt: on
@@ -1,7 +1,7 @@
1
1
  """Future for embeddings-related jobs."""
2
2
 
3
3
  from collections import namedtuple
4
- from typing import Generator
4
+ from typing import Any, Generator, Iterator, TypeVar, Union
5
5
 
6
6
  import numpy as np
7
7
 
@@ -25,7 +25,7 @@ from .schemas import (
25
25
  )
26
26
 
27
27
 
28
- class EmbeddingsResultFuture(MappedFuture, Future):
28
+ class EmbeddingsResultFuture(MappedFuture[bytes, np.ndarray]):
29
29
  """Future for manipulating results for embeddings-related requests."""
30
30
 
31
31
  job: EmbeddingsJob | AttnJob | LogitsJob
@@ -45,14 +45,17 @@ class EmbeddingsResultFuture(MappedFuture, Future):
45
45
  else sequences
46
46
  )
47
47
 
48
- def stream(self):
49
- return api.request_get_embeddings_stream(session=self.session, job_id=self.id)
50
-
51
- def get(self, verbose=False) -> list[np.ndarray]:
52
- return super().get(verbose=verbose)
48
+ def stream_sync(self):
49
+ """
50
+ Stream the embeddings results synchronously using the streaming endpoint.
51
+ """
52
+ for i, array in enumerate(
53
+ api.request_get_embeddings_stream(session=self.session, job_id=self.id)
54
+ ):
55
+ yield self.sequences[i], array
53
56
 
54
57
  @property
55
- def sequences(self) -> list[bytes] | list[str]:
58
+ def sequences(self):
56
59
  if self._sequences is None:
57
60
  self._sequences = api.get_request_sequences(
58
61
  session=self.session, job_id=self.job.job_id, job_type=self.job.job_type
@@ -74,12 +77,12 @@ class EmbeddingsResultFuture(MappedFuture, Future):
74
77
  """
75
78
  return self.sequences
76
79
 
77
- def get_item(self, sequence: bytes) -> np.ndarray:
80
+ def get_item(self, sequence: str | bytes) -> np.ndarray:
78
81
  """
79
82
  Get embedding results for specified sequence.
80
83
 
81
84
  Args:
82
- sequence (bytes): sequence to fetch results for
85
+ sequence (str | bytes): sequence to fetch results for
83
86
 
84
87
  Returns:
85
88
  np.ndarray: embeddings
@@ -93,10 +96,13 @@ class EmbeddingsResultFuture(MappedFuture, Future):
93
96
  return api.result_decode(data)
94
97
 
95
98
 
96
- class EmbeddingsScoreFuture(StreamingFuture, Future):
97
- """Future for manipulating results for embeddings score-related requests."""
99
+ Score = namedtuple("Score", ["name", "sequence", "score"])
100
+ SingleSiteScore = namedtuple("SingleSiteScore", ["mut_code", "score"])
101
+ S = TypeVar("S", bound=Union[Score, SingleSiteScore])
98
102
 
99
- job: ScoreJob | ScoreIndelJob | ScoreSingleSiteJob
103
+
104
+ class BaseScoreFuture(StreamingFuture[S]):
105
+ """Future for manipulating results for embeddings score-related requests."""
100
106
 
101
107
  def __init__(
102
108
  self,
@@ -105,45 +111,67 @@ class EmbeddingsScoreFuture(StreamingFuture, Future):
105
111
  sequences: list[bytes] | list[str] | None = None,
106
112
  ):
107
113
  super().__init__(session=session, job=job)
108
- self._sequences = sequences
114
+ # ensure all list[bytes]
115
+ self._sequences = (
116
+ [seq.encode() if isinstance(seq, str) else seq for seq in sequences]
117
+ if sequences is not None
118
+ else sequences
119
+ )
109
120
 
110
121
  @property
111
- def sequences(self) -> list[bytes] | list[str]:
122
+ def sequences(self) -> list[bytes]:
112
123
  if self._sequences is None:
113
124
  self._sequences = api.get_request_sequences(self.session, self.job.job_id)
114
125
  return self._sequences
115
126
 
116
- def stream(self) -> Generator:
117
- if (
118
- self.job_type == JobType.poet_generate
119
- or self.job_type == JobType.embeddings_generate
120
- ):
121
- stream = api.request_get_generate_result(
122
- session=self.session, job_id=self.id
123
- )
124
- else:
125
- stream = api.request_get_score_result(session=self.session, job_id=self.id)
126
- # mut_code, ... for ssp
127
- # name, sequence, ... for score
128
- header = next(stream)
129
- score_start_index = 0
130
- for i, col_name in enumerate(header):
131
- if col_name.startswith("score"):
132
- score_start_index = i
133
- break
134
- Score = namedtuple("Score", header[:score_start_index] + ["score"])
127
+
128
+ class EmbeddingsScoreFuture(BaseScoreFuture[Score]):
129
+ """Future for manipulating results for embeddings score-related requests."""
130
+
131
+ job: ScoreJob | ScoreIndelJob
132
+
133
+ def stream(self) -> Iterator[Score]:
134
+ stream = api.request_get_score_result(session=self.session, job_id=self.id)
135
+ # name, sequence, ...
136
+ next(stream) # ignore header
137
+ for line in stream:
138
+ # combine scores into numpy array
139
+ scores = np.array([float(s) for s in line[2:]])
140
+ output = Score(name=line[0], sequence=line[1], score=scores)
141
+ yield output
142
+
143
+
144
+ class EmbeddingsScoreSingleSiteFuture(BaseScoreFuture[SingleSiteScore]):
145
+ """Future for manipulating results for embeddings score-related requests."""
146
+
147
+ job: ScoreSingleSiteJob
148
+
149
+ def stream(self) -> Iterator[SingleSiteScore]:
150
+ stream = api.request_get_score_result(session=self.session, job_id=self.id)
151
+ # name, sequence, ...
152
+ next(stream) # ignore header
135
153
  for line in stream:
136
154
  # combine scores into numpy array
137
- scores = np.array([float(s) for s in line[score_start_index:]])
138
- output = Score(*line[:score_start_index], scores)
155
+ scores = np.array([float(s) for s in line[1:]])
156
+ output = SingleSiteScore(mut_code=line[0], score=scores)
139
157
  yield output
140
158
 
141
159
 
142
- class EmbeddingsGenerateFuture(EmbeddingsScoreFuture, StreamingFuture, Future):
160
+ class EmbeddingsGenerateFuture(BaseScoreFuture[Score]):
143
161
  """Future for manipulating results for embeddings generate-related requests."""
144
162
 
145
163
  job: GenerateJob
146
164
 
165
+ def stream(self) -> Iterator[Score]:
166
+ stream = api.request_get_generate_result(session=self.session, job_id=self.id)
167
+ # name, sequence, ...
168
+ next(stream) # ignore header
169
+ for line in stream:
170
+ # combine scores into numpy array
171
+ scores = np.array([float(s) for s in line[2:]])
172
+ output = Score(name=line[0], sequence=line[1], score=scores)
173
+ yield output
174
+
147
175
  @property
148
176
  def sequences(self):
149
177
  raise Exception("generate job does not support listing sequences")