Metadata-Version: 2.4
Name: serva
Version: 0.3.0
Summary: Official Python client for the Serva encode/decode API
Author: Servamind
License: Proprietary - All Rights Reserved
Project-URL: Homepage, https://serva.servamind.com
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: huggingface_hub>=0.20
Requires-Dist: torch>=2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Dynamic: license-file

# serva

Python client for the Serva encode/decode API. Encode files into the `.serva`
format, decode them back, push datasets to the Hugging Face Hub, and load them
into PyTorch.

## Install

```bash
pip install serva
```

Grab an API key from [serva.servamind.com](https://serva.servamind.com) and pass
it to the client or set `SERVA_API_KEY`.

## Encode and decode

```python
from serva import Serva

client = Serva(api_key="sk_live_...")   # or set SERVA_API_KEY

result = client.encode("photo.raw", password="my-secret")
print(result.output_path, result.savings_percent)

client.decode("photo.serva", password="my-secret", output="photo.raw")
```

You decode with the same password you encoded with.

## Hugging Face

Push encoded datasets to the Hub and pull them back. Set `HF_TOKEN` or pass
`hf_token=...`; nothing extra to install.

```python
result = client.encode("photo.raw", password="my-secret")
client.hub.push(result, repo_id="your-name/my-dataset")

path = client.hub.pull("your-name/my-dataset", "photo.serva")
client.decode(path, password="my-secret", output="photo.raw")
```

## PyTorch

`ServaDataset` reads a folder of `.serva` files and returns each file's raw bytes
as a tensor, the model trains on the encoded bytes. Point it at a
directory, like `torchvision`'s `ImageFolder`.

```python
from serva.torch import ServaDataset
from torch.utils.data import DataLoader

ds = ServaDataset("data/train")
loader = DataLoader(ds, batch_size=32, shuffle=True)

for batch in loader:
    ...   # your model, your training step
```

The folder layout decides what you get:

- **Class subfolders** (`ants/*.serva`, `bees/*.serva`) → `(tensor, label)`.
- **A flat folder** → just the tensor, for text or other unlabeled data.

Use `label_fn` when labels aren't in folder names (a CSV lookup, a regression
target):

```python
ds = ServaDataset("data/train", label_fn=lambda path: scores[path.stem])
```

By default files are padded to a fixed length so batches stack. To keep every
byte and avoid padding side effects, use `length=None` with `pad_collate` it
pads each batch only to its longest file and returns a mask marking real bytes,
so the model ignores the padding:

```python
from serva.torch import ServaDataset, pad_collate

ds = ServaDataset("data/train", length=None)
loader = DataLoader(ds, batch_size=32, collate_fn=pad_collate)

for bytes, mask, labels in loader:
    ...   # pass mask to your model so padded positions are ignored
```

`ServaDataset` only turns `.serva` files into tensors. Reshaping is plain PyTorch 
that's what `transform` and the DataLoader's `collate_fn` are for.

## Configuration

| Setting | How | Default |
|---|---|---|
| API key | `Serva(api_key=...)` or `SERVA_API_KEY` | — (required) |
| Base URL | `Serva(base_url=...)` | production API |
| Hugging Face token | `Serva(hf_token=...)` or `HF_TOKEN` | — |

## Errors

Everything raises a subclass of `ServaError`: `AuthError` (401),
`PaymentRequiredError` (403), `FileTooLargeError` (413), `RateLimitError` (429),
and `HubError` for a failed Hugging Face operation.

## Versioning

Semantic versioning. Read the installed version from `serva.__version__`.
