dyno-phi 0.2.4__tar.gz → 0.3.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 (218) hide show
  1. dyno_phi-0.3.1/.gitignore +125 -0
  2. dyno_phi-0.3.1/CHANGELOG.md +61 -0
  3. dyno_phi-0.3.1/PKG-INFO +209 -0
  4. dyno_phi-0.3.1/README.md +178 -0
  5. dyno_phi-0.3.1/examples/README.md +25 -0
  6. dyno_phi-0.3.1/examples/async_concurrent.py +31 -0
  7. dyno_phi-0.3.1/examples/compose_dag.py +22 -0
  8. dyno_phi-0.3.1/examples/download_results.py +21 -0
  9. dyno_phi-0.3.1/examples/pipelines/fold_and_analyze.yaml +10 -0
  10. dyno_phi-0.3.1/examples/pipelines/mpnn_esmfold_alphafold.yaml +15 -0
  11. dyno_phi-0.3.1/examples/quickstart/README.md +10 -0
  12. dyno_phi-0.3.1/examples/quickstart/trp_cage.fasta +2 -0
  13. dyno_phi-0.3.1/examples/run_pipeline.py +23 -0
  14. dyno_phi-0.3.1/examples/submit_fold.py +17 -0
  15. dyno_phi-0.3.1/pyproject.toml +95 -0
  16. dyno_phi-0.3.1/src/phi/__init__.py +41 -0
  17. dyno_phi-0.3.1/src/phi/_schema_validation.py +169 -0
  18. dyno_phi-0.3.1/src/phi/_transport.py +215 -0
  19. dyno_phi-0.3.1/src/phi/_version.py +1 -0
  20. dyno_phi-0.3.1/src/phi/async_client.py +121 -0
  21. dyno_phi-0.3.1/src/phi/cli/__init__.py +5 -0
  22. dyno_phi-0.3.1/src/phi/cli/__main__.py +4 -0
  23. dyno_phi-0.3.1/src/phi/cli/commands/__init__.py +0 -0
  24. dyno_phi-0.3.1/src/phi/cli/commands/artifacts.py +104 -0
  25. dyno_phi-0.3.1/src/phi/cli/commands/auth.py +166 -0
  26. dyno_phi-0.3.1/src/phi/cli/commands/datasets.py +244 -0
  27. dyno_phi-0.3.1/src/phi/cli/commands/documents.py +299 -0
  28. dyno_phi-0.3.1/src/phi/cli/commands/export.py +108 -0
  29. dyno_phi-0.3.1/src/phi/cli/commands/jobs.py +218 -0
  30. dyno_phi-0.3.1/src/phi/cli/commands/logs.py +186 -0
  31. dyno_phi-0.3.1/src/phi/cli/commands/models.py +115 -0
  32. dyno_phi-0.3.1/src/phi/cli/commands/pipeline.py +115 -0
  33. dyno_phi-0.3.1/src/phi/cli/commands/projects.py +106 -0
  34. dyno_phi-0.3.1/src/phi/cli/commands/quickstart.py +118 -0
  35. dyno_phi-0.3.1/src/phi/cli/commands/quota.py +61 -0
  36. dyno_phi-0.3.1/src/phi/cli/commands/runs.py +308 -0
  37. dyno_phi-0.3.1/src/phi/cli/commands/use.py +54 -0
  38. dyno_phi-0.3.1/src/phi/cli/completion.py +43 -0
  39. dyno_phi-0.3.1/src/phi/cli/document_sync.py +256 -0
  40. dyno_phi-0.3.1/src/phi/cli/errors.py +63 -0
  41. dyno_phi-0.3.1/src/phi/cli/main.py +108 -0
  42. dyno_phi-0.3.1/src/phi/cli/params.py +190 -0
  43. dyno_phi-0.3.1/src/phi/cli/render.py +76 -0
  44. dyno_phi-0.3.1/src/phi/cli/state.py +141 -0
  45. dyno_phi-0.3.1/src/phi/client.py +121 -0
  46. dyno_phi-0.3.1/src/phi/config.py +100 -0
  47. dyno_phi-0.3.1/src/phi/errors.py +133 -0
  48. dyno_phi-0.3.1/src/phi/files.py +265 -0
  49. dyno_phi-0.3.1/src/phi/graph.py +455 -0
  50. dyno_phi-0.3.1/src/phi/models/__init__.py +7 -0
  51. dyno_phi-0.3.1/src/phi/models/_generated.py +65 -0
  52. dyno_phi-0.3.1/src/phi/models/artifacts.py +23 -0
  53. dyno_phi-0.3.1/src/phi/models/common.py +7 -0
  54. dyno_phi-0.3.1/src/phi/models/datasets.py +90 -0
  55. dyno_phi-0.3.1/src/phi/models/designs.py +48 -0
  56. dyno_phi-0.3.1/src/phi/models/documents.py +58 -0
  57. dyno_phi-0.3.1/src/phi/models/imports.py +29 -0
  58. dyno_phi-0.3.1/src/phi/models/job_types.py +22 -0
  59. dyno_phi-0.3.1/src/phi/models/jobs.py +105 -0
  60. dyno_phi-0.3.1/src/phi/models/logs.py +18 -0
  61. dyno_phi-0.3.1/src/phi/models/projects.py +29 -0
  62. dyno_phi-0.3.1/src/phi/models/quota.py +25 -0
  63. dyno_phi-0.3.1/src/phi/models/run_admin.py +14 -0
  64. dyno_phi-0.3.1/src/phi/models/runs.py +148 -0
  65. dyno_phi-0.3.1/src/phi/models/sequences.py +5 -0
  66. dyno_phi-0.3.1/src/phi/models/tool_configs.py +14 -0
  67. dyno_phi-0.3.1/src/phi/profiles.py +83 -0
  68. dyno_phi-0.3.1/src/phi/py.typed +0 -0
  69. dyno_phi-0.3.1/src/phi/resources/__init__.py +106 -0
  70. dyno_phi-0.3.1/src/phi/resources/artifacts.py +143 -0
  71. dyno_phi-0.3.1/src/phi/resources/datasets.py +427 -0
  72. dyno_phi-0.3.1/src/phi/resources/designs.py +181 -0
  73. dyno_phi-0.3.1/src/phi/resources/documents.py +640 -0
  74. dyno_phi-0.3.1/src/phi/resources/files.py +37 -0
  75. dyno_phi-0.3.1/src/phi/resources/imports.py +27 -0
  76. dyno_phi-0.3.1/src/phi/resources/job_types.py +118 -0
  77. dyno_phi-0.3.1/src/phi/resources/jobs.py +440 -0
  78. dyno_phi-0.3.1/src/phi/resources/logs.py +140 -0
  79. dyno_phi-0.3.1/src/phi/resources/projects.py +118 -0
  80. dyno_phi-0.3.1/src/phi/resources/quota.py +65 -0
  81. dyno_phi-0.3.1/src/phi/resources/run_admin.py +51 -0
  82. dyno_phi-0.3.1/src/phi/resources/runs.py +288 -0
  83. dyno_phi-0.3.1/src/phi/resources/sequences.py +415 -0
  84. dyno_phi-0.3.1/src/phi/resources/tool_configs.py +23 -0
  85. dyno_phi-0.3.1/src/phi/resources/uploads.py +28 -0
  86. dyno_phi-0.3.1/src/phi/schema_cache.py +66 -0
  87. dyno_phi-0.3.1/src/phi/waiters.py +249 -0
  88. dyno_phi-0.3.1/tests/__init__.py +0 -0
  89. dyno_phi-0.3.1/tests/cli/__init__.py +0 -0
  90. dyno_phi-0.3.1/tests/cli/conftest.py +20 -0
  91. dyno_phi-0.3.1/tests/cli/test_artifacts.py +201 -0
  92. dyno_phi-0.3.1/tests/cli/test_auth.py +268 -0
  93. dyno_phi-0.3.1/tests/cli/test_cli_scaffold.py +326 -0
  94. dyno_phi-0.3.1/tests/cli/test_completion.py +122 -0
  95. dyno_phi-0.3.1/tests/cli/test_datasets.py +263 -0
  96. dyno_phi-0.3.1/tests/cli/test_document_sync.py +277 -0
  97. dyno_phi-0.3.1/tests/cli/test_documents.py +278 -0
  98. dyno_phi-0.3.1/tests/cli/test_export.py +162 -0
  99. dyno_phi-0.3.1/tests/cli/test_jobs.py +338 -0
  100. dyno_phi-0.3.1/tests/cli/test_json_contract.py +408 -0
  101. dyno_phi-0.3.1/tests/cli/test_logs.py +271 -0
  102. dyno_phi-0.3.1/tests/cli/test_models_cmd.py +84 -0
  103. dyno_phi-0.3.1/tests/cli/test_params.py +326 -0
  104. dyno_phi-0.3.1/tests/cli/test_pipeline.py +251 -0
  105. dyno_phi-0.3.1/tests/cli/test_projects.py +160 -0
  106. dyno_phi-0.3.1/tests/cli/test_quickstart.py +198 -0
  107. dyno_phi-0.3.1/tests/cli/test_quota.py +93 -0
  108. dyno_phi-0.3.1/tests/cli/test_runs.py +391 -0
  109. dyno_phi-0.3.1/tests/conftest.py +32 -0
  110. dyno_phi-0.3.1/tests/live/__init__.py +0 -0
  111. dyno_phi-0.3.1/tests/live/conftest.py +260 -0
  112. dyno_phi-0.3.1/tests/live/test_live_artifacts_logs.py +161 -0
  113. dyno_phi-0.3.1/tests/live/test_live_auth_discovery.py +126 -0
  114. dyno_phi-0.3.1/tests/live/test_live_datasets_export.py +150 -0
  115. dyno_phi-0.3.1/tests/live/test_live_errors.py +111 -0
  116. dyno_phi-0.3.1/tests/live/test_live_jobs.py +162 -0
  117. dyno_phi-0.3.1/tests/live/test_live_pipelines.py +177 -0
  118. dyno_phi-0.3.1/tests/live/test_live_quickstart_sdk.py +130 -0
  119. dyno_phi-0.3.1/tests/test_artifacts.py +81 -0
  120. dyno_phi-0.3.1/tests/test_config.py +142 -0
  121. dyno_phi-0.3.1/tests/test_datasets.py +400 -0
  122. dyno_phi-0.3.1/tests/test_designs.py +178 -0
  123. dyno_phi-0.3.1/tests/test_docs_examples.py +154 -0
  124. dyno_phi-0.3.1/tests/test_documents.py +290 -0
  125. dyno_phi-0.3.1/tests/test_errors.py +103 -0
  126. dyno_phi-0.3.1/tests/test_files.py +340 -0
  127. dyno_phi-0.3.1/tests/test_graph.py +413 -0
  128. dyno_phi-0.3.1/tests/test_imports.py +69 -0
  129. dyno_phi-0.3.1/tests/test_job_types.py +157 -0
  130. dyno_phi-0.3.1/tests/test_jobs.py +455 -0
  131. dyno_phi-0.3.1/tests/test_logs.py +144 -0
  132. dyno_phi-0.3.1/tests/test_packaging.py +152 -0
  133. dyno_phi-0.3.1/tests/test_parity.py +46 -0
  134. dyno_phi-0.3.1/tests/test_projects.py +201 -0
  135. dyno_phi-0.3.1/tests/test_quota.py +105 -0
  136. dyno_phi-0.3.1/tests/test_run_admin.py +74 -0
  137. dyno_phi-0.3.1/tests/test_runs.py +432 -0
  138. dyno_phi-0.3.1/tests/test_schema_validation.py +98 -0
  139. dyno_phi-0.3.1/tests/test_sequences.py +383 -0
  140. dyno_phi-0.3.1/tests/test_tool_configs.py +42 -0
  141. dyno_phi-0.3.1/tests/test_transport.py +351 -0
  142. dyno_phi-0.3.1/tests/test_uploads.py +56 -0
  143. dyno_phi-0.3.1/tests/test_waiters.py +318 -0
  144. dyno_phi-0.2.4/.claude/settings.json +0 -10
  145. dyno_phi-0.2.4/.claude/skills/phi/SKILL.md +0 -304
  146. dyno_phi-0.2.4/.claude-plugin/marketplace.json +0 -26
  147. dyno_phi-0.2.4/.github/workflows/ci.yml +0 -34
  148. dyno_phi-0.2.4/.github/workflows/publish.yml +0 -75
  149. dyno_phi-0.2.4/.gitignore +0 -49
  150. dyno_phi-0.2.4/.pre-commit-config.yaml +0 -27
  151. dyno_phi-0.2.4/CHANGELOG.md +0 -84
  152. dyno_phi-0.2.4/CLI-REFERENCE.md +0 -792
  153. dyno_phi-0.2.4/LICENSE +0 -21
  154. dyno_phi-0.2.4/PKG-INFO +0 -277
  155. dyno_phi-0.2.4/README.md +0 -236
  156. dyno_phi-0.2.4/biomodals/TEMPLATE_NEW_BIOMODAL.py +0 -391
  157. dyno_phi-0.2.4/biomodals/__init__.py +0 -13
  158. dyno_phi-0.2.4/biomodals/base.py +0 -400
  159. dyno_phi-0.2.4/biomodals/modal_af2rank.py +0 -639
  160. dyno_phi-0.2.4/biomodals/modal_align_structures.py +0 -676
  161. dyno_phi-0.2.4/biomodals/modal_alphafold.py +0 -683
  162. dyno_phi-0.2.4/biomodals/modal_bindcraft.py +0 -1191
  163. dyno_phi-0.2.4/biomodals/modal_boltz.py +0 -484
  164. dyno_phi-0.2.4/biomodals/modal_boltzgen.py +0 -862
  165. dyno_phi-0.2.4/biomodals/modal_chai1.py +0 -361
  166. dyno_phi-0.2.4/biomodals/modal_esm2_predict_masked.py +0 -289
  167. dyno_phi-0.2.4/biomodals/modal_esmfold.py +0 -663
  168. dyno_phi-0.2.4/biomodals/modal_ligandmpnn.py +0 -362
  169. dyno_phi-0.2.4/biomodals/modal_proteinmpnn.py +0 -783
  170. dyno_phi-0.2.4/biomodals/modal_rf3.py +0 -673
  171. dyno_phi-0.2.4/biomodals/modal_rfdiffusion3.py +0 -1919
  172. dyno_phi-0.2.4/biomodals/modal_rso.py +0 -432
  173. dyno_phi-0.2.4/biomodals/modal_tm_score.py +0 -417
  174. dyno_phi-0.2.4/biomodals/utils/__init__.py +0 -1
  175. dyno_phi-0.2.4/biomodals/utils/extract_chain_as_mol2.py +0 -73
  176. dyno_phi-0.2.4/biomodals/utils/extract_ligands.py +0 -240
  177. dyno_phi-0.2.4/examples/README.md +0 -65
  178. dyno_phi-0.2.4/examples/binders/pdl1/binder_009.pdb +0 -1343
  179. dyno_phi-0.2.4/examples/binders/pdl1/binder_047.pdb +0 -1309
  180. dyno_phi-0.2.4/examples/binders/pdl1/binder_106.pdb +0 -1532
  181. dyno_phi-0.2.4/examples/binders/pdl1/binder_188.pdb +0 -1194
  182. dyno_phi-0.2.4/examples/binders/pdl1/binder_246.pdb +0 -1438
  183. dyno_phi-0.2.4/examples/fixtures/pdl1/5O45.pdb +0 -5146
  184. dyno_phi-0.2.4/examples/fixtures/pdl1/pdl1_pdb_19_132.pdb +0 -3094
  185. dyno_phi-0.2.4/phi-plugin/.claude-plugin/plugin.json +0 -11
  186. dyno_phi-0.2.4/phi-plugin/README.md +0 -55
  187. dyno_phi-0.2.4/phi-plugin/skills/phi/SKILL.md +0 -304
  188. dyno_phi-0.2.4/pyproject.toml +0 -128
  189. dyno_phi-0.2.4/src/phi/__init__.py +0 -4
  190. dyno_phi-0.2.4/src/phi/_version.py +0 -1
  191. dyno_phi-0.2.4/src/phi/api.py +0 -158
  192. dyno_phi-0.2.4/src/phi/cli.py +0 -106
  193. dyno_phi-0.2.4/src/phi/commands/__init__.py +0 -1
  194. dyno_phi-0.2.4/src/phi/commands/auth.py +0 -85
  195. dyno_phi-0.2.4/src/phi/commands/datasets.py +0 -142
  196. dyno_phi-0.2.4/src/phi/commands/filter.py +0 -86
  197. dyno_phi-0.2.4/src/phi/commands/jobs.py +0 -154
  198. dyno_phi-0.2.4/src/phi/commands/models.py +0 -177
  199. dyno_phi-0.2.4/src/phi/commands/research.py +0 -90
  200. dyno_phi-0.2.4/src/phi/commands/structure.py +0 -197
  201. dyno_phi-0.2.4/src/phi/commands/tutorial.py +0 -88
  202. dyno_phi-0.2.4/src/phi/config.py +0 -162
  203. dyno_phi-0.2.4/src/phi/display.py +0 -414
  204. dyno_phi-0.2.4/src/phi/download.py +0 -253
  205. dyno_phi-0.2.4/src/phi/parser.py +0 -672
  206. dyno_phi-0.2.4/src/phi/polling.py +0 -124
  207. dyno_phi-0.2.4/src/phi/research.py +0 -216
  208. dyno_phi-0.2.4/src/phi/structure.py +0 -106
  209. dyno_phi-0.2.4/src/phi/types.py +0 -33
  210. dyno_phi-0.2.4/src/phi/upload.py +0 -146
  211. dyno_phi-0.2.4/tests/__init__.py +0 -1
  212. dyno_phi-0.2.4/tests/test_api.py +0 -125
  213. dyno_phi-0.2.4/tests/test_config.py +0 -109
  214. dyno_phi-0.2.4/tests/test_display.py +0 -47
  215. dyno_phi-0.2.4/tests/test_download.py +0 -75
  216. dyno_phi-0.2.4/tests/test_research.py +0 -117
  217. dyno_phi-0.2.4/tests/test_structure.py +0 -149
  218. dyno_phi-0.2.4/tests/test_upload.py +0 -73
