Metadata-Version: 2.4
Name: mlgatee
Version: 0.8.0
Summary: Deploy ML models to MLGatee from a notebook, a script or the terminal.
Author-email: MLGatee <hello@mlgatee.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://mlgatee.com
Project-URL: Documentation, https://mlgatee.com/docs.html
Project-URL: Web app, https://app.mlgatee.com
Keywords: mlops,model-deployment,model-serving,machine-learning,inference,api
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: joblib; extra == "dev"
Requires-Dist: numpy; extra == "dev"
Requires-Dist: pandas; extra == "dev"
Requires-Dist: scikit-learn; extra == "dev"
Provides-Extra: tensorflow
Requires-Dist: tensorflow; extra == "tensorflow"
Requires-Dist: ai-edge-litert; extra == "tensorflow"
Provides-Extra: torch
Requires-Dist: torch; extra == "torch"
Requires-Dist: onnx; extra == "torch"
Requires-Dist: onnxscript; extra == "torch"
Requires-Dist: onnxruntime; extra == "torch"
Provides-Extra: huggingface
Requires-Dist: transformers; extra == "huggingface"
Requires-Dist: torch; extra == "huggingface"
Requires-Dist: onnx; extra == "huggingface"
Requires-Dist: onnxruntime; extra == "huggingface"
Dynamic: license-file

# mlgatee

