Metadata-Version: 2.4
Name: octomil-sdk
Version: 2.5.2
Summary: Octomil — serve, deploy, and observe ML models on edge devices
Home-page: https://github.com/octomil/octomil-python
Author: Octomil
Author-email: team@octomil.com
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2.0.0
Requires-Dist: psutil>=5.9.0
Requires-Dist: httpx>=0.24.0
Requires-Dist: click>=8.0.0
Requires-Dist: pandas>=1.5.0
Requires-Dist: pyarrow>=10.0.0
Requires-Dist: qrcode[pil]>=7.0
Requires-Dist: huggingface_hub>=0.20.0
Requires-Dist: mlx-lm>=0.10.0; sys_platform == "darwin" and platform_machine == "arm64"
Requires-Dist: llama-cpp-python>=0.2.0; sys_platform != "darwin" or platform_machine != "arm64"
Provides-Extra: serve
Requires-Dist: fastapi>=0.100.0; extra == "serve"
Requires-Dist: uvicorn[standard]>=0.20.0; extra == "serve"
Provides-Extra: mlx
Requires-Dist: mlx-lm>=0.10.0; extra == "mlx"
Provides-Extra: llama
Requires-Dist: llama-cpp-python>=0.2.0; extra == "llama"
Provides-Extra: onnx
Requires-Dist: onnxruntime>=1.16.0; extra == "onnx"
Provides-Extra: whisper
Requires-Dist: pywhispercpp>=1.0.0; extra == "whisper"
Provides-Extra: ml
Requires-Dist: torch>=2.0.0; extra == "ml"
Requires-Dist: numpy>=1.24.0; extra == "ml"
Requires-Dist: pandas>=1.5.0; extra == "ml"
Provides-Extra: secagg
Requires-Dist: cryptography>=41.0.0; extra == "secagg"
Provides-Extra: test
Requires-Dist: pytest>=7.0.0; extra == "test"
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
Requires-Dist: torch>=2.0.0; extra == "test"
Requires-Dist: numpy>=1.24.0; extra == "test"
Requires-Dist: pandas>=1.5.0; extra == "test"
Requires-Dist: keyring>=23.0.0; extra == "test"
Requires-Dist: cryptography>=41.0.0; extra == "test"
Requires-Dist: fastapi>=0.100.0; extra == "test"
Requires-Dist: uvicorn[standard]>=0.20.0; extra == "test"
Requires-Dist: flwr-datasets>=0.3.0; extra == "test"
Provides-Extra: interactive
Requires-Dist: prompt_toolkit>=3.0.0; extra == "interactive"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: torch>=2.0.0; extra == "dev"
Requires-Dist: numpy>=1.24.0; extra == "dev"
Requires-Dist: pandas>=1.5.0; extra == "dev"
Requires-Dist: keyring>=23.0.0; extra == "dev"
Requires-Dist: cryptography>=41.0.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: fastapi>=0.100.0; extra == "dev"
Requires-Dist: uvicorn[standard]>=0.20.0; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

<p align="center">
  <strong>Octomil</strong><br>
  On-device AI inference. Deploy, route, observe.
</p>

<p align="center">
  <a href="https://github.com/octomil/octomil-python/actions/workflows/ci.yml"><img src="https://github.com/octomil/octomil-python/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <a href="https://pypi.org/project/octomil-sdk/"><img src="https://img.shields.io/pypi/v/octomil-sdk.svg" alt="PyPI"></a>
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT"></a>
</p>

---

## Install

```bash
pip install octomil-sdk
```

## Quick Start

Serve a model locally with an OpenAI-compatible API:

```bash
octomil serve gemma-1b
```

```bash
curl http://localhost:8080/v1/chat/completions \
  -d '{"model": "gemma-1b", "messages": [{"role": "user", "content": "Hello"}]}'
```

## SDK Usage

```python
from octomil import Octomil

client = Octomil(api_key="oct_...", org_id="org_123")

# Register a model
model = client.registry.ensure_model(name="sentiment", framework="pytorch")

# Gradual rollout
client.rollouts.create(model_id=model["id"], version="1.0.0", rollout_percentage=10)

# A/B test
client.experiments.create(name="v1-vs-v2", model_id=model["id"],
                          control_version="1.0.0", treatment_version="1.1.0")
```

## CLI

| Command                     |                                            |
| --------------------------- | ------------------------------------------ |
| `octomil serve <model>`     | Local inference server (OpenAI-compatible) |
| `octomil pull <model>`      | Download a model                           |
| `octomil push <file>`       | Upload a model                             |
| `octomil deploy <model>`    | Deploy to devices                          |
| `octomil convert <file>`    | Convert to CoreML / TFLite                 |
| `octomil check <file>`      | Validate a model                           |
| `octomil scan <path>`       | Security scan                              |
| `octomil benchmark <model>` | Latency benchmarks                         |
| `octomil login`             | Authenticate                               |

## Federated Learning (Enterprise)

Train across devices without centralizing data:

```python
from octomil import DeviceAuthClient, FederatedClient

auth = DeviceAuthClient(base_url="https://api.octomil.com", org_id="org_123",
                        device_identifier="runtime-001")
await auth.bootstrap(bootstrap_bearer_token=token)

client = FederatedClient(auth_token_provider=lambda: auth.get_access_token_sync(),
                         org_id="org_123")
client.register()

assignment = client.get_round_assignment()
if assignment:
    client.participate_in_round(round_id=assignment["round_id"],
                                local_train_fn=my_train_fn)
```

## Documentation

[docs.octomil.com/sdks/python](https://docs.octomil.com/sdks/python)

## Releasing

Releases are managed with [Knope](https://knope.tech). From `main`:

```bash
knope release              # bumps versions, generates changelog, opens a PR
# merge the PR, then:
git pull origin main
knope release-pr-merged    # creates GitHub release + tag → triggers PyPI publish
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

## License

[MIT](LICENSE)
