amina-cli 0.2.1__tar.gz → 0.2.2__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 (64) hide show
  1. {amina_cli-0.2.1 → amina_cli-0.2.2}/.gitignore +10 -0
  2. {amina_cli-0.2.1 → amina_cli-0.2.2}/PKG-INFO +1 -1
  3. {amina_cli-0.2.1 → amina_cli-0.2.2}/pyproject.toml +1 -1
  4. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/__init__.py +1 -1
  5. amina_cli-0.2.2/src/amina_cli/commands/tools/properties/esm1v.py +175 -0
  6. {amina_cli-0.2.1 → amina_cli-0.2.2}/LICENSE +0 -0
  7. {amina_cli-0.2.1 → amina_cli-0.2.2}/README.md +0 -0
  8. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/auth.py +0 -0
  9. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/client.py +0 -0
  10. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/__init__.py +0 -0
  11. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/auth_cmd.py +0 -0
  12. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/init_cmd.py +0 -0
  13. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/jobs_cmd.py +0 -0
  14. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/run_cmd.py +0 -0
  15. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/__init__.py +0 -0
  16. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/__init__.py +0 -0
  17. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/hydrophobicity.py +0 -0
  18. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/mmseqs2_cluster.py +0 -0
  19. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/rmsd.py +0 -0
  20. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/sasa.py +0 -0
  21. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/simple_rmsd.py +0 -0
  22. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/surface_charge.py +0 -0
  23. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/analysis/usalign.py +0 -0
  24. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/design/__init__.py +0 -0
  25. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/design/esm_if1.py +0 -0
  26. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/design/protein_mc.py +0 -0
  27. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/design/proteinmpnn.py +0 -0
  28. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/design/rfdiffusion.py +0 -0
  29. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/display.py +0 -0
  30. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/folding/__init__.py +0 -0
  31. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/folding/boltz2.py +0 -0
  32. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/folding/esmfold.py +0 -0
  33. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/folding/openfold3.py +0 -0
  34. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/folding/protenix.py +0 -0
  35. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/__init__.py +0 -0
  36. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/autodock_vina.py +0 -0
  37. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/diffdock.py +0 -0
  38. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/dockq.py +0 -0
  39. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/emngly.py +0 -0
  40. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/glycosylation_ensemble.py +0 -0
  41. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/interface_identifier.py +0 -0
  42. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/isoglyp.py +0 -0
  43. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/lmngly.py +0 -0
  44. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/p2rank.py +0 -0
  45. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/interactions/pesto.py +0 -0
  46. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/properties/__init__.py +0 -0
  47. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/properties/aminosol.py +0 -0
  48. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/properties/esm2_embedding.py +0 -0
  49. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/__init__.py +0 -0
  50. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/activesite_verifier.py +0 -0
  51. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/chain_select.py +0 -0
  52. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/distance_calculator.py +0 -0
  53. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/maxit_convert.py +0 -0
  54. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/mol_size_calculator.py +0 -0
  55. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/obabel_convert.py +0 -0
  56. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/pdb_bfactor_overwrite.py +0 -0
  57. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/pdb_cleaner.py +0 -0
  58. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/pdb_quality_assessment.py +0 -0
  59. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/pdb_to_fasta.py +0 -0
  60. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools/utilities/protein_relaxer.py +0 -0
  61. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/commands/tools_cmd.py +0 -0
  62. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/main.py +0 -0
  63. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/registry.py +0 -0
  64. {amina_cli-0.2.1 → amina_cli-0.2.2}/src/amina_cli/storage.py +0 -0
@@ -39,8 +39,18 @@ uv.lock
39
39
 
40
40
  # OS
41
41
  .DS_Store
42
+ .DS_Store?
43
+ ._*
44
+ .AppleDouble
45
+ .LSOverride
46
+ .Spotlight-V100
47
+ .Trashes
48
+ Icon?
42
49
  Thumbs.db
43
50
 
51
+ # PyMOL
52
+ *.pml
53
+
44
54
  # Testing
45
55
  .pytest_cache/