@@ -0,0 +1,125 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+
8
+ # Virtual environments
9
+ .venv/
10
+ .venv-install/
11
+ venv/
12
+ env/
13
+ dockq-venv/
14
+
15
+ # Distribution / packaging
16
+ dist/
17
+ build/
18
+ *.egg-info/
19
+ *.egg
20
+
21
+ # Testing
22
+ .pytest_cache/
23
+ .coverage
24
+ htmlcov/
25
+ .tox/
26
+
27
+ # Type checking
28
+ .mypy_cache/
29
+ .dmypy.json
30
+ .pyright/
31
+
32
+ # Environment files — never commit secrets
33
+ .env
34
+ .env.local
35
+ .env.*.local
36
+ *.env
37
+
38
+ # GCP service account keys
39
+ *.json
40
+ !pyproject.json
41
+ !.cursor/environment.json
42
+ !tests/fixtures/metrics/ipsae_nonzero_multisubchain.json
43
+ !tests/fixtures/bindcraft/run_metadata.json
44
+ !clients/phi/tests/fixtures/job_types.json
45
+ !clients/phi/tests/fixtures/run_pipelines.json
46
+ !experiments/campaigns/y7_design/config/score_hit_calibration.json
47
+ # Anchored to the repo root so it only blocks a top-level credential dir,
48
+ # not source packages that happen to be named `secrets/`.
49
+ /secrets/
50
+
51
+ # Team-facing engineering docs live in docs/ (committed).
52
+ # Local-only scratchpads / agent ephemera go in .scratch/.
53
+ .scratch/
54
+ scratch/
55
+
56
+ # IDE
57
+ .vscode/
58
+ .idea/
59
+ *.swp
60
+ *.swo
61
+
62
+ # Agent-only Cursor rule — local edit-time tooling, not a committed
63
+ # team artifact. The team-facing version of the same content lives in
64
+ # docs/model-integration-watchlist.md.
65
+ .cursor/rules/model-integration.mdc
66
+
67
+ # macOS
68
+ .DS_Store
69
+
70
+ # Alembic auto-generated (keep versions/ tracked)
71
+ alembic/versions/*.pyc
72
+
73
+ # Terraform state and local overrides
74
+ infrastructure/**/.terraform/
75
+ infrastructure/**/terraform.tfstate
76
+ infrastructure/**/terraform.tfstate.backup
77
+ infrastructure/**/*.tfvars
78
+ !infrastructure/**/terraform.tfvars.example
79
+ # Committed env var files — no secrets here; image_tag is always CI-supplied
80
+ !infrastructure/terraform/staging.tfvars
81
+ !infrastructure/terraform/production.tfvars
82
+ infrastructure/**/.terraform.lock.hcl
83
+
84
+ # Cloud Build local artifacts
85
+ cloudbuild/*.log
86
+ /runners/capsid-fold-esmfold2-base/source-artifact.zip
87
+ /runners/capsid-fold-esmfold2-base/source-artifact.sha256
88
+
89
+ # Docker
90
+ .dockerignore.local
91
+
92
+ *.pdb
93
+ !tests/fixtures/metrics/ipsae_nonzero_multisubchain.pdb
94
+ !examples/bindcraft2/*.pdb
95
+ *.cif
96
+ !examples/bindcraft2/*.cif
97
+ *.csv
98
+
99
+ # Large binary data / experiment outputs — use GCS, not git
100
+ *.parquet
101
+ *.pq
102
+ *.npz
103
+
104
+ # Canvas HTML dashboards (generated, not source-controlled)
105
+ canvas/
106
+
107
+ # Y4 campaign data and validation packages (binary + large CSVs)
108
+ experiments/campaigns/y4_agent_designs/data/
109
+ experiments/campaigns/y4_agent_designs/*.zip
110
+ experiments/campaigns/y4_agent_designs/y4_validation_package_*/
111
+
112
+ # CXCR3 campaign pipeline scratch — BoltzGen staging, fold inputs, large score tables
113
+ experiments/cxcr3_vhh_design/data/designs/.staging/
114
+ experiments/cxcr3_vhh_design/data/designs/**/.harvested_*
115
+ experiments/cxcr3_vhh_design/data/control_folds/
116
+ experiments/cxcr3_vhh_design/data/control_folds_templated/
117
+ experiments/cxcr3_vhh_design/data/scored/wave1_designs.tsv
118
+ experiments/cxcr3_vhh_design/data/scored/wave1_keep.tsv
119
+ experiments/cxcr3_vhh_design/data/scored/wave1_keep_sequences.tsv
120
+ experiments/cxcr3_vhh_design/data/scored/refold_manifest*.tsv
121
+
122
+ # Agent-development guide is account/app-specific (DynoPhiAgent). Other
123
+ # contributors run different agents/apps, so keep it local-only, not in the
124
+ # shared repo.
125
+ docs/agent-development.md
@@ -0,0 +1,61 @@
1
+ # Changelog
2
+
3
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
4
+ package follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). The
5
+ version is read from `src/phi/_version.py`; a release is the tag `client-v<version>`
6
+ on `dynotx/phi-api`, which `.github/workflows/publish-client.yml` builds and publishes.
7
+
8
+ ## [0.3.1] - 2026-10-17
9
+
10
+ ### Changed
11
+
12
+ - The CLI is installed with the package: `pip install dyno-phi` puts `phi` on the
13
+ path. The `[cli]` extra is kept as a no-op alias, so `dyno-phi[cli]` still
14
+ installs.
15
+
16
+ ## [0.3.0] - 2026-10-17
17
+
18
+ The first release of the Phi SDK and CLI on PyPI, published from `clients/phi` in
19
+ `dynotx/phi-api`. It was distributed as `phi-client` 0.0.1 from this repository
20
+ over git during the internal preview.
21
+
22
+ `dyno-phi` 0.2.x on PyPI was an earlier, unrelated client of a retired API. 0.3.0
23
+ replaces it under the same name; nothing from 0.2.x carries over.
24
+
25
+ ### Added
26
+
27
+ - `PhiClient` and `AsyncPhiClient` with the same resources and signatures:
28
+ `projects`, `datasets`, `sequences`, `designs`, `jobs`, `job_types`, `runs`,
29
+ `run_admin`, `artifacts`, `files`, `uploads`, `logs`, `quota`, `tool_configs`,
30
+ `imports`, `documents`.
31
+ - Typed request and response models, local JSON Schema validation of `params` and
32
+ `inputs` for every job type (`client.job_types.validate_params`), waiters for
33
+ jobs and runs, and a typed error taxonomy (`PhiError` and its subclasses).
34
+ - The `phi` CLI behind the `[cli]` extra, every command taking `--json`:
35
+ `auth`, `projects`, `datasets`, `docs`, `models`, `jobs`, `runs`, `pipeline`,
36
+ `artifacts`, `export`, `logs`, `quota`, `use`, `quickstart`.
37
+ - Profiles in `~/.config/phi/config.toml`, selected with `--profile` or
38
+ `PHI_PROFILE`.
39
+ - A Claude Code skill (`skills/phi/SKILL.md`) that drives the CLI.
40
+
41
+ ### Changed from `dyno-phi` 0.2.x
42
+
43
+ - Environment: `PHI_API` is the base URL and `PHI_KEY` or `PHI_API_KEY` the key
44
+ (`DYNO_API_BASE_URL` and `DYNO_API_KEY` are not read). `PHI_ORG` names the
45
+ organization for a static key; a Clerk key carries its own.
46
+ - Command tree: `phi <group> <command>` as listed above. `phi upload`, `phi filter`,
47
+ `phi research`, `phi notes`, `phi tutorial`, the filter presets and the
48
+ per-model commands (`phi esmfold`, `phi alphafold`, ...) are gone; a model runs
49
+ as `phi jobs submit <JOB_TYPE>` and a chain of models as `phi runs submit` or
50
+ `phi pipeline run`. `phi quickstart` is the walkthrough.
51
+ - State: `.phi/state.json` holds the active project and dataset and the last job
52
+ and run, nothing else; the API key is never written there.
53
+ - Python 3.12 or newer. The SDK depends on `httpx` and `pydantic` alone; the CLI's
54
+ dependencies install only with the `[cli]` extra.
55
+ - Web app: results open at `design.dynotx.com`; the dashboard URLs the old client
56
+ printed no longer exist.
57
+
58
+ Versioning note: the client stays below 1.0 while the API it speaks to is itself
59
+ pre-1.0 (0.1.x) and the request shapes can still change between releases. 0.3.0
60
+ is the first release on this line only because 0.2.x was already taken on PyPI
61
+ by the earlier client; it is not a continuation of it.
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.5
2
+ Name: dyno-phi
3
+ Version: 0.3.1
4
+ Summary: Phi — Python SDK and CLI for the Phi protein design API
5
+ Project-URL: Homepage, https://design.dynotx.com
6
+ Project-URL: Documentation, https://design.dynotx.com/docs
7
+ Project-URL: Source, https://github.com/dynotx/phi-api/tree/main/clients/phi
8
+ Project-URL: Changelog, https://github.com/dynotx/phi-api/blob/main/clients/phi/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/dynotx/phi-api/issues
10
+ Author: Dyno Therapeutics
11
+ License-Expression: MIT
12
+ Keywords: binder-design,bioinformatics,cli,protein-design,protein-engineering,sdk,structure-prediction
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: click>=8.1
24
+ Requires-Dist: httpx>=0.27
25
+ Requires-Dist: pydantic>=2.9
26
+ Requires-Dist: pyyaml>=6
27
+ Requires-Dist: rich>=13
28
+ Requires-Dist: typer>=0.12
29
+ Provides-Extra: cli
30
+ Description-Content-Type: text/markdown
31
+
32
+ # dyno-phi
33
+
34
+ Python SDK and CLI for the [Phi](https://design.dynotx.com) protein design API.
35
+ The `phi` package exposes synchronous (`PhiClient`) and asynchronous
36
+ (`AsyncPhiClient`) clients and the `phi` CLI, installed together. It is
37
+ published to PyPI from `clients/phi` in
38
+ [`dynotx/phi-api`](https://github.com/dynotx/phi-api).
39
+
40
+ ## Install
41
+
42
+ The CLI as an isolated tool on your `PATH`:
43
+
44
+ ```bash
45
+ uv tool install dyno-phi
46
+ ```
47
+
48
+ `uv tool` provisions its own Python, which covers the client's **Python 3.12+**
49
+ requirement on stock macOS, where the system Python is 3.9. Re-run with
50
+ `--upgrade` to upgrade. `pip install dyno-phi` into a Python 3.12+ of your own
51
+ does the same. From a `phi-api` checkout, `just install-cli` runs the first
52
+ form and `just install-cli-dev` installs the working tree.
53
+
54
+ The SDK inside an existing project (the CLI comes with it; the `[cli]` extra
55
+ from 0.3.0 still installs and adds nothing):
56
+
57
+ ```bash
58
+ uv add dyno-phi # or: pip install dyno-phi
59
+ ```
60
+
61
+ Check the install with `phi --version`. `dyno-phi` 0.2.x was an earlier,
62
+ unrelated client of a retired API; if `phi --version` prints `0.2.x`, that
63
+ client is first on your `PATH` (`which -a phi` lists every match) and
64
+ `pip install --upgrade dyno-phi` in the Python that owns it replaces it.
65
+ Coming from 0.2.x: the key is `PHI_API_KEY` (or `PHI_KEY`) and the base URL
66
+ `PHI_API`, the commands are `phi <group> <command>` as listed under
67
+ [CLI](#cli), and Python 3.12+ is required; see
68
+ [`CHANGELOG.md`](https://github.com/dynotx/phi-api/blob/main/clients/phi/CHANGELOG.md).
69
+
70
+ If `uv`'s tool directory is behind another `phi` on `PATH`, sourcing uv's shell
71
+ shim is not enough to move it: the shim prepends the directory only when `PATH`
72
+ does not already contain it, and on macOS `path_helper` appends inherited
73
+ entries behind `/etc/paths.d`, so in a shell that inherits a `PATH` naming the
74
+ directory it stays last. Pin the order at the end of `~/.zshrc`:
75
+
76
+ ```zsh
77
+ typeset -U path PATH
78
+ path=("$HOME/.local/bin" $path)
79
+ ```
80
+
81
+ ## Authentication
82
+
83
+ Both the SDK and the CLI read connection settings from the environment, falling
84
+ back to `~/.config/phi/config.toml`:
85
+
86
+ | Variable | Purpose |
87
+ |---|---|
88
+ | `PHI_API` | Base URL of the API. Its host selects the environment class — `hosted`, `staging`, or `local`. |
89
+ | `PHI_KEY` / `PHI_API_KEY` | API key. |
90
+ | `PHI_ORG` | Organization ID. Required with a static key. |
91
+
92
+ ```bash
93
+ export PHI_API=https://phi-api-staging-917387676927.us-central1.run.app
94
+ export PHI_KEY=... # static staging key
95
+ export PHI_ORG=dynotx # literal static tenant, not the Clerk org
96
+ ```
97
+
98
+ With a Clerk key (`ak_...`) the tenant comes from the key, so `PHI_ORG` is
99
+ ignored; it is required only for a static key.
100
+
101
+ Pass `base_url=`, `api_key=`, and `org=` to the client constructor to override
102
+ the environment.
103
+
104
+ ## 60-second quickstart
105
+
106
+ ```bash
107
+ phi quickstart
108
+ ```
109
+
110
+ Creates the `quickstart` project, folds the Trp-cage mini-protein with `ESMFOLD`,
111
+ waits, and downloads the results. The manual equivalent is:
112
+
113
+ ```bash
114
+ phi jobs submit ESMFOLD --input sequences=@sequence.fasta --wait --out quickstart-output
115
+ ```
116
+
117
+ ## SDK usage
118
+
119
+ Submit a job and wait for it, closing the client on exit:
120
+
121
+ ```python
122
+ from phi import PhiClient
123
+
124
+ with PhiClient() as client:
125
+ submitted = client.jobs.submit("ESMFOLD", inputs={"sequences": ["NLYIQWLKDGGPSSGRPPPS"]})
126
+ job = client.jobs.wait(submitted.job_id)
127
+ print(job.status, job.outputs)
128
+ ```
129
+
130
+ `AsyncPhiClient` mirrors the same surface for concurrent work:
131
+
132
+ ```python
133
+ import asyncio
134
+
135
+ from phi import AsyncPhiClient
136
+
137
+
138
+ async def fold(sequences: list[str]) -> list[str]:
139
+ async with AsyncPhiClient() as client:
140
+ submitted = await asyncio.gather(
141
+ *(client.jobs.submit("ESMFOLD", inputs={"sequences": [seq]}) for seq in sequences)
142
+ )
143
+ jobs = await asyncio.gather(*(client.jobs.wait(job.job_id) for job in submitted))
144
+ return [job.status for job in jobs]
145
+
146
+
147
+ asyncio.run(fold(["NLYIQWLKDGGPSSGRPPPS", "GSHMKELVLALYDYQEKSPRE"]))
148
+ ```
149
+
150
+ Runnable end-to-end scripts live in [`examples/`](examples/): single fold job,
151
+ named pipeline, ad-hoc DAG, artifact download, and concurrent async submission.
152
+
153
+ ### Job types and local validation
154
+
155
+ `client.job_types` lists the job types the API advertises and the JSON Schema for
156
+ each one's `params` and `inputs`. Schemas are cached on disk per host for 24 hours;
157
+ pass `refresh=True` to refetch.
158
+
159
+ ```python
160
+ client.job_types.validate_params("PROTEINMPNN", {"num_seq_per_target": 8})
161
+ ```
162
+
163
+ `validate_params` and `validate_inputs` raise `PhiValidationError` on a bad key,
164
+ type, enum value, or numeric range. They are a **shallow pre-flight check**:
165
+ top-level keys only, with no descent into nested objects or array items. The
166
+ server validates fully, so a clean pass locally is not a guarantee the request
167
+ will be accepted.
168
+
169
+ ### Knowledge documents
170
+
171
+ `client.documents` and `AsyncPhiClient.documents` list, read, search, write, and
172
+ review tenant-scoped Markdown documents. Use `iter_documents()` and
173
+ `iter_versions()` to follow cursor pages. Updates take the active digest as
174
+ `if_digest`; a stale value raises `PhiConflictError`. `propose()` creates a draft
175
+ that remains outside active reads and search until a document writer calls
176
+ `activate()`.
177
+
178
+ ## CLI
179
+
180
+ Every command reads the same environment and accepts `--json` for scripting.
181
+
182
+ | Group | Commands |
183
+ |---|---|
184
+ | `auth` | `login`, `whoami`, `logout`, `profiles` |
185
+ | `projects` | `list`, `create`, `show`, `update`, `archive` |
186
+ | `datasets` | `list`, `create`, `show`, `update`, `delete`, `copy`, `export`, `sequences` |
187
+ | `docs` | `list`, `read`, `search`, `add`, `update`, `history`, `propose`, `activate`, `sync` |
188
+ | `models` | `list`, `show`, `schema` |
189
+ | `jobs` | `submit`, `list`, `status`, `cancel`, `wait`, `embeddings` |
190
+ | `runs` | `submit`, `estimate`, `list`, `status`, `timeline`, `dag`, `cancel`, `resume` |
191
+ | `pipeline` | `run`, `validate`, `estimate` |
192
+ | `artifacts` | `list`, `download` |
193
+ | `export` | `sequences`, `designs`, `structure`, `pae` |
194
+ | `logs` | `show`, `download`, `settings` |
195
+ | `quota` | (summary), `history` |
196
+ | `use` | Set the active project |
197
+ | `quickstart` | Run the end-to-end ESMFOLD example |
198
+
199
+ `phi docs sync <dir> --dry-run` safely plans publication from a clean knowledge
200
+ checkout. Without `--dry-run` it publishes only Git-tracked files in the
201
+ authored Markdown layer after the checkout's deny-list guard passes, defaults
202
+ platform documents to internal access, and skips unchanged content and access.
203
+ It does not delete remote-only documents.
204
+
205
+ ## Full reference
206
+
207
+ See [`docs/sdk-and-cli.md`](https://github.com/dynotx/phi-api/blob/main/docs/sdk-and-cli.md)
208
+ for environment and profile resolution, sync/async parity, the complete CLI
209
+ reference, the error taxonomy and how a release is cut.
@@ -0,0 +1,178 @@
1
+ # dyno-phi
2
+
3
+ Python SDK and CLI for the [Phi](https://design.dynotx.com) protein design API.
4
+ The `phi` package exposes synchronous (`PhiClient`) and asynchronous
5
+ (`AsyncPhiClient`) clients and the `phi` CLI, installed together. It is
6
+ published to PyPI from `clients/phi` in
7
+ [`dynotx/phi-api`](https://github.com/dynotx/phi-api).
8
+
9
+ ## Install
10
+
11
+ The CLI as an isolated tool on your `PATH`:
12
+
13
+ ```bash
14
+ uv tool install dyno-phi
15
+ ```
16
+
17
+ `uv tool` provisions its own Python, which covers the client's **Python 3.12+**
18
+ requirement on stock macOS, where the system Python is 3.9. Re-run with
19
+ `--upgrade` to upgrade. `pip install dyno-phi` into a Python 3.12+ of your own
20
+ does the same. From a `phi-api` checkout, `just install-cli` runs the first
21
+ form and `just install-cli-dev` installs the working tree.
22
+
23
+ The SDK inside an existing project (the CLI comes with it; the `[cli]` extra
24
+ from 0.3.0 still installs and adds nothing):
25
+
26
+ ```bash
27
+ uv add dyno-phi # or: pip install dyno-phi
28
+ ```
29
+
30
+ Check the install with `phi --version`. `dyno-phi` 0.2.x was an earlier,
31
+ unrelated client of a retired API; if `phi --version` prints `0.2.x`, that
32
+ client is first on your `PATH` (`which -a phi` lists every match) and
33
+ `pip install --upgrade dyno-phi` in the Python that owns it replaces it.
34
+ Coming from 0.2.x: the key is `PHI_API_KEY` (or `PHI_KEY`) and the base URL
35
+ `PHI_API`, the commands are `phi <group> <command>` as listed under
36
+ [CLI](#cli), and Python 3.12+ is required; see
37
+ [`CHANGELOG.md`](https://github.com/dynotx/phi-api/blob/main/clients/phi/CHANGELOG.md).
38
+
39
+ If `uv`'s tool directory is behind another `phi` on `PATH`, sourcing uv's shell
40
+ shim is not enough to move it: the shim prepends the directory only when `PATH`
41
+ does not already contain it, and on macOS `path_helper` appends inherited
42
+ entries behind `/etc/paths.d`, so in a shell that inherits a `PATH` naming the
43
+ directory it stays last. Pin the order at the end of `~/.zshrc`:
44
+
45
+ ```zsh
46
+ typeset -U path PATH
47
+ path=("$HOME/.local/bin" $path)
48
+ ```
49
+
50
+ ## Authentication
51
+
52
+ Both the SDK and the CLI read connection settings from the environment, falling
53
+ back to `~/.config/phi/config.toml`:
54
+
55
+ | Variable | Purpose |
56
+ |---|---|
57
+ | `PHI_API` | Base URL of the API. Its host selects the environment class — `hosted`, `staging`, or `local`. |
58
+ | `PHI_KEY` / `PHI_API_KEY` | API key. |
59
+ | `PHI_ORG` | Organization ID. Required with a static key. |
60
+
61
+ ```bash
62
+ export PHI_API=https://phi-api-staging-917387676927.us-central1.run.app
63
+ export PHI_KEY=... # static staging key
64
+ export PHI_ORG=dynotx # literal static tenant, not the Clerk org
65
+ ```
66
+
67
+ With a Clerk key (`ak_...`) the tenant comes from the key, so `PHI_ORG` is
68
+ ignored; it is required only for a static key.
69
+
70
+ Pass `base_url=`, `api_key=`, and `org=` to the client constructor to override
71
+ the environment.
72
+
73
+ ## 60-second quickstart
74
+
75
+ ```bash
76
+ phi quickstart
77
+ ```
78
+
79
+ Creates the `quickstart` project, folds the Trp-cage mini-protein with `ESMFOLD`,
80
+ waits, and downloads the results. The manual equivalent is:
81
+
82
+ ```bash
83
+ phi jobs submit ESMFOLD --input sequences=@sequence.fasta --wait --out quickstart-output
84
+ ```
85
+
86
+ ## SDK usage
87
+
88
+ Submit a job and wait for it, closing the client on exit:
89
+
90
+ ```python
91
+ from phi import PhiClient
92
+
93
+ with PhiClient() as client:
94
+ submitted = client.jobs.submit("ESMFOLD", inputs={"sequences": ["NLYIQWLKDGGPSSGRPPPS"]})
95
+ job = client.jobs.wait(submitted.job_id)
96
+ print(job.status, job.outputs)
97
+ ```
98
+
99
+ `AsyncPhiClient` mirrors the same surface for concurrent work:
100
+
101
+ ```python
102
+ import asyncio
103
+
104
+ from phi import AsyncPhiClient
105
+
106
+
107
+ async def fold(sequences: list[str]) -> list[str]:
108
+ async with AsyncPhiClient() as client:
109
+ submitted = await asyncio.gather(
110
+ *(client.jobs.submit("ESMFOLD", inputs={"sequences": [seq]}) for seq in sequences)
111
+ )
112
+ jobs = await asyncio.gather(*(client.jobs.wait(job.job_id) for job in submitted))
113
+ return [job.status for job in jobs]
114
+
115
+
116
+ asyncio.run(fold(["NLYIQWLKDGGPSSGRPPPS", "GSHMKELVLALYDYQEKSPRE"]))
117
+ ```
118
+
119
+ Runnable end-to-end scripts live in [`examples/`](examples/): single fold job,
120
+ named pipeline, ad-hoc DAG, artifact download, and concurrent async submission.
121
+
122
+ ### Job types and local validation
123
+
124
+ `client.job_types` lists the job types the API advertises and the JSON Schema for
125
+ each one's `params` and `inputs`. Schemas are cached on disk per host for 24 hours;
126
+ pass `refresh=True` to refetch.
127
+
128
+ ```python
129
+ client.job_types.validate_params("PROTEINMPNN", {"num_seq_per_target": 8})
130
+ ```
131
+
132
+ `validate_params` and `validate_inputs` raise `PhiValidationError` on a bad key,
133
+ type, enum value, or numeric range. They are a **shallow pre-flight check**:
134
+ top-level keys only, with no descent into nested objects or array items. The
135
+ server validates fully, so a clean pass locally is not a guarantee the request
136
+ will be accepted.
137
+
138
+ ### Knowledge documents
139
+
140
+ `client.documents` and `AsyncPhiClient.documents` list, read, search, write, and
141
+ review tenant-scoped Markdown documents. Use `iter_documents()` and
142
+ `iter_versions()` to follow cursor pages. Updates take the active digest as
143
+ `if_digest`; a stale value raises `PhiConflictError`. `propose()` creates a draft
144
+ that remains outside active reads and search until a document writer calls
145
+ `activate()`.
146
+
147
+ ## CLI
148
+
149
+ Every command reads the same environment and accepts `--json` for scripting.
150
+
151
+ | Group | Commands |
152
+ |---|---|
153
+ | `auth` | `login`, `whoami`, `logout`, `profiles` |
154
+ | `projects` | `list`, `create`, `show`, `update`, `archive` |
155
+ | `datasets` | `list`, `create`, `show`, `update`, `delete`, `copy`, `export`, `sequences` |
156
+ | `docs` | `list`, `read`, `search`, `add`, `update`, `history`, `propose`, `activate`, `sync` |
157
+ | `models` | `list`, `show`, `schema` |
158
+ | `jobs` | `submit`, `list`, `status`, `cancel`, `wait`, `embeddings` |
159
+ | `runs` | `submit`, `estimate`, `list`, `status`, `timeline`, `dag`, `cancel`, `resume` |
160
+ | `pipeline` | `run`, `validate`, `estimate` |
161
+ | `artifacts` | `list`, `download` |
162
+ | `export` | `sequences`, `designs`, `structure`, `pae` |
163
+ | `logs` | `show`, `download`, `settings` |
164
+ | `quota` | (summary), `history` |
165
+ | `use` | Set the active project |
166
+ | `quickstart` | Run the end-to-end ESMFOLD example |
167
+
168
+ `phi docs sync <dir> --dry-run` safely plans publication from a clean knowledge
169
+ checkout. Without `--dry-run` it publishes only Git-tracked files in the
170
+ authored Markdown layer after the checkout's deny-list guard passes, defaults
171
+ platform documents to internal access, and skips unchanged content and access.
172
+ It does not delete remote-only documents.
173
+
174
+ ## Full reference
175
+
176
+ See [`docs/sdk-and-cli.md`](https://github.com/dynotx/phi-api/blob/main/docs/sdk-and-cli.md)
177
+ for environment and profile resolution, sync/async parity, the complete CLI
178
+ reference, the error taxonomy and how a release is cut.
@@ -0,0 +1,25 @@
1
+ # phi examples
2
+
3
+ Runnable SDK scripts. Each reads connection settings from the environment
4
+ (`PHI_API`, `PHI_KEY` or `PHI_API_KEY`, and `PHI_ORG` for a static key) and can
5
+ be run directly:
6
+
7
+ ```bash
8
+ python examples/submit_fold.py
9
+ ```
10
+
11
+ | Script | What it shows |
12
+ |---|---|
13
+ | [`submit_fold.py`](submit_fold.py) | Submit one ESMFOLD job and wait for it to finish. |
14
+ | [`run_pipeline.py`](run_pipeline.py) | Run the named `SCORE_BACKBONES` pipeline seeded from a prior run. |
15
+ | [`compose_dag.py`](compose_dag.py) | Build an ad-hoc ProteinMPNN → ESMFold `PipelineGraph` and submit it as one job. |
16
+ | [`download_results.py`](download_results.py) | List a run's artifacts, download them, and read the manifest. |
17
+ | [`async_concurrent.py`](async_concurrent.py) | Submit several jobs concurrently with `AsyncPhiClient`. |
18
+
19
+ Scripts that need a project or run identifier take it as an argument, e.g.
20
+ `python examples/compose_dag.py <project_id>`.
21
+
22
+ Other assets in this directory:
23
+
24
+ - [`quickstart/`](quickstart/) — the input FASTA used by `phi quickstart`.
25
+ - [`pipelines/`](pipelines/) — graph YAML files for `phi pipeline run -f`.
@@ -0,0 +1,31 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+
5
+ from phi import AsyncPhiClient
6
+
7
+ SEQUENCES = [
8
+ "NLYIQWLKDGGPSSGRPPPS",
9
+ "GSHMKELVLALYDYQEKSPRE",
10
+ "MKTAYIAKQRQISFVKSHFSRQ",
11
+ ]
12
+
13
+
14
+ async def main(sequences: list[str] = SEQUENCES, batch_id: str = "esmfold-sweep") -> list[str]:
15
+ async with AsyncPhiClient() as client:
16
+ # One batch_id ties the sweep together: GET /v1/batches/{batch_id} reads "n of N done".
17
+ submitted = await asyncio.gather(
18
+ *(
19
+ client.jobs.submit("ESMFOLD", inputs={"sequences": [seq]}, batch_id=batch_id)
20
+ for seq in sequences
21
+ )
22
+ )
23
+ jobs = await asyncio.gather(*(client.jobs.wait(job.job_id) for job in submitted))
24
+ statuses: list[str] = [job.status for job in jobs]
25
+ for job in jobs:
26
+ print(f"{job.job_id}: {job.status}")
27
+ return statuses
28
+
29
+
30
+ if __name__ == "__main__":
31
+ asyncio.run(main())
@@ -0,0 +1,22 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+
5
+ from phi import PhiClient, PipelineGraph
6
+
7
+
8
+ def main(project_id: str) -> str:
9
+ graph = PipelineGraph()
10
+ design = graph.add("proteinmpnn")
11
+ fold = graph.add("esmfold")
12
+ graph.connect(design.sequences, fold.sequences)
13
+ graph.validate()
14
+
15
+ with PhiClient() as client:
16
+ submitted = client.jobs.submit_graph(graph, project_id=project_id)
17
+ print(f"{submitted.job_id}: {submitted.status} ({submitted.estimated_credits} credits)")
18
+ return submitted.job_id
19
+
20
+
21
+ if __name__ == "__main__":
22
+ main(sys.argv[1])
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ from phi import PhiClient
8
+
9
+
10
+ def main(run_id: str, out_dir: str | Path = "results") -> Path:
11
+ with PhiClient() as client:
12
+ artifacts = client.artifacts.list(run_id, suffix=".cif")
13
+ manifest_path = client.artifacts.download(artifacts, out_dir)
14
+ manifest = json.loads(manifest_path.read_text())
15
+ for entry in manifest:
16
+ print(f"{entry['status']:>10} {entry['path']}")
17
+ return manifest_path
18
+
19
+
20
+ if __name__ == "__main__":
21
+ main(sys.argv[1], sys.argv[2] if len(sys.argv) > 2 else "results")
@@ -0,0 +1,10 @@
1
+ nodes:
2
+ - id: fold
3
+ tool: esmfold
4
+ mode: ""
5
+ - id: score
6
+ tool: analysis
7
+ mode: ""
8
+ edges:
9
+ - from: fold.sequences
10
+ to: score.sequences