Deploy a trained model to [MLGatee](https://app.mlgatee.com) from a notebook, a script or
the terminal, and get a live, key-protected HTTPS endpoint.

```python
%pip install -q mlgatee

import mlgatee
mlgatee.login()                                  # paste an access token (hidden)
dep = mlgatee.deploy(model, name="churn-model")  # about 1.5 to 3 minutes
dep.predict([[5.1, 3.5, 1.4, 0.2]])
```

```
✓ saved with joblib (3 KB)
✓ uploaded
✓ checked without running it: numpy==2.5.3, scikit-learn==1.9.1

  Endpoint key (shown once, also in .key): mlg_live_…
  Save it somewhere safe: only its last 4 characters are kept.

… Installing libraries and downloading the model
… Starting the model server and loading the model
✓ live at https://mlg-churn-model-….onrender.com
```

Get an access token on **app.mlgatee.com → Settings → Access tokens**. MLGatee is
invite-only during the beta.

## How it works

The model is saved with `joblib` **in your own Python**, then goes through exactly the same
steps as an upload on the web app: MLGatee reads the file's bytes (it never runs your code),
picks the exact libraries, and gives the model its own server on Render.

**Deploying the same name again uploads a new version**: same address, same key. The current
version keeps answering until the new one is live; if the new build fails, it keeps answering.

**Rolling back** builds a new version from an earlier version's file: rolling v3 back to v2
creates v4 with v2's file. The 3 newest versions can be rolled back to.

## Python

| Call | What it does |
|---|---|
| `mlgatee.login(token=None, save=True)` | Signs in. Without `token` it asks (hidden). `save=True` keeps it in `~/.mlgatee/token`, readable only by you; use `save=False` on a shared computer. `MLGATEE_TOKEN` works too |
| `mlgatee.deploy(model, name)` | A model object or a file path (`.pkl`, `.joblib`, XGBoost `.json`/`.ubj`, `.onnx`, TensorFlow Lite `.tflite`). Returns a `Deployment` |
| `dep.predict(rows)` / `dep.predict_proba(rows)` | Calls the model. Rows can be lists, a NumPy array or a pandas DataFrame |
| `mlgatee.predict(name_or_url, rows, key=None)` | Same, by name or endpoint URL. The key comes from `key`, this session's `deploy()`, or `MLGATEE_KEY` |
| `mlgatee.models()` | Your models |
| `mlgatee.versions(name)` | A model's versions, newest first, with `current` and `can_roll_back` |
| `mlgatee.rollback(name, version)` | Back to an earlier version (one build); same address and key |
| `mlgatee.plan()` | Your plan (free or Pro), its limits, what you've used, and the machines you can deploy on |
| `mlgatee.deploy(model, name, plan="standard")` | Pro: a new model on an always-on machine, `"starter"` (512 MB) or `"standard"` (2 GB). A new version keeps the machine |
| `mlgatee.resume(name)` | Starts a Pro model that was paused after 48 hours without calls; same address and key, no build |
| `mlgatee.delete(name)` | Deletes a model and its endpoint (can't be undone) |
| `mlgatee.logout()` | Forgets the token here (revoke it on the web app to stop it everywhere) |

Errors are `mlgatee.MLGateeError` with a plain message and a stable `.code`.

## Terminal

```bash
pip install mlgatee
mlgatee login
mlgatee deploy model.pkl --name churn-model
mlgatee models
mlgatee versions churn-model
mlgatee rollback churn-model 2
mlgatee plan
mlgatee resume churn-model
mlgatee delete churn-model --yes
```

## Monitoring

```python
mlgatee.usage("churn-model")              # last 24 hours; "7d" for a week
print(mlgatee.usage_text(mlgatee.usage("churn-model")))
dep.usage()                               # the same, from a Deployment
```

```bash
mlgatee usage churn-model --window 7d
```

Calls, errors (bad requests and server errors), answer times (p50, p95, max), rows
predicted and when the model was last called, overall and per version: handy before
deciding on a rollback. MLGatee records counts and timings only, never inputs or outputs.
A model deployed before monitoring existed starts reporting after its next build.

## Keras and PyTorch

Pass the model itself: it's converted here, in your Python, to a format MLGatee's free
machines run (TensorFlow Lite for Keras, ONNX for PyTorch), checked against the original,
then uploaded.

```python
mlgatee.deploy(keras_model, name="my-keras-model")                      # -> TensorFlow Lite
mlgatee.deploy(keras_model, name="my-keras-model", quantize=True)       # 8-bit weights, ~4x smaller
mlgatee.deploy(torch_model, name="my-torch-model", example_input=X[:5], task="classifier")  # -> ONNX
```

- Keras needs TensorFlow (the backend you trained with), PyTorch needs `torch` and `onnx`
  (`pip install "mlgatee[torch]"` installs the extras). With `example_input`, the converted
  model is compared with the original before uploading (needs `ai-edge-litert` / `onnxruntime`).
- `task="classifier"`: /predict returns the class and /predict_proba the probabilities
  (softmax of the scores). Without it, the model's outputs are returned as they are.
- Custom or Lambda layers, and operations TFLite/ONNX don't have, are refused with the
  converter's own message. Full TensorFlow and PyTorch will come on the paid plan.
- Already have a file? `mlgatee.deploy("model.tflite", ...)` or `"model.onnx"` works too.

## Hugging Face text models

Small text models (MiniLM-sized: up to about 25 MB with 8-bit weights) run on the free plan:

```python
mlgatee.deploy_hf("sentence-transformers/all-MiniLM-L6-v2", name="embeddings")
mlgatee.deploy_hf("philschmid/tiny-bert-sst2-distilled", name="sentiment")
```

Callers send plain texts: `{"input_data": ["great product!"]}`. A classifier answers label
names (and `/predict_proba` the probabilities); an embeddings model answers one normalised
vector per text. The model is exported to ONNX here, with 8-bit weights, checked against the
original, and packed with its tokenizer into one file (`pip install "mlgatee[huggingface]"`).
Bigger models (DistilBERT and up) don't fit the 50 MB limit; text generation comes later.

## Good to know

- Supported during the beta: scikit-learn, XGBoost, LightGBM and CatBoost, up to 50 MB, one
  model per person, 5 builds a day.
- A model that uses a class defined in your notebook can't be loaded on a server. The client
  catches this before uploading and says which class to move into a `.py` file.
- The endpoint key is shown once. Keep it out of notebooks you share.
- The free instance sleeps after 15 idle minutes; the next request takes about a minute.

## Development

```bash
pip install -e ".[dev]"
python -m pytest -q
```

Self-hosting MLGatee? Point the client at your project with `MLGATEE_URL` and
`MLGATEE_PUBLISHABLE_KEY`.

Apache-2.0.
