Metadata-Version: 2.4
Name: cyberlicensing
Version: 0.2.5
Summary: Client and manager helpers for CyberLicensing
Author-email: CyberLicensing <me@showdown.boo>
Project-URL: Homepage, https://licensing.showdown.boo/
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.31.0

# CyberLicensing Python SDK

Utilities for integrating with the CyberLicensing service.

## Installation

For now, install directly from the project root:

```bash
pip install cyberlicensing
```

## Client-side usage

```python
from cyberlicensing import LicenseClient

client = LicenseClient(
    base_url="https://licensing.showdown.boo",
    project_id=1,
)
result = client.validate_with_environment("LICENSE-KEY-1234")
print(result)
```

`validate_with_environment` automatically gathers HWID/IP metadata and sends it along with the required `project_id`. Use `validate_license` if you want to provide your own context.

The request body sent to the public endpoint `/api/validate_license` is compatible with the API contract:

```json
{
  "project_id": 1,
  "key": "LICENSE-KEY-1234",
  "hwid": "unique-hardware-id",
  "metadata": {
    "plan": "enterprise",
    "seats": 10
  }
}
```

### Client-editable metadata

Project managers can flag metadata fields as `client_editable` in the schema so that end-users can modify a limited subset of fields from the public client. Only those fields are accepted when calling `LicenseClient.validate_license(..., metadata=...)` or the dedicated helper `LicenseClient.update_client_metadata`.

Example workflow:

1. A project manager defines the schema field and marks it as client-editable.
2. The client application updates the metadata from the end-user device.

```python
from cyberlicensing import ManagerClient, LicenseClient

# Manager side: ensure the metadata schema declares client-editable fields
manager = ManagerClient(base_url="https://licensing.showdown.boo")
manager.authenticate("admin", "password")
manager.update_metadata_schema(
  project_id=1,
  fields=[
    {"name": "notes", "type": "string", "client_editable": True},
  ],
)

# Client side: update metadata for a specific license key
client = LicenseClient(base_url="https://licensing.showdown.boo", project_id=1)
client.update_client_metadata(
  key="CL-XXXX-XXXX",
  metadata={"notes": "Nouvelle machine"},
)
```

## Manager-side usage

```python
from cyberlicensing import ManagerClient

manager = ManagerClient(base_url="https://licensing.showdown.boo")
manager.authenticate("admin", "password")
projects = manager.list_projects()
project_id = projects[0]["id"]
license_data = manager.create_license(
    project_id,
    days_valid=30,
    metadata={"plan": "pro"},
)

# Update or revoke a license
manager.update_license(
    license_id=license_data["id"],
    is_active=False,
    metadata={"plan": "revoked", "notes": "Chargeback"},
)
```

Additional helpers:

- `list_licenses(project_id)` – list all licenses (keys + live metadata and usage counters) for a project
- `create_license(project_id, days_valid=None, metadata=None)` – generate a new license key
- `update_license(license_id, is_active=None, expires_at=None, reset_hwid=False, metadata=None)` – ban/disable, move expiration, reset HWID, or overwrite metadata
- `extend_license(project_id, license_id, days)` – convenience method to push expiration forward
- `delete_license(license_id)` – hard-delete a key

## Environment helpers

```python
from cyberlicensing import collect_environment_metadata

print(collect_environment_metadata())
```

Returns HWID, hostname, LAN IP, and (if available) public IP.