46
56
  .coverage
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amina-cli
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: CLI for AminoAnalytica protein engineering platform
5
5
  Project-URL: Homepage, https://aminoanalytica.com
6
6
  Project-URL: Documentation, https://docs.aminoanalytica.com
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "amina-cli"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "CLI for AminoAnalytica protein engineering platform"
5
5
  readme = "README.md"
6
6
  license = {text = "Apache-2.0"}
@@ -9,4 +9,4 @@ Quick start:
9
9
  amina run esmfold --sequence "MKFLILLFNILCLFPVLAADNH"
10
10
  """
11
11
 
12
- __version__ = "0.2.1"
12
+ __version__ = "0.2.2"
@@ -0,0 +1,175 @@
1
+ """ESM-1v variant effect prediction tool for the Amina CLI."""
2
+
3
+ import typer
4
+ from pathlib import Path
5
+ from typing import Optional
6
+ from rich.console import Console
7
+
8
+ METADATA = {
9
+ "name": "esm1v",
10
+ "display_name": "ESM-1v Variant Effect",
11
+ "category": "properties",
12
+ "description": "Predict variant effects on protein function using ESM-1v masked marginal scoring",
13
+ "modal_function_name": "esm1v_worker",
14
+ "modal_app_name": "esm1v-api",
15
+ "status": "available",
16
+ "outputs": {
17
+ "scores_csv_filepath": "Mutation scores CSV",
18
+ "heatmap_filepath": "DMS heatmap (PNG, --mode dms only)",
19
+ "summary_json_filepath": "Summary statistics (JSON)",
20
+ },
21
+ }
22
+
23
+ console = Console()
24
+
25
+
26
+ def register(app: typer.Typer):
27
+ """Register this tool's command with the app."""
28
+ from amina_cli.commands.tools import run_tool_with_progress
29
+
30
+ @app.command("esm1v")
31
+ def run_esm1v(
32
+ mode: str = typer.Option(
33
+ ...,
34
+ "--mode",
35
+ "-m",
36
+ help="Scoring mode: single, batch, or dms (deep mutational scan)",
37
+ ),
38
+ sequence: Optional[str] = typer.Option(
39
+ None,
40
+ "--sequence",
41
+ "-s",
42
+ help="Protein sequence (amino acid letters, max 1022 residues)",
43
+ ),
44
+ fasta: Optional[Path] = typer.Option(
45
+ None,
46
+ "--fasta",
47
+ "-f",
48
+ help="Path to FASTA file containing the protein sequence",
49
+ exists=True,
50
+ ),
51
+ mutations: Optional[str] = typer.Option(
52
+ None,
53
+ "--mutations",
54
+ help="Comma-separated mutations in XposY format, e.g. 'A56L,D78G'",
55
+ ),
56
+ mutations_csv: Optional[Path] = typer.Option(
57
+ None,
58
+ "--mutations-csv",
59
+ help="Path to CSV file with mutations (column: mutation)",
60
+ exists=True,
61
+ ),
62
+ num_models: int = typer.Option(
63
+ 5,
64
+ "--num-models",
65
+ "-n",
66
+ help="Number of ESM-1v ensemble checkpoints (1-5)",
67
+ ),
68
+ output: Optional[Path] = typer.Option(
69
+ None,
70
+ "--output",
71
+ "-o",
72
+ help="Output directory for results (required unless --background)",
73
+ ),
74
+ job_name: Optional[str] = typer.Option(
75
+ None,
76
+ "--job-name",
77
+ "-j",
78
+ help="Custom job name for output files (default: random 4-letter code)",
79
+ ),
80
+ background: bool = typer.Option(
81
+ False,
82
+ "--background",
83
+ help="Submit job and return immediately without waiting for completion",
84
+ ),
85
+ ):
86
+ """
87
+ Predict variant effects on protein function using ESM-1v masked marginal scoring.
88
+
89
+ Scores how amino acid substitutions affect protein fitness using masked
90
+ marginal scoring with up to 5 ensemble checkpoints.
91
+
92
+ Modes:
93
+ - single: Score one mutation (e.g., --mutations "A56L")
94
+ - batch: Score multiple mutations (comma-separated or CSV)
95
+ - dms: Full deep mutational scan (all 20 AAs at every position)
96
+
97
+ Examples:
98
+ amina run esm1v -m single -s "MKFLILLFNILCLFPVLAADNH" --mutations "M1A" -o ./output/
99
+ amina run esm1v -m batch -f seq.fasta --mutations "M1A,K2R,L5W" -o ./output/
100
+ amina run esm1v -m batch -f seq.fasta --mutations-csv muts.csv -o ./output/
101
+ amina run esm1v -m dms -s "MKFLILLFNILCLFPVLAADNH" -o ./output/
102
+ amina run esm1v -m dms -f seq.fasta -n 3 -o ./output/ # 3-model ensemble
103
+ """
104
+ # Validate required options
105
+ if output is None and not background:
106
+ console.print("[red]Error:[/red] --output / -o is required (unless using --background)")
107
+ raise typer.Exit(1)
108
+
109
+ # Validate mode
110
+ valid_modes = ["single", "batch", "dms"]
111
+ if mode.lower() not in valid_modes:
112
+ console.print(f"[red]Error:[/red] Invalid mode '{mode}'. Choose from: {', '.join(valid_modes)}")
113
+ raise typer.Exit(1)
114
+ mode = mode.lower()
115
+
116
+ # Validate num_models
117
+ if num_models < 1 or num_models > 5:
118
+ console.print("[red]Error:[/red] --num-models must be between 1 and 5")
119
+ raise typer.Exit(1)
120
+
121
+ # Validate sequence input (exactly one)
122
+ if sequence is None and fasta is None:
123
+ console.print("[red]Error:[/red] Provide --sequence or --fasta")
124
+ raise typer.Exit(1)
125
+ if sequence is not None and fasta is not None:
126
+ console.print("[red]Error:[/red] Provide only one of --sequence or --fasta")
127
+ raise typer.Exit(1)
128
+
129
+ # Validate mutation input based on mode
130
+ if mode in ("single", "batch"):
131
+ if mutations is None and mutations_csv is None:
132
+ console.print(f"[red]Error:[/red] Mode '{mode}' requires --mutations or --mutations-csv")
133
+ raise typer.Exit(1)
134
+ if mutations is not None and mutations_csv is not None:
135
+ console.print("[red]Error:[/red] Provide only one of --mutations or --mutations-csv")
136
+ raise typer.Exit(1)
137
+ elif mode == "dms":
138
+ if mutations is not None or mutations_csv is not None:
139
+ console.print("[red]Error:[/red] Mode 'dms' does not accept mutations input")
140
+ raise typer.Exit(1)
141
+
142
+ # Build params
143
+ params = {
144
+ "mode": mode,
145
+ "num_models": num_models,
146
+ }
147
+
148
+ # Sequence input
149
+ if sequence:
150
+ params["sequence"] = sequence.upper()
151
+ console.print(f"Sequence: {len(sequence)} residues")
152
+ elif fasta:
153
+ fasta_content = fasta.read_text()
154
+ if not fasta_content.strip().startswith(">"):
155
+ console.print("[red]Error:[/red] File does not appear to be in FASTA format")
156
+ raise typer.Exit(1)
157
+ params["fasta_content"] = fasta_content
158
+ console.print(f"Read sequence from {fasta}")
159
+
160
+ # Mutation input
161
+ if mutations:
162
+ params["mutations"] = mutations
163
+ num_muts = len([m for m in mutations.split(",") if m.strip()])
164
+ console.print(f"Mutations: {num_muts} specified")
165
+ elif mutations_csv:
166
+ params["mutations_csv_content"] = mutations_csv.read_text()
167
+ console.print(f"Read mutations from {mutations_csv}")
168
+
169
+ if job_name:
170
+ params["job_name"] = job_name
171
+
172
+ console.print(f"Mode: {mode} | Ensemble: {num_models} model(s)")
173
+
174
+ # Execute
175
+ run_tool_with_progress(METADATA["name"], params, output, background=background)
File without changes
File without changes