Metadata-Version: 2.4
Name: keyright
Version: 1.1.4
Summary: Keyright Python client SDK — offline/online software license validation and entitlements.
Author: Delta1 Labs
License-Expression: Apache-2.0
Project-URL: Homepage, https://delta1labs.com
Keywords: licensing,entitlements,license,keyright
Classifier: Programming Language :: Python :: 3
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=41
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Dynamic: license-file

# keyright (Python)

Python client SDK for [Keyright](https://delta1labs.com) — offline and online software-license validation with
full parity to the .NET reference client and the language-independent spec (`docs/license-format.md`).

## Install
```
pip install keyright
```

## Offline validation (full client)
```python
from keyright import KeyrightClient, KeyrightOptions

client = KeyrightClient.initialize(KeyrightOptions(
    product="nebula",
    public_key_base64=EMBEDDED_PUBLIC_KEY,          # base64 SubjectPublicKeyInfo
    # optional: additional_public_keys_base64=[...],  key rotation (FR-22)
    # optional: revocation_list_json=...,             offline revocation (FR-44)
))

info, source = client.validate()
if info.is_valid:
    print(info.status_badge, info.entitlements.is_enabled("advanced"))
```

Features: license-source precedence (explicit string/file, `KEYRIGHT_LICENSE` env, config, default path),
node-locking (FR-31/32), entitlements (FR-60, `is_enabled`/`get_limit`), key rotation (FR-22), offline
revocation lists (FR-44), trials from first activation + clock-tamper detection (FR-50/52), and localized
messages (`message(verdict, locale)`).

## Online activation
```python
info = client.activate("LIC-....")   # verifies + caches a signed lease; offline until the grace window ends
```

## Stateless verify (no node-lock/state)
```python
from keyright import verify, message
verdict = verify(license_dict, public_key_b64, expected_product="nebula")  # "valid" | "expired" | ...
print(message(verdict, "fr"))
```

## CLI
```
keyright-verify <license.json> <pubkey-b64-file> <now-iso> [product] [locale]
```
