Metadata-Version: 2.4
Name: excellgen
Version: 0.1.0
Summary: Call Excellgen's protein-engineering services from a notebook
Author-email: Excellgen <support@excellgen.com>
License-Expression: MIT
Project-URL: Homepage, https://excellgen.com
Project-URL: Documentation, https://excellgen.com/services
Keywords: protein,bioinformatics,antibody,mutation,ESM,ProteinMPNN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: pandas
Requires-Dist: pandas>=1.3; extra == "pandas"
Provides-Extra: excel
Requires-Dist: openpyxl>=3.0; extra == "excel"
Provides-Extra: all
Requires-Dist: pandas>=1.3; extra == "all"
Requires-Dist: openpyxl>=3.0; extra == "all"
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Dynamic: license-file

# excellgen

Call Excellgen's protein-engineering services from your own notebook. No install
of ESM-2, no CUDA, no environment.

```bash
pip install excellgen
```

```python
import excellgen as eg

eg.login()                                   # reads EXCELLGEN_API_KEY
df = eg.rank_mutations(sequence, "M1C;K2D")  # a DataFrame, waits for the answer
```

You need a membership and an API key from [excellgen.com](https://excellgen.com).

## What you can call

| Call | What it does |
|---|---|
| `rank_mutations(seq, muts)` | ESM-2 masked marginals. The most-cited zero-shot method, so your numbers are comparable with published work. |
| `rank_with_structure(seq, muts, pdb)` | Adds backbone geometry via ProteinMPNN. Measurably better than sequence alone, and it costs more — use it on a shortlist. |
| `rank_mutations_from_file(path)` | The same, reading your spreadsheet or FASTA directly. |
| `embed(seq)` | Per-residue and mean-pooled ESM-2 embeddings. |
| `humanise(seq)` | Scores an antibody against human and VHH repertoires and proposes substitutions. |
| `balance()` / `services()` / `cost_of(...)` | Credits remaining, what's available, what a run costs before you run it. |

## Three decisions worth knowing about

**Re-running a cell does not charge you twice.** Notebook users re-execute cells
constantly — after a typo, after a kernel restart, while fixing the plot below.
Each of those is a fresh charge against a naive client, and you would not notice
until the balance ran out. Every request is keyed on a hash of its own content,
so an identical call returns the result you already have. Pass `fresh=True` when
you actually mean to run it again.

**Calls block by default.** You want `df = eg.rank_mutations(...)` and the
answer. `eg.submit(...)` returns a `Job` for people who want to fire off twenty
and collect them later, but making that the default turns every notebook into a
polling loop.

**Results come back as DataFrames**, because that is what happens to them next.
pandas is optional — without it you get plain lists rather than an ImportError,
since a client that will not import is a client that fails at the worst moment.

## Reading your own files

`rank_mutations_from_file` reads what a lab actually produces: CSV, TSV, Excel,
FASTA, whatever the column happens to be called, mutations written as `M1C`,
`p.Met1Cys`, `Met1Cys`, `M-1-C` or `1 M->C`.

What it will not do is guess. A DNA-level notation like `c.3A>T` and an antibody
insertion code like `S100aA` are both refused by name, because the confident
wrong answer is worse than the refusal — inferring a protein change from a codon
requires a reading frame you did not supply, and Kabat insertion codes do not
index into a plain sequence. Anything unreadable is reported to you by row and
by reason, never silently dropped:

```python
df = eg.rank_mutations_from_file("variants.xlsx")
#   2 entries could not be read:
#     row 14: 'c.3A>T' - DNA notation; supply the protein-level change
#     row 27: 'S100aA' - antibody insertion code; needs an explicit numbering scheme
#   submitting 46 mutations
```

Excel support needs `pip install excellgen[excel]`. CSV, TSV and FASTA work out
of the box.

## Errors tell you what to do

Every error carries a next step, because a traceback in a notebook is where a
biologist stops and emails us.

```
This run needs 1,200 credits and 340 are available.

  -> Top up at excellgen.com, or reduce the batch size.
```

Failed runs are not billed.

## Your API key

`eg.login()` reads `EXCELLGEN_API_KEY` from the environment. You can pass a key
directly, but prefer the environment variable: notebooks get committed, shared
and pasted into issues far more often than their authors intend, and the key
travels with them.

## Licence

MIT. The client is yours to vendor, fork and modify — only the hosted services
it calls are metered.
