Metadata-Version: 2.1
Name: colabhive
Version: 0.9.2
Summary: Official Python SDK and CLI for ColabHive: inference, fine-tuning and coding agents
Author-email: ColabHive Team <support@colabhive.com>
License: MIT
Project-URL: Homepage, https://colabhive.com
Project-URL: Documentation, https://docs.colabhive.com
Project-URL: Coding agents, https://docs.colabhive.com/guides/agents/quickstart
Project-URL: Changelog, https://docs.colabhive.com/sdk/
Keywords: machine-learning,ml,ai,training,inference,colabhive
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"

# ColabHive Python SDK

Official Python client and command line for ColabHive: inference, fine-tuning and model operations
on the GPU and CPU infrastructure you use through ColabHive.

## Coding agents in one command

The package installs a `colabhive` command that configures [OpenCode](https://opencode.ai) against
ColabHive. It picks a model that is serving now, checks with a real request that it returns tool
calls, and writes the OpenCode provider without putting your API key in the file.

```bash
pip install -U colabhive
export COLABHIVE_API_KEY='hive_...'     # create one at https://console.colabhive.com/builder/settings/api-keys
colabhive agents init                  # picks, checks and configures a model
colabhive agents doctor                # re-checks the configured model end to end
```

Guide: https://docs.colabhive.com/guides/agents/quickstart

## Installation

```bash
pip install -U colabhive
```

## Quick Start

```python
from colabhive import ColabHive

# Initialize client
client = ColabHive(
    api_key="your_api_key_here",
    account_id="your_account_id_here"
)

# Upload dataset
dataset = client.datasets.upload(
    name="my_training_data",
    file="./data.csv"
)
print(f"Dataset uploaded: {dataset.id}")

# Train model
job = client.training.create(
    model="xgboost-regression",
    dataset_id=dataset.id,
    job_name="My First Model"
)
print(f"Training started: {job.id}")

# Wait for completion
job.wait()

if job.status == "completed":
    print("Training complete!")
    print(f"Metrics: {job.metrics}")
else:
    print(f"Training failed: {job.error_message}")
```

## Authentication

Create an API key in the Console under
[Settings → API Keys](https://console.colabhive.com/builder/settings/api-keys) (sign in with Google).
Keys start with `hive_`. The Python client also takes your account ID, shown in the Console.

```python
client = ColabHive(
    api_key="hive_...",
    account_id="<your-account-id>"
)
```

## Features

### Account preferences (since 0.9.1)

Share Hive spare-capacity lending is disabled by default. Any authenticated
account member can read the effective preference; the Builder API accepts a
change only from the account owner.

```python
current = client.accounts.get_preferences()
client.accounts.set_share_hive_opt_in(True)
client.accounts.set_share_hive_opt_in(False)  # opt out again
```

The authenticated credential selects the account; these methods do not accept
an account ID override.

### Datasets

```python
# Upload
dataset = client.datasets.upload(name="data", file="./train.csv")

# List
datasets = client.datasets.list(limit=10)

# Get
dataset = client.datasets.get("dataset-id")

# Delete
client.datasets.delete("dataset-id")
```

### Training

```python
# Create training job
job = client.training.create(
    model="xgboost-regression",
    dataset_id="dataset-id",
    job_name="Experiment 1",
    hyperparameters={
        "n_estimators": 100,
        "max_depth": 6
    }
)

# List jobs
jobs = client.training.list(limit=10, status="running")

# Get job
job = client.training.get("run-id")

# Wait for completion
job.wait(poll_interval=5, timeout=3600, verbose=True)

# Get metrics
metrics = job.metrics
print(metrics)

# Delete job
client.training.delete("run-id")
```

### Models

```python
# List models
models = client.models.list()

# Get model
model = client.models.get("model-id")

# Download model
path = client.models.download("model-id", "./my_model.pkl")

# Delete model
client.models.delete("model-id")
```

### Model Configurations

```python
# List available model configs
configs = client.training.model_configs(category="ml_classical")

for config in configs:
    print(config.model_name, config.display_name)
    print(config.default_hyperparameters)
```

### Endpoint scaling (0.7.1+)

Scale-to-zero remains the default. Use an explicit minimum policy when an
endpoint must keep replicas resident. An endpoint declares how many replicas
stay resident, never on which nodes: `required_node_ids` was retired on
2026-09-19 and a non-empty value is rejected with `422`.

```python
client.endpoints.set_scaling(
    "endpoint-id",
    scaling_mode="minimum",
    min_replicas=2,
    max_replicas=4,
)
```

Classic submissions support durable retry identity since 0.9.1. Store one UUID per logical model
call and reuse it only when retrying that same input:

```python
from uuid import uuid4

submission = client.endpoints.infer(
    "endpoint-id",
    {"messages": [{"role": "user", "content": "Hello"}]},
    sync=False,
    idempotency_key=str(uuid4()),
)
task_id = submission["task_id"]
```

### Cohort Latent Fabric (0.7.0+)

Cohort execution is additive, production-deployed and hidden unless the authenticated
account and causal/autoregressive LLM endpoint both pass capability checks. Classic
inference is unchanged when `execution` is omitted. Always preflight the specific
endpoint before opting in:

```python
from threading import Event

endpoint_id = "00000000-0000-4000-8000-000000000001"
client.cohorts.require_available(endpoint_id)

accepted = client.cohorts.run(
    endpoint_id=endpoint_id,
    input_data={"text": "bounded input"},
    execution={
        "mode": "cohort",
        "fallback": "single",
        "latency_budget_ms": 30_000,
        "cost_budget_credits": 1.0,
    },
    idempotency_key="unique-request-key",
)

stop = Event()
for event in client.cohorts.iter_events(
    accepted.task_id,
    follow=True,
    timeout=300,
    cancel_event=stop,
):
    print(event.type)

summary = client.cohorts.wait(accepted.task_id, timeout=300)
```

The follow iterator resumes by cursor, deduplicates reconnect overlap, retries
transient 429/5xx responses and remains bounded by timeout or cancellation. Public
models expose only redacted lifecycle, aggregate latency/cost and the terminal
answer; intermediate tensors are never SDK responses.

## Advanced Usage

### Context Manager

```python
with ColabHive(api_key="...", account_id="...") as client:
    dataset = client.datasets.upload("data", "./train.csv")
    job = client.training.create("xgboost-regression", dataset.id)
    job.wait()
```

### Custom Base URL

```python
# For production
client = ColabHive(
    api_key="...",
    account_id="...",
    base_url="https://api.colabhive.com"
)

# For local development
client = ColabHive(
    api_key="...",
    account_id="...",
    base_url="http://localhost:8014"
)
```

### Error Handling

```python
from colabhive import (
    APIError,
    ColabHive,
    ConflictError,
    NotFoundError,
    RateLimitError,
    ValidationError,
)

client = ColabHive(api_key="...", account_id="...")

try:
    dataset = client.datasets.upload("data", "./nonexistent.csv")
except ValidationError as e:
    print(f"Invalid request: {e.message}")
except NotFoundError as e:
    print(f"Not found: {e.message}")
except APIError as e:
    print(f"API error: {e.message} (status: {e.status_code})")
```

`ConflictError`, `ValidationError`, `RateLimitError` and `APIError` represent
409, 400/422, 429 and 5xx responses respectively.

## Requirements

- Python 3.8+
- httpx >= 0.24.0
- pydantic >= 2.0.0

## Documentation

- [Full Documentation](https://docs.colabhive.com)
- [API Reference](https://docs.colabhive.com/api)
- [Examples](https://docs.colabhive.com/examples)

## Support

- **Email**: support@colabhive.com
- **Documentation**: [docs.colabhive.com](https://docs.colabhive.com)

## License

MIT License - see [LICENSE](LICENSE) file for details.
