Metadata-Version: 2.4
Name: orcamonitor
Version: 1.0.0
Summary: OrcaMonitor license verification SDK for on-premise deployments
License: Proprietary
Project-URL: Homepage, https://orcamonitor.com
Project-URL: Documentation, https://docs.orcamonitor.com
Keywords: orcamonitor,license,on-premise
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# OrcaMonitor Python SDK

License verification SDK for OrcaMonitor on-premise Docker deployments.

Your source code stays inside your Docker image. The SDK only makes an outbound HTTPS call to the OrcaMonitor license server — nothing from your codebase is ever transmitted.

---

## Installation

**From your private registry (recommended for customers):**
```bash
pip install orcamonitor==1.0.0 --index-url https://pypi.orcamonitor.com
```

**During development (local wheel):**
```bash
pip install /path/to/sdk/python/
```

---

## Quick Start

```python
from orcamonitor import LicenseClient
from orcamonitor.exceptions import OrcaLicenseError

client = LicenseClient()        # reads ORCA_LICENSE_KEY + ORCA_API_URL from env
client.verify_on_startup()      # exits / raises if license is invalid
client.start_background_checks()

# Feature gating anywhere in your code
if client.feature("ai_remediation"):
    run_ai_engine()

if client.feature("ha_mode"):
    start_ha_cluster()
```

---

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| `ORCA_LICENSE_KEY` | ✅ | License key issued by OrcaMonitor (e.g. `OM-ENTA-2025-A1B2`) |
| `ORCA_API_URL` | ✅ | Base URL of the OrcaMonitor API (`https://api.orcamonitor.com`) |
| `ORCA_CACHE_PATH` | ❌ | Override cache file path (default: `/var/cache/orcamonitor/license.json`) |

---

## Docker Usage

### 1. Dockerfile

```dockerfile
FROM python:3.12-slim

# Install the SDK
RUN pip install orcamonitor==1.0.0 --index-url https://pypi.orcamonitor.com

# Create cache directory (persisted via volume for faster restarts)
RUN mkdir -p /var/cache/orcamonitor

# Your app code
COPY . /app
WORKDIR /app

# Entrypoint verifies license before starting your app
COPY entrypoint.py /app/entrypoint.py
ENTRYPOINT ["python", "/app/entrypoint.py"]
```

### 2. entrypoint.py (copy into your image)

```python
import sys
from orcamonitor import LicenseClient
from orcamonitor.exceptions import OrcaLicenseError

def get_device_count():
    # Return your actual device count here
    return 42

client = LicenseClient(device_count_fn=get_device_count)

try:
    client.verify_on_startup()
except OrcaLicenseError as e:
    print(f"LICENSE ERROR: {e}")
    sys.exit(1)

client.start_background_checks()

# Start your real app
import your_main_module
your_main_module.run()
```

### 3. docker-compose.yml

```yaml
services:
  your-app:
    image: your-app:latest
    environment:
      ORCA_LICENSE_KEY: "OM-ENTA-2025-XXXX"
      ORCA_API_URL: "https://api.orcamonitor.com"
    volumes:
      - orca_cache:/var/cache/orcamonitor   # persist cache across restarts
    restart: unless-stopped

volumes:
  orca_cache:
```

---

## Behaviour Reference

### On Startup (`verify_on_startup`)

| Scenario | Result |
|---|---|
| License valid | Returns `LicenseStatus`, app starts normally |
| License expired | Raises `LicenseInvalid` → container exits 1 |
| License suspended | Raises `LicenseInvalid` → container exits 1 |
| Key not found | Raises `LicenseNotFound` → container exits 1 |
| Device count exceeded | Raises `DeviceLimitExceeded` → container exits 1 |
| Server unreachable + cache fresh | Uses cache, logs warning, app starts |
| Server unreachable + no cache | Raises `LicenseServerUnreachable` → exits 1 |
| Server unreachable + cache expired | Raises `GracePeriodExpired` → exits 1 |

### Background Checks

- Re-verifies every **24 hours** by default (configurable via `check_interval_hours`)
- On failure: logs a warning, continues running on last known status
- Calls `on_warning` callback when license is about to expire (≤ 30 days)

### Grace Period

If the license server is temporarily unreachable, the SDK uses the locally cached result for up to **72 hours** (configurable via `grace_period_hours`). After that, the next background check will call `on_warning` but will not stop the app mid-run — only `verify_on_startup` is strict.

---

## Feature Flags

```python
client.feature("ai_remediation")  # or "aiRemediation"
client.feature("ha_mode")         # or "haMode"
client.feature("multi_site")      # or "multiSite"
client.feature("audit_log")       # or "auditLog"
client.feature("api_access")      # or "apiAccess"
client.feature("sso_ldap")        # or "ssoLdap"
client.feature("custom_runbooks") # or "customRunbooks"
```

---

## Full API

```python
LicenseClient(
    license_key        = None,    # str — defaults to ORCA_LICENSE_KEY env var
    api_url            = None,    # str — defaults to ORCA_API_URL env var
    device_count_fn    = None,    # callable () -> int
    grace_period_hours = 72.0,    # float
    check_interval_hours = 24.0,  # float
    cache_path         = None,    # pathlib.Path
    on_warning         = None,    # callable (str) -> None
)
```

---

## Security Notes

- The license key is transmitted over HTTPS only.
- No application source code, data, or internal metrics are sent — only the license key and optional device count.
- The cache file contains only license metadata (edition, features, expiry). Protect it with appropriate file permissions (`chmod 600`).
- For air-gapped environments, contact OrcaMonitor for an offline license option.
